diff options
Diffstat (limited to 'source/blender')
754 files changed, 21800 insertions, 12725 deletions
diff --git a/source/blender/avi/intern/avi.c b/source/blender/avi/intern/avi.c index a423c874adf..6ea94d3b2f3 100644 --- a/source/blender/avi/intern/avi.c +++ b/source/blender/avi/intern/avi.c @@ -676,7 +676,7 @@ AviError AVI_open_movie(const char *name, AviMovie *movie) * instead of an offset from the movie beginning... this is... * wacky, but we need to handle it. The wacky offset always * starts at movi_offset it seems... so we'll check that. - * Note the the offset needs an extra 4 bytes for some + * Note the offset needs an extra 4 bytes for some * undetermined reason */ if (movie->entries[0].Offset == movie->movi_offset) diff --git a/source/blender/blenfont/BLF_translation.h b/source/blender/blenfont/BLF_translation.h index c11996799ff..b42e6f80022 100644 --- a/source/blender/blenfont/BLF_translation.h +++ b/source/blender/blenfont/BLF_translation.h @@ -163,6 +163,8 @@ const char *BLF_translate_do_new_dataname(const char *msgctxt, const char *msgid #define BLF_I18NCONTEXT_ID_MESH "Mesh" #define BLF_I18NCONTEXT_ID_NODETREE "NodeTree" #define BLF_I18NCONTEXT_ID_OBJECT "Object" +#define BLF_I18NCONTEXT_ID_PAINTCURVE "PaintCurve" +#define BLF_I18NCONTEXT_ID_PALETTE "Palette" #define BLF_I18NCONTEXT_ID_PARTICLESETTINGS "ParticleSettings" #define BLF_I18NCONTEXT_ID_SCENE "Scene" #define BLF_I18NCONTEXT_ID_SCREEN "Screen" @@ -207,11 +209,15 @@ typedef struct BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_LAMP, "id_lamp"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_LIBRARY, "id_library"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_LATTICE, "id_lattice"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MASK, "id_mask"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MATERIAL, "id_material"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_METABALL, "id_metaball"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MESH, "id_mesh"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MOVIECLIP, "id_movieclip"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_NODETREE, "id_nodetree"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_OBJECT, "id_object"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_PAINTCURVE, "id_paintcurve"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_PALETTE, "id_palette"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_PARTICLESETTINGS, "id_particlesettings"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SCENE, "id_scene"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SCREEN, "id_screen"), \ @@ -223,8 +229,6 @@ typedef struct BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_VFONT, "id_vfont"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_WORLD, "id_world"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_WINDOWMANAGER, "id_windowmanager"), \ - BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MOVIECLIP, "id_movieclip"), \ - BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MASK, "id_mask"), \ {NULL, NULL, NULL} \ } diff --git a/source/blender/blenfont/intern/blf_dir.c b/source/blender/blenfont/intern/blf_dir.c index 4a36ae03bed..f493aa9af74 100644 --- a/source/blender/blenfont/intern/blf_dir.c +++ b/source/blender/blenfont/intern/blf_dir.c @@ -103,7 +103,7 @@ char **BLF_dir_get(int *ndir) char *path; int i, count; - count = BLI_countlist(&global_font_dir); + count = BLI_listbase_count(&global_font_dir); if (!count) return NULL; diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index 7978d28a4ef..c65a0825a49 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -262,8 +262,8 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c) g->xoff = -1; g->yoff = -1; bitmap = slot->bitmap; - g->width = bitmap.width; - g->height = bitmap.rows; + g->width = (int)bitmap.width; + g->height = (int)bitmap.rows; if (g->width && g->height) { if (sharp) { diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c index 12d71827136..10614e8ca59 100644 --- a/source/blender/blenfont/intern/blf_lang.c +++ b/source/blender/blenfont/intern/blf_lang.c @@ -42,6 +42,7 @@ #include "BLI_path_util.h" #include "BLI_string.h" +#include "BKE_appdir.h" #include "DNA_userdef_types.h" @@ -79,7 +80,7 @@ static void free_locales(void) static void fill_locales(void) { - const char * const languages_path = BLI_get_folder(BLENDER_DATAFILES, "locale"); + const char * const languages_path = BKE_appdir_folder_id(BLENDER_DATAFILES, "locale"); char languages[FILE_MAX]; LinkNode *lines = NULL, *line; char *str; @@ -187,7 +188,7 @@ EnumPropertyItem *BLF_RNA_lang_enum_properties(void) void BLF_lang_init(void) { #ifdef WITH_INTERNATIONAL - const char * const messagepath = BLI_get_folder(BLENDER_DATAFILES, "locale"); + const char * const messagepath = BKE_appdir_folder_id(BLENDER_DATAFILES, "locale"); if (messagepath) { bl_locale_init(messagepath, TEXT_DOMAIN_NAME); diff --git a/source/blender/blenfont/intern/blf_translation.c b/source/blender/blenfont/intern/blf_translation.c index 150ff1b2107..e7d2c14b16f 100644 --- a/source/blender/blenfont/intern/blf_translation.c +++ b/source/blender/blenfont/intern/blf_translation.c @@ -42,6 +42,8 @@ #include "BLI_path_util.h" #include "BLI_string.h" +#include "BKE_appdir.h" + #include "DNA_userdef_types.h" /* For user settings. */ #include "BPY_extern.h" @@ -62,7 +64,7 @@ unsigned char *BLF_get_unifont(int *r_unifont_size) { #ifdef WITH_INTERNATIONAL if (unifont_ttf == NULL) { - const char * const fontpath = BLI_get_folder(BLENDER_DATAFILES, "fonts"); + const char * const fontpath = BKE_appdir_folder_id(BLENDER_DATAFILES, "fonts"); if (fontpath) { char unifont_path[1024]; @@ -97,7 +99,7 @@ unsigned char *BLF_get_unifont_mono(int *r_unifont_size) { #ifdef WITH_INTERNATIONAL if (unifont_mono_ttf == NULL) { - const char *fontpath = BLI_get_folder(BLENDER_DATAFILES, "fonts"); + const char *fontpath = BKE_appdir_folder_id(BLENDER_DATAFILES, "fonts"); if (fontpath) { char unifont_path[1024]; diff --git a/source/blender/blenfont/intern/blf_util.c b/source/blender/blenfont/intern/blf_util.c index 06309a944e9..cdd81e33b0a 100644 --- a/source/blender/blenfont/intern/blf_util.c +++ b/source/blender/blenfont/intern/blf_util.c @@ -38,7 +38,6 @@ #include "blf_internal.h" #include "BLI_utildefines.h" -#include "BLI_string_utf8.h" unsigned int blf_next_p2(unsigned int x) { diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 229d2fc17cd..da4fcb4eca4 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -147,6 +147,7 @@ typedef int (*DMSetMaterial)(int mat_nr, void *attribs); typedef int (*DMCompareDrawOptions)(void *userData, int cur_index, int next_index); typedef void (*DMSetDrawInterpOptions)(void *userData, int index, float t); typedef DMDrawOption (*DMSetDrawOptions)(void *userData, int index); +typedef DMDrawOption (*DMSetDrawOptionsMappedTex)(void *userData, int origindex, int mat_nr); typedef DMDrawOption (*DMSetDrawOptionsTex)(struct MTFace *tface, const bool has_vcol, int matnr); typedef enum DMDrawFlag { @@ -423,7 +424,7 @@ struct DerivedMesh { * - Drawing options too complicated to enumerate, look at code. */ void (*drawMappedFacesTex)(DerivedMesh *dm, - DMSetDrawOptions setDrawOptions, + DMSetDrawOptionsMappedTex setDrawOptions, DMCompareDrawOptions compareDrawOptions, void *userData, DMDrawFlag uvflag); diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h index e79822daa4d..a5109acfa56 100644 --- a/source/blender/blenkernel/BKE_animsys.h +++ b/source/blender/blenkernel/BKE_animsys.h @@ -106,7 +106,7 @@ void BKE_keyingsets_free(struct ListBase *list); /* ************************************* */ /* Path Fixing API */ -/* Fix all the paths for the the given ID + Action */ +/* Fix all the paths for the given ID + Action */ void BKE_action_fix_paths_rename(struct ID *owner_id, struct bAction *act, const char *prefix, const char *oldName, const char *newName, int oldSubscript, int newSubscript, bool verify_paths); diff --git a/source/blender/blenkernel/BKE_appdir.h b/source/blender/blenkernel/BKE_appdir.h new file mode 100644 index 00000000000..5e42f17be03 --- /dev/null +++ b/source/blender/blenkernel/BKE_appdir.h @@ -0,0 +1,80 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef __BKE_APPDIR_H__ +#define __BKE_APPDIR_H__ + +/** \file BKE_appdir.h + * \ingroup bli + */ + +/* note on naming: typical _get() suffix is omitted here, + * since its the main purpose of the API. */ +const char *BKE_appdir_folder_default(void); +const char *BKE_appdir_folder_id(const int folder_id, const char *subfolder); +const char *BKE_appdir_folder_id_create(const int folder_id, const char *subfolder); +const char *BKE_appdir_folder_id_user_notest(const int folder_id, const char *subfolder); +const char *BKE_appdir_folder_id_version(const int folder_id, const int ver, const bool do_check); + +/* Initialize path to program executable */ +void BKE_appdir_program_path_init(const char *argv0); + +const char *BKE_appdir_program_path(void); +const char *BKE_appdir_program_dir(void); + +/* Initialize path to temporary directory. */ +void BKE_tempdir_init(char *userdir); +void BKE_tempdir_system_init(char *dir); + +const char *BKE_tempdir_base(void); +const char *BKE_tempdir_session(void); +void BKE_tempdir_session_purge(void); + + +/* folder_id */ +enum { + /* general, will find based on user/local/system priority */ + BLENDER_DATAFILES = 2, + + /* user-specific */ + BLENDER_USER_CONFIG = 31, + BLENDER_USER_DATAFILES = 32, + BLENDER_USER_SCRIPTS = 33, + BLENDER_USER_AUTOSAVE = 34, + + /* system */ + BLENDER_SYSTEM_DATAFILES = 52, + BLENDER_SYSTEM_SCRIPTS = 53, + BLENDER_SYSTEM_PYTHON = 54, +}; + +/* for BKE_appdir_folder_id_version only */ +enum { + BLENDER_RESOURCE_PATH_USER = 0, + BLENDER_RESOURCE_PATH_LOCAL = 1, + BLENDER_RESOURCE_PATH_SYSTEM = 2, +}; + +#define BLENDER_STARTUP_FILE "startup.blend" +#define BLENDER_USERPREF_FILE "userpref.blend" +#define BLENDER_QUIT_FILE "quit.blend" +#define BLENDER_BOOKMARK_FILE "bookmarks.txt" +#define BLENDER_HISTORY_FILE "recent-files.txt" + +#endif /* __BKE_APPDIR_H__ */ diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 6c8f90c60ae..8cd4e2584c6 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 272 -#define BLENDER_SUBVERSION 1 +#define BLENDER_SUBVERSION 3 /* 262 was the last editmesh release but it has compatibility code for bmesh data */ #define BLENDER_MINVERSION 270 #define BLENDER_MINSUBVERSION 5 diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index 877e376b343..ae0ef9ce314 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -56,6 +56,9 @@ struct Text; struct ImBuf; struct EditBone; struct bPoseChannel; +struct bGPdata; +struct bGPDlayer; +struct bGPDframe; struct wmWindow; struct wmWindowManager; struct SpaceText; @@ -275,6 +278,14 @@ struct bPoseChannel *CTX_data_active_pose_bone(const bContext *C); int CTX_data_selected_pose_bones(const bContext *C, ListBase *list); int CTX_data_visible_pose_bones(const bContext *C, ListBase *list); +struct bGPdata *CTX_data_gpencil_data(const bContext *C); +struct bGPDlayer *CTX_data_active_gpencil_layer(const bContext *C); +struct bGPDframe *CTX_data_active_gpencil_frame(const bContext *C); +int CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list); +int CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list); +int CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list); + + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 5de7d9936e6..13a1468aee8 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -49,6 +49,7 @@ struct rctf; typedef struct CurveCache { ListBase disp; ListBase bev; + ListBase deformed_nurbs; struct Path *path; } CurveCache; @@ -84,8 +85,8 @@ void BKE_curve_texspace_get(struct Curve *cu, float r_loc[3], float r_rot[3], fl bool BKE_curve_minmax(struct Curve *cu, bool use_radius, float min[3], float max[3]); bool BKE_curve_center_median(struct Curve *cu, float cent[3]); bool BKE_curve_center_bounds(struct Curve *cu, float cent[3]); -void BKE_curve_transform_ex(struct Curve *cu, float mat[4][4], bool do_keys, const float unit_scale); -void BKE_curve_transform(struct Curve *cu, float mat[4][4], bool do_keys); +void BKE_curve_transform_ex(struct Curve *cu, float mat[4][4], const bool do_keys, const float unit_scale); +void BKE_curve_transform(struct Curve *cu, float mat[4][4], const bool do_keys); void BKE_curve_translate(struct Curve *cu, float offset[3], const bool do_keys); void BKE_curve_material_index_remove(struct Curve *cu, int index); void BKE_curve_material_index_clear(struct Curve *cu); diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 9a6524cc9ab..30a58891bda 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -173,6 +173,7 @@ int CustomData_number_of_layers_typemask(const struct CustomData *data, CustomDa /* duplicate data of a layer with flag NOFREE, and remove that flag. * returns the layer data */ void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int type, const int totelem); +void *CustomData_duplicate_referenced_layer_n(struct CustomData *data, const int type, const int n, const int totelem); void *CustomData_duplicate_referenced_layer_named(struct CustomData *data, const int type, const char *name, const int totelem); bool CustomData_is_referenced_layer(struct CustomData *data, int type); @@ -327,6 +328,7 @@ int CustomData_sizeof(int type); /* get the name of a layer type */ const char *CustomData_layertype_name(int type); bool CustomData_layertype_is_singleton(int type); +int CustomData_layertype_layers_max(const int type); /* make sure the name of layer at index is unique */ void CustomData_set_layer_unique_name(struct CustomData *data, int index); diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index c377769b271..83783946d4f 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -44,6 +44,7 @@ struct DriverTarget; struct FCM_EnvelopeData; struct bContext; +struct AnimData; struct bAction; struct BezTriple; struct StructRNA; @@ -224,10 +225,10 @@ int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix, /* find an f-curve based on an rna property. */ struct FCurve *rna_get_fcurve(struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex, - struct bAction **action, bool *r_driven); + struct AnimData **adt, struct bAction **action, bool *r_driven); /* Same as above, but takes a context data, temp hack needed for complex paths like texture ones. */ struct FCurve *rna_get_fcurve_context_ui(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, - int rnaindex, struct bAction **action, bool *r_driven); + int rnaindex, struct AnimData **adt, struct bAction **action, bool *r_driven); /* Binary search algorithm for finding where to 'insert' BezTriple with given frame number. * Returns the index to insert at (data already at that index will be offset if replace is 0) diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h index 86c111653d1..084c5527f21 100644 --- a/source/blender/blenkernel/BKE_gpencil.h +++ b/source/blender/blenkernel/BKE_gpencil.h @@ -35,6 +35,7 @@ struct ListBase; struct bGPdata; struct bGPDlayer; struct bGPDframe; +struct bGPDstroke; /* ------------ Grease-Pencil API ------------------ */ @@ -43,17 +44,15 @@ void free_gpencil_frames(struct bGPDlayer *gpl); void free_gpencil_layers(struct ListBase *list); void BKE_gpencil_free(struct bGPdata *gpd); +void gpencil_stroke_sync_selection(struct bGPDstroke *gps); + struct bGPDframe *gpencil_frame_addnew(struct bGPDlayer *gpl, int cframe); struct bGPDlayer *gpencil_layer_addnew(struct bGPdata *gpd, const char *name, int setactive); struct bGPdata *gpencil_data_addnew(const char name[]); struct bGPDframe *gpencil_frame_duplicate(struct bGPDframe *src); struct bGPDlayer *gpencil_layer_duplicate(struct bGPDlayer *src); -struct bGPdata *gpencil_data_duplicate(struct bGPdata *gpd); - -//struct bGPdata *gpencil_data_getactive(struct ScrArea *sa); -//short gpencil_data_setactive(struct ScrArea *sa, struct bGPdata *gpd); -//struct ScrArea *gpencil_data_findowner(struct bGPdata *gpd); +struct bGPdata *gpencil_data_duplicate(struct bGPdata *gpd, bool internal_copy); void gpencil_frame_delete_laststroke(struct bGPDlayer *gpl, struct bGPDframe *gpf); diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h index 2ab3d84dea5..f33f3eba590 100644 --- a/source/blender/blenkernel/BKE_idprop.h +++ b/source/blender/blenkernel/BKE_idprop.h @@ -41,13 +41,13 @@ typedef union IDPropertyTemplate { double d; struct { char *str; - short len; + int len; char subtype; } string; struct ID *id; struct { - short type; - short len; + int len; + char type; } array; struct { int matvec_size; @@ -91,6 +91,7 @@ void IDP_SyncGroupValues(struct IDProperty *dest, const struct IDProperty *src) void IDP_SyncGroupTypes(struct IDProperty *dest, const struct IDProperty *src, const bool do_arraylen) ATTR_NONNULL(); void IDP_ReplaceGroupInGroup(struct IDProperty *dest, const struct IDProperty *src) ATTR_NONNULL(); void IDP_ReplaceInGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL(); +void IDP_ReplaceInGroup_ex(struct IDProperty *group, struct IDProperty *prop, struct IDProperty *prop_exist); void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overwrite) ATTR_NONNULL(); bool IDP_AddToGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL(); bool IDP_InsertToGroup(struct IDProperty *group, struct IDProperty *previous, @@ -100,9 +101,6 @@ void IDP_FreeFromGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_N IDProperty *IDP_GetPropertyFromGroup(struct IDProperty *prop, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); IDProperty *IDP_GetPropertyTypeFromGroup(struct IDProperty *prop, const char *name, const char type) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -void *IDP_GetGroupIterator(struct IDProperty *prop) ATTR_WARN_UNUSED_RESULT; -IDProperty *IDP_GroupIterNext(void *vself) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -void IDP_FreeIterBeforeEnd(void *vself) ATTR_NONNULL(); /*-------- Main Functions --------*/ struct IDProperty *IDP_GetProperties(struct ID *id, const bool create_if_needed) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); @@ -112,7 +110,7 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is bool IDP_EqualsProperties(struct IDProperty *prop1, struct IDProperty *prop2) ATTR_WARN_UNUSED_RESULT; -struct IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +struct IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); void IDP_FreeProperty(struct IDProperty *prop); diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index dc3d9f38b21..a225a27a00b 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -162,6 +162,7 @@ void BKE_image_alpha_mode_from_extension(struct Image *image); /* returns a new image or NULL if it can't load */ struct Image *BKE_image_load(struct Main *bmain, const char *filepath); /* returns existing Image when filename/type is same (frame optional) */ +struct Image *BKE_image_load_exists_ex(const char *filepath, bool *r_exists); struct Image *BKE_image_load_exists(const char *filepath); /* adds image, adds ibuf, generates color or pattern */ diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index 6183df8666d..31b2c7dc2b9 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -87,15 +87,29 @@ void BKE_key_evaluate_relative(const int start, int end, const int tot, char *ba float **per_keyblock_weights, const int mode); /* conversion functions */ -void BKE_key_convert_to_mesh(struct KeyBlock *kb, struct Mesh *me); -void BKE_key_convert_from_mesh(struct Mesh *me, struct KeyBlock *kb); -void BKE_key_convert_to_lattice(struct KeyBlock *kb, struct Lattice *lt); -void BKE_key_convert_from_lattice(struct Lattice *lt, struct KeyBlock *kb); -void BKE_key_convert_to_curve(struct KeyBlock *kb, struct Curve *cu, struct ListBase *nurb); -void BKE_key_convert_from_curve(struct Curve *cu, struct KeyBlock *kb, struct ListBase *nurb); -float (*BKE_key_convert_to_vertcos(struct Object *ob, struct KeyBlock *kb))[3]; -void BKE_key_convert_from_vertcos(struct Object *ob, struct KeyBlock *kb, float (*vertCos)[3]); -void BKE_key_convert_from_offset(struct Object *ob, struct KeyBlock *kb, float (*ofs)[3]); +/* Note: 'update_from' versions do not (re)allocate mem in kb, while 'convert_from' do. */ +void BKE_keyblock_update_from_lattice(struct Lattice *lt, struct KeyBlock *kb); +void BKE_keyblock_convert_from_lattice(struct Lattice *lt, struct KeyBlock *kb); +void BKE_keyblock_convert_to_lattice(struct KeyBlock *kb, struct Lattice *lt); + +void BKE_keyblock_update_from_curve(struct Curve *cu, struct KeyBlock *kb, struct ListBase *nurb); +void BKE_keyblock_convert_from_curve(struct Curve *cu, struct KeyBlock *kb, struct ListBase *nurb); +void BKE_keyblock_convert_to_curve(struct KeyBlock *kb, struct Curve *cu, struct ListBase *nurb); + +void BKE_keyblock_update_from_mesh(struct Mesh *me, struct KeyBlock *kb); +void BKE_keyblock_convert_from_mesh(struct Mesh *me, struct KeyBlock *kb); +void BKE_keyblock_convert_to_mesh(struct KeyBlock *kb, struct Mesh *me); + +void BKE_keyblock_update_from_vertcos(struct Object *ob, struct KeyBlock *kb, float (*vertCos)[3]); +void BKE_keyblock_convert_from_vertcos(struct Object *ob, struct KeyBlock *kb, float (*vertCos)[3]); +float (*BKE_keyblock_convert_to_vertcos(struct Object *ob, struct KeyBlock *kb))[3]; + +void BKE_keyblock_update_from_offset(struct Object *ob, struct KeyBlock *kb, float (*ofs)[3]); + +/* other management */ +bool BKE_keyblock_move(struct Object *ob, int org_index, int new_index); + +bool BKE_keyblock_is_basis(struct Key *key, const int index); /* key.c */ extern int slurph_opt; diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h index 341105cfdf7..a4aa58e22f1 100644 --- a/source/blender/blenkernel/BKE_movieclip.h +++ b/source/blender/blenkernel/BKE_movieclip.h @@ -46,6 +46,7 @@ void BKE_movieclip_unlink(struct Main *bmain, struct MovieClip *clip); struct MovieClip *BKE_movieclip_file_add(struct Main *bmain, const char *name); void BKE_movieclip_reload(struct MovieClip *clip); void BKE_movieclip_clear_cache(struct MovieClip *clip); +void BKE_movieclip_clear_proxy_cache(struct MovieClip *clip); struct ImBuf *BKE_movieclip_get_ibuf(struct MovieClip *clip, struct MovieClipUser *user); struct ImBuf *BKE_movieclip_get_postprocessed_ibuf(struct MovieClip *clip, struct MovieClipUser *user, int postprocess_flag); diff --git a/source/blender/blenkernel/BKE_object_deform.h b/source/blender/blenkernel/BKE_object_deform.h index 6de7ff9bc1c..0e5ad2d51c8 100644 --- a/source/blender/blenkernel/BKE_object_deform.h +++ b/source/blender/blenkernel/BKE_object_deform.h @@ -29,10 +29,47 @@ * used by painting and tools. */ +#ifdef __cplusplus +extern "C" { +#endif + struct Object; +struct ID; +struct MDeformVert; +struct bDeformGroup; + +/* General vgroup operations */ +void BKE_object_defgroup_remap_update_users(struct Object *ob, int *map); + +bool BKE_object_defgroup_array_get(struct ID *id, struct MDeformVert **dvert_arr, int *dvert_tot); + +struct bDeformGroup *BKE_object_defgroup_add(struct Object *ob); +struct bDeformGroup *BKE_object_defgroup_add_name(struct Object *ob, const char *name); +struct MDeformVert *BKE_object_defgroup_data_create(struct ID *id); + +bool BKE_object_defgroup_clear(struct Object *ob, struct bDeformGroup *dg, const bool use_selection); +bool BKE_object_defgroup_clear_all(struct Object *ob, const bool use_selection); + +void BKE_object_defgroup_remove(struct Object *ob, struct bDeformGroup *defgroup); +void BKE_object_defgroup_remove_all(struct Object *ob); + + +/* Select helpers */ +enum eVGroupSelect; +bool *BKE_object_defgroup_subset_from_select_type( + struct Object *ob, enum eVGroupSelect subset_type, int *r_defgroup_tot, int *r_subset_count); +void BKE_object_defgroup_subset_to_index_array( + const bool *defgroup_validmap, const int defgroup_tot, int *r_defgroup_subset_map); + + +/* ********** */ + +bool *BKE_object_defgroup_lock_flags_get(struct Object *ob, const int defbase_tot); +bool *BKE_object_defgroup_validmap_get(struct Object *ob, const int defbase_tot); +bool *BKE_object_defgroup_selected_get(struct Object *ob, int defbase_tot, int *r_dg_flags_sel_tot); -bool *BKE_objdef_lock_flags_get(struct Object *ob, const int defbase_tot); -bool *BKE_objdef_validmap_get(struct Object *ob, const int defbase_tot); -bool *BKE_objdef_selected_get(struct Object *ob, int defbase_tot, int *r_dg_flags_sel_tot); +#ifdef __cplusplus +} +#endif #endif /* __BKE_OBJECT_DEFORM_H__ */ diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index f84a6378fb3..204fbbf5bfc 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -378,7 +378,7 @@ void free_keyed_keys(struct ParticleSystem *psys); void psys_free_particles(struct ParticleSystem *psys); void psys_free_children(struct ParticleSystem *psys); -void psys_interpolate_particle(short type, struct ParticleKey keys[4], float dt, struct ParticleKey *result, int velocity); +void psys_interpolate_particle(short type, struct ParticleKey keys[4], float dt, struct ParticleKey *result, bool velocity); void psys_vec_rot_to_face(struct DerivedMesh *dm, struct ParticleData *pa, float vec[3]); void psys_mat_hair_to_object(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]); void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]); diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 1bfe0eeea0b..eac4f6a56a5 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -110,7 +110,7 @@ char *BKE_scene_find_marker_name(struct Scene *scene, int frame); char *BKE_scene_find_last_marker_name(struct Scene *scene, int frame); /* checks for cycle, returns 1 if it's all OK */ -int BKE_scene_validate_setscene(struct Main *bmain, struct Scene *sce); +bool BKE_scene_validate_setscene(struct Main *bmain, struct Scene *sce); float BKE_scene_frame_get(struct Scene *scene); float BKE_scene_frame_get_from_ctime(struct Scene *scene, const float frame); @@ -131,7 +131,9 @@ int get_render_shadow_samples(struct RenderData *r, int samples); float get_render_aosss_error(struct RenderData *r, float error); bool BKE_scene_use_new_shading_nodes(struct Scene *scene); + bool BKE_scene_uses_blender_internal(struct Scene *scene); +bool BKE_scene_uses_blender_game(struct Scene *scene); void BKE_scene_disable_color_management(struct Scene *scene); bool BKE_scene_check_color_management_enabled(const struct Scene *scene); diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 13cc5d2e84f..5a0c7ac1ce1 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -217,6 +217,10 @@ void BKE_sequence_clipboard_pointers_free(struct Sequence *seq); void BKE_sequence_clipboard_pointers_store(struct Sequence *seq); void BKE_sequence_clipboard_pointers_restore(struct Sequence *seq, struct Main *bmain); +void BKE_sequencer_base_clipboard_pointers_free(struct ListBase *seqbase); +void BKE_sequencer_base_clipboard_pointers_store(struct ListBase *seqbase); +void BKE_sequencer_base_clipboard_pointers_restore(struct ListBase *seqbase, struct Main *bmain); + void BKE_sequence_free(struct Scene *scene, struct Sequence *seq); const char *BKE_sequence_give_name(struct Sequence *seq); void BKE_sequence_calc(struct Scene *scene, struct Sequence *seq); @@ -308,7 +312,7 @@ void BKE_sequencer_offset_animdata(struct Scene *scene, struct Sequence *seq, in void BKE_sequencer_dupe_animdata(struct Scene *scene, const char *name_src, const char *name_dst); bool BKE_sequence_base_shuffle(struct ListBase *seqbasep, struct Sequence *test, struct Scene *evil_scene); bool BKE_sequence_base_shuffle_time(ListBase *seqbasep, struct Scene *evil_scene); -bool BKE_sequence_base_isolated_sel_check(struct ListBase *seqbase, bool one_only); +bool BKE_sequence_base_isolated_sel_check(struct ListBase *seqbase); void BKE_sequencer_free_imbuf(struct Scene *scene, struct ListBase *seqbasep, bool for_render); struct Sequence *BKE_sequence_dupli_recursive(struct Scene *scene, struct Scene *scene_to, struct Sequence *seq, int dupe_flag); int BKE_sequence_swap(struct Sequence *seq_a, struct Sequence *seq_b, const char **error_str); @@ -326,7 +330,9 @@ void BKE_sequencer_update_sound(struct Scene *scene, struct bSound *sound); void BKE_sequencer_refresh_sound_length(struct Scene *scene); void BKE_sequence_base_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq); -void BKE_sequence_base_dupli_recursive(struct Scene *scene, struct Scene *scene_to, ListBase *nseqbase, ListBase *seqbase, int dupe_flag); +void BKE_sequence_base_dupli_recursive( + struct Scene *scene, struct Scene *scene_to, ListBase *nseqbase, ListBase *seqbase, + int dupe_flag); bool BKE_sequence_is_valid_check(struct Sequence *seq); void BKE_sequencer_clear_scene_in_allseqs(struct Main *bmain, struct Scene *sce); @@ -371,12 +377,23 @@ struct Sequence *BKE_sequence_alloc(ListBase *lb, int cfra, int machine); void BKE_sequence_alpha_mode_from_extension(struct Sequence *seq); void BKE_sequence_init_colorspace(struct Sequence *seq); +/* RNA enums, just to be more readable */ +enum { + SEQ_SIDE_NONE = 0, + SEQ_SIDE_LEFT, + SEQ_SIDE_RIGHT, + SEQ_SIDE_BOTH +}; +int BKE_sequencer_find_next_prev_edit( + struct Scene *scene, int cfra, const short side, + const bool do_skip_mute, const bool do_center, const bool do_unselected); + struct Sequence *BKE_sequencer_add_image_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load); struct Sequence *BKE_sequencer_add_sound_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load); struct Sequence *BKE_sequencer_add_movie_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load); /* view3d draw callback, run when not in background view */ -typedef struct ImBuf *(*SequencerDrawView)(struct Scene *, struct Object *, int, int, unsigned int, int, bool, bool, int, char[256]); +typedef struct ImBuf *(*SequencerDrawView)(struct Scene *, struct Object *, int, int, unsigned int, int, bool, bool, bool, int, char[256]); extern SequencerDrawView sequencer_view3d_cb; /* copy/paste */ diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h index 50ca5fcdf7b..f318c74258b 100644 --- a/source/blender/blenkernel/BKE_sound.h +++ b/source/blender/blenkernel/BKE_sound.h @@ -71,8 +71,6 @@ void sound_delete(struct Main *bmain, struct bSound *sound); void sound_cache(struct bSound *sound); -void sound_cache_notifying(struct Main *main, struct bSound *sound); - void sound_delete_cache(struct bSound *sound); void sound_load(struct Main *main, struct bSound *sound); @@ -132,7 +130,7 @@ int sound_scene_playing(struct Scene *scene); void sound_free_waveform(struct bSound *sound); -void sound_read_waveform(struct bSound *sound); +void sound_read_waveform(struct bSound *sound, bool locked, short *stop); void sound_update_scene(struct Main *bmain, struct Scene *scene); diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 8bc619c1b27..e5fb60cf1b5 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -145,6 +145,9 @@ void BKE_tracking_plane_marker_delete(struct MovieTrackingPlaneTrack *plane_trac struct MovieTrackingPlaneMarker *BKE_tracking_plane_marker_get(struct MovieTrackingPlaneTrack *plane_track, int framenr); struct MovieTrackingPlaneMarker *BKE_tracking_plane_marker_get_exact(struct MovieTrackingPlaneTrack *plane_track, int framenr); struct MovieTrackingPlaneMarker *BKE_tracking_plane_marker_ensure(struct MovieTrackingPlaneTrack *plane_track, int framenr); +void BKE_tracking_plane_marker_get_subframe_corners(struct MovieTrackingPlaneTrack *plane_track, + float framenr, + float corners[4][2]); /* **** Object **** */ struct MovieTrackingObject *BKE_tracking_object_add(struct MovieTracking *tracking, const char *name); @@ -210,16 +213,18 @@ void BKE_tracking_disable_channels(struct ImBuf *ibuf, bool disable_red, bool di bool disable_blue, bool grayscale); /* **** 2D tracking **** */ -struct MovieTrackingContext *BKE_tracking_context_new(struct MovieClip *clip, struct MovieClipUser *user, - const bool backwards, const bool sequence); -void BKE_tracking_context_free(struct MovieTrackingContext *context); -void BKE_tracking_context_sync(struct MovieTrackingContext *context); -void BKE_tracking_context_sync_user(const struct MovieTrackingContext *context, struct MovieClipUser *user); -bool BKE_tracking_context_step(struct MovieTrackingContext *context); -void BKE_tracking_context_finish(struct MovieTrackingContext *context); - void BKE_tracking_refine_marker(struct MovieClip *clip, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, bool backwards); +/* *** 2D auto track *** */ + +struct AutoTrackContext *BKE_autotrack_context_new(struct MovieClip *clip, struct MovieClipUser *user, + const bool backwards, const bool sequence); +bool BKE_autotrack_context_step(struct AutoTrackContext *context); +void BKE_autotrack_context_sync(struct AutoTrackContext *context); +void BKE_autotrack_context_sync_user(struct AutoTrackContext *context, struct MovieClipUser *user); +void BKE_autotrack_context_finish(struct AutoTrackContext *context); +void BKE_autotrack_context_free(struct AutoTrackContext *context); + /* **** Plane tracking **** */ void BKE_tracking_track_plane_from_existing_motion(struct MovieTrackingPlaneTrack *plane_track, int start_frame); diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index f4a3a0c10dd..5850b1614e7 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -37,6 +37,7 @@ set(INC ../modifiers ../nodes ../render/extern/include + ../../../intern/ghost ../../../intern/guardedalloc ../../../intern/glew-mx ../../../intern/iksolver/extern @@ -63,6 +64,7 @@ set(SRC intern/addon.c intern/anim.c intern/anim_sys.c + intern/appdir.c intern/armature.c intern/autoexec.c intern/blender.c @@ -158,6 +160,7 @@ set(SRC intern/text.c intern/texture.c intern/tracking.c + intern/tracking_auto.c intern/tracking_detect.c intern/tracking_plane_tracker.c intern/tracking_region_tracker.c @@ -175,6 +178,7 @@ set(SRC BKE_addon.h BKE_anim.h BKE_animsys.h + BKE_appdir.h BKE_armature.h BKE_autoexec.h BKE_blender.h @@ -273,8 +277,21 @@ set(SRC intern/pbvh_intern.h ) +if(WITH_BINRELOC) + list(APPEND INC_SYS + ${BINRELOC_INCLUDE_DIRS} + ) + add_definitions(-DWITH_BINRELOC) +endif() + add_definitions(${GL_DEFINITIONS}) +if(WIN32) + list(APPEND INC + ../../../intern/utfconv + ) +endif() + if(WITH_AUDASPACE) list(APPEND INC ../../../intern/audaspace/intern diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index 9243c85167b..3da3d647275 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -46,6 +46,7 @@ incs = [ '#/intern/rigidbody', '#/extern/bullet2/src', env['BF_GLEW_INC'], + '#/intern/ghost', '#/intern/glew-mx', '#/intern/audaspace/intern', '#/intern/elbeem/extern', @@ -167,7 +168,11 @@ if env['WITH_BF_FREESTYLE']: if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'): incs += ' ' + env['BF_PTHREADS_INC'] + incs += ' ../../../intern/utfconv' +if env['WITH_BF_BINRELOC']: + incs += ' #extern/binreloc/include' + defs.append('WITH_BINRELOC') if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): env.BlenderLib ( libname = 'bf_blenkernel', sources = sources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [166,25]) #, cc_compileflags = env['CCFLAGS'].append('/WX') ) diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c index 623fb50b62c..9e5d4afffe2 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -172,29 +172,19 @@ static void *_ehash_lookup(EHash *eh, void *key) /**/ -typedef struct _EHashIterator { - EHash *eh; - int curBucket; - EHEntry *curEntry; -} EHashIterator; - -static EHashIterator *_ehashIterator_new(EHash *eh) +static void _ehashIterator_init(EHash *eh, EHashIterator *ehi) { - EHashIterator *ehi = EHASH_alloc(eh, sizeof(*ehi)); + /* fill all members */ ehi->eh = eh; - ehi->curEntry = NULL; ehi->curBucket = -1; + ehi->curEntry = NULL; + while (!ehi->curEntry) { ehi->curBucket++; if (ehi->curBucket == ehi->eh->curSize) break; ehi->curEntry = ehi->eh->buckets[ehi->curBucket]; } - return ehi; -} -static void _ehashIterator_free(EHashIterator *ehi) -{ - EHASH_free(ehi->eh, ehi); } static void *_ehashIterator_getCurrent(EHashIterator *ehi) @@ -3051,17 +3041,17 @@ void *ccgSubSurf_getFaceGridData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int /*** External API iterator functions ***/ -CCGVertIterator *ccgSubSurf_getVertIterator(CCGSubSurf *ss) +void ccgSubSurf_initVertIterator(CCGSubSurf *ss, CCGVertIterator *viter) { - return (CCGVertIterator *) _ehashIterator_new(ss->vMap); + _ehashIterator_init(ss->vMap, viter); } -CCGEdgeIterator *ccgSubSurf_getEdgeIterator(CCGSubSurf *ss) +void ccgSubSurf_initEdgeIterator(CCGSubSurf *ss, CCGEdgeIterator *eiter) { - return (CCGEdgeIterator *) _ehashIterator_new(ss->eMap); + _ehashIterator_init(ss->eMap, eiter); } -CCGFaceIterator *ccgSubSurf_getFaceIterator(CCGSubSurf *ss) +void ccgSubSurf_initFaceIterator(CCGSubSurf *ss, CCGFaceIterator *fiter) { - return (CCGFaceIterator *) _ehashIterator_new(ss->fMap); + _ehashIterator_init(ss->fMap, fiter); } CCGVert *ccgVertIterator_getCurrent(CCGVertIterator *vi) @@ -3076,10 +3066,6 @@ void ccgVertIterator_next(CCGVertIterator *vi) { _ehashIterator_next((EHashIterator *) vi); } -void ccgVertIterator_free(CCGVertIterator *vi) -{ - _ehashIterator_free((EHashIterator *) vi); -} CCGEdge *ccgEdgeIterator_getCurrent(CCGEdgeIterator *vi) { @@ -3093,10 +3079,6 @@ void ccgEdgeIterator_next(CCGEdgeIterator *vi) { _ehashIterator_next((EHashIterator *) vi); } -void ccgEdgeIterator_free(CCGEdgeIterator *vi) -{ - _ehashIterator_free((EHashIterator *) vi); -} CCGFace *ccgFaceIterator_getCurrent(CCGFaceIterator *vi) { @@ -3110,10 +3092,6 @@ void ccgFaceIterator_next(CCGFaceIterator *vi) { _ehashIterator_next((EHashIterator *) vi); } -void ccgFaceIterator_free(CCGFaceIterator *vi) -{ - _ehashIterator_free((EHashIterator *) vi); -} /*** Extern API final vert/edge/face interface ***/ diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h index fdf6d2df99f..2b86a2a66b2 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.h +++ b/source/blender/blenkernel/intern/CCGSubSurf.h @@ -53,6 +53,13 @@ typedef struct CCGAllocatorIFC { void (*release) (CCGAllocatorHDL a); } CCGAllocatorIFC; +/* private, so we can allocate on the stack */ +typedef struct _EHashIterator { + struct _EHash *eh; + int curBucket; + struct _EHEntry *curEntry; +} EHashIterator; + /***/ typedef enum { @@ -163,27 +170,24 @@ int ccgSubSurf_getNumFinalFaces (const CCGSubSurf *ss); /***/ -typedef struct CCGVertIterator CCGVertIterator; -typedef struct CCGEdgeIterator CCGEdgeIterator; -typedef struct CCGFaceIterator CCGFaceIterator; +typedef struct _EHashIterator CCGVertIterator; +typedef struct _EHashIterator CCGEdgeIterator; +typedef struct _EHashIterator CCGFaceIterator; -CCGVertIterator* ccgSubSurf_getVertIterator (CCGSubSurf *ss); -CCGEdgeIterator* ccgSubSurf_getEdgeIterator (CCGSubSurf *ss); -CCGFaceIterator* ccgSubSurf_getFaceIterator (CCGSubSurf *ss); +void ccgSubSurf_initVertIterator(CCGSubSurf *ss, CCGVertIterator *viter); +void ccgSubSurf_initEdgeIterator(CCGSubSurf *ss, CCGEdgeIterator *eiter); +void ccgSubSurf_initFaceIterator(CCGSubSurf *ss, CCGFaceIterator *fiter); CCGVert* ccgVertIterator_getCurrent (CCGVertIterator *vi); int ccgVertIterator_isStopped (CCGVertIterator *vi); void ccgVertIterator_next (CCGVertIterator *vi); -void ccgVertIterator_free (CCGVertIterator *vi); CCGEdge* ccgEdgeIterator_getCurrent (CCGEdgeIterator *ei); int ccgEdgeIterator_isStopped (CCGEdgeIterator *ei); void ccgEdgeIterator_next (CCGEdgeIterator *ei); -void ccgEdgeIterator_free (CCGEdgeIterator *ei); CCGFace* ccgFaceIterator_getCurrent (CCGFaceIterator *fi); int ccgFaceIterator_isStopped (CCGFaceIterator *fi); void ccgFaceIterator_next (CCGFaceIterator *fi); -void ccgFaceIterator_free (CCGFaceIterator *fi); #endif /* __CCGSUBSURF_H__ */ diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 81c03d8081b..e8000a09d82 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -73,13 +73,11 @@ static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm); #include "BLI_sys_types.h" /* for intptr_t support */ #include "GPU_buffers.h" -#include "GPU_draw.h" #include "GPU_extensions.h" #include "GPU_glew.h" -#include "GPU_material.h" /* very slow! enable for testing only! */ -// #define USE_MODIFIER_VALIDATE +//#define USE_MODIFIER_VALIDATE #ifdef USE_MODIFIER_VALIDATE # define ASSERT_IS_VALID_DM(dm) (BLI_assert((dm == NULL) || (DM_is_valid(dm) == true))) @@ -914,7 +912,7 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, if (mti->isDisabled && mti->isDisabled(md, 0)) return NULL; if (build_shapekey_layers && me->key && (kb = BLI_findlink(&me->key->block, ob->shapenr - 1))) { - BKE_key_convert_to_mesh(kb, me); + BKE_keyblock_convert_to_mesh(kb, me); } if (mti->type == eModifierTypeType_OnlyDeform) { @@ -1221,14 +1219,14 @@ static void calc_weightpaint_vert_array(Object *ob, DerivedMesh *dm, int const d unsigned int i; /* variables for multipaint */ - const int defbase_tot = BLI_countlist(&ob->defbase); + const int defbase_tot = BLI_listbase_count(&ob->defbase); const int defbase_act = ob->actdef - 1; int defbase_sel_tot = 0; bool *defbase_sel = NULL; if (draw_flag & CALC_WP_MULTIPAINT) { - defbase_sel = BKE_objdef_selected_get(ob, defbase_tot, &defbase_sel_tot); + defbase_sel = BKE_object_defgroup_selected_get(ob, defbase_tot, &defbase_sel_tot); } for (i = numVerts; i != 0; i--, wc++, dv++) { @@ -1486,8 +1484,8 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); const bool has_multires = (mmd && mmd->sculptlvl != 0); bool multires_applied = false; - const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt; - const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm); + const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt && !useRenderParams; + const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm) && !useRenderParams; const int draw_flag = dm_drawflag_calc(scene->toolsettings); /* Generic preview only in object mode! */ @@ -1977,10 +1975,10 @@ bool editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh * if (!modifier_isEnabled(scene, md, required_mode)) return 0; if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) { modifier_setError(md, "Modifier requires original data, bad stack position"); - return 0; + return false; } - return 1; + return true; } static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, DerivedMesh **cage_r, @@ -2960,7 +2958,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, a = attribs->tottface++; if (layer != -1) { - attribs->tface[a].array = tfdata->layers[layer].data; + attribs->tface[a].array = NULL; attribs->tface[a].em_offset = ldata->layers[layer].offset; } else { @@ -3007,7 +3005,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, a = attribs->totmcol++; if (layer != -1) { - attribs->mcol[a].array = tfdata->layers[layer].data; + attribs->mcol[a].array = NULL; /* odd, store the offset for a different layer type here, but editmode draw code expects it */ attribs->mcol[a].em_offset = ldata->layers[layer].offset; } diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index c6dcca576fb..c1173cb2391 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -966,7 +966,7 @@ bActionGroup *BKE_pose_add_group(bPose *pose, const char *name) BLI_addtail(&pose->agroups, grp); BLI_uniquename(&pose->agroups, grp, name, '.', offsetof(bActionGroup, name), sizeof(grp->name)); - pose->active_group = BLI_countlist(&pose->agroups); + pose->active_group = BLI_listbase_count(&pose->agroups); return grp; } @@ -1028,12 +1028,12 @@ bool action_has_motion(const bAction *act) if (act) { for (fcu = act->curves.first; fcu; fcu = fcu->next) { if (fcu->totvert) - return 1; + return true; } } /* nothing found */ - return 0; + return false; } /* Calculate the extents of given action */ diff --git a/source/blender/blenkernel/intern/addon.c b/source/blender/blenkernel/intern/addon.c index 119fa266908..28667d458b8 100644 --- a/source/blender/blenkernel/intern/addon.c +++ b/source/blender/blenkernel/intern/addon.c @@ -29,15 +29,9 @@ #include "BLI_utildefines.h" #include "BLI_ghash.h" -#include "BLI_string.h" #include "BKE_addon.h" /* own include */ -#include "RNA_access.h" -#include "RNA_define.h" - -#include "BLF_translation.h" - #include "MEM_guardedalloc.h" static GHash *global_addonpreftype_hash = NULL; diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index aff99d3e1bf..b878dbe1f39 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -627,6 +627,9 @@ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float qua if (!bl->nr) return 0; if (bl->poly > -1) cycl = 1; + /* values below zero for non-cyclic curves give strange results */ + BLI_assert(cycl || ctime >= 0.0f); + ctime *= (path->len - 1); s1 = (int)floor(ctime); diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 2fb832dc72d..8e36449f214 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -83,7 +83,7 @@ bool id_type_can_have_animdata(ID *id) { /* sanity check */ if (id == NULL) - return 0; + return false; /* Only some ID-blocks have this info for now */ /* TODO: finish adding this for the other blocktypes */ @@ -100,13 +100,14 @@ bool id_type_can_have_animdata(ID *id) case ID_SCE: case ID_MC: case ID_MSK: + case ID_GD: { - return 1; + return true; } /* no AnimData */ default: - return 0; + return false; } } @@ -193,20 +194,20 @@ bool BKE_animdata_set_action(ReportList *reports, ID *id, bAction *act) /* can set */ adt->action = act; id_us_plus((ID *)adt->action); - ok = 1; + ok = true; } else { /* cannot set */ BKE_reportf(reports, RPT_ERROR, "Could not set action '%s' onto ID '%s', as it does not have suitably rooted paths " "for this purpose", act->id.name + 2, id->name); - /* ok = 0; */ + /* ok = false; */ } } else { /* just clearing the action... */ adt->action = NULL; - ok = 1; + ok = true; } return ok; @@ -289,7 +290,7 @@ bool BKE_copy_animdata_id(ID *id_to, ID *id_from, const bool do_action) AnimData *adt; if ((id_to && id_from) && (GS(id_to->name) != GS(id_from->name))) - return 0; + return false; BKE_free_animdata(id_to); @@ -299,7 +300,7 @@ bool BKE_copy_animdata_id(ID *id_to, ID *id_from, const bool do_action) iat->adt = BKE_copy_animdata(adt, do_action); } - return 1; + return true; } void BKE_copy_animdata_id_action(ID *id) @@ -1031,6 +1032,9 @@ void BKE_animdata_main_cb(Main *mainptr, ID_AnimData_Edit_Callback func, void *u /* line styles */ ANIMDATA_IDS_CB(mainptr->linestyle.first); + + /* grease pencil */ + ANIMDATA_IDS_CB(mainptr->gpencil.first); } /* Fix all RNA-Paths throughout the database (directly access the Global.main version) @@ -1119,6 +1123,9 @@ void BKE_all_animdata_fix_paths_rename(ID *ref_id, const char *prefix, const cha /* linestyles */ RENAMEFIX_ANIM_IDS(mainptr->linestyle.first); + /* grease pencil */ + RENAMEFIX_ANIM_IDS(mainptr->gpencil.first); + /* scenes */ RENAMEFIX_ANIM_NODETREE_IDS(mainptr->scene.first, Scene); } @@ -1346,11 +1353,11 @@ static bool animsys_remap_path(AnimMapper *UNUSED(remap), char *path, char **dst /* nothing suitable found, so just set dst to look at path (i.e. no alloc/free needed) */ *dst = path; - return 0; + return false; } -/* less then 1.0 evaluates to false, use epsilon to avoid float error */ +/* less than 1.0 evaluates to false, use epsilon to avoid float error */ #define ANIMSYS_FLOAT_AS_BOOL(value) ((value) > ((1.0f - FLT_EPSILON))) /* Write the given value to a setting using RNA, and return success */ @@ -1375,7 +1382,7 @@ static bool animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_ind path, array_index, array_len - 1); } - return 0; + return false; } switch (RNA_property_type(prop)) { @@ -1429,7 +1436,7 @@ static bool animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_ind break; default: /* nothing can be done here... so it is unsuccessful? */ - return 0; + return false; } /* RNA property update disabled for now - [#28525] [#28690] [#28774] [#28777] */ @@ -1468,7 +1475,7 @@ static bool animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_ind } /* successful */ - return 1; + return true; } else { /* failed to get path */ @@ -1479,7 +1486,7 @@ static bool animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_ind (ptr->id.data) ? (((ID *)ptr->id.data)->name + 2) : "<No ID>", path, array_index); } - return 0; + return false; } } @@ -2680,6 +2687,9 @@ void BKE_animsys_evaluate_all_animation(Main *main, Scene *scene, float ctime) /* linestyles */ EVAL_ANIM_IDS(main->linestyle.first, ADT_RECALC_ANIM); + /* grease pencil */ + EVAL_ANIM_IDS(main->gpencil.first, ADT_RECALC_ANIM); + /* objects */ /* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets * this tagged by Depsgraph on framechange. This optimization means that objects diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c new file mode 100644 index 00000000000..e2e6e828335 --- /dev/null +++ b/source/blender/blenkernel/intern/appdir.c @@ -0,0 +1,808 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + */ + +/** \file blender/blenlib/intern/appdir.c + * \ingroup bke + * + * Access to application level directories. + */ + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include "BLI_utildefines.h" +#include "BLI_string.h" +#include "BLI_fileops.h" +#include "BLI_path_util.h" + +#include "BKE_appdir.h" /* own include */ + +#include "GHOST_Path-api.h" + +#include "../blenkernel/BKE_blender.h" /* BLENDER_VERSION, bad level include (no function call) */ + +#include "MEM_guardedalloc.h" + +#ifdef WIN32 +# include "utf_winfunc.h" +# include "utfconv.h" +# include <io.h> +# ifdef _WIN32_IE +# undef _WIN32_IE +# endif +# define _WIN32_IE 0x0501 +# include <windows.h> +# include <shlobj.h> +# include "BLI_winstuff.h" +#else /* non windows */ +# ifdef WITH_BINRELOC +# include "binreloc.h" +# endif +# include <unistd.h> /* mkdtemp on OSX (and probably all *BSD?), not worth making specific check for this OS. */ +#endif /* WIN32 */ + +/* local */ +static char bprogname[FILE_MAX]; /* full path to program executable */ +static char bprogdir[FILE_MAX]; /* full path to directory in which executable is located */ +static char btempdir_base[FILE_MAX]; /* persistent temporary directory */ +static char btempdir_session[FILE_MAX] = ""; /* volatile temporary directory */ + +/* This is now only used to really get the user's default document folder */ +/* On Windows I chose the 'Users/<MyUserName>/Documents' since it's used + * as default location to save documents */ +const char *BKE_appdir_folder_default(void) +{ +#ifndef WIN32 + const char * const xdg_documents_dir = getenv("XDG_DOCUMENTS_DIR"); + + if (xdg_documents_dir) + return xdg_documents_dir; + + return getenv("HOME"); +#else /* Windows */ + static char documentfolder[MAXPATHLEN]; + HRESULT hResult; + + /* Check for %HOME% env var */ + if (uput_getenv("HOME", documentfolder, MAXPATHLEN)) { + if (BLI_is_dir(documentfolder)) return documentfolder; + } + + /* add user profile support for WIN 2K / NT. + * This is %APPDATA%, which translates to either + * %USERPROFILE%\Application Data or since Vista + * to %USERPROFILE%\AppData\Roaming + */ + hResult = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, documentfolder); + + if (hResult == S_OK) { + if (BLI_is_dir(documentfolder)) return documentfolder; + } + + return NULL; +#endif /* WIN32 */ +} + + +// #define PATH_DEBUG + +/* returns a formatted representation of the specified version number. Non-reentrant! */ +static char *blender_version_decimal(const int ver) +{ + static char version_str[5]; + sprintf(version_str, "%d.%02d", ver / 100, ver % 100); + return version_str; +} + +/** + * Concatenates path_base, (optional) path_sep and (optional) folder_name into targetpath, + * returning true if result points to a directory. + */ +static bool test_path(char *targetpath, const char *path_base, const char *path_sep, const char *folder_name) +{ + char tmppath[FILE_MAX]; + + if (path_sep) BLI_join_dirfile(tmppath, sizeof(tmppath), path_base, path_sep); + else BLI_strncpy(tmppath, path_base, sizeof(tmppath)); + + /* rare cases folder_name is omitted (when looking for ~/.blender/2.xx dir only) */ + if (folder_name) + BLI_make_file_string("/", targetpath, tmppath, folder_name); + else + BLI_strncpy(targetpath, tmppath, sizeof(tmppath)); + /* FIXME: why is "//" on front of tmppath expanded to "/" (by BLI_join_dirfile) + * if folder_name is specified but not otherwise? */ + + if (BLI_is_dir(targetpath)) { +#ifdef PATH_DEBUG + printf("\t%s found: %s\n", __func__, targetpath); +#endif + return true; + } + else { +#ifdef PATH_DEBUG + printf("\t%s missing: %s\n", __func__, targetpath); +#endif + //targetpath[0] = '\0'; + return false; + } +} + +/** + * Puts the value of the specified environment variable into *path if it exists + * and points at a directory. Returns true if this was done. + */ +static bool test_env_path(char *path, const char *envvar) +{ + const char *env = envvar ? getenv(envvar) : NULL; + if (!env) return false; + + if (BLI_is_dir(env)) { + BLI_strncpy(path, env, FILE_MAX); +#ifdef PATH_DEBUG + printf("\t%s env %s found: %s\n", __func__, envvar, env); +#endif + return true; + } + else { + path[0] = '\0'; +#ifdef PATH_DEBUG + printf("\t%s env %s missing: %s\n", __func__, envvar, env); +#endif + return false; + } +} + +/** + * Constructs in \a targetpath the name of a directory relative to a version-specific + * subdirectory in the parent directory of the Blender executable. + * + * \param targetpath String to return path + * \param folder_name Optional folder name within version-specific directory + * \param subfolder_name Optional subfolder name within folder_name + * \param ver To construct name of version-specific directory within bprogdir + * \return true if such a directory exists. + */ +static bool get_path_local(char *targetpath, const char *folder_name, const char *subfolder_name, const int ver) +{ + char relfolder[FILE_MAX]; + +#ifdef PATH_DEBUG + printf("%s...\n", __func__); +#endif + + if (folder_name) { + if (subfolder_name) { + BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name); + } + else { + BLI_strncpy(relfolder, folder_name, sizeof(relfolder)); + } + } + else { + relfolder[0] = '\0'; + } + + /* try EXECUTABLE_DIR/2.5x/folder_name - new default directory for local blender installed files */ +#ifdef __APPLE__ + static char osx_resourses[FILE_MAX]; /* due new codesign situation in OSX > 10.9.5 we must move the blender_version dir with contents to Resources */ + sprintf(osx_resourses, "%s../Resources", bprogdir); + return test_path(targetpath, osx_resourses, blender_version_decimal(ver), relfolder); +#else + return test_path(targetpath, bprogdir, blender_version_decimal(ver), relfolder); +#endif +} + +/** + * Is this an install with user files kept together with the Blender executable and its + * installation files. + */ +static bool is_portable_install(void) +{ + /* detect portable install by the existence of config folder */ + const int ver = BLENDER_VERSION; + char path[FILE_MAX]; + + return get_path_local(path, "config", NULL, ver); +} + +/** + * Returns the path of a folder within the user-files area. + * + * + * \param targetpath String to return path + * \param folder_name default name of folder within user area + * \param subfolder_name optional name of subfolder within folder + * \param envvar name of environment variable which, if defined, overrides folder_name + * \param ver Blender version, used to construct a subdirectory name + * \return true if it was able to construct such a path. + */ +static bool get_path_user(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver) +{ + char user_path[FILE_MAX]; + const char *user_base_path; + + /* for portable install, user path is always local */ + if (is_portable_install()) + return get_path_local(targetpath, folder_name, subfolder_name, ver); + + user_path[0] = '\0'; + + if (test_env_path(user_path, envvar)) { + if (subfolder_name) { + return test_path(targetpath, user_path, NULL, subfolder_name); + } + else { + BLI_strncpy(targetpath, user_path, FILE_MAX); + return true; + } + } + + user_base_path = (const char *)GHOST_getUserDir(ver, blender_version_decimal(ver)); + if (user_base_path) + BLI_strncpy(user_path, user_base_path, FILE_MAX); + + if (!user_path[0]) + return false; + +#ifdef PATH_DEBUG + printf("%s: %s\n", __func__, user_path); +#endif + + if (subfolder_name) { + return test_path(targetpath, user_path, folder_name, subfolder_name); + } + else { + return test_path(targetpath, user_path, NULL, folder_name); + } +} + +/** + * Returns the path of a folder within the Blender installation directory. + * + * \param targetpath String to return path + * \param folder_name default name of folder within installation area + * \param subfolder_name optional name of subfolder within folder + * \param envvar name of environment variable which, if defined, overrides folder_name + * \param ver Blender version, used to construct a subdirectory name + * \return true if it was able to construct such a path. + */ +static bool get_path_system(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver) +{ + char system_path[FILE_MAX]; + const char *system_base_path; + char cwd[FILE_MAX]; + char relfolder[FILE_MAX]; + + if (folder_name) { + if (subfolder_name) { + BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name); + } + else { + BLI_strncpy(relfolder, folder_name, sizeof(relfolder)); + } + } + else { + relfolder[0] = '\0'; + } + + /* first allow developer only overrides to the system path + * these are only used when running blender from source */ + + /* try CWD/release/folder_name */ + if (BLI_current_working_dir(cwd, sizeof(cwd))) { + if (test_path(targetpath, cwd, "release", relfolder)) { + return true; + } + } + + /* try EXECUTABLE_DIR/release/folder_name */ + if (test_path(targetpath, bprogdir, "release", relfolder)) + return true; + + /* end developer overrides */ + + + + system_path[0] = '\0'; + + if (test_env_path(system_path, envvar)) { + if (subfolder_name) { + return test_path(targetpath, system_path, NULL, subfolder_name); + } + else { + BLI_strncpy(targetpath, system_path, FILE_MAX); + return true; + } + } + + system_base_path = (const char *)GHOST_getSystemDir(ver, blender_version_decimal(ver)); + if (system_base_path) + BLI_strncpy(system_path, system_base_path, FILE_MAX); + + if (!system_path[0]) + return false; + +#ifdef PATH_DEBUG + printf("%s: %s\n", __func__, system_path); +#endif + + if (subfolder_name) { + /* try $BLENDERPATH/folder_name/subfolder_name */ + return test_path(targetpath, system_path, folder_name, subfolder_name); + } + else { + /* try $BLENDERPATH/folder_name */ + return test_path(targetpath, system_path, NULL, folder_name); + } +} + +/* get a folder out of the 'folder_id' presets for paths */ +/* returns the path if found, NULL string if not */ +const char *BKE_appdir_folder_id(const int folder_id, const char *subfolder) +{ + const int ver = BLENDER_VERSION; + static char path[FILE_MAX] = ""; + + switch (folder_id) { + case BLENDER_DATAFILES: /* general case */ + if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver)) break; + if (get_path_local(path, "datafiles", subfolder, ver)) break; + if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES", ver)) break; + return NULL; + + case BLENDER_USER_DATAFILES: + if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver)) break; + return NULL; + + case BLENDER_SYSTEM_DATAFILES: + if (get_path_local(path, "datafiles", subfolder, ver)) break; + if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES", ver)) break; + return NULL; + + case BLENDER_USER_AUTOSAVE: + if (get_path_user(path, "autosave", subfolder, "BLENDER_USER_DATAFILES", ver)) break; + return NULL; + + case BLENDER_USER_CONFIG: + if (get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG", ver)) break; + return NULL; + + case BLENDER_USER_SCRIPTS: + if (get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS", ver)) break; + return NULL; + + case BLENDER_SYSTEM_SCRIPTS: + if (get_path_local(path, "scripts", subfolder, ver)) break; + if (get_path_system(path, "scripts", subfolder, "BLENDER_SYSTEM_SCRIPTS", ver)) break; + return NULL; + + case BLENDER_SYSTEM_PYTHON: + if (get_path_local(path, "python", subfolder, ver)) break; + if (get_path_system(path, "python", subfolder, "BLENDER_SYSTEM_PYTHON", ver)) break; + return NULL; + + default: + BLI_assert(0); + break; + } + + return path; +} + +/** + * Returns the path to a folder in the user area without checking that it actually exists first. + */ +const char *BKE_appdir_folder_id_user_notest(const int folder_id, const char *subfolder) +{ + const int ver = BLENDER_VERSION; + static char path[FILE_MAX] = ""; + + switch (folder_id) { + case BLENDER_USER_DATAFILES: + get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver); + break; + case BLENDER_USER_CONFIG: + get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG", ver); + break; + case BLENDER_USER_AUTOSAVE: + get_path_user(path, "autosave", subfolder, "BLENDER_USER_AUTOSAVE", ver); + break; + case BLENDER_USER_SCRIPTS: + get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS", ver); + break; + default: + BLI_assert(0); + break; + } + + if ('\0' == path[0]) { + return NULL; + } + return path; +} + +/** + * Returns the path to a folder in the user area, creating it if it doesn't exist. + */ +const char *BKE_appdir_folder_id_create(int folder_id, const char *subfolder) +{ + const char *path; + + /* only for user folders */ + if (!ELEM(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_SCRIPTS, BLENDER_USER_AUTOSAVE)) + return NULL; + + path = BKE_appdir_folder_id(folder_id, subfolder); + + if (!path) { + path = BKE_appdir_folder_id_user_notest(folder_id, subfolder); + if (path) BLI_dir_create_recursive(path); + } + + return path; +} + +/** + * Returns the path of the top-level version-specific local, user or system directory. + * If do_check, then the result will be NULL if the directory doesn't exist. + */ +const char *BKE_appdir_folder_id_version(const int folder_id, const int ver, const bool do_check) +{ + static char path[FILE_MAX] = ""; + bool ok; + switch (folder_id) { + case BLENDER_RESOURCE_PATH_USER: + ok = get_path_user(path, NULL, NULL, NULL, ver); + break; + case BLENDER_RESOURCE_PATH_LOCAL: + ok = get_path_local(path, NULL, NULL, ver); + break; + case BLENDER_RESOURCE_PATH_SYSTEM: + ok = get_path_system(path, NULL, NULL, NULL, ver); + break; + default: + path[0] = '\0'; /* in case do_check is false */ + ok = false; + BLI_assert(!"incorrect ID"); + break; + } + + if (!ok && do_check) { + return NULL; + } + + return path; +} + +#ifdef PATH_DEBUG +# undef PATH_DEBUG +#endif + + +/* -------------------------------------------------------------------- */ +/* Preset paths */ + +/** + * Tries appending each of the semicolon-separated extensions in the PATHEXT + * environment variable (Windows-only) onto *name in turn until such a file is found. + * Returns success/failure. + */ +static int add_win32_extension(char *name) +{ + int retval = 0; + int type; + + type = BLI_exists(name); + if ((type == 0) || S_ISDIR(type)) { +#ifdef _WIN32 + char filename[FILE_MAX]; + char ext[FILE_MAX]; + const char *extensions = getenv("PATHEXT"); + if (extensions) { + char *temp; + do { + strcpy(filename, name); + temp = strstr(extensions, ";"); + if (temp) { + strncpy(ext, extensions, temp - extensions); + ext[temp - extensions] = 0; + extensions = temp + 1; + strcat(filename, ext); + } + else { + strcat(filename, extensions); + } + + type = BLI_exists(filename); + if (type && (!S_ISDIR(type))) { + retval = 1; + strcpy(name, filename); + break; + } + } while (temp); + } +#endif + } + else { + retval = 1; + } + + return (retval); +} + +/** + * Checks if name is a fully qualified filename to an executable. + * If not it searches $PATH for the file. On Windows it also + * adds the correct extension (.com .exe etc) from + * $PATHEXT if necessary. Also on Windows it translates + * the name to its 8.3 version to prevent problems with + * spaces and stuff. Final result is returned in fullname. + * + * \param fullname The full path and full name of the executable + * (must be FILE_MAX minimum) + * \param name The name of the executable (usually argv[0]) to be checked + */ +static void bli_where_am_i(char *fullname, const size_t maxlen, const char *name) +{ + char filename[FILE_MAX]; + const char *path = NULL, *temp; + +#ifdef _WIN32 + const char *separator = ";"; +#else + const char *separator = ":"; +#endif + + +#ifdef WITH_BINRELOC + /* linux uses binreloc since argv[0] is not reliable, call br_init( NULL ) first */ + path = br_find_exe(NULL); + if (path) { + BLI_strncpy(fullname, path, maxlen); + free((void *)path); + return; + } +#endif + +#ifdef _WIN32 + wchar_t *fullname_16 = MEM_mallocN(maxlen * sizeof(wchar_t), "ProgramPath"); + if (GetModuleFileNameW(0, fullname_16, maxlen)) { + conv_utf_16_to_8(fullname_16, fullname, maxlen); + if (!BLI_exists(fullname)) { + printf("path can't be found: \"%.*s\"\n", (int)maxlen, fullname); + MessageBox(NULL, "path contains invalid characters or is too long (see console)", "Error", MB_OK); + } + MEM_freeN(fullname_16); + return; + } + + MEM_freeN(fullname_16); +#endif + + /* unix and non linux */ + if (name && name[0]) { + + BLI_strncpy(fullname, name, maxlen); + if (name[0] == '.') { + char wdir[FILE_MAX] = ""; + BLI_current_working_dir(wdir, sizeof(wdir)); /* backup cwd to restore after */ + + // not needed but avoids annoying /./ in name + if (name[1] == SEP) + BLI_join_dirfile(fullname, maxlen, wdir, name + 2); + else + BLI_join_dirfile(fullname, maxlen, wdir, name); + + add_win32_extension(fullname); /* XXX, doesnt respect length */ + } + else if (BLI_last_slash(name)) { + // full path + BLI_strncpy(fullname, name, maxlen); + add_win32_extension(fullname); + } + else { + // search for binary in $PATH + path = getenv("PATH"); + if (path) { + do { + temp = strstr(path, separator); + if (temp) { + strncpy(filename, path, temp - path); + filename[temp - path] = 0; + path = temp + 1; + } + else { + strncpy(filename, path, sizeof(filename)); + } + BLI_path_append(fullname, maxlen, name); + if (add_win32_extension(filename)) { + BLI_strncpy(fullname, filename, maxlen); + break; + } + } while (temp); + } + } +#if defined(DEBUG) + if (strcmp(name, fullname)) { + printf("guessing '%s' == '%s'\n", name, fullname); + } +#endif + } +} + +void BKE_appdir_program_path_init(const char *argv0) +{ + bli_where_am_i(bprogname, sizeof(bprogname), argv0); + BLI_split_dir_part(bprogname, bprogdir, sizeof(bprogdir)); +} + +/** + * Path to executable + */ +const char *BKE_appdir_program_path(void) +{ + return bprogname; +} + +/** + * Path to directory of executable + */ +const char *BKE_appdir_program_dir(void) +{ + return bprogdir; +} + +/** + * Gets the temp directory when blender first runs. + * If the default path is not found, use try $TEMP + * + * Also make sure the temp dir has a trailing slash + * + * \param fullname The full path to the temporary temp directory + * \param basename The full path to the persistent temp directory (may be NULL) + * \param maxlen The size of the fullname buffer + * \param userdir Directory specified in user preferences + */ +static void BLI_where_is_temp(char *fullname, char *basename, const size_t maxlen, char *userdir) +{ + /* Clear existing temp dir, if needed. */ + BKE_tempdir_session_purge(); + + fullname[0] = '\0'; + if (basename) { + basename[0] = '\0'; + } + + if (userdir && BLI_is_dir(userdir)) { + BLI_strncpy(fullname, userdir, maxlen); + } + + +#ifdef WIN32 + if (fullname[0] == '\0') { + const char *tmp = getenv("TEMP"); /* Windows */ + if (tmp && BLI_is_dir(tmp)) { + BLI_strncpy(fullname, tmp, maxlen); + } + } +#else + /* Other OS's - Try TMP and TMPDIR */ + if (fullname[0] == '\0') { + const char *tmp = getenv("TMP"); + if (tmp && BLI_is_dir(tmp)) { + BLI_strncpy(fullname, tmp, maxlen); + } + } + + if (fullname[0] == '\0') { + const char *tmp = getenv("TMPDIR"); + if (tmp && BLI_is_dir(tmp)) { + BLI_strncpy(fullname, tmp, maxlen); + } + } +#endif + + if (fullname[0] == '\0') { + BLI_strncpy(fullname, "/tmp/", maxlen); + } + else { + /* add a trailing slash if needed */ + BLI_add_slash(fullname); +#ifdef WIN32 + if (userdir && userdir != fullname) { + BLI_strncpy(userdir, fullname, maxlen); /* also set user pref to show %TEMP%. /tmp/ is just plain confusing for Windows users. */ + } +#endif + } + + /* Now that we have a valid temp dir, add system-generated unique sub-dir. */ + if (basename) { + /* 'XXXXXX' is kind of tag to be replaced by mktemp-familly by an uuid. */ + char *tmp_name = BLI_strdupcat(fullname, "blender_XXXXXX"); + const size_t ln = strlen(tmp_name) + 1; + if (ln <= maxlen) { +#ifdef WIN32 + if (_mktemp_s(tmp_name, ln) == 0) { + BLI_dir_create_recursive(tmp_name); + } +#else + mkdtemp(tmp_name); +#endif + } + if (BLI_is_dir(tmp_name)) { + BLI_strncpy(basename, fullname, maxlen); + BLI_strncpy(fullname, tmp_name, maxlen); + BLI_add_slash(fullname); + } + else { + printf("Warning! Could not generate a temp file name for '%s', falling back to '%s'\n", tmp_name, fullname); + } + + MEM_freeN(tmp_name); + } +} + +/** + * Sets btempdir_base to userdir if specified and is a valid directory, otherwise + * chooses a suitable OS-specific temporary directory. + * Sets btempdir_session to a mkdtemp-generated sub-dir of btempdir_base. + * + * \note On Window userdir will be set to the temporary directory! + */ +void BKE_tempdir_init(char *userdir) +{ + BLI_where_is_temp(btempdir_session, btempdir_base, FILE_MAX, userdir); +; +} + +/** + * Path to temporary directory (with trailing slash) + */ +const char *BKE_tempdir_session(void) +{ + return btempdir_session[0] ? btempdir_session : BKE_tempdir_base(); +} + +/** + * Path to persistent temporary directory (with trailing slash) + */ +const char *BKE_tempdir_base(void) +{ + return btempdir_base; +} + +/** + * Path to the system temporary directory (with trailing slash) + */ +void BKE_tempdir_system_init(char *dir) +{ + BLI_where_is_temp(dir, NULL, FILE_MAX, NULL); +} + +/** + * Delete content of this instance's temp dir. + */ +void BKE_tempdir_session_purge(void) +{ + if (btempdir_session[0] && BLI_is_dir(btempdir_session)) { + BLI_delete(btempdir_session, true, true); + } +} diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index bb05b5de8a6..f4a5d33854a 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -840,7 +840,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float /* bone defmats are already in the channels, chan_mat */ /* initialize B_bone matrices and dual quaternions */ - totchan = BLI_countlist(&armOb->pose->chanbase); + totchan = BLI_listbase_count(&armOb->pose->chanbase); if (use_quaternion) { dualquats = MEM_callocN(sizeof(DualQuat) * totchan, "dualquats"); @@ -866,7 +866,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float armature_def_nr = defgroup_name_index(target, defgrp_name); if (ELEM(target->type, OB_MESH, OB_LATTICE)) { - defbase_tot = BLI_countlist(&target->defbase); + defbase_tot = BLI_listbase_count(&target->defbase); if (target->type == OB_MESH) { Mesh *me = target->data; @@ -1654,6 +1654,7 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected pchanw.next = pchan->next; pchanw.parent = pchan->parent; pchanw.child = pchan->child; + pchanw.custom_tx = pchan->custom_tx; pchanw.mpath = pchan->mpath; pchan->mpath = NULL; @@ -1662,7 +1663,7 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected if (pchanw.prop) { pchanw.prop = IDP_CopyProperty(pchanw.prop); - /* use the values from the the existing props */ + /* use the values from the existing props */ if (pchan->prop) { IDP_SyncGroupValues(pchanw.prop, pchan->prop); } @@ -1916,7 +1917,7 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos if (ikData->points) MEM_freeN(ikData->points); ikData->numpoints = ikData->chainlen + 1; - ikData->points = MEM_callocN(sizeof(float) * ikData->numpoints, "Spline IK Binding"); + ikData->points = MEM_mallocN(sizeof(float) * ikData->numpoints, "Spline IK Binding"); /* bind 'tip' of chain (i.e. first joint = tip of bone with the Spline IK Constraint) */ ikData->points[0] = 1.0f; @@ -1944,6 +1945,9 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos ikData->flag |= CONSTRAINT_SPLINEIK_BOUND; } + /* disallow negative values (happens with float precision) */ + CLAMP_MIN(ikData->points[segcount], 0.0f); + /* apply corrections for sensitivity to scaling on a copy of the bind points, * since it's easier to determine the positions of all the joints beforehand this way */ @@ -1989,7 +1993,7 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos tree->chainlen = segcount; /* copy over the array of links to bones in the chain (from tip to root) */ - tree->chain = MEM_callocN(sizeof(bPoseChannel *) * segcount, "SplineIK Chain"); + tree->chain = MEM_mallocN(sizeof(bPoseChannel *) * segcount, "SplineIK Chain"); memcpy(tree->chain, pchanChain, sizeof(bPoseChannel *) * segcount); /* store reference to joint position array */ diff --git a/source/blender/blenkernel/intern/autoexec.c b/source/blender/blenkernel/intern/autoexec.c index 872780bd50a..d9462cd0262 100644 --- a/source/blender/blenkernel/intern/autoexec.c +++ b/source/blender/blenkernel/intern/autoexec.c @@ -34,9 +34,12 @@ #include "BLI_utildefines.h" #include "BLI_fnmatch.h" -#include "BLI_string.h" #include "BLI_path_util.h" +#ifdef WIN32 +# include "BLI_string.h" +#endif + #include "BKE_autoexec.h" /* own include */ /** diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index adfe43cb2a3..96f769587d9 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -61,6 +61,7 @@ #include "IMB_imbuf.h" #include "IMB_moviecache.h" +#include "BKE_appdir.h" #include "BKE_blender.h" #include "BKE_bpath.h" #include "BKE_brush.h" @@ -493,10 +494,11 @@ bool BKE_read_file_from_memory( BLO_update_defaults_startup_blend(bfd->main); setup_app_data(C, bfd, "<memory2>"); } - else + else { BKE_reports_prepend(reports, "Loading failed: "); + } - return (bfd ? 1 : 0); + return (bfd != NULL); } /* memfile is the undo buffer */ @@ -516,10 +518,11 @@ bool BKE_read_file_from_memfile( setup_app_data(C, bfd, "<memory1>"); } - else + else { BKE_reports_prepend(reports, "Loading failed: "); + } - return (bfd ? 1 : 0); + return (bfd != NULL); } /* only read the userdef from a .blend */ @@ -687,7 +690,7 @@ void BKE_write_undo(bContext *C, const char *name) counter = counter % U.undosteps; BLI_snprintf(numstr, sizeof(numstr), "%d.blend", counter); - BLI_make_file_string("/", filepath, BLI_temp_dir_session(), numstr); + BLI_make_file_string("/", filepath, BKE_tempdir_session(), numstr); /* success = */ /* UNUSED */ BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL); @@ -834,13 +837,13 @@ bool BKE_undo_save_file(const char *filename) int file, oflags; if ((U.uiflag & USER_GLOBALUNDO) == 0) { - return 0; + return false; } uel = curundo; if (uel == NULL) { fprintf(stderr, "No undo buffer to save recovery file\n"); - return 0; + return false; } /* note: This is currently used for autosave and 'quit.blend', where _not_ following symlinks is OK, @@ -862,7 +865,7 @@ bool BKE_undo_save_file(const char *filename) if (file == -1) { fprintf(stderr, "Unable to save '%s': %s\n", filename, errno ? strerror(errno) : "Unknown error opening file"); - return 0; + return false; } for (chunk = uel->memfile.chunks.first; chunk; chunk = chunk->next) { @@ -876,9 +879,9 @@ bool BKE_undo_save_file(const char *filename) if (chunk) { fprintf(stderr, "Unable to save '%s': %s\n", filename, errno ? strerror(errno) : "Unknown error writing file"); - return 0; + return false; } - return 1; + return true; } /* sets curscene */ diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index 5731455fc01..4a564614ff3 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -995,7 +995,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) case eBoidRulesetType_Random: { /* use random rule for each particle (allways same for same particle though) */ - rule = BLI_findlink(&state->rules, rand % BLI_countlist(&state->rules)); + rule = BLI_findlink(&state->rules, rand % BLI_listbase_count(&state->rules)); apply_boid_rule(bbd, rule, &val, pa, -1.0); break; diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index ae6ae6087af..92f66cdde76 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -33,7 +33,6 @@ #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_rand.h" -#include "BLI_rect.h" #include "BKE_brush.h" #include "BKE_colortools.h" @@ -49,7 +48,6 @@ #include "IMB_imbuf_types.h" #include "RE_render_ext.h" /* externtex */ -#include "RE_shader_ext.h" static RNG *brush_rng; @@ -1048,7 +1046,7 @@ struct ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br, bool secondary) for (i = 0; i < side; ++i) { for (j = 0; j < side; ++j) { - float magn = sqrtf(powf(i - half, 2) + powf(j - half, 2)); + float magn = sqrtf(pow2f(i - half) + pow2f(j - half)); im->rect_float[i * side + j] = BKE_brush_curve_strength_clamp(br, magn, half); } } diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index 1402f62291f..5454062ad1f 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -454,7 +454,7 @@ void BKE_camera_view_frame(Scene *scene, Camera *camera, float r_vec[4][3]) float dummy_drawsize; const float dummy_scale[3] = {1.0f, 1.0f, 1.0f}; - BKE_camera_view_frame_ex(scene, camera, false, 1.0, dummy_scale, + BKE_camera_view_frame_ex(scene, camera, 0.0, true, dummy_scale, dummy_asp, dummy_shift, &dummy_drawsize, r_vec); } diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index bfc70c91181..6ac85695570 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -35,7 +35,6 @@ */ #include "BLI_math.h" -#include "BLI_blenlib.h" #include "BLI_edgehash.h" #include "BLI_utildefines.h" #include "BLI_stackdefines.h" @@ -49,7 +48,6 @@ #include "BKE_editmesh.h" #include "BKE_curve.h" -#include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" @@ -61,7 +59,6 @@ #include "GPU_draw.h" #include "GPU_extensions.h" #include "GPU_glew.h" -#include "GPU_material.h" #include <string.h> #include <limits.h> @@ -343,106 +340,64 @@ static void cdDM_update_normals_from_pbvh(DerivedMesh *dm) static void cdDM_drawVerts(DerivedMesh *dm) { - CDDerivedMesh *cddm = (CDDerivedMesh *) dm; - MVert *mv = cddm->mvert; - int i; - - if (GPU_buffer_legacy(dm)) { - glBegin(GL_POINTS); - for (i = 0; i < dm->numVertData; i++, mv++) - glVertex3fv(mv->co); - glEnd(); - } - else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ - GPU_vertex_setup(dm); - if (!GPU_buffer_legacy(dm)) { - if (dm->drawObject->tot_triangle_point) - glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_triangle_point); - else - glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_loose_point); - } - GPU_buffer_unbind(); - } + GPU_vertex_setup(dm); + if (dm->drawObject->tot_triangle_point) + glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_triangle_point); + else + glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_loose_point); + GPU_buffer_unbind(); } static void cdDM_drawUVEdges(DerivedMesh *dm) { CDDerivedMesh *cddm = (CDDerivedMesh *) dm; MFace *mf = cddm->mface; - MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE); int i; if (mf) { - if (GPU_buffer_legacy(dm)) { - glBegin(GL_LINES); - for (i = 0; i < dm->numTessFaceData; i++, mf++, tf++) { - if (!(mf->flag & ME_HIDE)) { - glVertex2fv(tf->uv[0]); - glVertex2fv(tf->uv[1]); - - glVertex2fv(tf->uv[1]); - glVertex2fv(tf->uv[2]); - - if (!mf->v4) { - glVertex2fv(tf->uv[2]); - glVertex2fv(tf->uv[0]); - } - else { - glVertex2fv(tf->uv[2]); - glVertex2fv(tf->uv[3]); - - glVertex2fv(tf->uv[3]); - glVertex2fv(tf->uv[0]); - } - } + int prevstart = 0; + int prevdraw = 1; + int draw = 1; + int curpos = 0; + + GPU_uvedge_setup(dm); + for (i = 0; i < dm->numTessFaceData; i++, mf++) { + if (!(mf->flag & ME_HIDE)) { + draw = 1; } - glEnd(); - } - else { - int prevstart = 0; - int prevdraw = 1; - int draw = 1; - int curpos = 0; - - GPU_uvedge_setup(dm); - if (!GPU_buffer_legacy(dm)) { - for (i = 0; i < dm->numTessFaceData; i++, mf++) { - if (!(mf->flag & ME_HIDE)) { - draw = 1; - } - else { - draw = 0; - } - if (prevdraw != draw) { - if (prevdraw > 0 && (curpos - prevstart) > 0) { - glDrawArrays(GL_LINES, prevstart, curpos - prevstart); - } - prevstart = curpos; - } - if (mf->v4) { - curpos += 8; - } - else { - curpos += 6; - } - prevdraw = draw; - } + else { + draw = 0; + } + if (prevdraw != draw) { if (prevdraw > 0 && (curpos - prevstart) > 0) { glDrawArrays(GL_LINES, prevstart, curpos - prevstart); } + prevstart = curpos; + } + if (mf->v4) { + curpos += 8; } - GPU_buffer_unbind(); + else { + curpos += 6; + } + prevdraw = draw; + } + if (prevdraw > 0 && (curpos - prevstart) > 0) { + glDrawArrays(GL_LINES, prevstart, curpos - prevstart); } + GPU_buffer_unbind(); } } static void cdDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdges) { CDDerivedMesh *cddm = (CDDerivedMesh *) dm; - MVert *mvert = cddm->mvert; MEdge *medge = cddm->medge; int i; - + int prevstart = 0; + int prevdraw = 1; + bool draw = true; + if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) { @@ -451,97 +406,60 @@ static void cdDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdg return; } - if (GPU_buffer_legacy(dm)) { - DEBUG_VBO("Using legacy code. cdDM_drawEdges\n"); - glBegin(GL_LINES); - for (i = 0; i < dm->numEdgeData; i++, medge++) { - if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) && - (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE))) - { - glVertex3fv(mvert[medge->v1].co); - glVertex3fv(mvert[medge->v2].co); - } + GPU_edge_setup(dm); + for (i = 0; i < dm->numEdgeData; i++, medge++) { + if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) && + (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE))) + { + draw = true; } - glEnd(); - } - else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ - int prevstart = 0; - int prevdraw = 1; - bool draw = true; - - GPU_edge_setup(dm); - if (!GPU_buffer_legacy(dm)) { - for (i = 0; i < dm->numEdgeData; i++, medge++) { - if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) && - (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE))) - { - draw = true; - } - else { - draw = false; - } - if (prevdraw != draw) { - if (prevdraw > 0 && (i - prevstart) > 0) { - GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2); - } - prevstart = i; - } - prevdraw = draw; - } + else { + draw = false; + } + if (prevdraw != draw) { if (prevdraw > 0 && (i - prevstart) > 0) { GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2); } + prevstart = i; } - GPU_buffer_unbind(); + prevdraw = draw; } + if (prevdraw > 0 && (i - prevstart) > 0) { + GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2); + } + GPU_buffer_unbind(); } static void cdDM_drawLooseEdges(DerivedMesh *dm) { CDDerivedMesh *cddm = (CDDerivedMesh *) dm; - MVert *mvert = cddm->mvert; MEdge *medge = cddm->medge; int i; - - if (GPU_buffer_legacy(dm)) { - DEBUG_VBO("Using legacy code. cdDM_drawLooseEdges\n"); - glBegin(GL_LINES); - for (i = 0; i < dm->numEdgeData; i++, medge++) { - if (medge->flag & ME_LOOSEEDGE) { - glVertex3fv(mvert[medge->v1].co); - glVertex3fv(mvert[medge->v2].co); - } + + int prevstart = 0; + int prevdraw = 1; + int draw = 1; + + GPU_edge_setup(dm); + for (i = 0; i < dm->numEdgeData; i++, medge++) { + if (medge->flag & ME_LOOSEEDGE) { + draw = 1; } - glEnd(); - } - else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ - int prevstart = 0; - int prevdraw = 1; - int draw = 1; - - GPU_edge_setup(dm); - if (!GPU_buffer_legacy(dm)) { - for (i = 0; i < dm->numEdgeData; i++, medge++) { - if (medge->flag & ME_LOOSEEDGE) { - draw = 1; - } - else { - draw = 0; - } - if (prevdraw != draw) { - if (prevdraw > 0 && (i - prevstart) > 0) { - GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2); - } - prevstart = i; - } - prevdraw = draw; - } + else { + draw = 0; + } + if (prevdraw != draw) { if (prevdraw > 0 && (i - prevstart) > 0) { GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2); } + prevstart = i; } - GPU_buffer_unbind(); + prevdraw = draw; + } + if (prevdraw > 0 && (i - prevstart) > 0) { + GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2); } + GPU_buffer_unbind(); } static void cdDM_drawFacesSolid(DerivedMesh *dm, @@ -549,11 +467,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, bool UNUSED(fast), DMSetMaterial setMaterial) { CDDerivedMesh *cddm = (CDDerivedMesh *) dm; - MVert *mvert = cddm->mvert; - MFace *mface = cddm->mface; - const float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL); - const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); - int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1; + int a; if (cddm->pbvh && cddm->pbvh_draw) { if (dm->numTessFaceData) { @@ -566,121 +480,37 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, return; } - - if (GPU_buffer_legacy(dm)) { - DEBUG_VBO("Using legacy code. cdDM_drawFacesSolid\n"); - glBegin(glmode = GL_QUADS); - for (a = 0; a < dm->numTessFaceData; a++, mface++) { - int new_glmode, new_matnr, new_shademodel; - - new_glmode = mface->v4 ? GL_QUADS : GL_TRIANGLES; - new_matnr = mface->mat_nr + 1; - new_shademodel = (lnors || (mface->flag & ME_SMOOTH)) ? GL_SMOOTH : GL_FLAT; - - - if ((new_glmode != glmode) || (new_shademodel != shademodel) || - (setMaterial && (new_matnr != matnr))) - { - glEnd(); - - if (setMaterial) { - drawCurrentMat = setMaterial(matnr = new_matnr, NULL); - } - - glShadeModel(shademodel = new_shademodel); - glBegin(glmode = new_glmode); - } - - if (drawCurrentMat) { - if (lnors) { - glNormal3sv((const GLshort *)lnors[0][0]); - glVertex3fv(mvert[mface->v1].co); - glNormal3sv((const GLshort *)lnors[0][1]); - glVertex3fv(mvert[mface->v2].co); - glNormal3sv((const GLshort *)lnors[0][2]); - glVertex3fv(mvert[mface->v3].co); - if (mface->v4) { - glNormal3sv((const GLshort *)lnors[0][3]); - glVertex3fv(mvert[mface->v4].co); - } - } - else if (shademodel == GL_FLAT) { - if (nors) { - glNormal3fv(nors); - } - else { - /* TODO make this better (cache facenormals as layer?) */ - float nor[3]; - if (mface->v4) { - normal_quad_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co); - } - else { - normal_tri_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co); - } - glNormal3fv(nor); - } - glVertex3fv(mvert[mface->v1].co); - glVertex3fv(mvert[mface->v2].co); - glVertex3fv(mvert[mface->v3].co); - if (mface->v4) { - glVertex3fv(mvert[mface->v4].co); - } - } - else { /* shademodel == GL_SMOOTH */ - glNormal3sv(mvert[mface->v1].no); - glVertex3fv(mvert[mface->v1].co); - glNormal3sv(mvert[mface->v2].no); - glVertex3fv(mvert[mface->v2].co); - glNormal3sv(mvert[mface->v3].no); - glVertex3fv(mvert[mface->v3].co); - if (mface->v4) { - glNormal3sv(mvert[mface->v4].no); - glVertex3fv(mvert[mface->v4].co); - } - } - } - - if (nors) - nors += 3; - if (lnors) - lnors++; - } - glEnd(); - } - else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ - GPU_vertex_setup(dm); - GPU_normal_setup(dm); - if (!GPU_buffer_legacy(dm)) { - glShadeModel(GL_SMOOTH); - for (a = 0; a < dm->drawObject->totmaterial; a++) { - if (!setMaterial || setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) { - glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start, - dm->drawObject->materials[a].totpoint); - } - } + + GPU_vertex_setup(dm); + GPU_normal_setup(dm); + glShadeModel(GL_SMOOTH); + for (a = 0; a < dm->drawObject->totmaterial; a++) { + if (!setMaterial || setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) { + glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start, + dm->drawObject->materials[a].totpoint); } - GPU_buffer_unbind(); } + GPU_buffer_unbind(); glShadeModel(GL_FLAT); } static void cdDM_drawFacesTex_common(DerivedMesh *dm, DMSetDrawOptionsTex drawParams, - DMSetDrawOptions drawParamsMapped, + DMSetDrawOptionsMappedTex drawParamsMapped, DMCompareDrawOptions compareDrawOptions, void *userData, DMDrawFlag uvflag) { CDDerivedMesh *cddm = (CDDerivedMesh *) dm; - MVert *mv = cddm->mvert; const MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE); - const float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL); - const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE); MCol *mcol; int i, orig; int colType, startFace = 0; bool use_tface = (uvflag & DM_DRAW_USE_ACTIVE_UV) != 0; + int tottri; + int next_actualFace; + /* double lookup */ const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); @@ -717,208 +547,81 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, } cdDM_update_normals_from_pbvh(dm); - - if (GPU_buffer_legacy(dm)) { - int mat_nr_cache = -1; - MTFace *tf_base = DM_get_tessface_data_layer(dm, CD_MTFACE); - MTFace *tf_stencil_base = NULL; - MTFace *tf_stencil = NULL; - - if (uvflag & DM_DRAW_USE_TEXPAINT_UV) { - int stencil = CustomData_get_stencil_layer(&dm->faceData, CD_MTFACE); - tf_stencil_base = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, stencil); + + GPU_vertex_setup(dm); + GPU_normal_setup(dm); + if (uvflag & DM_DRAW_USE_TEXPAINT_UV) + GPU_texpaint_uv_setup(dm); + else + GPU_uv_setup(dm); + if (mcol) { + GPU_color_setup(dm, colType); + } + + tottri = dm->drawObject->tot_triangle_point / 3; + next_actualFace = dm->drawObject->triangle_to_mface[0]; + + glShadeModel(GL_SMOOTH); + /* lastFlag = 0; */ /* UNUSED */ + for (i = 0; i < tottri; i++) { + int actualFace = next_actualFace; + DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; + int flush = 0; + + if (i != tottri - 1) + next_actualFace = dm->drawObject->triangle_to_mface[i + 1]; + + if (drawParams) { + draw_option = drawParams(use_tface && tf ? &tf[actualFace] : NULL, (mcol != NULL), mf[actualFace].mat_nr); } - - DEBUG_VBO("Using legacy code. cdDM_drawFacesTex_common\n"); - for (i = 0; i < dm->numTessFaceData; i++, mf++) { - MVert *mvert; - DMDrawOption draw_option; - unsigned char *cp = NULL; - - if (uvflag & DM_DRAW_USE_TEXPAINT_UV) { - if (mf->mat_nr != mat_nr_cache) { - tf_base = DM_paint_uvlayer_active_get(dm, mf->mat_nr); - - mat_nr_cache = mf->mat_nr; - } - } - - tf = tf_base ? tf_base + i : NULL; - tf_stencil = tf_stencil_base ? tf_stencil_base + i : NULL; - - if (drawParams) { - draw_option = drawParams(use_tface ? tf : NULL, (mcol != NULL), mf->mat_nr); - } - else { - if (index_mf_to_mpoly) { - orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i); - if (orig == ORIGINDEX_NONE) { - /* XXX, this is not really correct - * it will draw the previous faces context for this one when we don't know its settings. - * but better then skipping it altogether. - campbell */ - draw_option = DM_DRAW_OPTION_NORMAL; - } - else if (drawParamsMapped) { - draw_option = drawParamsMapped(userData, orig); - } - else { - if (nors) { - nors += 3; - } - continue; - } + else { + if (index_mf_to_mpoly) { + orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace); + if (orig == ORIGINDEX_NONE) { + /* XXX, this is not really correct + * it will draw the previous faces context for this one when we don't know its settings. + * but better then skipping it altogether. - campbell */ + draw_option = DM_DRAW_OPTION_NORMAL; } else if (drawParamsMapped) { - draw_option = drawParamsMapped(userData, i); - } - else { - if (nors) { - nors += 3; - } - continue; + draw_option = drawParamsMapped(userData, orig, mf[actualFace].mat_nr); } } - - if (draw_option != DM_DRAW_OPTION_SKIP) { - if (draw_option != DM_DRAW_OPTION_NO_MCOL && mcol) - cp = (unsigned char *) &mcol[i * 4]; - - if (!(lnors || (mf->flag & ME_SMOOTH))) { - if (nors) { - glNormal3fv(nors); - } - else { - float nor[3]; - if (mf->v4) { - normal_quad_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co); - } - else { - normal_tri_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co); - } - glNormal3fv(nor); - } - } - - glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES); - if (tf) glTexCoord2fv(tf->uv[0]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[0]); - if (cp) glColor3ub(cp[3], cp[2], cp[1]); - mvert = &mv[mf->v1]; - if (lnors) glNormal3sv((const GLshort *)lnors[0][0]); - else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); - glVertex3fv(mvert->co); - - if (tf) glTexCoord2fv(tf->uv[1]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[1]); - if (cp) glColor3ub(cp[7], cp[6], cp[5]); - mvert = &mv[mf->v2]; - if (lnors) glNormal3sv((const GLshort *)lnors[0][1]); - else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); - glVertex3fv(mvert->co); - - if (tf) glTexCoord2fv(tf->uv[2]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[2]); - if (cp) glColor3ub(cp[11], cp[10], cp[9]); - mvert = &mv[mf->v3]; - if (lnors) glNormal3sv((const GLshort *)lnors[0][2]); - else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); - glVertex3fv(mvert->co); - - if (mf->v4) { - if (tf) glTexCoord2fv(tf->uv[3]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[3]); - if (cp) glColor3ub(cp[15], cp[14], cp[13]); - mvert = &mv[mf->v4]; - if (lnors) glNormal3sv((const GLshort *)lnors[0][3]); - else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); - glVertex3fv(mvert->co); - } - glEnd(); + else if (drawParamsMapped) { + draw_option = drawParamsMapped(userData, actualFace, mf[actualFace].mat_nr); } - - if (nors) - nors += 3; - if (lnors) - lnors++; - } - } - else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ - GPU_vertex_setup(dm); - GPU_normal_setup(dm); - if (uvflag & DM_DRAW_USE_TEXPAINT_UV) - GPU_texpaint_uv_setup(dm); - else - GPU_uv_setup(dm); - if (mcol) { - GPU_color_setup(dm, colType); } - - if (!GPU_buffer_legacy(dm)) { - int tottri = dm->drawObject->tot_triangle_point / 3; - int next_actualFace = dm->drawObject->triangle_to_mface[0]; - - glShadeModel(GL_SMOOTH); - /* lastFlag = 0; */ /* UNUSED */ - for (i = 0; i < tottri; i++) { - int actualFace = next_actualFace; - DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; - int flush = 0; - - if (i != tottri - 1) - next_actualFace = dm->drawObject->triangle_to_mface[i + 1]; - - if (drawParams) { - draw_option = drawParams(use_tface && tf ? &tf[actualFace] : NULL, (mcol != NULL), mf[actualFace].mat_nr); - } - else { - if (index_mf_to_mpoly) { - orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace); - if (orig == ORIGINDEX_NONE) { - /* XXX, this is not really correct - * it will draw the previous faces context for this one when we don't know its settings. - * but better then skipping it altogether. - campbell */ - draw_option = DM_DRAW_OPTION_NORMAL; - } - else if (drawParamsMapped) { - draw_option = drawParamsMapped(userData, orig); - } - } - else if (drawParamsMapped) { - draw_option = drawParamsMapped(userData, actualFace); - } - } - - /* flush buffer if current triangle isn't drawable or it's last triangle */ - flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1); - - if (!flush && compareDrawOptions) { - /* also compare draw options and flush buffer if they're different + + /* flush buffer if current triangle isn't drawable or it's last triangle */ + flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1); + + if (!flush && compareDrawOptions) { + /* also compare draw options and flush buffer if they're different * need for face selection highlight in edit mode */ - flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0; - } - - if (flush) { - int first = startFace * 3; - /* Add one to the length if we're drawing at the end of the array */ - int count = (i - startFace + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3; - - if (count) { - if (mcol && draw_option != DM_DRAW_OPTION_NO_MCOL) - GPU_color_switch(1); - else - GPU_color_switch(0); - - glDrawArrays(GL_TRIANGLES, first, count); - } - - startFace = i + 1; - } + flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0; + } + + if (flush) { + int first = startFace * 3; + /* Add one to the length if we're drawing at the end of the array */ + int count = (i - startFace + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3; + + if (count) { + if (mcol && draw_option != DM_DRAW_OPTION_NO_MCOL) + GPU_color_switch(1); + else + GPU_color_switch(0); + + glDrawArrays(GL_TRIANGLES, first, count); } + + startFace = i + 1; } - - GPU_buffer_unbind(); - glShadeModel(GL_FLAT); } + + GPU_buffer_unbind(); + glShadeModel(GL_FLAT); + } static void cdDM_drawFacesTex(DerivedMesh *dm, @@ -968,7 +671,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, /* back-buffer always uses legacy since VBO's would need the * color array temporarily overwritten for drawing, then reset. */ - if (GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) { + if (G.f & G_BACKBUFSEL) { DEBUG_VBO("Using legacy code. cdDM_drawMappedFaces\n"); for (i = 0; i < dm->numTessFaceData; i++, mf++) { int drawSmooth = ((flag & DM_DRAW_ALWAYS_SMOOTH) || lnors) ? 1 : (mf->flag & ME_SMOOTH); @@ -1070,79 +773,85 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, } else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ int prevstart = 0; + int tottri; + GPU_vertex_setup(dm); GPU_normal_setup(dm); if (useColors && mcol) { GPU_color_setup(dm, colType); } - if (!GPU_buffer_legacy(dm)) { - int tottri = dm->drawObject->tot_triangle_point / 3; - glShadeModel(GL_SMOOTH); + tottri = dm->drawObject->tot_triangle_point / 3; + glShadeModel(GL_SMOOTH); + + if (tottri == 0) { + /* avoid buffer problems in following code */ + } + if (setDrawOptions == NULL) { + /* just draw the entire face array */ + glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3); + } + else { + /* we need to check if the next material changes */ + int next_actualFace = dm->drawObject->triangle_to_mface[0]; + int prev_mat_nr = -1; - if (tottri == 0) { - /* avoid buffer problems in following code */ - } - if (setDrawOptions == NULL) { - /* just draw the entire face array */ - glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3); - } - else { - /* we need to check if the next material changes */ - int next_actualFace = dm->drawObject->triangle_to_mface[0]; + for (i = 0; i < tottri; i++) { + //int actualFace = dm->drawObject->triangle_to_mface[i]; + int actualFace = next_actualFace; + MFace *mface = mf + actualFace; + /*int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mface->flag & ME_SMOOTH);*/ /* UNUSED */ + DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; + int flush = 0; - for (i = 0; i < tottri; i++) { - //int actualFace = dm->drawObject->triangle_to_mface[i]; - int actualFace = next_actualFace; - MFace *mface = mf + actualFace; - /*int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mface->flag & ME_SMOOTH);*/ /* UNUSED */ - DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; - int flush = 0; - - if (i != tottri - 1) - next_actualFace = dm->drawObject->triangle_to_mface[i + 1]; - - orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace; - - if (orig == ORIGINDEX_NONE) + if (i != tottri - 1) + next_actualFace = dm->drawObject->triangle_to_mface[i + 1]; + + orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace; + + if (mface->mat_nr != prev_mat_nr) { + if (setMaterial) draw_option = setMaterial(mface->mat_nr + 1, NULL); - else if (setDrawOptions != NULL) - draw_option = setDrawOptions(userData, orig); - - if (draw_option == DM_DRAW_OPTION_STIPPLE) { - glEnable(GL_POLYGON_STIPPLE); - glPolygonStipple(stipple_quarttone); - } - - /* Goal is to draw as long of a contiguous triangle + + prev_mat_nr = mface->mat_nr; + } + + if (setDrawOptions != NULL && (orig != ORIGINDEX_NONE)) + draw_option = setDrawOptions(userData, orig); + + if (draw_option == DM_DRAW_OPTION_STIPPLE) { + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_quarttone); + } + + /* Goal is to draw as long of a contiguous triangle * array as possible, so draw when we hit either an * invisible triangle or at the end of the array */ - - /* flush buffer if current triangle isn't drawable or it's last triangle... */ - flush = (ELEM(draw_option, DM_DRAW_OPTION_SKIP, DM_DRAW_OPTION_STIPPLE)) || (i == tottri - 1); - - /* ... or when material setting is dissferent */ - flush |= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr; - - if (!flush && compareDrawOptions) { - flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0; - } - - if (flush) { - int first = prevstart * 3; - /* Add one to the length if we're drawing at the end of the array */ - int count = (i - prevstart + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3; - - if (count) - glDrawArrays(GL_TRIANGLES, first, count); - - prevstart = i + 1; - - if (draw_option == DM_DRAW_OPTION_STIPPLE) - glDisable(GL_POLYGON_STIPPLE); - } + + /* flush buffer if current triangle isn't drawable or it's last triangle... */ + flush = (ELEM(draw_option, DM_DRAW_OPTION_SKIP, DM_DRAW_OPTION_STIPPLE)) || (i == tottri - 1); + + /* ... or when material setting is dissferent */ + flush |= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr; + + if (!flush && compareDrawOptions) { + flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0; + } + + if (flush) { + int first = prevstart * 3; + /* Add one to the length if we're drawing at the end of the array */ + int count = (i - prevstart + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3; + + if (count) + glDrawArrays(GL_TRIANGLES, first, count); + + prevstart = i + 1; + + if (draw_option == DM_DRAW_OPTION_STIPPLE) + glDisable(GL_POLYGON_STIPPLE); } } - + glShadeModel(GL_FLAT); } GPU_buffer_unbind(); @@ -1150,7 +859,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, } static void cdDM_drawMappedFacesTex(DerivedMesh *dm, - DMSetDrawOptions setDrawOptions, + DMSetDrawOptionsMappedTex setDrawOptions, DMCompareDrawOptions compareDrawOptions, void *userData, DMDrawFlag flag) { @@ -1270,7 +979,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, glShadeModel(GL_SMOOTH); - if (GPU_buffer_legacy(dm) || setDrawOptions != NULL) { + if (setDrawOptions != NULL) { DEBUG_VBO("Using legacy code. cdDM_drawMappedFacesGLSL\n"); memset(&attribs, 0, sizeof(attribs)); @@ -1329,11 +1038,11 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, ln3 = &lnors[a][2]; ln4 = &lnors[a][3]; } - + cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, ln1, smoothnormal); cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, ln2, smoothnormal); cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, ln3, smoothnormal); - + if (mface->v4) cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, ln4, smoothnormal); else @@ -1347,214 +1056,213 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int numdata = 0, elementsize = 0, offset; int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0; int i; - + const MFace *mf = mface; GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/ memset(&attribs, 0, sizeof(attribs)); - + GPU_vertex_setup(dm); GPU_normal_setup(dm); - - if (!GPU_buffer_legacy(dm)) { - for (i = 0; i < dm->drawObject->tot_triangle_point / 3; i++) { - - a = dm->drawObject->triangle_to_mface[i]; - - mface = mf + a; - new_matnr = mface->mat_nr + 1; - - if (new_matnr != matnr) { - numfaces = curface - start; - if (numfaces > 0) { - - if (do_draw) { - - if (numdata != 0) { - - GPU_buffer_unlock(buffer); - - GPU_interleaved_attrib_setup(buffer, datatypes, numdata); - } - - glDrawArrays(GL_TRIANGLES, start * 3, numfaces * 3); - - if (numdata != 0) { - - GPU_buffer_free(buffer); - - buffer = NULL; - } - + + for (i = 0; i < dm->drawObject->tot_triangle_point / 3; i++) { + + a = dm->drawObject->triangle_to_mface[i]; + + mface = mf + a; + new_matnr = mface->mat_nr + 1; + + if (new_matnr != matnr) { + numfaces = curface - start; + if (numfaces > 0) { + + if (do_draw) { + + if (numdata != 0) { + + GPU_buffer_unlock(buffer); + + GPU_interleaved_attrib_setup(buffer, datatypes, numdata); + } + + glDrawArrays(GL_TRIANGLES, start * 3, numfaces * 3); + + if (numdata != 0) { + + GPU_buffer_free(buffer); + + buffer = NULL; } + } - numdata = 0; - start = curface; - /* prevdraw = do_draw; */ /* UNUSED */ - do_draw = setMaterial(matnr = new_matnr, &gattribs); - if (do_draw) { - DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); - - if (attribs.totorco && attribs.orco.array) { - datatypes[numdata].index = attribs.orco.gl_index; - datatypes[numdata].size = 3; + } + numdata = 0; + start = curface; + /* prevdraw = do_draw; */ /* UNUSED */ + do_draw = setMaterial(matnr = new_matnr, &gattribs); + if (do_draw) { + DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); + + if (attribs.totorco && attribs.orco.array) { + datatypes[numdata].index = attribs.orco.gl_index; + datatypes[numdata].size = 3; + datatypes[numdata].type = GL_FLOAT; + numdata++; + } + for (b = 0; b < attribs.tottface; b++) { + if (attribs.tface[b].array) { + datatypes[numdata].index = attribs.tface[b].gl_index; + datatypes[numdata].size = 2; datatypes[numdata].type = GL_FLOAT; numdata++; } - for (b = 0; b < attribs.tottface; b++) { - if (attribs.tface[b].array) { - datatypes[numdata].index = attribs.tface[b].gl_index; - datatypes[numdata].size = 2; - datatypes[numdata].type = GL_FLOAT; - numdata++; - } - } - for (b = 0; b < attribs.totmcol; b++) { - if (attribs.mcol[b].array) { - datatypes[numdata].index = attribs.mcol[b].gl_index; - datatypes[numdata].size = 4; - datatypes[numdata].type = GL_UNSIGNED_BYTE; - numdata++; - } - } - if (attribs.tottang && attribs.tang.array) { - datatypes[numdata].index = attribs.tang.gl_index; + } + for (b = 0; b < attribs.totmcol; b++) { + if (attribs.mcol[b].array) { + datatypes[numdata].index = attribs.mcol[b].gl_index; datatypes[numdata].size = 4; - datatypes[numdata].type = GL_FLOAT; + datatypes[numdata].type = GL_UNSIGNED_BYTE; numdata++; } - if (numdata != 0) { - elementsize = GPU_attrib_element_size(datatypes, numdata); - buffer = GPU_buffer_alloc(elementsize * dm->drawObject->tot_triangle_point); - if (buffer == NULL) { - GPU_buffer_unbind(); - dm->drawObject->legacy = 1; - return; - } - varray = GPU_buffer_lock_stream(buffer); - if (varray == NULL) { - GPU_buffer_unbind(); - GPU_buffer_free(buffer); - dm->drawObject->legacy = 1; - return; - } + } + if (attribs.tottang && attribs.tang.array) { + datatypes[numdata].index = attribs.tang.gl_index; + datatypes[numdata].size = 4; + datatypes[numdata].type = GL_FLOAT; + numdata++; + } + if (numdata != 0) { + elementsize = GPU_attrib_element_size(datatypes, numdata); + buffer = GPU_buffer_alloc(elementsize * dm->drawObject->tot_triangle_point, false); + if (buffer == NULL) { + GPU_buffer_unbind(); + buffer = GPU_buffer_alloc(elementsize * dm->drawObject->tot_triangle_point, true); + return; } - else { - /* if the buffer was set, don't use it again. - * prevdraw was assumed true but didnt run so set to false - [#21036] */ - /* prevdraw = 0; */ /* UNUSED */ - buffer = NULL; + varray = GPU_buffer_lock_stream(buffer); + if (varray == NULL) { + GPU_buffer_unbind(); + GPU_buffer_free(buffer); + fprintf(stderr, "Out of memory, can't draw object\n"); + return; } } + else { + /* if the buffer was set, don't use it again. + * prevdraw was assumed true but didnt run so set to false - [#21036] */ + /* prevdraw = 0; */ /* UNUSED */ + buffer = NULL; + } } - + } + + if (do_draw && numdata != 0) { + offset = 0; + if (attribs.totorco && attribs.orco.array) { + copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v1]); + copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v2]); + copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v3]); + offset += sizeof(float) * 3; + } + for (b = 0; b < attribs.tottface; b++) { + if (attribs.tface[b].array) { + MTFace *tf = &attribs.tface[b].array[a]; + copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[0]); + copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[1]); + + copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[2]); + offset += sizeof(float) * 2; + } + } + for (b = 0; b < attribs.totmcol; b++) { + if (attribs.mcol[b].array) { + MCol *cp = &attribs.mcol[b].array[a * 4 + 0]; + GLubyte col[4]; + col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; + copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col); + cp = &attribs.mcol[b].array[a * 4 + 1]; + col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; + copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col); + cp = &attribs.mcol[b].array[a * 4 + 2]; + col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; + copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col); + offset += sizeof(unsigned char) * 4; + } + } + if (attribs.tottang && attribs.tang.array) { + const float *tang = attribs.tang.array[a * 4 + 0]; + copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang); + tang = attribs.tang.array[a * 4 + 1]; + copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang); + tang = attribs.tang.array[a * 4 + 2]; + copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang); + offset += sizeof(float) * 4; + } + (void)offset; + } + curface++; + if (mface->v4) { if (do_draw && numdata != 0) { offset = 0; if (attribs.totorco && attribs.orco.array) { - copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v1]); - copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v2]); - copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v3]); + copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v3]); + copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v4]); + copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v1]); offset += sizeof(float) * 3; } for (b = 0; b < attribs.tottface; b++) { if (attribs.tface[b].array) { MTFace *tf = &attribs.tface[b].array[a]; - copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[0]); - copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[1]); - - copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[2]); + copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[2]); + copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[3]); + copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[0]); offset += sizeof(float) * 2; } } for (b = 0; b < attribs.totmcol; b++) { if (attribs.mcol[b].array) { - MCol *cp = &attribs.mcol[b].array[a * 4 + 0]; + MCol *cp = &attribs.mcol[b].array[a * 4 + 2]; GLubyte col[4]; col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col); - cp = &attribs.mcol[b].array[a * 4 + 1]; + cp = &attribs.mcol[b].array[a * 4 + 3]; col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col); - cp = &attribs.mcol[b].array[a * 4 + 2]; + cp = &attribs.mcol[b].array[a * 4 + 0]; col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col); offset += sizeof(unsigned char) * 4; } } if (attribs.tottang && attribs.tang.array) { - const float *tang = attribs.tang.array[a * 4 + 0]; + const float *tang = attribs.tang.array[a * 4 + 2]; copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang); - tang = attribs.tang.array[a * 4 + 1]; + tang = attribs.tang.array[a * 4 + 3]; copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang); - tang = attribs.tang.array[a * 4 + 2]; + tang = attribs.tang.array[a * 4 + 0]; copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang); offset += sizeof(float) * 4; } (void)offset; } curface++; - if (mface->v4) { - if (do_draw && numdata != 0) { - offset = 0; - if (attribs.totorco && attribs.orco.array) { - copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v3]); - copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v4]); - copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v1]); - offset += sizeof(float) * 3; - } - for (b = 0; b < attribs.tottface; b++) { - if (attribs.tface[b].array) { - MTFace *tf = &attribs.tface[b].array[a]; - copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[2]); - copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[3]); - copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[0]); - offset += sizeof(float) * 2; - } - } - for (b = 0; b < attribs.totmcol; b++) { - if (attribs.mcol[b].array) { - MCol *cp = &attribs.mcol[b].array[a * 4 + 2]; - GLubyte col[4]; - col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; - copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col); - cp = &attribs.mcol[b].array[a * 4 + 3]; - col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; - copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col); - cp = &attribs.mcol[b].array[a * 4 + 0]; - col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; - copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col); - offset += sizeof(unsigned char) * 4; - } - } - if (attribs.tottang && attribs.tang.array) { - const float *tang = attribs.tang.array[a * 4 + 2]; - copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang); - tang = attribs.tang.array[a * 4 + 3]; - copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang); - tang = attribs.tang.array[a * 4 + 0]; - copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang); - offset += sizeof(float) * 4; - } - (void)offset; - } - curface++; - i++; - } + i++; } - numfaces = curface - start; - if (numfaces > 0) { - if (do_draw) { - if (numdata != 0) { - GPU_buffer_unlock(buffer); - GPU_interleaved_attrib_setup(buffer, datatypes, numdata); - } - glDrawArrays(GL_TRIANGLES, start * 3, (curface - start) * 3); + } + numfaces = curface - start; + if (numfaces > 0) { + if (do_draw) { + if (numdata != 0) { + GPU_buffer_unlock(buffer); + GPU_interleaved_attrib_setup(buffer, datatypes, numdata); } + glDrawArrays(GL_TRIANGLES, start * 3, (curface - start) * 3); } - GPU_buffer_unbind(); } + GPU_buffer_unbind(); + GPU_buffer_free(buffer); } - + glShadeModel(GL_FLAT); } @@ -2725,10 +2433,10 @@ static bool poly_gset_compare_fn(const void *k1, const void *k2) (pk1->totloops == pk2->totloops)) { /* Equality - note that this does not mean equality of polys */ - return 0; + return false; } else { - return 1; + return true; } } diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index aacf02555d4..3932a8ead2f 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -789,7 +789,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) // Kicking goal factor to simplify things...who uses that anyway? // ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal ); - verts->goal = powf(verts->goal, 4.0f); + verts->goal = pow4f(verts->goal); if ( verts->goal >= SOFTGOALSNAP ) verts->flags |= CLOTH_VERT_FLAG_PINNED; } diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 2f600935b1e..3030ee4b4a4 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -648,7 +648,7 @@ static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, Collis { int i; - *collisions = (CollPair *) MEM_mallocN(sizeof(CollPair) * numresult * 64, "collision array" ); // * 4 since cloth_collision_static can return more than 1 collision + *collisions = (CollPair *) MEM_mallocN(sizeof(CollPair) * numresult * 4, "collision array" ); // * 4 since cloth_collision_static can return more than 1 collision *collisions_index = *collisions; for ( i = 0; i < numresult; i++ ) { diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index a63e06c7cb8..89c3e4b0cfc 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -50,7 +50,6 @@ #include "IMB_colormanagement.h" -#include "IMB_imbuf.h" #include "IMB_imbuf_types.h" /* ********************************* color curve ********************* */ diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index e4b60c12d64..8fedf37fb95 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -185,6 +185,10 @@ void BKE_constraints_clear_evalob(bConstraintOb *cob) /* calculate delta of constraints evaluation */ invert_m4_m4(imat, cob->startmat); + /* XXX This would seem to be in wrong order. However, it does not work in 'right' order - would be nice to + * understand why premul is needed here instead of usual postmul? + * In any case, we **do not get a delta** here (e.g. startmat & matrix having same location, still gives + * a 'delta' with non-null translation component :/ ).*/ mul_m4_m4m4(delta, cob->matrix, imat); /* copy matrices back to source */ @@ -1967,7 +1971,7 @@ static void pycon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTa static void pycon_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets) { #ifndef WITH_PYTHON - (void)con; (void)cob; (void)targets; /* unused */ + UNUSED_VARS(con, cob, targets); return; #else bPythonConstraint *data = con->data; @@ -2613,6 +2617,8 @@ static void stretchto_new_data(void *cdata) data->plane = 0; data->orglength = 0.0; data->bulge = 1.0; + data->bulge_max = 1.0f; + data->bulge_min = 1.0f; } static void stretchto_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata) @@ -2689,39 +2695,28 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t bulge = powf(data->orglength / dist, data->bulge); - if (data->flag & STRETCHTOCON_USE_BULGE_MAX) { - const float bulge_median = ((data->flag & STRETCHTOCON_USE_BULGE_MIN) ? - 0.5f * (data->bulge_min + data->bulge_max) : 0.0f); - const float bulge_range = data->bulge_max - bulge_median; - float x, bulge_smoothed; - - x = bulge_range != 0.0f ? (bulge - bulge_median) / bulge_range : 0.0f; - CLAMP(x, -1.0f, 1.0f); - bulge_smoothed = bulge_median + bulge_range * sinf(0.5f*M_PI * x); - - if (data->flag & STRETCHTOCON_USE_BULGE_MIN) { - CLAMP_MIN(bulge, data->bulge_min); + if (bulge > 1.0f) { + if (data->flag & STRETCHTOCON_USE_BULGE_MAX) { + float bulge_max = max_ff(data->bulge_max, 1.0f); + float hard = min_ff(bulge, bulge_max); + + float range = bulge_max - 1.0f; + float scale = (range > 0.0f) ? 1.0f / range : 0.0f; + float soft = 1.0f + range * atanf((bulge - 1.0f) * scale) / (0.5f * M_PI); + + bulge = interpf(soft, hard, data->bulge_smooth); } - CLAMP_MAX(bulge, data->bulge_max); - - bulge = interpf(bulge_smoothed, bulge, data->bulge_smooth); } - else if (data->flag & STRETCHTOCON_USE_BULGE_MIN) { - /* The quadratic formula below creates a smooth asymptote - * of the clamped bulge value. By scaling x with the inverse smooth factor - * the smoothed area becomes smaller ("less smoothing"). - * For very small smoothing factor below epsilon it is replaced - * by the clamped version to avoid floating point precision issues. - */ - const float epsilon = 0.000001f; - if (data->bulge_smooth < epsilon) { - CLAMP_MIN(bulge, data->bulge_min); - } - else { - float scale = data->bulge_smooth; - float inv_scale = 1.0f / scale; - float x = (bulge - data->bulge_min) * 0.5f * inv_scale; - bulge = scale * (x + sqrtf((x * x) + 1.0f)) + data->bulge_min; + if (bulge < 1.0f) { + if (data->flag & STRETCHTOCON_USE_BULGE_MIN) { + float bulge_min = CLAMPIS(data->bulge_max, 0.0f, 1.0f); + float hard = max_ff(bulge, bulge_min); + + float range = 1.0f - bulge_min; + float scale = (range > 0.0f) ? 1.0f / range : 0.0f; + float soft = 1.0f - range * atanf((1.0f - bulge) * scale) / (0.5f * M_PI); + + bulge = interpf(soft, hard, data->bulge_smooth); } } @@ -3466,10 +3461,16 @@ static void shrinkwrap_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra } /* transform normal into requested space */ - unit_m4(mat); - BKE_constraint_mat_convertspace(cob->ob, cob->pchan, mat, CONSTRAINT_SPACE_LOCAL, scon->projAxisSpace); - invert_m4(mat); - mul_mat3_m4_v3(mat, no); + /* We cannot use BKE_constraint_mat_convertspace here, it does not take into account scaling... + * In theory we would not need it, but in this case we'd have to tweak SpaceTransform to also + * optionally ignore scaling when handling normals - simpler to directly call BKE_object_to_mat4 + * if needed! See T42447. */ + if (scon->projAxisSpace == CONSTRAINT_SPACE_WORLD) { + BKE_object_to_mat4(cob->ob, mat); + invert_m4(mat); + mul_mat3_m4_v3(mat, no); + } + /* Else, we remain in local space, nothing to do. */ if (normalize_v3(no) < FLT_EPSILON) { fail = true; @@ -4394,10 +4395,10 @@ bool BKE_constraint_remove(ListBase *list, bConstraint *con) if (con) { BKE_constraint_free_data(con); BLI_freelinkN(list, con); - return 1; + return true; } else - return 0; + return false; } /* ......... */ @@ -4661,15 +4662,15 @@ bool BKE_constraints_proxylocked_owner(Object *ob, bPoseChannel *pchan) /* On bone-level, check if bone is on proxy-protected layer */ if ((pchan->bone) && (pchan->bone->layer & arm->layer_protected)) - return 1; + return true; } else { /* FIXME: constraints on object-level are not handled well yet */ - return 1; + return true; } } - return 0; + return false; } /* -------- Target-Matrix Stuff ------- */ diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index de285f87444..8f6c9735aaf 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -37,6 +37,7 @@ #include "DNA_windowmanager_types.h" #include "DNA_object_types.h" #include "DNA_linestyle_types.h" +#include "DNA_gpencil_types.h" #include "BLI_listbase.h" #include "BLI_string.h" @@ -257,7 +258,7 @@ static void *ctx_wm_python_context_get( } } #else - (void)C, (void)member, (void)member_type; + UNUSED_VARS(C, member, member_type); #endif /* don't allow UI context access from non-main threads */ @@ -588,7 +589,7 @@ int ctx_data_list_count(const bContext *C, int (*func)(const bContext *, ListBas ListBase list; if (func(C, &list)) { - int tot = BLI_countlist(&list); + int tot = BLI_listbase_count(&list); BLI_freelistN(&list); return tot; } @@ -1090,3 +1091,34 @@ int CTX_data_visible_pose_bones(const bContext *C, ListBase *list) { return ctx_data_collection_get(C, "visible_pose_bones", list); } + +bGPdata *CTX_data_gpencil_data(const bContext *C) +{ + return ctx_data_pointer_get(C, "gpencil_data"); +} + +bGPDlayer *CTX_data_active_gpencil_layer(const bContext *C) +{ + return ctx_data_pointer_get(C, "active_gpencil_layer"); +} + +bGPDframe *CTX_data_active_gpencil_frame(const bContext *C) +{ + return ctx_data_pointer_get(C, "active_gpencil_frame"); +} + +int CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list) +{ + return ctx_data_collection_get(C, "visible_gpencil_layers", list); +} + +int CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list) +{ + return ctx_data_collection_get(C, "editable_gpencil_layers", list); +} + +int CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list) +{ + return ctx_data_collection_get(C, "editable_gpencil_strokes", list); +} + diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index ca58035d638..937ceffc765 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -4312,7 +4312,7 @@ bool BKE_curve_center_bounds(Curve *cu, float cent[3]) } -void BKE_curve_transform_ex(Curve *cu, float mat[4][4], bool do_keys, float unit_scale) +void BKE_curve_transform_ex(Curve *cu, float mat[4][4], const bool do_keys, const float unit_scale) { Nurb *nu; BPoint *bp; @@ -4348,13 +4348,13 @@ void BKE_curve_transform_ex(Curve *cu, float mat[4][4], bool do_keys, float unit } } -void BKE_curve_transform(Curve *cu, float mat[4][4], bool do_keys) +void BKE_curve_transform(Curve *cu, float mat[4][4], const bool do_keys) { float unit_scale = mat4_to_scale(mat); BKE_curve_transform_ex(cu, mat, do_keys, unit_scale); } -void BKE_curve_translate(Curve *cu, float offset[3], bool do_keys) +void BKE_curve_translate(Curve *cu, float offset[3], const bool do_keys) { ListBase *nurb_lb = BKE_curve_nurbs_get(cu); Nurb *nu; diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 63eb3b397b0..5e86ca596cf 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -144,6 +144,9 @@ typedef struct LayerTypeInfo { /** a function to determine file size */ size_t (*filesize)(CDataFile *cdf, const void *data, int count); + + /** a function to determine max allowed number of layers, should be NULL or return -1 if no limit */ + int (*layers_max)(void); } LayerTypeInfo; static void layerCopy_mdeformvert(const void *source, void *dest, @@ -379,6 +382,11 @@ static void layerDefault_tface(void *data, int count) tf[i] = default_tf; } +static int layerMaxNum_tface(void) +{ + return MAX_MTFACE; +} + static void layerCopy_propFloat(const void *source, void *dest, int count) { @@ -745,6 +753,11 @@ static void layerInterp_mloopcol(void **sources, const float *weights, mc->a = (int)col.a; } +static int layerMaxNum_mloopcol(void) +{ + return MAX_MCOL; +} + static void layerCopyValue_mloopuv(const void *source, void *dest) { const MLoopUV *luv1 = source; @@ -1093,12 +1106,12 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { /* 4: CD_MFACE */ {sizeof(MFace), "MFace", 1, NULL, NULL, NULL, NULL, NULL, NULL}, /* 5: CD_MTFACE */ - {sizeof(MTFace), "MTFace", 1, N_("UVMap"), layerCopy_tface, NULL, - layerInterp_tface, layerSwap_tface, layerDefault_tface}, + {sizeof(MTFace), "MTFace", 1, N_("UVMap"), layerCopy_tface, NULL, layerInterp_tface, layerSwap_tface, + layerDefault_tface, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, layerMaxNum_tface}, /* 6: CD_MCOL */ /* 4 MCol structs per face */ {sizeof(MCol) * 4, "MCol", 4, N_("Col"), NULL, NULL, layerInterp_mcol, - layerSwap_mcol, layerDefault_mcol}, + layerSwap_mcol, layerDefault_mcol, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, layerMaxNum_mloopcol}, /* 7: CD_ORIGINDEX */ {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, layerDefault_origindex}, /* 8: CD_NORMAL */ @@ -1119,15 +1132,16 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { {sizeof(float) * 3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, /* 15: CD_MTEXPOLY */ /* note, when we expose the UV Map / TexFace split to the user, change this back to face Texture */ - {sizeof(MTexPoly), "MTexPoly", 1, N_("UVMap") /* "Face Texture" */, NULL, NULL, NULL, NULL, NULL}, + {sizeof(MTexPoly), "MTexPoly", 1, N_("UVMap") /* "Face Texture" */, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, layerMaxNum_tface}, /* 16: CD_MLOOPUV */ {sizeof(MLoopUV), "MLoopUV", 1, N_("UVMap"), NULL, NULL, layerInterp_mloopuv, NULL, NULL, layerEqual_mloopuv, layerMultiply_mloopuv, layerInitMinMax_mloopuv, - layerAdd_mloopuv, layerDoMinMax_mloopuv, layerCopyValue_mloopuv}, + layerAdd_mloopuv, layerDoMinMax_mloopuv, layerCopyValue_mloopuv, NULL, NULL, NULL, layerMaxNum_tface}, /* 17: CD_MLOOPCOL */ {sizeof(MLoopCol), "MLoopCol", 1, N_("Col"), NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol, - layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol}, + layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol, NULL, NULL, NULL, layerMaxNum_mloopcol}, /* 18: CD_TANGENT */ {sizeof(float) * 4 * 4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, /* 19: CD_MDISPS */ @@ -1319,7 +1333,8 @@ bool CustomData_merge(const struct CustomData *source, struct CustomData *dest, /*const LayerTypeInfo *typeInfo;*/ CustomDataLayer *layer, *newlayer; void *data; - int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0, lastflag = 0; + int i, type, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0, lastflag = 0; + int number = 0, maxnumber = -1; bool changed = false; for (i = 0; i < source->totlayer; ++i) { @@ -1330,6 +1345,7 @@ bool CustomData_merge(const struct CustomData *source, struct CustomData *dest, if (type != lasttype) { number = 0; + maxnumber = CustomData_layertype_layers_max(type); lastactive = layer->active; lastrender = layer->active_rnd; lastclone = layer->active_clone; @@ -1342,6 +1358,7 @@ bool CustomData_merge(const struct CustomData *source, struct CustomData *dest, if (lastflag & CD_FLAG_NOCOPY) continue; else if (!(mask & CD_TYPE_AS_MASK(type))) continue; + else if ((maxnumber != -1) && (number >= maxnumber)) continue; else if (CustomData_get_layer_named(dest, type, layer->name)) continue; switch (alloctype) { @@ -1781,7 +1798,8 @@ bool CustomData_free_layer(CustomData *data, int type, int totelem, int index) const int n = index - CustomData_get_layer_index(data, type); int i; - if (index < 0) return 0; + if (index < 0) + return false; customData_free_layer__internal(&data->layers[index], totelem); @@ -1811,14 +1829,15 @@ bool CustomData_free_layer(CustomData *data, int type, int totelem, int index) customData_update_offsets(data); - return 1; + return true; } bool CustomData_free_layer_active(CustomData *data, int type, int totelem) { int index = 0; index = CustomData_get_active_layer_index(data, type); - if (index == -1) return 0; + if (index == -1) + return false; return CustomData_free_layer(data, type, totelem, index); } @@ -1856,14 +1875,13 @@ int CustomData_number_of_layers_typemask(const CustomData *data, CustomDataMask return number; } -void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int type, const int totelem) +static void *customData_duplicate_referenced_layer_index(CustomData *data, const int layer_index, const int totelem) { CustomDataLayer *layer; - int layer_index; - /* get the layer index of the first layer of type */ - layer_index = CustomData_get_active_layer_index(data, type); - if (layer_index == -1) return NULL; + if (layer_index == -1) { + return NULL; + } layer = &data->layers[layer_index]; @@ -1879,8 +1897,9 @@ void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int t typeInfo->copy(layer->data, dest_data, totelem); layer->data = dest_data; } - else + else { layer->data = MEM_dupallocN(layer->data); + } layer->flag &= ~CD_FLAG_NOFREE; } @@ -1888,37 +1907,34 @@ void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int t return layer->data; } -void *CustomData_duplicate_referenced_layer_named(struct CustomData *data, - const int type, const char *name, const int totelem) +void *CustomData_duplicate_referenced_layer(CustomData *data, const int type, const int totelem) { - CustomDataLayer *layer; int layer_index; - /* get the layer index of the desired layer */ - layer_index = CustomData_get_named_layer_index(data, type, name); - if (layer_index == -1) return NULL; + /* get the layer index of the first layer of type */ + layer_index = CustomData_get_active_layer_index(data, type); - layer = &data->layers[layer_index]; + return customData_duplicate_referenced_layer_index(data, layer_index, totelem); +} - if (layer->flag & CD_FLAG_NOFREE) { - /* MEM_dupallocN won't work in case of complex layers, like e.g. - * CD_MDEFORMVERT, which has pointers to allocated data... - * So in case a custom copy function is defined, use it! - */ - const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); +void *CustomData_duplicate_referenced_layer_n(CustomData *data, const int type, const int n, const int totelem) +{ + int layer_index; - if (typeInfo->copy) { - char *dest_data = MEM_mallocN(typeInfo->size * totelem, "CD duplicate ref layer"); - typeInfo->copy(layer->data, dest_data, totelem); - layer->data = dest_data; - } - else - layer->data = MEM_dupallocN(layer->data); + /* get the layer index of the desired layer */ + layer_index = CustomData_get_layer_index_n(data, type, n); - layer->flag &= ~CD_FLAG_NOFREE; - } + return customData_duplicate_referenced_layer_index(data, layer_index, totelem); +} - return layer->data; +void *CustomData_duplicate_referenced_layer_named(CustomData *data, const int type, const char *name, const int totelem) +{ + int layer_index; + + /* get the layer index of the desired layer */ + layer_index = CustomData_get_named_layer_index(data, type, name); + + return customData_duplicate_referenced_layer_index(data, layer_index, totelem); } bool CustomData_is_referenced_layer(struct CustomData *data, int type) @@ -1928,7 +1944,8 @@ bool CustomData_is_referenced_layer(struct CustomData *data, int type) /* get the layer index of the first layer of type */ layer_index = CustomData_get_active_layer_index(data, type); - if (layer_index == -1) return 0; + if (layer_index == -1) + return false; layer = &data->layers[layer_index]; @@ -2246,8 +2263,8 @@ bool CustomData_set_layer_name(const CustomData *data, int type, int n, const ch /* get the layer index of the first layer of type */ int layer_index = CustomData_get_layer_index_n(data, type, n); - if (layer_index == -1) return false; - if (!name) return false; + if ((layer_index == -1) || !name) + return false; BLI_strncpy(data->layers[layer_index].name, name, sizeof(data->layers[layer_index].name)); @@ -3039,6 +3056,24 @@ bool CustomData_layertype_is_singleton(int type) return typeInfo->defaultname == NULL; } +/** + * \return Maximum number of layers of given \a type, -1 means 'no limit'. + */ +int CustomData_layertype_layers_max(const int type) +{ + const LayerTypeInfo *typeInfo = layerType_getInfo(type); + + /* Same test as for singleton above. */ + if (typeInfo->defaultname == NULL) { + return 1; + } + else if (typeInfo->layers_max == NULL) { + return -1; + } + + return typeInfo->layers_max(); +} + static bool CustomData_is_property_layer(int type) { if ((type == CD_PROP_FLT) || (type == CD_PROP_INT) || (type == CD_PROP_STR)) diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 528ff2d7b19..d3148dbc8e9 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -441,7 +441,7 @@ int defgroup_name_index(Object *ob, const char *name) /* note, must be freed */ int *defgroup_flip_map(Object *ob, int *flip_map_len, const bool use_default) { - int defbase_tot = *flip_map_len = BLI_countlist(&ob->defbase); + int defbase_tot = *flip_map_len = BLI_listbase_count(&ob->defbase); if (defbase_tot == 0) { return NULL; @@ -480,7 +480,7 @@ int *defgroup_flip_map(Object *ob, int *flip_map_len, const bool use_default) /* note, must be freed */ int *defgroup_flip_map_single(Object *ob, int *flip_map_len, const bool use_default, int defgroup) { - int defbase_tot = *flip_map_len = BLI_countlist(&ob->defbase); + int defbase_tot = *flip_map_len = BLI_listbase_count(&ob->defbase); if (defbase_tot == 0) { return NULL; diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 44a0b93fc01..566aa6657b9 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2357,6 +2357,15 @@ void DAG_on_visible_update(Main *bmain, const bool do_time) ob->recalc |= OB_RECALC_DATA; lib_id_recalc_tag(bmain, &ob->id); } + /* This should not be needed here, but in some cases, like after a redo, we can end up with + * a wrong final matrix (see T42472). + * Quoting Sergey, this comes from BKE_object_handle_update_ex, which is calling + * BKE_object_where_is_calc_ex when it shouldn't, but that issue is not easily fixable. + */ + else { + ob->recalc |= OB_RECALC_OB; + lib_id_recalc_tag(bmain, &ob->id); + } if (ob->proxy && (ob->proxy_group == NULL)) { ob->proxy->recalc |= OB_RECALC_DATA; lib_id_recalc_tag(bmain, &ob->id); diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 98f0025921d..80a8d373220 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -37,7 +37,6 @@ #include "MEM_guardedalloc.h" #include "DNA_curve_types.h" -#include "DNA_meshdata_types.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" #include "DNA_vfont_types.h" @@ -1271,6 +1270,7 @@ void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase, } if (!for_orco) { + BKE_nurbList_duplicate(&ob->curve_cache->deformed_nurbs, &nubase); curve_calc_modifiers_post(scene, ob, &nubase, dispbase, r_dm_final, for_render, use_render_resolution); } @@ -1729,8 +1729,10 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba } } - if (!for_orco) + if (!for_orco) { + BKE_nurbList_duplicate(&ob->curve_cache->deformed_nurbs, &nubase); curve_calc_modifiers_post(scene, ob, &nubase, dispbase, r_dm_final, for_render, use_render_resolution); + } if (cu->flag & CU_DEFORM_FILL && !ob->derivedFinal) { curve_to_filledpoly(cu, &nubase, dispbase); diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 4719013e2f8..e3fa4733e6c 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -71,10 +71,6 @@ #include "BKE_scene.h" #include "BKE_texture.h" -#include "RNA_access.h" -#include "RNA_define.h" -#include "RNA_enum_types.h" - /* for image output */ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -257,20 +253,20 @@ static int dynamicPaint_surfaceNumOfPoints(DynamicPaintSurface *surface) bool dynamicPaint_surfaceHasColorPreview(DynamicPaintSurface *surface) { if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) { - return 0; + return false; } else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE || surface->type == MOD_DPAINT_SURFACE_T_WAVE) { - return 0; + return false; } else { - return 1; + return true; } } else { - return 1; + return true; } } @@ -325,7 +321,7 @@ bool dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, Object else if (output == 1) name = surface->output_name2; else - return 0; + return false; if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) { @@ -336,7 +332,7 @@ bool dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, Object return (defgroup_name_index(ob, surface->output_name) != -1); } - return 0; + return false; } static bool surface_duplicateOutputExists(void *arg, const char *name) @@ -1106,13 +1102,13 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str canvas = pmd->canvas = MEM_callocN(sizeof(DynamicPaintCanvasSettings), "DynamicPaint Canvas"); if (!canvas) - return 0; + return false; canvas->pmd = pmd; canvas->dm = NULL; /* Create one surface */ if (!dynamicPaint_createNewSurface(canvas, scene)) - return 0; + return false; } else if (type == MOD_DYNAMICPAINT_TYPE_BRUSH) { @@ -1122,7 +1118,7 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str brush = pmd->brush = MEM_callocN(sizeof(DynamicPaintBrushSettings), "DynamicPaint Paint"); if (!brush) - return 0; + return false; brush->pmd = pmd; brush->psys = NULL; @@ -1157,7 +1153,7 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str brush->paint_ramp = add_colorband(false); if (!brush->paint_ramp) - return 0; + return false; ramp = brush->paint_ramp->data; /* Add default smooth-falloff ramp. */ ramp[0].r = ramp[0].g = ramp[0].b = ramp[0].a = 1.0f; @@ -1173,7 +1169,7 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str brush->vel_ramp = add_colorband(false); if (!brush->vel_ramp) - return 0; + return false; ramp = brush->vel_ramp->data; ramp[0].r = ramp[0].g = ramp[0].b = ramp[0].a = ramp[0].pos = 0.0f; ramp[1].r = ramp[1].g = ramp[1].b = ramp[1].a = ramp[1].pos = 1.0f; @@ -1181,10 +1177,11 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str } } } - else - return 0; + else { + return false; + } - return 1; + return true; } void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct DynamicPaintModifierData *tpmd) @@ -1630,12 +1627,12 @@ bool dynamicPaint_resetSurface(Scene *scene, DynamicPaintSurface *surface) if (surface->data) dynamicPaint_freeSurfaceData(surface); /* don't reallocate for image sequence types. they get handled only on bake */ - if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) return 1; - if (numOfPoints < 1) return 0; + if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) return true; + if (numOfPoints < 1) return false; /* allocate memory */ surface->data = MEM_callocN(sizeof(PaintSurfaceData), "PaintSurfaceData"); - if (!surface->data) return 0; + if (!surface->data) return false; /* allocate data depending on surface type and format */ surface->data->total_points = numOfPoints; @@ -1646,7 +1643,7 @@ bool dynamicPaint_resetSurface(Scene *scene, DynamicPaintSurface *surface) if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) dynamicPaint_setInitialColor(scene, surface); - return 1; + return true; } /* make sure allocated surface size matches current requirements */ @@ -1655,7 +1652,7 @@ static bool dynamicPaint_checkSurfaceData(Scene *scene, DynamicPaintSurface *sur if (!surface->data || ((dynamicPaint_surfaceNumOfPoints(surface) != surface->data->total_points))) { return dynamicPaint_resetSurface(scene, surface); } - return 1; + return true; } diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index ce7804d9878..559eefc834e 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -56,6 +56,7 @@ #include "MEM_guardedalloc.h" #include "GPU_extensions.h" +#include "GPU_draw.h" #include "GPU_glew.h" extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */ @@ -607,13 +608,17 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int drawSmooth; efa = ltri[0]->f; - drawSmooth = lnors || ((flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH)); - + drawSmooth = lnors || ((flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH)); + draw_option = (!setDrawOptions ? DM_DRAW_OPTION_NORMAL : setDrawOptions(userData, BM_elem_index_get(efa))); + if (draw_option != DM_DRAW_OPTION_SKIP) { const GLenum poly_type = GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */ + + GPU_enable_material(efa->mat_nr + 1, NULL); + if (draw_option == DM_DRAW_OPTION_STIPPLE) { /* enabled with stipple */ if (poly_prev != GL_ZERO) glEnd(); @@ -717,7 +722,7 @@ static void bmdm_get_tri_colpreview(BMLoop *ls[3], MLoopCol *lcol[3], unsigned c static void emDM_drawFacesTex_common(DerivedMesh *dm, DMSetDrawOptionsTex drawParams, - DMSetDrawOptions drawParamsMapped, + DMSetDrawOptionsMappedTex drawParamsMapped, DMCompareDrawOptions compareDrawOptions, void *userData) { @@ -785,7 +790,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, if (drawParams) draw_option = drawParams(&mtf, has_vcol, efa->mat_nr); else if (drawParamsMapped) - draw_option = drawParamsMapped(userData, BM_elem_index_get(efa)); + draw_option = drawParamsMapped(userData, BM_elem_index_get(efa), BM_elem_index_get(efa)); else draw_option = DM_DRAW_OPTION_NORMAL; @@ -854,7 +859,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, if (drawParams) draw_option = drawParams(&mtf, has_vcol, efa->mat_nr); else if (drawParamsMapped) - draw_option = drawParamsMapped(userData, BM_elem_index_get(efa)); + draw_option = drawParamsMapped(userData, BM_elem_index_get(efa), BM_elem_index_get(efa)); else draw_option = DM_DRAW_OPTION_NORMAL; @@ -916,7 +921,7 @@ static void emDM_drawFacesTex(DerivedMesh *dm, } static void emDM_drawMappedFacesTex(DerivedMesh *dm, - DMSetDrawOptions setDrawOptions, + DMSetDrawOptionsMappedTex setDrawOptions, DMCompareDrawOptions compareDrawOptions, void *userData, DMDrawFlag UNUSED(flag)) { @@ -970,7 +975,7 @@ static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const B GLubyte col[4]; if (attribs->mcol[i].em_offset != -1) { const MLoopCol *cp = BM_ELEM_CD_GET_VOID_P(loop, attribs->mcol[i].em_offset); - col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; + copy_v4_v4_char((char *)col, &cp->r); } else { col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0; diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index e90a0891436..64300ad6f52 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -309,17 +309,18 @@ int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix, return matches; } -FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction **action, bool *r_driven) +FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, AnimData **adt, bAction **action, bool *r_driven) { - return rna_get_fcurve_context_ui(NULL, ptr, prop, rnaindex, action, r_driven); + return rna_get_fcurve_context_ui(NULL, ptr, prop, rnaindex, adt, action, r_driven); } FCurve *rna_get_fcurve_context_ui(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int rnaindex, - bAction **action, bool *r_driven) + AnimData **animdata, bAction **action, bool *r_driven) { FCurve *fcu = NULL; PointerRNA tptr = *ptr; + if (animdata) *animdata = NULL; *r_driven = false; /* there must be some RNA-pointer + property combon */ @@ -350,11 +351,14 @@ FCurve *rna_get_fcurve_context_ui(bContext *C, PointerRNA *ptr, PropertyRNA *pro if (!fcu && (adt->drivers.first)) { fcu = list_find_fcurve(&adt->drivers, path, rnaindex); - if (fcu) + if (fcu) { + if (animdata) *animdata = adt; *r_driven = true; + } } if (fcu && action) { + if (animdata) *animdata = adt; *action = adt->action; break; } @@ -683,11 +687,11 @@ bool fcurve_are_keyframes_usable(FCurve *fcu) { /* F-Curve must exist */ if (fcu == NULL) - return 0; + return false; /* F-Curve must not have samples - samples are mutually exclusive of keyframes */ if (fcu->fpt) - return 0; + return false; /* if it has modifiers, none of these should "drastically" alter the curve */ if (fcu->modifiers.first) { @@ -714,7 +718,7 @@ bool fcurve_are_keyframes_usable(FCurve *fcu) FMod_Generator *data = (FMod_Generator *)fcm->data; if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0) - return 0; + return false; break; } case FMODIFIER_TYPE_FN_GENERATOR: @@ -722,18 +726,18 @@ bool fcurve_are_keyframes_usable(FCurve *fcu) FMod_FunctionGenerator *data = (FMod_FunctionGenerator *)fcm->data; if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0) - return 0; + return false; break; } /* always harmful - cannot allow */ default: - return 0; + return false; } } } /* keyframes are usable */ - return 1; + return true; } bool BKE_fcurve_is_protected(FCurve *fcu) @@ -2153,18 +2157,29 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime v4[0] = bezt->vec[1][0]; v4[1] = bezt->vec[1][1]; - /* adjust handles so that they don't overlap (forming a loop) */ - correct_bezpart(v1, v2, v3, v4); - - /* try to get a value for this position - if failure, try another set of points */ - b = findzero(evaltime, v1[0], v2[0], v3[0], v4[0], opl); - if (b) { - berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1); - cvalue = opl[0]; - /* break; */ + if (fabsf(v1[1] - v4[1]) < FLT_EPSILON && + fabsf(v2[1] - v3[1]) < FLT_EPSILON && + fabsf(v3[1] - v4[1]) < FLT_EPSILON) + { + /* Optimisation: If all the handles are flat/at the same values, + * the value is simply the shared value (see T40372 -> F91346) + */ + cvalue = v1[1]; } else { - if (G.debug & G_DEBUG) printf(" ERROR: findzero() failed at %f with %f %f %f %f\n", evaltime, v1[0], v2[0], v3[0], v4[0]); + /* adjust handles so that they don't overlap (forming a loop) */ + correct_bezpart(v1, v2, v3, v4); + + /* try to get a value for this position - if failure, try another set of points */ + b = findzero(evaltime, v1[0], v2[0], v3[0], v4[0], opl); + if (b) { + berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1); + cvalue = opl[0]; + /* break; */ + } + else { + if (G.debug & G_DEBUG) printf(" ERROR: findzero() failed at %f with %f %f %f %f\n", evaltime, v1[0], v2[0], v3[0], v4[0]); + } } break; diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index 56b087e7eb6..af0db5e1c47 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -27,8 +27,6 @@ * \ingroup bke */ - - #include <math.h> #include <stdio.h> #include <stddef.h> @@ -1173,7 +1171,7 @@ bool remove_fmodifier(ListBase *modifiers, FModifier *fcm) /* sanity check */ if (fcm == NULL) - return 0; + return false; /* free modifier's special data (stored inside fcm->data) */ if (fcm->data) { @@ -1187,13 +1185,13 @@ bool remove_fmodifier(ListBase *modifiers, FModifier *fcm) /* remove modifier from stack */ if (modifiers) { BLI_freelinkN(modifiers, fcm); - return 1; + return true; } else { /* XXX this case can probably be removed some day, as it shouldn't happen... */ printf("remove_fmodifier() - no modifier stack given\n"); MEM_freeN(fcm); - return 0; + return false; } } @@ -1264,7 +1262,7 @@ bool list_has_suitable_fmodifier(ListBase *modifiers, int mtype, short acttype) /* sanity checks */ if (ELEM(NULL, modifiers, modifiers->first)) - return 0; + return false; /* find the first mdifier fitting these criteria */ for (fcm = modifiers->first; fcm; fcm = fcm->next) { @@ -1279,11 +1277,11 @@ bool list_has_suitable_fmodifier(ListBase *modifiers, int mtype, short acttype) /* if both are ok, we've found a hit */ if (mOk && aOk) - return 1; + return true; } /* no matches */ - return 0; + return false; } /* Evaluation API --------------------------- */ diff --git a/source/blender/blenkernel/intern/freestyle.c b/source/blender/blenkernel/intern/freestyle.c index 4aa1b49ea13..cc9ad63d451 100644 --- a/source/blender/blenkernel/intern/freestyle.c +++ b/source/blender/blenkernel/intern/freestyle.c @@ -181,7 +181,7 @@ static FreestyleLineSet *alloc_lineset(void) FreestyleLineSet *BKE_freestyle_lineset_add(FreestyleConfig *config, const char *name) { - int lineset_index = BLI_countlist(&config->linesets); + int lineset_index = BLI_listbase_count(&config->linesets); FreestyleLineSet *lineset = alloc_lineset(); BLI_addtail(&config->linesets, (void *)lineset); diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index e226e9d9797..dd2155505fb 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -45,6 +45,7 @@ #include "DNA_gpencil_types.h" #include "DNA_userdef_types.h" +#include "BKE_animsys.h" #include "BKE_global.h" #include "BKE_gpencil.h" #include "BKE_library.h" @@ -115,6 +116,12 @@ void BKE_gpencil_free(bGPdata *gpd) { /* free layers */ free_gpencil_layers(&gpd->layers); + + /* free animation data */ + if (gpd->adt) { + BKE_free_animdata(&gpd->id); + gpd->adt = NULL; + } } /* -------- Container Creation ---------- */ @@ -276,7 +283,7 @@ bGPDlayer *gpencil_layer_duplicate(bGPDlayer *src) } /* make a copy of a given gpencil datablock */ -bGPdata *gpencil_data_duplicate(bGPdata *src) +bGPdata *gpencil_data_duplicate(bGPdata *src, bool internal_copy) { bGPDlayer *gpl, *gpld; bGPdata *dst; @@ -286,7 +293,14 @@ bGPdata *gpencil_data_duplicate(bGPdata *src) return NULL; /* make a copy of the base-data */ - dst = MEM_dupallocN(src); + if (internal_copy) { + /* make a straight copy for undo buffers used during stroke drawing */ + dst = MEM_dupallocN(src); + } + else { + /* make a copy when others use this */ + dst = BKE_libblock_copy(&src->id); + } /* copy layers */ BLI_listbase_clear(&dst->layers); @@ -300,6 +314,31 @@ bGPdata *gpencil_data_duplicate(bGPdata *src) return dst; } +/* -------- GP-Stroke API --------- */ + +/* ensure selection status of stroke is in sync with its points */ +void gpencil_stroke_sync_selection(bGPDstroke *gps) +{ + bGPDspoint *pt; + int i; + + /* error checking */ + if (gps == NULL) + return; + + /* we'll stop when we find the first selected point, + * so initially, we must deselect + */ + gps->flag &= ~GP_STROKE_SELECT; + + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) { + gps->flag |= GP_STROKE_SELECT; + break; + } + } +} + /* -------- GP-Frame API ---------- */ /* delete the last stroke of the given frame */ @@ -359,7 +398,7 @@ bGPDframe *gpencil_layer_getframe(bGPDlayer *gpl, int cframe, short addnew) /* do not allow any changes to layer's active frame if layer is locked from changes * or if the layer has been set to stay on the current frame */ - if (gpl->flag & (GP_LAYER_LOCKED | GP_LAYER_FRAMELOCK)) + if (gpl->flag & GP_LAYER_FRAMELOCK) return gpf; /* do not allow any changes to actframe if frame has painting tag attached to it */ if (gpf->flag & GP_FRAME_PAINT) @@ -468,16 +507,23 @@ bGPDframe *gpencil_layer_getframe(bGPDlayer *gpl, int cframe, short addnew) bool gpencil_layer_delframe(bGPDlayer *gpl, bGPDframe *gpf) { bool changed = false; - + /* error checking */ if (ELEM(NULL, gpl, gpf)) return false; - + + /* if this frame was active, make the previous frame active instead + * since it's tricky to set active frame otherwise + */ + if (gpl->actframe == gpf) + gpl->actframe = gpf->prev; + else + gpl->actframe = NULL; + /* free the frame and its data */ changed = free_gpencil_strokes(gpf); BLI_freelinkN(&gpl->frames, gpf); - gpl->actframe = NULL; - + return changed; } diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index 4dbd15a3774..2b99b5f4620 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -42,10 +42,18 @@ #include "MEM_guardedalloc.h" +#include "BLI_strict_flags.h" + /* IDPropertyTemplate is a union in DNA_ID.h */ +/** + * if the new is 'IDP_ARRAY_REALLOC_LIMIT' items less, + * than #IDProperty.totallen, reallocate anyway. + */ +#define IDP_ARRAY_REALLOC_LIMIT 200 + /*local size table.*/ -static char idp_size_table[] = { +static size_t idp_size_table[] = { 1, /*strings*/ sizeof(int), sizeof(float), @@ -158,9 +166,8 @@ void IDP_ResizeIDPArray(IDProperty *prop, int newlen) BLI_assert(prop->type == IDP_IDPARRAY); /* first check if the array buffer size has room */ - /* if newlen is 200 items less then totallen, reallocate anyway */ if (newlen <= prop->totallen) { - if (newlen < prop->len && prop->totallen - newlen < 200) { + if (newlen < prop->len && prop->totallen - newlen < IDP_ARRAY_REALLOC_LIMIT) { int i; for (i = newlen; i < prop->len; i++) @@ -194,7 +201,7 @@ void IDP_ResizeIDPArray(IDProperty *prop, int newlen) */ newsize = newlen; newsize = (newsize >> 3) + (newsize < 9 ? 3 : 6) + newsize; - prop->data.pointer = MEM_recallocN(prop->data.pointer, sizeof(IDProperty) * newsize); + prop->data.pointer = MEM_recallocN(prop->data.pointer, sizeof(IDProperty) * (size_t)newsize); prop->len = newlen; prop->totallen = newsize; } @@ -235,8 +242,7 @@ void IDP_ResizeArray(IDProperty *prop, int newlen) const bool is_grow = newlen >= prop->len; /* first check if the array buffer size has room */ - /* if newlen is 200 chars less then totallen, reallocate anyway */ - if (newlen <= prop->totallen && prop->totallen - newlen < 200) { + if (newlen <= prop->totallen && prop->totallen - newlen < IDP_ARRAY_REALLOC_LIMIT) { idp_resize_group_array(prop, newlen, prop->data.pointer); prop->len = newlen; return; @@ -256,7 +262,8 @@ void IDP_ResizeArray(IDProperty *prop, int newlen) if (is_grow == false) idp_resize_group_array(prop, newlen, prop->data.pointer); - prop->data.pointer = MEM_recallocN(prop->data.pointer, idp_size_table[(int)prop->subtype] * newsize); + prop->data.pointer = MEM_recallocN( + prop->data.pointer, idp_size_table[(int)prop->subtype] * (size_t)newsize); if (is_grow == true) idp_resize_group_array(prop, newlen, prop->data.pointer); @@ -321,8 +328,8 @@ static IDProperty *IDP_CopyArray(const IDProperty *prop) * * \param st The string to assign. * \param name The property name. - * \param maxlen The size of the new string (including the \0 terminator) - * \return + * \param maxlen The size of the new string (including the \0 terminator). + * \return The new string property. */ IDProperty *IDP_NewString(const char *st, const char *name, int maxlen) { @@ -336,14 +343,14 @@ IDProperty *IDP_NewString(const char *st, const char *name, int maxlen) } else { /* include null terminator '\0' */ - int stlen = strlen(st) + 1; + int stlen = (int)strlen(st) + 1; if (maxlen > 0 && maxlen < stlen) stlen = maxlen; - prop->data.pointer = MEM_mallocN(stlen, "id property string 2"); + prop->data.pointer = MEM_mallocN((size_t)stlen, "id property string 2"); prop->len = prop->totallen = stlen; - BLI_strncpy(prop->data.pointer, st, stlen); + BLI_strncpy(prop->data.pointer, st, (size_t)stlen); } prop->type = IDP_STRING; @@ -374,18 +381,18 @@ void IDP_AssignString(IDProperty *prop, const char *st, int maxlen) int stlen; BLI_assert(prop->type == IDP_STRING); - stlen = strlen(st); + stlen = (int)strlen(st); if (maxlen > 0 && maxlen < stlen) stlen = maxlen; if (prop->subtype == IDP_STRING_SUB_BYTE) { IDP_ResizeArray(prop, stlen); - memcpy(prop->data.pointer, st, stlen); + memcpy(prop->data.pointer, st, (size_t)stlen); } else { stlen++; IDP_ResizeArray(prop, stlen); - BLI_strncpy(prop->data.pointer, st, stlen); + BLI_strncpy(prop->data.pointer, st, (size_t)stlen); } } @@ -395,7 +402,7 @@ void IDP_ConcatStringC(IDProperty *prop, const char *st) BLI_assert(prop->type == IDP_STRING); - newlen = prop->len + strlen(st); + newlen = prop->len + (int)strlen(st); /* we have to remember that prop->len includes the null byte for strings. * so there's no need to add +1 to the resize function.*/ IDP_ResizeArray(prop, newlen); @@ -571,18 +578,18 @@ void IDP_ReplaceGroupInGroup(IDProperty *dest, const IDProperty *src) * Checks if a property with the same name as prop exists, and if so replaces it. * Use this to preserve order! */ -void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop) +void IDP_ReplaceInGroup_ex(IDProperty *group, IDProperty *prop, IDProperty *prop_exist) { - IDProperty *loop; - BLI_assert(group->type == IDP_GROUP); - if ((loop = IDP_GetPropertyFromGroup(group, prop->name))) { - BLI_insertlinkafter(&group->data.group, loop, prop); + BLI_assert(prop_exist == IDP_GetPropertyFromGroup(group, prop->name)); + + if ((prop_exist = IDP_GetPropertyFromGroup(group, prop->name))) { + BLI_insertlinkafter(&group->data.group, prop_exist, prop); - BLI_remlink(&group->data.group, loop); - IDP_FreeProperty(loop); - MEM_freeN(loop); + BLI_remlink(&group->data.group, prop_exist); + IDP_FreeProperty(prop_exist); + MEM_freeN(prop_exist); } else { group->len++; @@ -590,6 +597,13 @@ void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop) } } +void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop) +{ + IDProperty *prop_exist = IDP_GetPropertyFromGroup(group, prop->name); + + IDP_ReplaceInGroup_ex(group, prop, prop_exist); +} + /** * If a property is missing in \a dest, add it. */ @@ -623,8 +637,8 @@ void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overw * * The sanity check just means the property is not added to the group if another property * exists with the same name; the client code using ID properties then needs to detect this - * (the function that adds new properties to groups, IDP_AddToGroup,returns 0 if a property can't - * be added to the group, and 1 if it can) and free the property. + * (the function that adds new properties to groups, IDP_AddToGroup, returns false if a property can't + * be added to the group, and true if it can) and free the property. * * Currently the code to free ID properties is designed to leave the actual struct * you pass it un-freed, this is needed for how the system works. This means @@ -639,10 +653,10 @@ bool IDP_AddToGroup(IDProperty *group, IDProperty *prop) if (IDP_GetPropertyFromGroup(group, prop->name) == NULL) { group->len++; BLI_addtail(&group->data.group, prop); - return 1; + return true; } - return 0; + return false; } /** @@ -656,10 +670,10 @@ bool IDP_InsertToGroup(IDProperty *group, IDProperty *previous, IDProperty *pnew if (IDP_GetPropertyFromGroup(group, pnew->name) == NULL) { group->len++; BLI_insertlinkafter(&group->data.group, previous, pnew); - return 1; + return true; } - return 0; + return false; } /** @@ -700,56 +714,6 @@ IDProperty *IDP_GetPropertyTypeFromGroup(IDProperty *prop, const char *name, con return (idprop && idprop->type == type) ? idprop : NULL; } -typedef struct IDPIter { - void *next; - IDProperty *parent; -} IDPIter; - -/** - * Get an iterator to iterate over the members of an id property group. - * Note that this will automatically free the iterator once iteration is complete; - * if you stop the iteration before hitting the end, make sure to call - * IDP_FreeIterBeforeEnd(). - */ -void *IDP_GetGroupIterator(IDProperty *prop) -{ - IDPIter *iter; - - BLI_assert(prop->type == IDP_GROUP); - iter = MEM_mallocN(sizeof(IDPIter), "IDPIter"); - iter->next = prop->data.group.first; - iter->parent = prop; - return (void *) iter; -} - -/** - * Returns the next item in the iteration. To use, simple for a loop like the following: - * while (IDP_GroupIterNext(iter) != NULL) { - * ... - * } - */ -IDProperty *IDP_GroupIterNext(void *vself) -{ - IDPIter *self = (IDPIter *) vself; - Link *next = (Link *) self->next; - if (self->next == NULL) { - MEM_freeN(self); - return NULL; - } - - self->next = next->next; - return (void *) next; -} - -/** - * Frees the iterator pointed to at vself, only use this if iteration is stopped early; - * when the iterator hits the end of the list it'll automatically free itself.\ - */ -void IDP_FreeIterBeforeEnd(void *vself) -{ - MEM_freeN(vself); -} - /* Ok, the way things work, Groups free the ID Property structs of their children. * This is because all ID Property freeing functions free only direct data (not the ID Property * struct itself), but for Groups the child properties *are* considered @@ -811,11 +775,11 @@ IDProperty *IDP_GetProperties(ID *id, const bool create_if_needed) bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is_strict) { if (prop1 == NULL && prop2 == NULL) - return 1; + return true; else if (prop1 == NULL || prop2 == NULL) - return is_strict ? 0 : 1; + return is_strict ? false : true; else if (prop1->type != prop2->type) - return 0; + return false; switch (prop1->type) { case IDP_INT: @@ -838,27 +802,32 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is case IDP_DOUBLE: return (IDP_Double(prop1) == IDP_Double(prop2)); case IDP_STRING: - return ((prop1->len == prop2->len) && strncmp(IDP_String(prop1), IDP_String(prop2), prop1->len) == 0); + { + return (((prop1->len == prop2->len) && + strncmp(IDP_String(prop1), IDP_String(prop2), (size_t)prop1->len) == 0)); + } case IDP_ARRAY: if (prop1->len == prop2->len && prop1->subtype == prop2->subtype) { - return memcmp(IDP_Array(prop1), IDP_Array(prop2), idp_size_table[(int)prop1->subtype] * prop1->len); + return (memcmp(IDP_Array(prop1), + IDP_Array(prop2), + idp_size_table[(int)prop1->subtype] * (size_t)prop1->len) == 0); } - return 0; + return false; case IDP_GROUP: { IDProperty *link1, *link2; if (is_strict && prop1->len != prop2->len) - return 0; + return false; for (link1 = prop1->data.group.first; link1; link1 = link1->next) { link2 = IDP_GetPropertyFromGroup(prop2, link1->name); if (!IDP_EqualsProperties_ex(link1, link2, is_strict)) - return 0; + return false; } - return 1; + return true; } case IDP_IDPARRAY: { @@ -867,12 +836,12 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is int i; if (prop1->len != prop2->len) - return 0; + return false; for (i = 0; i < prop1->len; i++) if (!IDP_EqualsProperties(&array1[i], &array2[i])) - return 0; - return 1; + return false; + return true; } default: /* should never get here */ @@ -880,7 +849,7 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is break; } - return 1; + return true; } bool IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2) @@ -913,7 +882,7 @@ bool IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2) * IDP_AddToGroup or MEM_freeN the property, doing anything else might result in * a memory leak. */ -IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *name) +IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *name) { IDProperty *prop = NULL; @@ -940,8 +909,10 @@ IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *n { prop = MEM_callocN(sizeof(IDProperty), "IDProperty array"); prop->subtype = val->array.type; - if (val->array.len) - prop->data.pointer = MEM_callocN(idp_size_table[val->array.type] * val->array.len, "id property array"); + if (val->array.len) { + prop->data.pointer = MEM_callocN( + idp_size_table[val->array.type] * (size_t)val->array.len, "id property array"); + } prop->len = prop->totallen = val->array.len; break; } @@ -961,9 +932,9 @@ IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *n prop->len = 0; } else { - prop->data.pointer = MEM_mallocN(val->string.len, "id property string 2"); + prop->data.pointer = MEM_mallocN((size_t)val->string.len, "id property string 2"); prop->len = prop->totallen = val->string.len; - memcpy(prop->data.pointer, st, val->string.len); + memcpy(prop->data.pointer, st, (size_t)val->string.len); } prop->subtype = IDP_STRING_SUB_BYTE; } @@ -975,10 +946,10 @@ IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *n prop->len = 1; /*NULL string, has len of 1 to account for null byte.*/ } else { - int stlen = strlen(st) + 1; - prop->data.pointer = MEM_mallocN(stlen, "id property string 3"); + int stlen = (int)strlen(st) + 1; + prop->data.pointer = MEM_mallocN((size_t)stlen, "id property string 3"); prop->len = prop->totallen = stlen; - memcpy(prop->data.pointer, st, stlen); + memcpy(prop->data.pointer, st, (size_t)stlen); } prop->subtype = IDP_STRING_SUB_UTF8; } diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 5c673eeef3f..36cd7e69601 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -249,7 +249,7 @@ void BKE_image_de_interlace(Image *ima, int odd) /* ***************** ALLOC & FREE, DATA MANAGING *************** */ -static void image_free_cahced_frames(Image *image) +static void image_free_cached_frames(Image *image) { if (image->cache) { IMB_moviecache_free(image->cache); @@ -263,7 +263,7 @@ static void image_free_cahced_frames(Image *image) */ void BKE_image_free_buffers(Image *ima) { - image_free_cahced_frames(ima); + image_free_cached_frames(ima); if (ima->anim) IMB_free_anim(ima->anim); ima->anim = NULL; @@ -273,7 +273,13 @@ void BKE_image_free_buffers(Image *ima) ima->rr = NULL; } - GPU_free_image(ima); + if (!G.background) { + /* Background mode doesn't use opnegl, + * so we can avoid freeing GPU images and save some + * time by skipping mutex lock. + */ + GPU_free_image(ima); + } ima->ok = IMA_OK; } @@ -661,7 +667,7 @@ Image *BKE_image_load(Main *bmain, const char *filepath) /* otherwise creates new. */ /* does not load ibuf itself */ /* pass on optional frame for #name images */ -Image *BKE_image_load_exists(const char *filepath) +Image *BKE_image_load_exists_ex(const char *filepath, bool *r_exists) { Image *ima; char str[FILE_MAX], strtest[FILE_MAX]; @@ -681,16 +687,24 @@ Image *BKE_image_load_exists(const char *filepath) ima->id.us++; /* officially should not, it doesn't link here! */ if (ima->ok == 0) ima->ok = IMA_OK; - /* RETURN! */ + if (r_exists) + *r_exists = true; return ima; } } } } + if (r_exists) + *r_exists = false; return BKE_image_load(G.main, filepath); } +Image *BKE_image_load_exists(const char *filepath) +{ + return BKE_image_load_exists_ex(filepath, NULL); +} + static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, const float color[4], ColorManagedColorspaceSettings *colorspace_settings) { @@ -2529,7 +2543,7 @@ static ImBuf *image_load_sequence_multilayer(Image *ima, ImageUser *iuser, int f * need to ensure there's no image buffers are hanging around * with dead links after freeing the render result. */ - image_free_cahced_frames(ima); + image_free_cached_frames(ima); RE_FreeRenderResult(ima->rr); ima->rr = NULL; } @@ -3393,9 +3407,9 @@ bool BKE_image_has_alpha(struct Image *image) BKE_image_release_ibuf(image, ibuf, lock); if (planes == 32) - return 1; + return true; else - return 0; + return false; } void BKE_image_get_size(Image *image, ImageUser *iuser, int *width, int *height) diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 4cf9d52989f..fe64af184a9 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -144,14 +144,6 @@ DO_INLINE void mul_fvector_S(float to[3], float from[3], float scalar) to[1] = from[1] * scalar; to[2] = from[2] * scalar; } -/* simple cross product */ -/* STATUS: verified */ -DO_INLINE void cross_fvector(float to[3], float vectorA[3], float vectorB[3]) -{ - to[0] = vectorA[1] * vectorB[2] - vectorA[2] * vectorB[1]; - to[1] = vectorA[2] * vectorB[0] - vectorA[0] * vectorB[2]; - to[2] = vectorA[0] * vectorB[1] - vectorA[1] * vectorB[0]; -} /* simple v^T * v product ("outer product") */ /* STATUS: HAS TO BE verified (*should* work) */ DO_INLINE void mul_fvectorT_fvector(float to[3][3], float vectorA[3], float vectorB[3]) @@ -337,6 +329,7 @@ DO_INLINE void initdiag_fmatrixS(float to[3][3], float aS) to[2][2] = aS; } +#if 0 /* calculate determinant of 3x3 matrix */ DO_INLINE float det_fmatrix(float m[3][3]) { @@ -371,6 +364,7 @@ DO_INLINE void inverse_fmatrix(float to[3][3], float from[3][3]) } } +#endif /* 3x3 matrix multiplied by a scalar */ /* STATUS: verified */ @@ -398,14 +392,6 @@ DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][3], float from[3]) to[1] = dot_v3v3(matrix[1], from); to[2] = dot_v3v3(matrix[2], from); } -/* 3x3 matrix multiplied by a 3x3 matrix */ -/* STATUS: verified */ -DO_INLINE void mul_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) -{ - mul_fvector_fmatrix(to[0], matrixA[0], matrixB); - mul_fvector_fmatrix(to[1], matrixA[1], matrixB); - mul_fvector_fmatrix(to[2], matrixA[2], matrixB); -} /* 3x3 matrix addition with 3x3 matrix */ DO_INLINE void add_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) { @@ -413,27 +399,6 @@ DO_INLINE void add_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float ma VECADD(to[1], matrixA[1], matrixB[1]); VECADD(to[2], matrixA[2], matrixB[2]); } -/* 3x3 matrix add-addition with 3x3 matrix */ -DO_INLINE void addadd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) -{ - VECADDADD(to[0], matrixA[0], matrixB[0]); - VECADDADD(to[1], matrixA[1], matrixB[1]); - VECADDADD(to[2], matrixA[2], matrixB[2]); -} -/* 3x3 matrix sub-addition with 3x3 matrix */ -DO_INLINE void addsub_fmatrixS_fmatrixS(float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS) -{ - VECADDSUBSS(to[0], matrixA[0], aS, matrixB[0], bS); - VECADDSUBSS(to[1], matrixA[1], aS, matrixB[1], bS); - VECADDSUBSS(to[2], matrixA[2], aS, matrixB[2], bS); -} -/* A -= B + C (3x3 matrix sub-addition with 3x3 matrix) */ -DO_INLINE void subadd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) -{ - VECSUBADD(to[0], matrixA[0], matrixB[0]); - VECSUBADD(to[1], matrixA[1], matrixB[1]); - VECSUBADD(to[2], matrixA[2], matrixB[2]); -} /* A -= B*x + C*y (3x3 matrix sub-addition with 3x3 matrix) */ DO_INLINE void subadd_fmatrixS_fmatrixS(float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS) { @@ -448,44 +413,9 @@ DO_INLINE void sub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float ma sub_v3_v3v3(to[1], matrixA[1], matrixB[1]); sub_v3_v3v3(to[2], matrixA[2], matrixB[2]); } -/* A += B - C (3x3 matrix add-subtraction with 3x3 matrix) */ -DO_INLINE void addsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) -{ - VECADDSUB(to[0], matrixA[0], matrixB[0]); - VECADDSUB(to[1], matrixA[1], matrixB[1]); - VECADDSUB(to[2], matrixA[2], matrixB[2]); -} ///////////////////////////////////////////////////////////////// // special functions ///////////////////////////////////////////////////////////////// -/* a vector multiplied and added to/by a 3x3 matrix */ -DO_INLINE void muladd_fvector_fmatrix(float to[3], float from[3], float matrix[3][3]) -{ - to[0] += matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2]; - to[1] += matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2]; - to[2] += matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2]; -} -/* 3x3 matrix multiplied and added to/by a 3x3 matrix and added to another 3x3 matrix */ -DO_INLINE void muladd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) -{ - muladd_fvector_fmatrix(to[0], matrixA[0], matrixB); - muladd_fvector_fmatrix(to[1], matrixA[1], matrixB); - muladd_fvector_fmatrix(to[2], matrixA[2], matrixB); -} -/* a vector multiplied and sub'd to/by a 3x3 matrix */ -DO_INLINE void mulsub_fvector_fmatrix(float to[3], float from[3], float matrix[3][3]) -{ - to[0] -= matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2]; - to[1] -= matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2]; - to[2] -= matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2]; -} -/* 3x3 matrix multiplied and sub'd to/by a 3x3 matrix and added to another 3x3 matrix */ -DO_INLINE void mulsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) -{ - mulsub_fvector_fmatrix(to[0], matrixA[0], matrixB); - mulsub_fvector_fmatrix(to[1], matrixA[1], matrixB); - mulsub_fvector_fmatrix(to[2], matrixA[2], matrixB); -} /* 3x3 matrix multiplied+added by a vector */ /* STATUS: verified */ DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][3], float from[3]) @@ -494,13 +424,6 @@ DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][3], float fro to[1] += dot_v3v3(matrix[1], from); to[2] += dot_v3v3(matrix[2], from); } -/* 3x3 matrix multiplied+sub'ed by a vector */ -DO_INLINE void mulsub_fmatrix_fvector(float to[3], float matrix[3][3], float from[3]) -{ - to[0] -= dot_v3v3(matrix[0], from); - to[1] -= dot_v3v3(matrix[1], from); - to[2] -= dot_v3v3(matrix[2], from); -} ///////////////////////////////////////////////////////////////// /////////////////////////// @@ -569,15 +492,6 @@ DO_INLINE void initdiag_bfmatrix(fmatrix3x3 *matrix, float m3[3][3]) } } -/* multiply big matrix with scalar*/ -DO_INLINE void mul_bfmatrix_S(fmatrix3x3 *matrix, float scalar) -{ - unsigned int i = 0; - for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) { - mul_fmatrix_S(matrix[i].m, scalar); - } -} - /* SPARSE SYMMETRIC multiply big matrix with long vector*/ /* STATUS: verified */ DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector) @@ -610,83 +524,6 @@ DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector } -/* SPARSE SYMMETRIC multiply big matrix with long vector (for diagonal preconditioner) */ -/* STATUS: verified */ -DO_INLINE void mul_prevfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector) -{ - unsigned int i = 0; - - for (i = 0; i < from[0].vcount; i++) { - mul_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]); - } -} - -/* SPARSE SYMMETRIC add big matrix with big matrix: A = B + C*/ -DO_INLINE void add_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix) -{ - unsigned int i = 0; - - /* process diagonal elements */ - for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) { - add_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); - } - -} -/* SPARSE SYMMETRIC add big matrix with big matrix: A += B + C */ -DO_INLINE void addadd_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix) -{ - unsigned int i = 0; - - /* process diagonal elements */ - for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) { - addadd_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); - } - -} -/* SPARSE SYMMETRIC subadd big matrix with big matrix: A -= B + C */ -DO_INLINE void subadd_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix) -{ - unsigned int i = 0; - - /* process diagonal elements */ - for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) { - subadd_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); - } - -} -/* A = B - C (SPARSE SYMMETRIC sub big matrix with big matrix) */ -DO_INLINE void sub_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix) -{ - unsigned int i = 0; - - /* process diagonal elements */ - for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) { - sub_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); - } - -} -/* SPARSE SYMMETRIC sub big matrix with big matrix S (special constraint matrix with limited entries) */ -DO_INLINE void sub_bfmatrix_Smatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix) -{ - unsigned int i = 0; - - /* process diagonal elements */ - for (i = 0; i < matrix[0].vcount; i++) { - sub_fmatrix_fmatrix(to[matrix[i].c].m, from[matrix[i].c].m, matrix[i].m); - } - -} -/* A += B - C (SPARSE SYMMETRIC addsub big matrix with big matrix) */ -DO_INLINE void addsub_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix) -{ - unsigned int i = 0; - - /* process diagonal elements */ - for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) { - addsub_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); - } - -} /* SPARSE SYMMETRIC sub big matrix with big matrix*/ /* A -= B * float + C * float --> for big matrix */ /* VERIFIED */ @@ -849,14 +686,18 @@ int implicit_free(ClothModifierData *clmd) DO_INLINE float fb(float length, float L) { float x = length / L; - return (-11.541f * powf(x, 4) + 34.193f * powf(x, 3) - 39.083f * powf(x, 2) + 23.116f * x - 9.713f); + float xx = x * x; + float xxx = xx * x; + float xxxx = xxx * x; + return (-11.541f * xxxx + 34.193f * xxx - 39.083f * xx + 23.116f * x - 9.713f); } DO_INLINE float fbderiv(float length, float L) { float x = length/L; - - return (-46.164f * powf(x, 3) + 102.579f * powf(x, 2) - 78.166f * x + 23.116f); + float xx = x * x; + float xxx = xx * x; + return (-46.164f * xxx + 102.579f * xx - 78.166f * x + 23.116f); } DO_INLINE float fbstar(float length, float L, float kb, float cb) @@ -958,6 +799,7 @@ static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z return conjgrad_loopcount<conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable } +#if 0 // block diagonalizer DO_INLINE void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv) { @@ -972,7 +814,6 @@ DO_INLINE void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv) } } -#if 0 /* // version 1.3 static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv) @@ -1146,30 +987,6 @@ static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector } #endif -// outer product is NOT cross product!!! -DO_INLINE void dfdx_spring_type1(float to[3][3], float extent[3], float length, float L, float dot, float k) -{ - // dir is unit length direction, rest is spring's restlength, k is spring constant. - // return (outerprod(dir, dir)*k + (I - outerprod(dir, dir))*(k - ((k*L)/length))); - float temp[3][3]; - float temp1 = k * (1.0f - (L / length)); - - mul_fvectorT_fvectorS(temp, extent, extent, 1.0f / dot); - sub_fmatrix_fmatrix(to, I, temp); - mul_fmatrix_S(to, temp1); - - mul_fvectorT_fvectorS(temp, extent, extent, k/ dot); - add_fmatrix_fmatrix(to, to, temp); - - /* - mul_fvectorT_fvector(temp, dir, dir); - sub_fmatrix_fmatrix(to, I, temp); - mul_fmatrix_S(to, k* (1.0f-(L/length))); - mul_fmatrix_S(temp, k); - add_fmatrix_fmatrix(to, temp, to); - */ -} - DO_INLINE void dfdx_spring_type2(float to[3][3], float dir[3], float length, float L, float k, float cb) { // return outerprod(dir, dir)*fbstar_jacobi(length, L, k, cb); @@ -1195,17 +1012,6 @@ DO_INLINE void dfdx_spring(float to[3][3], float dir[3], float length, float L, mul_fmatrix_S(to, -k); } -// unused atm -DO_INLINE void dfdx_damp(float to[3][3], float dir[3], float length, const float vel[3], float rest, float damping) -{ - // inner spring damping vel is the relative velocity of the endpoints. - // return (I-outerprod(dir, dir)) * (-damping * -(dot(dir, vel)/Max(length, rest))); - mul_fvectorT_fvector(to, dir, dir); - sub_fmatrix_fmatrix(to, I, to); - mul_fmatrix_S(to, (-damping * -(dot_v3v3(dir, vel)/MAX2(length, rest)))); - -} - DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *UNUSED(lF), lfVector *X, lfVector *V, fmatrix3x3 *UNUSED(dFdV), fmatrix3x3 *UNUSED(dFdX), float time) { Cloth *cloth = clmd->clothObject; diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 51cf26063c7..34877c7559c 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -1523,7 +1523,7 @@ static void ipo_to_animdata(ID *id, Ipo *ipo, char actname[], char constname[], if (G.debug & G_DEBUG) { printf("ipo to animdata - ID:%s, IPO:%s, actname:%s constname:%s seqname:%s curves:%d\n", id->name + 2, ipo->id.name + 2, (actname) ? actname : "<None>", (constname) ? constname : "<None>", (seq) ? (seq->name + 2) : "<None>", - BLI_countlist(&ipo->curve)); + BLI_listbase_count(&ipo->curve)); } /* Convert curves to animato system (separated into separate lists of F-Curves for animation and drivers), diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 2dc615c19f9..3ba0c6e5ffa 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -1086,7 +1086,7 @@ static float *get_weights_array(Object *ob, char *vgroup, WeightsArrayCache *cac if (cache) { if (cache->defgroup_weights == NULL) { - int num_defgroup = BLI_countlist(&ob->defbase); + int num_defgroup = BLI_listbase_count(&ob->defbase); cache->defgroup_weights = MEM_callocN(sizeof(*cache->defgroup_weights) * num_defgroup, "cached defgroup weights"); @@ -1518,7 +1518,7 @@ KeyBlock *BKE_keyblock_add(Key *key, const char *name) BLI_addtail(&key->block, kb); kb->type = KEY_CARDINAL; - tot = BLI_countlist(&key->block); + tot = BLI_listbase_count(&key->block); if (name) { BLI_strncpy(kb->name, name, sizeof(kb->name)); } @@ -1669,31 +1669,43 @@ char *BKE_keyblock_curval_rnapath_get(Key *key, KeyBlock *kb) /* conversion functions */ /************************* Lattice ************************/ -void BKE_key_convert_from_lattice(Lattice *lt, KeyBlock *kb) +void BKE_keyblock_update_from_lattice(Lattice *lt, KeyBlock *kb) { BPoint *bp; - float *fp; + float (*fp)[3]; int a, tot; + BLI_assert(kb->totelem == lt->pntsu * lt->pntsv * lt->pntsw); + + tot = kb->totelem; + if (tot == 0) return; + + bp = lt->def; + fp = kb->data; + for (a = 0; a < kb->totelem; a++, fp++, bp++) { + copy_v3_v3(*fp, bp->vec); + } +} + +void BKE_keyblock_convert_from_lattice(Lattice *lt, KeyBlock *kb) +{ + int tot; + tot = lt->pntsu * lt->pntsv * lt->pntsw; if (tot == 0) return; - if (kb->data) MEM_freeN(kb->data); + MEM_SAFE_FREE(kb->data); - kb->data = MEM_mallocN(lt->key->elemsize * tot, "kb->data"); + kb->data = MEM_mallocN(lt->key->elemsize * tot, __func__); kb->totelem = tot; - bp = lt->def; - fp = kb->data; - for (a = 0; a < kb->totelem; a++, fp += 3, bp++) { - copy_v3_v3(fp, bp->vec); - } + BKE_keyblock_update_from_lattice(lt, kb); } -void BKE_key_convert_to_lattice(KeyBlock *kb, Lattice *lt) +void BKE_keyblock_convert_to_lattice(KeyBlock *kb, Lattice *lt) { BPoint *bp; - const float *fp; + const float (*fp)[3]; int a, tot; bp = lt->def; @@ -1702,13 +1714,13 @@ void BKE_key_convert_to_lattice(KeyBlock *kb, Lattice *lt) tot = lt->pntsu * lt->pntsv * lt->pntsw; tot = min_ii(kb->totelem, tot); - for (a = 0; a < tot; a++, fp += 3, bp++) { - copy_v3_v3(bp->vec, fp); + for (a = 0; a < tot; a++, fp++, bp++) { + copy_v3_v3(bp->vec, *fp); } } /************************* Curve ************************/ -void BKE_key_convert_from_curve(Curve *cu, KeyBlock *kb, ListBase *nurb) +void BKE_keyblock_update_from_curve(Curve *UNUSED(cu), KeyBlock *kb, ListBase *nurb) { Nurb *nu; BezTriple *bezt; @@ -1717,49 +1729,52 @@ void BKE_key_convert_from_curve(Curve *cu, KeyBlock *kb, ListBase *nurb) int a, tot; /* count */ - tot = BKE_nurbList_verts_count(nurb); - if (tot == 0) return; - - if (kb->data) MEM_freeN(kb->data); + BLI_assert(BKE_nurbList_verts_count(nurb) == kb->totelem); - kb->data = MEM_mallocN(cu->key->elemsize * tot, "kb->data"); - kb->totelem = tot; + tot = kb->totelem; + if (tot == 0) return; - nu = nurb->first; fp = kb->data; - while (nu) { - + for (nu = nurb->first; nu; nu = nu->next) { if (nu->bezt) { - bezt = nu->bezt; - a = nu->pntsu; - while (a--) { - copy_v3_v3(fp, bezt->vec[0]); - fp += 3; - copy_v3_v3(fp, bezt->vec[1]); - fp += 3; - copy_v3_v3(fp, bezt->vec[2]); - fp += 3; + for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) { + int i; + + for (i = 0; i < 3; i++, fp += 3) { + copy_v3_v3(fp, bezt->vec[i]); + } fp[0] = bezt->alfa; fp += 3; /* alphas */ - bezt++; } } else { - bp = nu->bp; - a = nu->pntsu * nu->pntsv; - while (a--) { + + ; + for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, fp += 4, bp++) { copy_v3_v3(fp, bp->vec); fp[3] = bp->alfa; - - fp += 4; - bp++; } } - nu = nu->next; } } -void BKE_key_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb) +void BKE_keyblock_convert_from_curve(Curve *cu, KeyBlock *kb, ListBase *nurb) +{ + int tot; + + /* count */ + tot = BKE_nurbList_verts_count(nurb); + if (tot == 0) return; + + MEM_SAFE_FREE(kb->data); + + kb->data = MEM_mallocN(cu->key->elemsize * tot, __func__); + kb->totelem = tot; + + BKE_keyblock_update_from_curve(cu, kb, nurb); +} + +void BKE_keyblock_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb) { Nurb *nu; BezTriple *bezt; @@ -1767,74 +1782,68 @@ void BKE_key_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb) const float *fp; int a, tot; - nu = nurb->first; - fp = kb->data; - tot = BKE_nurbList_verts_count(nurb); - tot = min_ii(kb->totelem, tot); - while (nu && tot > 0) { - + fp = kb->data; + for (nu = nurb->first; nu && tot > 0; nu = nu->next) { if (nu->bezt) { - bezt = nu->bezt; - a = nu->pntsu; - while (a-- && tot > 0) { - copy_v3_v3(bezt->vec[0], fp); - fp += 3; - copy_v3_v3(bezt->vec[1], fp); - fp += 3; - copy_v3_v3(bezt->vec[2], fp); - fp += 3; + for (a = nu->pntsu, bezt = nu->bezt; a && tot > 0; a--, tot -= 3, bezt++) { + int i; + + for (i = 0; i < 3; i++, fp += 3) { + copy_v3_v3(bezt->vec[i], fp); + } bezt->alfa = fp[0]; fp += 3; /* alphas */ - - tot -= 3; - bezt++; } } else { - bp = nu->bp; - a = nu->pntsu * nu->pntsv; - while (a-- && tot > 0) { + for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a && tot; a--, tot--, fp += 4, bp++) { copy_v3_v3(bp->vec, fp); bp->alfa = fp[3]; - - fp += 4; - tot--; - bp++; } } - nu = nu->next; } } /************************* Mesh ************************/ -void BKE_key_convert_from_mesh(Mesh *me, KeyBlock *kb) +void BKE_keyblock_update_from_mesh(Mesh *me, KeyBlock *kb) { MVert *mvert; - float *fp; - int a; - - if (me->totvert == 0) return; + float (*fp)[3]; + int a, tot; - if (kb->data) MEM_freeN(kb->data); + BLI_assert(me->totvert == kb->totelem); - kb->data = MEM_mallocN(me->key->elemsize * me->totvert, "kb->data"); - kb->totelem = me->totvert; + tot = me->totvert; + if (tot == 0) return; mvert = me->mvert; fp = kb->data; - for (a = 0; a < kb->totelem; a++, fp += 3, mvert++) { - copy_v3_v3(fp, mvert->co); - + for (a = 0; a < tot; a++, fp++, mvert++) { + copy_v3_v3(*fp, mvert->co); } } -void BKE_key_convert_to_mesh(KeyBlock *kb, Mesh *me) +void BKE_keyblock_convert_from_mesh(Mesh *me, KeyBlock *kb) +{ + int tot = me->totvert; + + if (me->totvert == 0) return; + + MEM_SAFE_FREE(kb->data); + + kb->data = MEM_mallocN(me->key->elemsize * tot, __func__); + kb->totelem = tot; + + BKE_keyblock_update_from_mesh(me, kb); +} + +void BKE_keyblock_convert_to_mesh(KeyBlock *kb, Mesh *me) { MVert *mvert; - const float *fp; + const float (*fp)[3]; int a, tot; mvert = me->mvert; @@ -1842,94 +1851,76 @@ void BKE_key_convert_to_mesh(KeyBlock *kb, Mesh *me) tot = min_ii(kb->totelem, me->totvert); - for (a = 0; a < tot; a++, fp += 3, mvert++) { - copy_v3_v3(mvert->co, fp); + for (a = 0; a < tot; a++, fp++, mvert++) { + copy_v3_v3(mvert->co, *fp); } } -/************************* vert coords ************************/ -float (*BKE_key_convert_to_vertcos(Object *ob, KeyBlock *kb))[3] +/************************* raw coords ************************/ +void BKE_keyblock_update_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3]) { - float (*vertCos)[3], *co; - const float *fp = kb->data; - int tot = 0, a; + float (*co)[3] = vertCos; + float *fp = kb->data; + int tot, a; - /* Count of vertex coords in array */ - if (ob->type == OB_MESH) { - Mesh *me = (Mesh *)ob->data; - tot = me->totvert; - } - else if (ob->type == OB_LATTICE) { - Lattice *lt = (Lattice *)ob->data; - tot = lt->pntsu * lt->pntsv * lt->pntsw; +#ifndef NDEBUG + if (ob->type == OB_LATTICE) { + Lattice *lt = ob->data; + BLI_assert((lt->pntsu * lt->pntsv * lt->pntsw) == kb->totelem); } else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { - Curve *cu = (Curve *)ob->data; - tot = BKE_nurbList_verts_count(&cu->nurb); + Curve *cu = ob->data; + BLI_assert(BKE_nurbList_verts_count(&cu->nurb) == kb->totelem); } + else if (ob->type == OB_MESH) { + Mesh *me = ob->data; + BLI_assert(me->totvert == kb->totelem); + } + else { + BLI_assert(0 == kb->totelem); + } +#endif - if (tot == 0) return NULL; - - vertCos = MEM_mallocN(tot * sizeof(*vertCos), "BKE_key_convert_to_vertcos vertCos"); - - /* Copy coords to array */ - co = (float *)vertCos; + tot = kb->totelem; + if (tot == 0) return; + /* Copy coords to keyblock */ if (ELEM(ob->type, OB_MESH, OB_LATTICE)) { - for (a = 0; a < tot; a++, fp += 3, co += 3) { - copy_v3_v3(co, fp); + for (a = 0; a < tot; a++, fp += 3, co++) { + copy_v3_v3(fp, *co); } } else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { Curve *cu = (Curve *)ob->data; - Nurb *nu = cu->nurb.first; + Nurb *nu; BezTriple *bezt; BPoint *bp; - while (nu) { + for (nu = cu->nurb.first; nu; nu = nu->next) { if (nu->bezt) { - int i; - bezt = nu->bezt; - a = nu->pntsu; + for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) { + int i; - while (a--) { - for (i = 0; i < 3; i++) { - copy_v3_v3(co, fp); - fp += 3; co += 3; + for (i = 0; i < 3; i++, fp += 3, co++) { + copy_v3_v3(fp, *co); } - fp += 3; /* skip alphas */ - - bezt++; } } else { - bp = nu->bp; - a = nu->pntsu * nu->pntsv; - - while (a--) { - copy_v3_v3(co, fp); - - fp += 4; - co += 3; - - bp++; + for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, bp++, fp += 4, co++) { + copy_v3_v3(fp, *co); } } - - nu = nu->next; } } - - return vertCos; } -void BKE_key_convert_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3]) +void BKE_keyblock_convert_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3]) { - float *co = (float *)vertCos, *fp; - int tot = 0, a, elemsize; + int tot = 0, elemsize; - if (kb->data) MEM_freeN(kb->data); + MEM_SAFE_FREE(kb->data); /* Count of vertex coords in array */ if (ob->type == OB_MESH) { @@ -1948,110 +1939,212 @@ void BKE_key_convert_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3]) tot = BKE_nurbList_verts_count(&cu->nurb); } - if (tot == 0) { - kb->data = NULL; - return; - } + if (tot == 0) return; - fp = kb->data = MEM_mallocN(tot * elemsize, "BKE_key_convert_to_vertcos vertCos"); + kb->data = MEM_mallocN(tot * elemsize, __func__); /* Copy coords to keyblock */ + BKE_keyblock_update_from_vertcos(ob, kb, vertCos); +} + +float (*BKE_keyblock_convert_to_vertcos(Object *ob, KeyBlock *kb))[3] +{ + float (*vertCos)[3], (*co)[3]; + const float *fp = kb->data; + int tot = 0, a; + + /* Count of vertex coords in array */ + if (ob->type == OB_MESH) { + Mesh *me = (Mesh *)ob->data; + tot = me->totvert; + } + else if (ob->type == OB_LATTICE) { + Lattice *lt = (Lattice *)ob->data; + tot = lt->pntsu * lt->pntsv * lt->pntsw; + } + else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { + Curve *cu = (Curve *)ob->data; + tot = BKE_nurbList_verts_count(&cu->nurb); + } + + if (tot == 0) return NULL; + + co = vertCos = MEM_mallocN(tot * sizeof(*vertCos), __func__); + /* Copy coords to array */ if (ELEM(ob->type, OB_MESH, OB_LATTICE)) { - for (a = 0; a < tot; a++, fp += 3, co += 3) { - copy_v3_v3(fp, co); + for (a = 0; a < tot; a++, fp += 3, co++) { + copy_v3_v3(*co, fp); } } else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { Curve *cu = (Curve *)ob->data; - Nurb *nu = cu->nurb.first; + Nurb *nu; BezTriple *bezt; BPoint *bp; - while (nu) { + for (nu = cu->nurb.first; nu; nu = nu->next) { if (nu->bezt) { - int i; - bezt = nu->bezt; - a = nu->pntsu; + for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) { + int i; - while (a--) { - for (i = 0; i < 3; i++) { - copy_v3_v3(fp, co); - fp += 3; co += 3; + for (i = 0; i < 3; i++, fp += 3, co++) { + copy_v3_v3(*co, fp); } - fp += 3; /* skip alphas */ - - bezt++; } } else { - bp = nu->bp; - a = nu->pntsu * nu->pntsv; - - while (a--) { - copy_v3_v3(fp, co); - - fp += 4; - co += 3; - - bp++; + for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, bp++, fp += 4, co++) { + copy_v3_v3(*co, fp); } } - - nu = nu->next; } } + + return vertCos; } -void BKE_key_convert_from_offset(Object *ob, KeyBlock *kb, float (*ofs)[3]) +/************************* raw coord offsets ************************/ +void BKE_keyblock_update_from_offset(Object *ob, KeyBlock *kb, float (*ofs)[3]) { int a; - float *co = (float *)ofs, *fp = kb->data; + float *fp = kb->data; if (ELEM(ob->type, OB_MESH, OB_LATTICE)) { - for (a = 0; a < kb->totelem; a++, fp += 3, co += 3) { - add_v3_v3(fp, co); + for (a = 0; a < kb->totelem; a++, fp += 3, ofs++) { + add_v3_v3(fp, *ofs); } } else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { Curve *cu = (Curve *)ob->data; - Nurb *nu = cu->nurb.first; + Nurb *nu; BezTriple *bezt; BPoint *bp; - while (nu) { + for (nu = cu->nurb.first; nu; nu = nu->next) { if (nu->bezt) { - int i; - bezt = nu->bezt; - a = nu->pntsu; + for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) { + int i; - while (a--) { - for (i = 0; i < 3; i++) { - add_v3_v3(fp, co); - fp += 3; co += 3; + for (i = 0; i < 3; i++, fp += 3, ofs++) { + add_v3_v3(fp, *ofs); } - fp += 3; /* skip alphas */ - - bezt++; } } else { - bp = nu->bp; - a = nu->pntsu * nu->pntsv; + for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, bp++, fp += 4, ofs++) { + add_v3_v3(fp, *ofs); + } + } + } + } +} - while (a--) { - add_v3_v3(fp, co); +/* ==========================================================*/ - fp += 4; - co += 3; +/** Move shape key from org_index to new_index. Safe, clamps index to valid range, updates reference keys, + * the object's active shape index, the 'frame' value in case of absolute keys, etc. + * Note indices are expected in real values (not 'fake' shapenr +1 ones). + * + * \param org_index if < 0, current object's active shape will be used as skey to move. + * \return true if something was done, else false. + */ +bool BKE_keyblock_move(Object *ob, int org_index, int new_index) +{ + Key *key = BKE_key_from_object(ob); + KeyBlock *kb; + const int act_index = ob->shapenr - 1; + const int totkey = key->totkey; + int i; + bool rev, in_range = false; - bp++; - } - } + if (org_index < 0) { + org_index = act_index; + } + + CLAMP(new_index, 0, key->totkey - 1); + CLAMP(org_index, 0, key->totkey - 1); + + if (new_index == org_index) { + return false; + } + + rev = ((new_index - org_index) < 0) ? true : false; + + /* We swap 'org' element with its previous/next neighbor (depending on direction of the move) repeatedly, + * until we reach final position. + * This allows us to only loop on the list once! */ + for (kb = (rev ? key->block.last : key->block.first), i = (rev ? totkey - 1 : 0); + kb; + kb = (rev ? kb->prev : kb->next), rev ? i-- : i++) + { + if (i == org_index) { + in_range = true; /* Start list items swapping... */ + } + else if (i == new_index) { + in_range = false; /* End list items swapping. */ + } + + if (in_range) { + KeyBlock *other_kb = rev ? kb->prev : kb->next; + + /* Swap with previous/next list item. */ + BLI_listbase_swaplinks(&key->block, kb, other_kb); + + /* Swap absolute positions. */ + SWAP(float, kb->pos, other_kb->pos); - nu = nu->next; + kb = other_kb; + } + + /* Adjust relative indices, this has to be done on the whole list! */ + if (kb->relative == org_index) { + kb->relative = new_index; + } + else if (kb->relative < org_index && kb->relative >= new_index) { + /* remove after, insert before this index */ + kb->relative++; + } + else if (kb->relative > org_index && kb->relative <= new_index) { + /* remove before, insert after this index */ + kb->relative--; + } + } + + /* Need to update active shape number if it's affected, same principle as for relative indices above. */ + if (org_index == act_index) { + ob->shapenr = new_index + 1; + } + else if (act_index < org_index && act_index >= new_index) { + ob->shapenr++; + } + else if (act_index > org_index && act_index <= new_index) { + ob->shapenr--; + } + + /* First key is always refkey, matches interface and BKE_key_sort */ + key->refkey = key->block.first; + + return true; +} + +/** + * Check if given keyblock (as index) is used as basis by others in given key. + */ +bool BKE_keyblock_is_basis(Key *key, const int index) +{ + KeyBlock *kb; + int i; + + if (key->type == KEY_RELATIVE) { + for (i = 0, kb = key->block.first; kb; i++, kb = kb->next) { + if ((i != index) && (kb->relative == index)) { + return true; + } } } + + return false; } diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c index 4a413850ec0..e738b16c8cc 100644 --- a/source/blender/blenkernel/intern/lamp.c +++ b/source/blender/blenkernel/intern/lamp.c @@ -41,7 +41,6 @@ #include "DNA_scene_types.h" #include "DNA_texture_types.h" -#include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_utildefines.h" diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 3f12e3efcc7..7732d592da6 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -575,7 +575,7 @@ static bool where_on_path_deform(Object *ob, float ctime, float vec[4], float di /* test for cyclic */ bl = ob->curve_cache->bev.first; - if (!bl->nr) return 0; + if (!bl->nr) return false; if (bl->poly > -1) cycl = 1; if (cycl == 0) { @@ -608,9 +608,9 @@ static bool where_on_path_deform(Object *ob, float ctime, float vec[4], float di /* weight - not used but could be added */ } } - return 1; + return true; } - return 0; + return false; } /* for each point, rotate & translate to curve */ @@ -634,9 +634,7 @@ static bool calc_curve_deform(Scene *scene, Object *par, float co[3], #endif if (par->curve_cache->path == NULL) { - return 0; /* happens on append, cyclic dependencies - * and empty curves - */ + return false; /* happens on append, cyclic dependencies and empty curves */ } /* options */ @@ -718,9 +716,9 @@ static bool calc_curve_deform(Scene *scene, Object *par, float co[3], if (r_quat) copy_qt_qt(r_quat, quat); - return 1; + return true; } - return 0; + return false; } void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, DerivedMesh *dm, float (*vertexCos)[3], @@ -939,10 +937,10 @@ bool object_deform_mball(Object *ob, ListBase *dispbase) (float(*)[3])dl->verts, dl->nr, NULL, 1.0f); } - return 1; + return true; } else { - return 0; + return false; } } diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c index bcdaf9b7af0..5bee93349d8 100644 --- a/source/blender/blenkernel/intern/linestyle.c +++ b/source/blender/blenkernel/intern/linestyle.c @@ -53,8 +53,6 @@ #include "BKE_colortools.h" #include "BKE_animsys.h" -#include "RNA_access.h" - static const char *modifier_name[LS_MODIFIER_NUM] = { NULL, "Along Stroke", diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 83ad2f1b2d2..b8c78ce912c 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -59,8 +59,6 @@ #include "BKE_movieclip.h" #include "BKE_image.h" -#include "NOD_composite.h" - static struct { ListBase splines; struct GHash *id_hash; @@ -1187,11 +1185,12 @@ void BKE_mask_point_parent_matrix_get(MaskSplinePoint *point, float ctime, float MovieTrackingPlaneTrack *plane_track = BKE_tracking_plane_track_get_named(tracking, ob, parent->sub_parent); if (plane_track) { - MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, clip_framenr); + float corners[4][2]; float aspx, aspy; float frame_size[2], H[3][3], mask_from_clip_matrix[3][3], mask_to_clip_matrix[3][3]; - BKE_tracking_homography_between_two_quads(parent->parent_corners_orig, plane_marker->corners, H); + BKE_tracking_plane_marker_get_subframe_corners(plane_track, ctime, corners); + BKE_tracking_homography_between_two_quads(parent->parent_corners_orig, corners, H); unit_m3(mask_from_clip_matrix); @@ -1457,7 +1456,7 @@ void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const bool d { if (found == 1) { #if 0 - printf("%s: exact %d %d (%d)\n", __func__, (int)ctime, BLI_countlist(&masklay->splines_shapes), + printf("%s: exact %d %d (%d)\n", __func__, (int)ctime, BLI_listbase_count(&masklay->splines_shapes), masklay_shape_a->frame); #endif @@ -1466,7 +1465,7 @@ void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const bool d else if (found == 2) { float w = masklay_shape_b->frame - masklay_shape_a->frame; #if 0 - printf("%s: tween %d %d (%d %d)\n", __func__, (int)ctime, BLI_countlist(&masklay->splines_shapes), + printf("%s: tween %d %d (%d %d)\n", __func__, (int)ctime, BLI_listbase_count(&masklay->splines_shapes), masklay_shape_a->frame, masklay_shape_b->frame); #endif BKE_mask_layer_shape_to_mask_interp(masklay, masklay_shape_a, masklay_shape_b, @@ -1833,7 +1832,7 @@ static int mask_layer_shape_sort_cb(const void *masklay_shape_a_ptr, const void void BKE_mask_layer_shape_sort(MaskLayer *masklay) { - BLI_sortlist(&masklay->splines_shapes, mask_layer_shape_sort_cb); + BLI_listbase_sort(&masklay->splines_shapes, mask_layer_shape_sort_cb); } bool BKE_mask_layer_shape_spline_from_index(MaskLayer *masklay, int index, diff --git a/source/blender/blenkernel/intern/mask_evaluate.c b/source/blender/blenkernel/intern/mask_evaluate.c index 3ed6148054c..5517fc36bc1 100644 --- a/source/blender/blenkernel/intern/mask_evaluate.c +++ b/source/blender/blenkernel/intern/mask_evaluate.c @@ -40,8 +40,6 @@ #include "BLI_math.h" #include "DNA_mask_types.h" -#include "DNA_node_types.h" -#include "DNA_scene_types.h" #include "BKE_curve.h" #include "BKE_mask.h" diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 4dc8ed21463..387d093051e 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -572,7 +572,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas unsigned int masklay_index; MemArena *sf_arena; - mr_handle->layers_tot = (unsigned int)BLI_countlist(&mask->masklayers); + mr_handle->layers_tot = (unsigned int)BLI_listbase_count(&mask->masklayers); mr_handle->layers = MEM_mallocN(sizeof(MaskRasterLayer) * mr_handle->layers_tot, "MaskRasterLayer"); BLI_rctf_init_minmax(&mr_handle->bounds); @@ -608,7 +608,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas continue; } - tot_splines = (unsigned int)BLI_countlist(&masklay->splines); + tot_splines = (unsigned int)BLI_listbase_count(&masklay->splines); open_spline_ranges = MEM_callocN(sizeof(*open_spline_ranges) * tot_splines, __func__); BLI_scanfill_begin_arena(&sf_ctx, sf_arena); @@ -956,7 +956,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas &isect_remvertbase, &isect_remedgebase))) { - unsigned int sf_vert_tot_isect = (unsigned int)BLI_countlist(&sf_ctx.fillvertbase); + unsigned int sf_vert_tot_isect = (unsigned int)BLI_listbase_count(&sf_ctx.fillvertbase); unsigned int i = sf_vert_tot; face_coords = MEM_reallocN(face_coords, sizeof(float[3]) * (sf_vert_tot + sf_vert_tot_isect)); diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 29f700cf242..ad1692eadf3 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -116,7 +116,7 @@ void BKE_material_free_ex(Material *ma, bool do_id_user) MEM_freeN(ma->texpaintslot); if (ma->gpumaterial.first) - GPU_material_free(ma); + GPU_material_free(&ma->gpumaterial); } void init_material(Material *ma) @@ -1153,28 +1153,28 @@ static bool material_in_nodetree(bNodeTree *ntree, Material *mat) if (node->id) { if (GS(node->id->name) == ID_MA) { if (node->id == (ID *)mat) { - return 1; + return true; } } else if (node->type == NODE_GROUP) { if (material_in_nodetree((bNodeTree *)node->id, mat)) { - return 1; + return true; } } } } - return 0; + return false; } bool material_in_material(Material *parmat, Material *mat) { if (parmat == mat) - return 1; + return true; else if (parmat->nodetree && parmat->use_nodes) return material_in_nodetree(parmat->nodetree, mat); else - return 0; + return false; } @@ -1336,7 +1336,7 @@ void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma) short index = 0, i; bool use_nodes = BKE_scene_use_new_shading_nodes(scene); - bool is_bi = BKE_scene_uses_blender_internal(scene); + bool is_bi = BKE_scene_uses_blender_internal(scene) || BKE_scene_uses_blender_game(scene); if (!ma) return; @@ -1740,7 +1740,7 @@ void paste_matcopybuf(Material *ma) MEM_freeN(ma->nodetree); } - GPU_material_free(ma); + GPU_material_free(&ma->gpumaterial); id = (ma->id); memcpy(ma, &matcopybuf, sizeof(Material)); diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 453c6df6e3b..4c45269cb0b 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -2436,10 +2436,10 @@ bool BKE_mball_center_bounds(MetaBall *mb, float r_cent[3]) if (BKE_mball_minmax(mb, min, max)) { mid_v3_v3v3(r_cent, min, max); - return 1; + return true; } - return 0; + return false; } void BKE_mball_transform(MetaBall *mb, float mat[4][4]) diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index f3a9e894eb3..3a6c949fe9c 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -755,7 +755,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh, MDeformWeight *dw; for (j = 0, dw = dv->dw; j < dv->totweight; j++, dw++) { - /* note, greater then max defgroups is accounted for in our code, but not < 0 */ + /* note, greater than max defgroups is accounted for in our code, but not < 0 */ if (!finite(dw->weight)) { PRINT_ERR("\tVertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight); if (do_fixes) { diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index a9e853c873e..54ab5a8aca7 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -47,7 +47,6 @@ #include "DNA_armature_types.h" #include "DNA_object_types.h" -#include "DNA_meshdata_types.h" #include "BLI_utildefines.h" #include "BLI_path_util.h" @@ -57,6 +56,7 @@ #include "BLF_translation.h" +#include "BKE_appdir.h" #include "BKE_key.h" #include "BKE_multires.h" #include "BKE_DerivedMesh.h" @@ -713,7 +713,7 @@ const char *modifier_path_relbase(Object *ob) else { /* last resort, better then using "" which resolves to the current * working directory */ - return BLI_temp_dir_session(); + return BKE_tempdir_session(); } } @@ -723,7 +723,7 @@ void modifier_path_init(char *path, int path_maxlen, const char *name) /* elubie: changed this to default to the same dir as the render output * to prevent saving to C:\ on Windows */ BLI_join_dirfile(path, path_maxlen, - G.relbase_valid ? "//" : BLI_temp_dir_session(), + G.relbase_valid ? "//" : BKE_tempdir_session(), name); } diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index e28adb7c0e0..0e9a7ce45cf 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -69,7 +69,6 @@ #include "BKE_image.h" /* openanim */ #include "BKE_tracking.h" -#include "IMB_colormanagement.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" #include "IMB_moviecache.h" @@ -78,8 +77,6 @@ # include "intern/openexr/openexr_multi.h" #endif -#include "NOD_composite.h" - /*********************** movieclip buffer loaders *************************/ static int sequence_guess_offset(const char *full_name, int head_len, unsigned short numlen) @@ -528,6 +525,15 @@ static bool put_imbuf_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, i } } +static bool moviecache_check_free_proxy(ImBuf *UNUSED(ibuf), + void *userkey, + void *UNUSED(userdata)) +{ + MovieClipImBufCacheKey *key = (MovieClipImBufCacheKey *)userkey; + + return !(key->proxy == IMB_PROXY_NONE && key->render_flag == 0); +} + /*********************** common functions *************************/ /* only image block itself */ @@ -1170,6 +1176,15 @@ void BKE_movieclip_clear_cache(MovieClip *clip) free_buffers(clip); } +void BKE_movieclip_clear_proxy_cache(MovieClip *clip) +{ + if (clip->cache && clip->cache->moviecache) { + IMB_moviecache_cleanup(clip->cache->moviecache, + moviecache_check_free_proxy, + NULL); + } +} + void BKE_movieclip_reload(MovieClip *clip) { /* clear cache */ @@ -1261,7 +1276,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip scopes->frame_width = ibuf->x; scopes->frame_height = ibuf->y; - scopes->use_track_mask = track->flag & TRACK_PREVIEW_ALPHA; + scopes->use_track_mask = (track->flag & TRACK_PREVIEW_ALPHA) != 0; } IMB_freeImBuf(ibuf); diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index df992cc9aed..0adc65bd806 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -126,7 +126,7 @@ static BLI_bitmap *multires_mdisps_upsample_hidden(BLI_bitmap *lo_hidden, if (lo_level == hi_level) return MEM_dupallocN(lo_hidden); - subd = BLI_BITMAP_NEW(hi_gridsize * hi_gridsize, "MDisps.hidden upsample"); + subd = BLI_BITMAP_NEW(SQUARE(hi_gridsize), "MDisps.hidden upsample"); factor = BKE_ccg_factor(lo_level, hi_level); offset = 1 << (hi_level - lo_level - 1); @@ -182,9 +182,7 @@ static BLI_bitmap *multires_mdisps_downsample_hidden(BLI_bitmap *old_hidden, BLI_assert(new_level <= old_level); factor = BKE_ccg_factor(new_level, old_level); - new_hidden = BLI_BITMAP_NEW(new_gridsize * new_gridsize, - "downsample hidden"); - + new_hidden = BLI_BITMAP_NEW(SQUARE(new_gridsize), "downsample hidden"); for (y = 0; y < new_gridsize; y++) { @@ -250,15 +248,15 @@ static MDisps *multires_mdisps_initialize_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 = gridsize * gridsize; - int i, j, k; + int gridarea = SQUARE(gridsize); + int i, j; for (i = 0; i < me->totpoly; i++) { - int hide = 0; + 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 = 1; + hide = true; break; } } @@ -599,7 +597,7 @@ static void multires_grid_paint_mask_downsample(GridPaintMask *gpm, int level) { if (level < gpm->level) { int gridsize = BKE_ccg_gridsize(level); - float *data = MEM_callocN(sizeof(float) * gridsize * gridsize, + float *data = MEM_callocN(sizeof(float) * SQUARE(gridsize), "multires_grid_paint_mask_downsample"); int x, y; @@ -1602,7 +1600,7 @@ void multires_load_old_250(Mesh *me) int nvert = mf->v4 ? 4 : 3; int totdisp = mdisps[i].totdisp / nvert; - for (j = 0; j < mf->v4 ? 4 : 3; j++, k++) { + for (j = 0; j < nvert; j++, k++) { mdisps2[k].disps = MEM_callocN(sizeof(float) * 3 * totdisp, "multires disp in conversion"); mdisps2[k].totdisp = totdisp; mdisps2[k].level = mdisps[i].level; diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index 19e45142960..b4d63f8053b 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -268,7 +268,7 @@ NlaTrack *add_nlatrack(AnimData *adt, NlaTrack *prev) /* set settings requiring the track to not be part of the stack yet */ nlt->flag = NLATRACK_SELECTED; - nlt->index = BLI_countlist(&adt->nla_tracks); + nlt->index = BLI_listbase_count(&adt->nla_tracks); /* add track to stack, and make it the active one */ if (prev) @@ -567,7 +567,7 @@ bool BKE_nlastrips_has_space(ListBase *strips, float start, float end) /* sanity checks */ if ((strips == NULL) || IS_EQF(start, end)) - return 0; + return false; if (start > end) { puts("BKE_nlastrips_has_space() error... start and end arguments swapped"); SWAP(float, start, end); @@ -579,17 +579,17 @@ bool BKE_nlastrips_has_space(ListBase *strips, float start, float end) * we've gone past the window we need to check for, so things are fine */ if (strip->start >= end) - return 1; + return true; /* if the end of the strip is greater than either of the boundaries, the range * must fall within the extents of the strip */ if ((strip->end > start) || (strip->end > end)) - return 0; + return false; } /* if we are still here, we haven't encountered any overlapping strips */ - return 1; + return true; } /* Rearrange the strips in the track so that they are always in order @@ -646,11 +646,11 @@ bool BKE_nlastrips_add_strip(ListBase *strips, NlaStrip *strip) /* sanity checks */ if (ELEM(NULL, strips, strip)) - return 0; + return false; /* check if any space to add */ if (BKE_nlastrips_has_space(strips, strip->start, strip->end) == 0) - return 0; + return false; /* find the right place to add the strip to the nominated track */ for (ns = strips->first; ns; ns = ns->next) { @@ -667,7 +667,7 @@ bool BKE_nlastrips_add_strip(ListBase *strips, NlaStrip *strip) } /* added... */ - return 1; + return true; } @@ -785,11 +785,11 @@ bool BKE_nlameta_add_strip(NlaStrip *mstrip, NlaStrip *strip) { /* sanity checks */ if (ELEM(NULL, mstrip, strip)) - return 0; + return false; /* firstly, check if the meta-strip has space for this */ if (BKE_nlastrips_has_space(&mstrip->strips, strip->start, strip->end) == 0) - return 0; + return false; /* check if this would need to be added to the ends of the meta, * and subsequently, if the neighboring strips allow us enough room @@ -803,10 +803,10 @@ bool BKE_nlameta_add_strip(NlaStrip *mstrip, NlaStrip *strip) BLI_addhead(&mstrip->strips, strip); mstrip->start = strip->start; - return 1; + return true; } else /* failed... no room before */ - return 0; + return false; } else if (strip->end > mstrip->end) { /* check if strip to the right (if it exists) starts before the @@ -817,10 +817,10 @@ bool BKE_nlameta_add_strip(NlaStrip *mstrip, NlaStrip *strip) BLI_addtail(&mstrip->strips, strip); mstrip->end = strip->end; - return 1; + return true; } else /* failed... no room after */ - return 0; + return false; } else { /* just try to add to the meta-strip (no dimension changes needed) */ @@ -988,7 +988,7 @@ bool BKE_nlatrack_has_space(NlaTrack *nlt, float start, float end) * - bounds cannot be equal (0-length is nasty) */ if ((nlt == NULL) || (nlt->flag & NLATRACK_PROTECTED) || IS_EQF(start, end)) - return 0; + return false; if (start > end) { puts("BKE_nlatrack_has_space() error... start and end arguments swapped"); @@ -1019,7 +1019,7 @@ bool BKE_nlatrack_add_strip(NlaTrack *nlt, NlaStrip *strip) { /* sanity checks */ if (ELEM(NULL, nlt, strip)) - return 0; + return false; /* try to add the strip to the track using a more generic function */ return BKE_nlastrips_add_strip(&nlt->strips, strip); @@ -1036,11 +1036,11 @@ bool BKE_nlatrack_get_bounds(NlaTrack *nlt, float bounds[2]) if (bounds) bounds[0] = bounds[1] = 0.0f; else - return 0; + return false; /* sanity checks */ if (ELEM(NULL, nlt, nlt->strips.first)) - return 0; + return false; /* lower bound is first strip's start frame */ strip = nlt->strips.first; @@ -1051,7 +1051,7 @@ bool BKE_nlatrack_get_bounds(NlaTrack *nlt, float bounds[2]) bounds[1] = strip->end; /* done */ - return 1; + return true; } /* NLA Strips -------------------------------------- */ @@ -1105,7 +1105,7 @@ bool BKE_nlastrip_within_bounds(NlaStrip *strip, float min, float max) /* sanity checks */ if ((strip == NULL) || IS_EQF(stripLen, 0.0f) || IS_EQF(boundsLen, 0.0f)) - return 0; + return false; /* only ok if at least part of the strip is within the bounding window * - first 2 cases cover when the strip length is less than the bounding area @@ -1115,17 +1115,17 @@ bool BKE_nlastrip_within_bounds(NlaStrip *strip, float min, float max) !(IN_RANGE(strip->start, min, max) || IN_RANGE(strip->end, min, max))) { - return 0; + return false; } if ((stripLen > boundsLen) && !(IN_RANGE(min, strip->start, strip->end) || IN_RANGE(max, strip->start, strip->end)) ) { - return 0; + return false; } /* should be ok! */ - return 1; + return true; } @@ -1209,11 +1209,11 @@ static bool nlastrip_is_first(AnimData *adt, NlaStrip *strip) /* sanity checks */ if (ELEM(NULL, adt, strip)) - return 0; + return false; /* check if strip has any strips before it */ if (strip->prev) - return 0; + return false; /* check other tracks to see if they have a strip that's earlier */ /* TODO: or should we check that the strip's track is also the first? */ @@ -1222,12 +1222,12 @@ static bool nlastrip_is_first(AnimData *adt, NlaStrip *strip) ns = nlt->strips.first; if (ns) { if (ns->start < strip->start) - return 0; + return false; } } /* should be first now */ - return 1; + return true; } /* Animated Strips ------------------------------------------- */ @@ -1239,16 +1239,16 @@ bool BKE_nlatrack_has_animated_strips(NlaTrack *nlt) /* sanity checks */ if (ELEM(NULL, nlt, nlt->strips.first)) - return 0; + return false; /* check each strip for F-Curves only (don't care about whether the flags are set) */ for (strip = nlt->strips.first; strip; strip = strip->next) { if (strip->fcurves.first) - return 1; + return true; } /* none found */ - return 0; + return false; } /* Check if given NLA-Tracks have any strips with own F-Curves */ @@ -1258,16 +1258,16 @@ bool BKE_nlatracks_have_animated_strips(ListBase *tracks) /* sanity checks */ if (ELEM(NULL, tracks, tracks->first)) - return 0; + return false; /* check each track, stopping on the first hit */ for (nlt = tracks->first; nlt; nlt = nlt->next) { if (BKE_nlatrack_has_animated_strips(nlt)) - return 1; + return true; } /* none found */ - return 0; + return false; } /* Validate the NLA-Strips 'control' F-Curves based on the flags set*/ @@ -1587,13 +1587,13 @@ bool BKE_nla_tweakmode_enter(AnimData *adt) /* verify that data is valid */ if (ELEM(NULL, adt, adt->nla_tracks.first)) - return 0; + return false; /* if block is already in tweakmode, just leave, but we should report * that this block is in tweakmode (as our returncode) */ if (adt->flag & ADT_NLA_EDIT_ON) - return 1; + return true; /* go over the tracks, finding the active one, and its active strip * - if we cannot find both, then there's nothing to do @@ -1642,7 +1642,7 @@ bool BKE_nla_tweakmode_enter(AnimData *adt) printf("NLA tweakmode enter - neither active requirement found\n"); printf("\tactiveTrack = %p, activeStrip = %p\n", (void *)activeTrack, (void *)activeStrip); } - return 0; + return false; } /* go over all the tracks up to the active one, tagging each strip that uses the same @@ -1677,7 +1677,7 @@ bool BKE_nla_tweakmode_enter(AnimData *adt) adt->flag |= ADT_NLA_EDIT_ON; /* done! */ - return 1; + return true; } /* Exit tweakmode for this AnimData block */ diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 7ab1479905a..b6c9e9309b8 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -2268,8 +2268,8 @@ bool ntreeHasType(const bNodeTree *ntree, int type) if (ntree) for (node = ntree->nodes.first; node; node = node->next) if (node->type == type) - return 1; - return 0; + return true; + return false; } bool ntreeHasTree(const bNodeTree *ntree, const bNodeTree *lookup) @@ -2534,8 +2534,8 @@ bool BKE_node_clipboard_validate(void) /* lists must be aligned */ - BLI_assert(BLI_countlist(&node_clipboard.nodes) == - BLI_countlist(&node_clipboard.nodes_extra_info)); + BLI_assert(BLI_listbase_count(&node_clipboard.nodes) == + BLI_listbase_count(&node_clipboard.nodes_extra_info)); for (node = node_clipboard.nodes.first, node_info = node_clipboard.nodes_extra_info.first; node; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 7a8843f3308..a0d1b25a103 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -96,6 +96,7 @@ #include "BKE_editmesh.h" #include "BKE_mball.h" #include "BKE_modifier.h" +#include "BKE_node.h" #include "BKE_object.h" #include "BKE_paint.h" #include "BKE_particle.h" @@ -107,6 +108,7 @@ #include "BKE_sequencer.h" #include "BKE_speaker.h" #include "BKE_softbody.h" +#include "BKE_subsurf.h" #include "BKE_material.h" #include "BKE_camera.h" #include "BKE_image.h" @@ -119,6 +121,8 @@ #include "BPY_extern.h" #endif +#include "CCGSubSurf.h" + #include "GPU_material.h" /* Vertex parent modifies original BMesh which is not safe for threading. @@ -185,6 +189,7 @@ void BKE_object_free_curve_cache(Object *ob) if (ob->curve_cache->path) { free_path(ob->curve_cache->path); } + BKE_nurbList_free(&ob->curve_cache->deformed_nurbs); MEM_freeN(ob->curve_cache); ob->curve_cache = NULL; } @@ -321,18 +326,7 @@ void BKE_object_free_derived_caches(Object *ob) ob->derivedDeform = NULL; } - if (ob->curve_cache) { - BKE_displist_free(&ob->curve_cache->disp); - BKE_curve_bevelList_free(&ob->curve_cache->bev); - if (ob->curve_cache->path) { - free_path(ob->curve_cache->path); - ob->curve_cache->path = NULL; - } - - /* Signal for viewport to run DAG workarounds. */ - MEM_freeN(ob->curve_cache); - ob->curve_cache = NULL; - } + BKE_object_free_curve_cache(ob); } /* do not free object itself */ @@ -442,6 +436,7 @@ void BKE_object_unlink(Object *ob) Scene *sce; SceneRenderLayer *srl; FreestyleLineSet *lineset; + bNodeTree *ntree; Curve *cu; Tex *tex; Group *group; @@ -643,17 +638,22 @@ void BKE_object_unlink(Object *ob) } /* materials */ - mat = bmain->mat.first; - while (mat) { - + for (mat = bmain->mat.first; mat; mat = mat->id.next) { + if (mat->nodetree) { + ntreeSwitchID(mat->nodetree, &ob->id, NULL); + } for (a = 0; a < MAX_MTEX; a++) { if (mat->mtex[a] && ob == mat->mtex[a]->object) { /* actually, test for lib here... to do */ mat->mtex[a]->object = NULL; } } + } - mat = mat->id.next; + /* node trees */ + for (ntree = bmain->nodetree.first; ntree; ntree = ntree->id.next) { + if (ntree->type == NTREE_SHADER) + ntreeSwitchID(ntree, &ob->id, NULL); } /* textures */ @@ -1078,14 +1078,14 @@ static int lod_cmp(const void *a, const void *b) void BKE_object_lod_sort(Object *ob) { - BLI_sortlist(&ob->lodlevels, lod_cmp); + BLI_listbase_sort(&ob->lodlevels, lod_cmp); } bool BKE_object_lod_remove(Object *ob, int level) { LodLevel *rem; - if (level < 1 || level > BLI_countlist(&ob->lodlevels) - 1) + if (level < 1 || level > BLI_listbase_count(&ob->lodlevels) - 1) return false; rem = BLI_findlink(&ob->lodlevels, level); @@ -1098,7 +1098,7 @@ bool BKE_object_lod_remove(Object *ob, int level) MEM_freeN(rem); /* If there are no user defined lods, remove the base lod as well */ - if (BLI_countlist(&ob->lodlevels) == 1) { + if (BLI_listbase_is_single(&ob->lodlevels)) { LodLevel *base = ob->lodlevels.first; BLI_remlink(&ob->lodlevels, base); MEM_freeN(base); @@ -1136,7 +1136,7 @@ static LodLevel *lod_level_select(Object *ob, const float camera_position[3]) bool BKE_object_lod_is_usable(Object *ob, Scene *scene) { - bool active = (scene) ? ob == OBACT : 0; + bool active = (scene) ? ob == OBACT : false; return (ob->mode == OB_MODE_OBJECT || !active); } @@ -1402,10 +1402,10 @@ bool BKE_object_pose_context_check(Object *ob) (ob->pose) && (ob->mode & OB_MODE_POSE)) { - return 1; + return true; } else { - return 0; + return false; } } @@ -2161,26 +2161,60 @@ static void give_parvert(Object *par, int nr, float vec[3]) int numVerts = dm->getNumVerts(dm); if (nr < numVerts) { - /* avoid dm->getVertDataArray() since it allocates arrays in the dm (not thread safe) */ - int i; + bool use_special_ss_case = false; + + if (dm->type == DM_TYPE_CCGDM) { + ModifierData *md; + VirtualModifierData virtualModifierData; + use_special_ss_case = true; + for (md = modifiers_getVirtualModifierList(par, &virtualModifierData); + md != NULL; + md = md->next) + { + ModifierTypeInfo *mti = modifierType_getInfo(md->type); + /* TODO(sergey): Check for disabled modifiers. */ + if (mti->type != eModifierTypeType_OnlyDeform && md->next != NULL) { + use_special_ss_case = false; + break; + } + } + } - if (em && dm->type == DM_TYPE_EDITBMESH) { - if (em->bm->elem_table_dirty & BM_VERT) { -#ifdef VPARENT_THREADING_HACK - BLI_mutex_lock(&vparent_lock); + if (!use_special_ss_case) { + /* avoid dm->getVertDataArray() since it allocates arrays in the dm (not thread safe) */ + if (em && dm->type == DM_TYPE_EDITBMESH) { if (em->bm->elem_table_dirty & BM_VERT) { - BM_mesh_elem_table_ensure(em->bm, BM_VERT); - } - BLI_mutex_unlock(&vparent_lock); +#ifdef VPARENT_THREADING_HACK + BLI_mutex_lock(&vparent_lock); + if (em->bm->elem_table_dirty & BM_VERT) { + BM_mesh_elem_table_ensure(em->bm, BM_VERT); + } + BLI_mutex_unlock(&vparent_lock); #else - BLI_assert(!"Not safe for threading"); - BM_mesh_elem_table_ensure(em->bm, BM_VERT); + BLI_assert(!"Not safe for threading"); + BM_mesh_elem_table_ensure(em->bm, BM_VERT); #endif + } + } + } + + if (use_special_ss_case) { + /* Special case if the last modifier is SS and no constructive modifier are in front of it. */ + CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; + CCGVert *ccg_vert = ccgSubSurf_getVert(ccgdm->ss, SET_INT_IN_POINTER(nr)); + /* In case we deleted some verts, nr may refer to inexistent one now, see T42557. */ + if (ccg_vert) { + float *co = ccgSubSurf_getVertData(ccgdm->ss, ccg_vert); + add_v3_v3(vec, co); + count++; } } + else if (CustomData_has_layer(&dm->vertData, CD_ORIGINDEX) && + !(em && dm->type == DM_TYPE_EDITBMESH)) + { + int i; - /* get the average of all verts with (original index == nr) */ - if (CustomData_has_layer(&dm->vertData, CD_ORIGINDEX)) { + /* Get the average of all verts with (original index == nr). */ for (i = 0; i < numVerts; i++) { const int *index = dm->getVertData(dm, i, CD_ORIGINDEX); if (*index == nr) { @@ -2219,8 +2253,18 @@ static void give_parvert(Object *par, int nr, float vec[3]) } } else if (ELEM(par->type, OB_CURVE, OB_SURF)) { - Curve *cu = par->data; - ListBase *nurb = BKE_curve_nurbs_get(cu); + ListBase *nurb; + + /* Unless there's some weird depsgraph failure the cache should exist. */ + BLI_assert(par->curve_cache != NULL); + + if (par->curve_cache->deformed_nurbs.first != NULL) { + nurb = &par->curve_cache->deformed_nurbs; + } + else { + Curve *cu = par->data; + nurb = BKE_curve_nurbs_get(cu); + } BKE_nurbList_index_get_co(nurb, nr, vec); } @@ -2357,7 +2401,7 @@ static bool where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat /* include framerate */ fac1 = (1.0f / (1.0f + fabsf(ob->sf))); - if (fac1 >= 1.0f) return 0; + if (fac1 >= 1.0f) return false; fac2 = 1.0f - fac1; fp1 = obmat[0]; @@ -2366,7 +2410,7 @@ static bool where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat fp1[0] = fac1 * fp1[0] + fac2 * fp2[0]; } - return 1; + return true; } /* note, scene is the active scene while actual_scene is the scene the object resides in */ @@ -3255,7 +3299,7 @@ int BKE_object_insert_ptcache(Object *ob) LinkData *link = NULL; int i = 0; - BLI_sortlist(&ob->pc_ids, pc_cmp); + BLI_listbase_sort(&ob->pc_ids, pc_cmp); for (link = ob->pc_ids.first, i = 0; link; link = link->next, i++) { int index = GET_INT_FROM_POINTER(link->data); @@ -3316,7 +3360,7 @@ static KeyBlock *insert_meshkey(Scene *scene, Object *ob, const char *name, cons if (newkey || from_mix == false) { /* create from mesh */ kb = BKE_keyblock_add_ctime(key, name, false); - BKE_key_convert_from_mesh(me, kb); + BKE_keyblock_convert_from_mesh(me, kb); } else { /* copy from current values */ @@ -3353,7 +3397,7 @@ static KeyBlock *insert_lattkey(Scene *scene, Object *ob, const char *name, cons kb->totelem = basekb->totelem; } else { - BKE_key_convert_from_lattice(lt, kb); + BKE_keyblock_convert_from_lattice(lt, kb); } } else { @@ -3393,7 +3437,7 @@ static KeyBlock *insert_curvekey(Scene *scene, Object *ob, const char *name, con kb->totelem = basekb->totelem; } else { - BKE_key_convert_from_curve(cu, kb, lb); + BKE_keyblock_convert_from_curve(cu, kb, lb); } } else { diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c index e53bd26b9a2..e46929dde4a 100644 --- a/source/blender/blenkernel/intern/object_deform.c +++ b/source/blender/blenkernel/intern/object_deform.c @@ -27,18 +27,457 @@ #include "MEM_guardedalloc.h" +#include "BLF_translation.h" + #include "BLI_utildefines.h" #include "BLI_ghash.h" #include "BLI_listbase.h" +#include "DNA_armature_types.h" +#include "DNA_cloth_types.h" +#include "DNA_curve_types.h" +#include "DNA_lattice_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_mesh_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" +#include "DNA_object_force.h" +#include "DNA_particle_types.h" +#include "DNA_scene_types.h" + #include "BKE_action.h" +#include "BKE_deform.h" +#include "BKE_editmesh.h" #include "BKE_object_deform.h" /* own include */ #include "BKE_object.h" #include "BKE_modifier.h" -#include "DNA_armature_types.h" -#include "DNA_modifier_types.h" -#include "DNA_object_types.h" +/** \name Misc helpers + * \{ */ + +static Lattice *object_defgroup_lattice_get(ID *id) +{ + Lattice *lt = (Lattice *)id; + BLI_assert(GS(id->name) == ID_LT); + return (lt->editlatt) ? lt->editlatt->latt : lt; +} + +/** + * Update users of vgroups from this object, according to given map. + * + * Use it when you remove or reorder vgroups in the object. + * + * \param map an array mapping old indices to new indices. + */ +void BKE_object_defgroup_remap_update_users(Object *ob, int *map) +{ + ModifierData *md; + ParticleSystem *psys; + int a; + + /* these cases don't use names to refer to vertex groups, so when + * they get removed the numbers get out of sync, this corrects that */ + + if (ob->soft) { + ob->soft->vertgroup = map[ob->soft->vertgroup]; + } + + for (md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_Explode) { + ExplodeModifierData *emd = (ExplodeModifierData *)md; + emd->vgroup = map[emd->vgroup]; + } + else if (md->type == eModifierType_Cloth) { + ClothModifierData *clmd = (ClothModifierData *)md; + ClothSimSettings *clsim = clmd->sim_parms; + + if (clsim) { + clsim->vgroup_mass = map[clsim->vgroup_mass]; + clsim->vgroup_bend = map[clsim->vgroup_bend]; + clsim->vgroup_struct = map[clsim->vgroup_struct]; + } + } + } + + for (psys = ob->particlesystem.first; psys; psys = psys->next) { + for (a = 0; a < PSYS_TOT_VG; a++) { + psys->vgroup[a] = map[psys->vgroup[a]]; + } + } +} +/** \} */ + + +/** \name Group creation + * \{ */ + +/** + * Add a vgroup of given name to object. *Does not* handle MDeformVert data at all! + */ +bDeformGroup *BKE_object_defgroup_add_name(Object *ob, const char *name) +{ + bDeformGroup *defgroup; + + if (!ob || !OB_TYPE_SUPPORT_VGROUP(ob->type)) + return NULL; + + defgroup = BKE_defgroup_new(ob, name); + + ob->actdef = BLI_listbase_count(&ob->defbase); + + return defgroup; +} + +/** + * Add a vgroup of default name to object. *Does not* handle MDeformVert data at all! + */ +bDeformGroup *BKE_object_defgroup_add(Object *ob) +{ + return BKE_object_defgroup_add_name(ob, DATA_("Group")); +} + +/** + * Create MDeformVert data for given ID. Work in Object mode only. + */ +MDeformVert *BKE_object_defgroup_data_create(ID *id) +{ + if (GS(id->name) == ID_ME) { + Mesh *me = (Mesh *)id; + me->dvert = CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert); + return me->dvert; + } + else if (GS(id->name) == ID_LT) { + Lattice *lt = (Lattice *)id; + lt->dvert = MEM_callocN(sizeof(MDeformVert) * lt->pntsu * lt->pntsv * lt->pntsw, "lattice deformVert"); + return lt->dvert; + } + + return NULL; +} +/** \} */ + + +/** \name Group clearing + * \{ */ + +/** + * Remove all verts (or only selected ones) from given vgroup. Work in Object and Edit modes. + * + * \param allverts If true, remove all vertices, else only selected ones. + * \return True if any vertex was removed, false otherwise. + */ +bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_selection) +{ + MDeformVert *dv; + const int def_nr = BLI_findindex(&ob->defbase, dg); + bool changed = false; + + if (ob->type == OB_MESH) { + Mesh *me = ob->data; + + if (me->edit_btmesh) { + BMEditMesh *em = me->edit_btmesh; + const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); + + if (cd_dvert_offset != -1) { + BMVert *eve; + BMIter iter; + + BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { + dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); + + if (dv && dv->dw && (!use_selection || BM_elem_flag_test(eve, BM_ELEM_SELECT))) { + MDeformWeight *dw = defvert_find_index(dv, def_nr); + defvert_remove_group(dv, dw); /* dw can be NULL */ + changed = true; + } + } + } + } + else { + if (me->dvert) { + MVert *mv; + int i; + + mv = me->mvert; + dv = me->dvert; + + for (i = 0; i < me->totvert; i++, mv++, dv++) { + if (mv->flag & SELECT) { + if (dv->dw && (!use_selection || (mv->flag & SELECT))) { + MDeformWeight *dw = defvert_find_index(dv, def_nr); + defvert_remove_group(dv, dw); /* dw can be NULL */ + changed = true; + } + } + } + } + } + } + else if (ob->type == OB_LATTICE) { + Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data)); + + if (lt->dvert) { + BPoint *bp; + int i, tot = lt->pntsu * lt->pntsv * lt->pntsw; + + for (i = 0, bp = lt->def; i < tot; i++, bp++) { + if (!use_selection || (bp->f1 & SELECT)) { + MDeformWeight *dw; + + dv = <->dvert[i]; + + dw = defvert_find_index(dv, def_nr); + defvert_remove_group(dv, dw); /* dw can be NULL */ + changed = true; + } + } + } + } + + return changed; +} + +/** + * Remove all verts (or only selected ones) from all vgroups. Work in Object and Edit modes. + * + * \param allverts If true, remove all vertices, else only selected ones. + * \return True if any vertex was removed, false otherwise. + */ +bool BKE_object_defgroup_clear_all(Object *ob, const bool use_selection) +{ + bDeformGroup *dg; + bool changed = false; + + for (dg = ob->defbase.first; dg; dg = dg->next) { + if (BKE_object_defgroup_clear(ob, dg, use_selection)) { + changed = true; + } + } + + return changed; +} +/** \} */ + + +/** \name Group removal + * \{ */ + +static void object_defgroup_remove_update_users(Object *ob, const int idx) +{ + int i, defbase_tot = BLI_listbase_count(&ob->defbase) + 1; + int *map = MEM_mallocN(sizeof(int) * defbase_tot, "vgroup del"); + + map[idx] = map[0] = 0; + for (i = 1; i < idx; i++) { + map[i] = i; + } + for (i = idx + 1; i < defbase_tot; i++) { + map[i] = i - 1; + } + + BKE_object_defgroup_remap_update_users(ob, map); + MEM_freeN(map); +} + +static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const int def_nr) +{ + object_defgroup_remove_update_users(ob, def_nr + 1); + + /* Remove the group */ + BLI_freelinkN(&ob->defbase, dg); + + /* Update the active deform index if necessary */ + if (ob->actdef > def_nr) + ob->actdef--; + + /* remove all dverts */ + if (BLI_listbase_is_empty(&ob->defbase)) { + if (ob->type == OB_MESH) { + Mesh *me = ob->data; + CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); + me->dvert = NULL; + } + else if (ob->type == OB_LATTICE) { + Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data)); + if (lt->dvert) { + MEM_freeN(lt->dvert); + lt->dvert = NULL; + } + } + } + else if (ob->actdef < 1) { /* Keep a valid active index if we still have some vgroups. */ + ob->actdef = 1; + } +} + +static void object_defgroup_remove_object_mode(Object *ob, bDeformGroup *dg) +{ + MDeformVert *dvert_array = NULL; + int dvert_tot = 0; + const int def_nr = BLI_findindex(&ob->defbase, dg); + + BLI_assert(def_nr != -1); + + BKE_object_defgroup_array_get(ob->data, &dvert_array, &dvert_tot); + + if (dvert_array) { + int i, j; + MDeformVert *dv; + for (i = 0, dv = dvert_array; i < dvert_tot; i++, dv++) { + MDeformWeight *dw; + + dw = defvert_find_index(dv, def_nr); + defvert_remove_group(dv, dw); /* dw can be NULL */ + + /* inline, make into a function if anything else needs to do this */ + for (j = 0; j < dv->totweight; j++) { + if (dv->dw[j].def_nr > def_nr) { + dv->dw[j].def_nr--; + } + } + /* done */ + } + } + + object_defgroup_remove_common(ob, dg, def_nr); +} + +static void object_defgroup_remove_edit_mode(Object *ob, bDeformGroup *dg) +{ + int i; + const int def_nr = BLI_findindex(&ob->defbase, dg); + + BLI_assert(def_nr != -1); + + /* Make sure that no verts are using this group - if none were removed, we can skip next per-vert update. */ + if (!BKE_object_defgroup_clear(ob, dg, false)) { + /* Nothing to do. */ + } + /* Else, make sure that any groups with higher indices are adjusted accordingly */ + else if (ob->type == OB_MESH) { + Mesh *me = ob->data; + BMEditMesh *em = me->edit_btmesh; + const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); + + BMIter iter; + BMVert *eve; + MDeformVert *dvert; + + BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { + dvert = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); + + if (dvert) { + for (i = 0; i < dvert->totweight; i++) { + if (dvert->dw[i].def_nr > def_nr) { + dvert->dw[i].def_nr--; + } + } + } + } + } + else if (ob->type == OB_LATTICE) { + Lattice *lt = ((Lattice *)(ob->data))->editlatt->latt; + BPoint *bp; + MDeformVert *dvert = lt->dvert; + int a, tot; + + if (dvert) { + tot = lt->pntsu * lt->pntsv * lt->pntsw; + for (a = 0, bp = lt->def; a < tot; a++, bp++, dvert++) { + for (i = 0; i < dvert->totweight; i++) { + if (dvert->dw[i].def_nr > def_nr) { + dvert->dw[i].def_nr--; + } + } + } + } + } + + object_defgroup_remove_common(ob, dg, def_nr); +} + +/** + * Remove given vgroup from object. Work in Object and Edit modes. + */ +void BKE_object_defgroup_remove(Object *ob, bDeformGroup *defgroup) +{ + if (BKE_object_is_in_editmode_vgroup(ob)) + object_defgroup_remove_edit_mode(ob, defgroup); + else + object_defgroup_remove_object_mode(ob, defgroup); +} + +/** + * Remove all vgroups from object. Work in Object and Edit modes. + */ +void BKE_object_defgroup_remove_all(Object *ob) +{ + bDeformGroup *dg = (bDeformGroup *)ob->defbase.first; + const bool edit_mode = BKE_object_is_in_editmode_vgroup(ob); + + if (dg) { + while (dg) { + bDeformGroup *next_dg = dg->next; + + if (edit_mode) + object_defgroup_remove_edit_mode(ob, dg); + else + object_defgroup_remove_object_mode(ob, dg); + + dg = next_dg; + } + } + else { /* ob->defbase is empty... */ + /* remove all dverts */ + if (ob->type == OB_MESH) { + Mesh *me = ob->data; + CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); + me->dvert = NULL; + } + else if (ob->type == OB_LATTICE) { + Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data)); + if (lt->dvert) { + MEM_freeN(lt->dvert); + lt->dvert = NULL; + } + } + /* Fix counters/indices */ + ob->actdef = 0; + } +} + +/** + * Get MDeformVert vgroup data from given object. Should only be used in Object mode. + * + * \return True if the id type supports weights. + */ +bool BKE_object_defgroup_array_get(ID *id, MDeformVert **dvert_arr, int *dvert_tot) +{ + if (id) { + switch (GS(id->name)) { + case ID_ME: + { + Mesh *me = (Mesh *)id; + *dvert_arr = me->dvert; + *dvert_tot = me->totvert; + return true; + } + case ID_LT: + { + Lattice *lt = object_defgroup_lattice_get(id); + *dvert_arr = lt->dvert; + *dvert_tot = lt->pntsu * lt->pntsv * lt->pntsw; + return true; + } + } + } + + *dvert_arr = NULL; + *dvert_tot = 0; + return false; +} +/** \} */ /* --- functions for getting vgroup aligned maps --- */ @@ -46,11 +485,11 @@ * gets the status of "flag" for each bDeformGroup * in ob->defbase and returns an array containing them */ -bool *BKE_objdef_lock_flags_get(Object *ob, const int defbase_tot) +bool *BKE_object_defgroup_lock_flags_get(Object *ob, const int defbase_tot) { bool is_locked = false; int i; - //int defbase_tot = BLI_countlist(&ob->defbase); + //int defbase_tot = BLI_listbase_count(&ob->defbase); bool *lock_flags = MEM_mallocN(defbase_tot * sizeof(bool), "defflags"); bDeformGroup *defgroup; @@ -66,21 +505,21 @@ bool *BKE_objdef_lock_flags_get(Object *ob, const int defbase_tot) return NULL; } -bool *BKE_objdef_validmap_get(Object *ob, const int defbase_tot) +bool *BKE_object_defgroup_validmap_get(Object *ob, const int defbase_tot) { bDeformGroup *dg; ModifierData *md; - bool *vgroup_validmap; + bool *defgroup_validmap; GHash *gh; int i, step1 = 1; - //int defbase_tot = BLI_countlist(&ob->defbase); + //int defbase_tot = BLI_listbase_count(&ob->defbase); VirtualModifierData virtualModifierData; if (BLI_listbase_is_empty(&ob->defbase)) { return NULL; } - gh = BLI_ghash_str_new_ex("BKE_objdef_validmap_get gh", defbase_tot); + gh = BLI_ghash_str_new_ex(__func__, defbase_tot); /* add all names to a hash table */ for (dg = ob->defbase.first; dg; dg = dg->next) { @@ -115,23 +554,23 @@ bool *BKE_objdef_validmap_get(Object *ob, const int defbase_tot) } } - vgroup_validmap = MEM_mallocN(sizeof(*vgroup_validmap) * defbase_tot, "wpaint valid map"); + defgroup_validmap = MEM_mallocN(sizeof(*defgroup_validmap) * defbase_tot, "wpaint valid map"); /* add all names to a hash table */ for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) { - vgroup_validmap[i] = (BLI_ghash_lookup(gh, dg->name) != NULL); + defgroup_validmap[i] = (BLI_ghash_lookup(gh, dg->name) != NULL); } BLI_assert(i == BLI_ghash_size(gh)); BLI_ghash_free(gh, NULL, NULL); - return vgroup_validmap; + return defgroup_validmap; } /* Returns total selected vgroups, * wpi.defbase_sel is assumed malloc'd, all values are set */ -bool *BKE_objdef_selected_get(Object *ob, int defbase_tot, int *r_dg_flags_sel_tot) +bool *BKE_object_defgroup_selected_get(Object *ob, int defbase_tot, int *r_dg_flags_sel_tot) { bool *dg_selection = MEM_mallocN(defbase_tot * sizeof(bool), __func__); bDeformGroup *defgroup; @@ -158,3 +597,86 @@ bool *BKE_objdef_selected_get(Object *ob, int defbase_tot, int *r_dg_flags_sel_t return dg_selection; } + + +/** + * Return the subset type of the Vertex Group Selection + */ +bool *BKE_object_defgroup_subset_from_select_type( + Object *ob, eVGroupSelect subset_type, int *r_defgroup_tot, int *r_subset_count) +{ + bool *defgroup_validmap = NULL; + *r_defgroup_tot = BLI_listbase_count(&ob->defbase); + + switch (subset_type) { + case WT_VGROUP_ACTIVE: + { + const int def_nr_active = ob->actdef - 1; + defgroup_validmap = MEM_mallocN(*r_defgroup_tot * sizeof(*defgroup_validmap), __func__); + memset(defgroup_validmap, false, *r_defgroup_tot * sizeof(*defgroup_validmap)); + if ((def_nr_active >= 0) && (def_nr_active < *r_defgroup_tot)) { + *r_subset_count = 1; + defgroup_validmap[def_nr_active] = true; + } + else { + *r_subset_count = 0; + } + break; + } + case WT_VGROUP_BONE_SELECT: + { + defgroup_validmap = BKE_object_defgroup_selected_get(ob, *r_defgroup_tot, r_subset_count); + break; + } + case WT_VGROUP_BONE_DEFORM: + { + int i; + defgroup_validmap = BKE_object_defgroup_validmap_get(ob, *r_defgroup_tot); + *r_subset_count = 0; + for (i = 0; i < *r_defgroup_tot; i++) { + if (defgroup_validmap[i] == true) { + *r_subset_count += 1; + } + } + break; + } + case WT_VGROUP_BONE_DEFORM_OFF: + { + int i; + defgroup_validmap = BKE_object_defgroup_validmap_get(ob, *r_defgroup_tot); + *r_subset_count = 0; + for (i = 0; i < *r_defgroup_tot; i++) { + defgroup_validmap[i] = !defgroup_validmap[i]; + if (defgroup_validmap[i] == true) { + *r_subset_count += 1; + } + } + break; + } + case WT_VGROUP_ALL: + default: + { + defgroup_validmap = MEM_mallocN(*r_defgroup_tot * sizeof(*defgroup_validmap), __func__); + memset(defgroup_validmap, true, *r_defgroup_tot * sizeof(*defgroup_validmap)); + *r_subset_count = *r_defgroup_tot; + break; + } + } + + return defgroup_validmap; +} + +/** + * store indices from the defgroup_validmap (faster lookups in some cases) + */ +void BKE_object_defgroup_subset_to_index_array( + const bool *defgroup_validmap, const int defgroup_tot, int *r_defgroup_subset_map) +{ + int i, j = 0; + for (i = 0; i < defgroup_tot; i++) { + if (defgroup_validmap[i]) { + r_defgroup_subset_map[j++] = i; + } + } +} + diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c index 0d82c6e89a1..2bee6b76ad6 100644 --- a/source/blender/blenkernel/intern/object_dupli.c +++ b/source/blender/blenkernel/intern/object_dupli.c @@ -1240,7 +1240,7 @@ int count_duplilist(Object *ob) DupliApplyData *duplilist_apply(Object *ob, ListBase *duplilist) { DupliApplyData *apply_data = NULL; - int num_objects = BLI_countlist(duplilist); + int num_objects = BLI_listbase_count(duplilist); if (num_objects > 0) { DupliObject *dob; diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index d16575d80c8..96fff339521 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -316,7 +316,7 @@ void BKE_paint_curve_set(Brush *br, PaintCurve *pc) void BKE_palette_color_remove(Palette *palette, PaletteColor *color) { if (color) { - int numcolors = BLI_countlist(&palette->colors); + int numcolors = BLI_listbase_count(&palette->colors); if ((numcolors == palette->active_color + 1) && (numcolors != 1)) palette->active_color--; @@ -352,7 +352,7 @@ PaletteColor *BKE_palette_color_add(Palette *palette) { PaletteColor *color = MEM_callocN(sizeof(*color), "Pallete Color"); BLI_addtail(&palette->colors, color); - palette->active_color = BLI_countlist(&palette->colors) - 1; + palette->active_color = BLI_listbase_count(&palette->colors) - 1; return color; } @@ -644,11 +644,11 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob) VirtualModifierData virtualModifierData; if (mmd || ob->sculpt->bm) - return 0; + return false; /* non-locked shape keys could be handled in the same way as deformed mesh */ if ((ob->shapeflag & OB_SHAPE_LOCK) == 0 && me->key && ob->shapenr) - return 1; + return true; md = modifiers_getVirtualModifierList(ob, &virtualModifierData); @@ -658,11 +658,11 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob) if (!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue; if (ELEM(md->type, eModifierType_ShapeKey, eModifierType_Multires)) continue; - if (mti->type == eModifierTypeType_OnlyDeform) return 1; - else if ((sd->flags & SCULPT_ONLY_DEFORM) == 0) return 1; + if (mti->type == eModifierTypeType_OnlyDeform) return true; + else if ((sd->flags & SCULPT_ONLY_DEFORM) == 0) return true; } - return 0; + return false; } /** @@ -740,7 +740,7 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, BKE_free_sculptsession_deformMats(ss); - ss->orig_cos = (ss->kb) ? BKE_key_convert_to_vertcos(ob, ss->kb) : BKE_mesh_vertexCos_get(me, NULL); + ss->orig_cos = (ss->kb) ? BKE_keyblock_convert_to_vertcos(ob, ss->kb) : BKE_mesh_vertexCos_get(me, NULL); BKE_crazyspace_build_sculpt(scene, ob, &ss->deform_imats, &ss->deform_cos); BKE_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos); @@ -755,14 +755,14 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, } if (ss->kb != NULL && ss->deform_cos == NULL) { - ss->deform_cos = BKE_key_convert_to_vertcos(ob, ss->kb); + ss->deform_cos = BKE_keyblock_convert_to_vertcos(ob, ss->kb); } /* if pbvh is deformed, key block is already applied to it */ if (ss->kb) { bool pbvh_deformd = BKE_pbvh_isDeformed(ss->pbvh); if (!pbvh_deformd || ss->deform_cos == NULL) { - float (*vertCos)[3] = BKE_key_convert_to_vertcos(ob, ss->kb); + float (*vertCos)[3] = BKE_keyblock_convert_to_vertcos(ob, ss->kb); if (vertCos) { if (!pbvh_deformd) { diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 530573d6e38..d577293fccb 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -981,14 +981,14 @@ bool psys_render_simplify_params(ParticleSystem *psys, ChildParticle *cpa, float int b; if (!(psys->renderdata && (psys->part->simplify_flag & PART_SIMPLIFY_ENABLE))) - return 0; + return false; data = psys->renderdata; if (!data->do_simplify) - return 0; + return false; b = (data->index_mf_to_mpoly) ? DM_origindex_mface_mpoly(data->index_mf_to_mpoly, data->index_mp_to_orig, cpa->num) : cpa->num; if (b == ORIGINDEX_NONE) { - return 0; + return false; } elem = &data->elems[b]; @@ -1043,7 +1043,7 @@ static float interpolate_particle_value(float v1, float v2, float v3, float v4, return value; } -void psys_interpolate_particle(short type, ParticleKey keys[4], float dt, ParticleKey *result, int velocity) +void psys_interpolate_particle(short type, ParticleKey keys[4], float dt, ParticleKey *result, bool velocity) { float t[4]; @@ -1073,7 +1073,6 @@ void psys_interpolate_particle(short type, ParticleKey keys[4], float dt, Partic } - typedef struct ParticleInterpolationData { HairKey *hkey[2]; @@ -3514,8 +3513,8 @@ ModifierData *object_add_particle_system(Scene *scene, Object *ob, const char *n psys->part = psys_new_settings(DATA_("ParticleSettings"), NULL); - if (BLI_countlist(&ob->particlesystem) > 1) - BLI_snprintf(psys->name, sizeof(psys->name), DATA_("ParticleSystem %i"), BLI_countlist(&ob->particlesystem)); + if (BLI_listbase_count_ex(&ob->particlesystem, 2) > 1) + BLI_snprintf(psys->name, sizeof(psys->name), DATA_("ParticleSystem %i"), BLI_listbase_count(&ob->particlesystem)); else BLI_strncpy(psys->name, DATA_("ParticleSystem"), sizeof(psys->name)); @@ -3524,7 +3523,7 @@ ModifierData *object_add_particle_system(Scene *scene, Object *ob, const char *n if (name) BLI_strncpy_utf8(md->name, name, sizeof(md->name)); else - BLI_snprintf(md->name, sizeof(md->name), DATA_("ParticleSystem %i"), BLI_countlist(&ob->particlesystem)); + BLI_snprintf(md->name, sizeof(md->name), DATA_("ParticleSystem %i"), BLI_listbase_count(&ob->particlesystem)); modifier_unique_name(&ob->modifiers, md); psmd = (ParticleSystemModifierData *) md; @@ -4564,8 +4563,7 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa psys_particle_on_emitter(psmd, PART_FROM_FACE, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, loc, nor, 0, 0, 0, 0); if (psys->part->rotmode == PART_ROT_VEL) { - copy_m3_m4(nmat, ob->imat); - transpose_m3(nmat); + transpose_m3_m4(nmat, ob->imat); mul_m3_v3(nmat, nor); normalize_v3(nor); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 155299b69c3..7ad99c14565 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2764,24 +2764,6 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa sphdata->pass++; } -/* powf is really slow for raising to integer powers. */ -MINLINE float pow2(float x) -{ - return x * x; -} -MINLINE float pow3(float x) -{ - return pow2(x) * x; -} -MINLINE float pow4(float x) -{ - return pow2(pow2(x)); -} -MINLINE float pow7(float x) -{ - return pow2(pow3(x)) * x; -} - static void sphclassical_density_accum_cb(void *userdata, int index, float UNUSED(squared_dist)) { SPHRangeData *pfr = (SPHRangeData *)userdata; @@ -2803,7 +2785,7 @@ static void sphclassical_density_accum_cb(void *userdata, int index, float UNUSE /* Smoothing factor. Utilise the Wendland kernel. gnuplot: * q1(x) = (2.0 - x)**4 * ( 1.0 + 2.0 * x) * plot [0:2] q1(x) */ - q = qfac / pow3(pfr->h) * pow4(2.0f - rij_h) * ( 1.0f + 2.0f * rij_h); + q = qfac / pow3f(pfr->h) * pow4f(2.0f - rij_h) * ( 1.0f + 2.0f * rij_h); q *= pfr->npsys->part->mass; if (pfr->use_size) @@ -2857,7 +2839,7 @@ static void sphclassical_force_cb(void *sphdata_v, ParticleKey *state, float *fo float rest_density = fluid->rest_density * (fluid->flag & SPH_FAC_DENSITY ? 4.77f : 1.0f); // Use speed of sound squared - float stiffness = pow2(fluid->stiffness_k); + float stiffness = pow2f(fluid->stiffness_k); ParticleData *npa; float vec[3]; @@ -2878,10 +2860,10 @@ static void sphclassical_force_cb(void *sphdata_v, ParticleKey *state, float *fo pfr.pa = pa; sph_evaluate_func(NULL, psys, state->co, &pfr, interaction_radius, sphclassical_neighbour_accum_cb); - pressure = stiffness * (pow7(pa->sphdensity / rest_density) - 1.0f); + pressure = stiffness * (pow7f(pa->sphdensity / rest_density) - 1.0f); /* multiply by mass so that we return a force, not accel */ - qfac2 *= sphdata->mass / pow3(pfr.h); + qfac2 *= sphdata->mass / pow3f(pfr.h); pfn = pfr.neighbors; for (i = 0; i < pfr.tot_neighbors; i++, pfn++) { @@ -2902,19 +2884,19 @@ static void sphclassical_force_cb(void *sphdata_v, ParticleKey *state, float *fo if (rij_h > 2.0f) continue; - npressure = stiffness * (pow7(npa->sphdensity / rest_density) - 1.0f); + npressure = stiffness * (pow7f(npa->sphdensity / rest_density) - 1.0f); /* First derivative of smoothing factor. Utilise the Wendland kernel. * gnuplot: * q2(x) = 2.0 * (2.0 - x)**4 - 4.0 * (2.0 - x)**3 * (1.0 + 2.0 * x) * plot [0:2] q2(x) * Particles > 2h away are excluded above. */ - dq = qfac2 * (2.0f * pow4(2.0f - rij_h) - 4.0f * pow3(2.0f - rij_h) * (1.0f + 2.0f * rij_h) ); + dq = qfac2 * (2.0f * pow4f(2.0f - rij_h) - 4.0f * pow3f(2.0f - rij_h) * (1.0f + 2.0f * rij_h) ); if (pfn->psys->part->flag & PART_SIZEMASS) dq *= npa->size; - pressureTerm = pressure / pow2(pa->sphdensity) + npressure / pow2(npa->sphdensity); + pressureTerm = pressure / pow2f(pa->sphdensity) + npressure / pow2f(npa->sphdensity); /* Note that 'minus' is removed, because vec = vecBA, not vecAB. * This applies to the viscosity calculation below, too. */ diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index ff6fae08460..bd953890443 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -943,7 +943,7 @@ static bool update_search_cb(PBVHNode *node, void *data_v) if (node->flag & PBVH_Leaf) return (node->flag & flag) != 0; - return 1; + return true; } static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes, @@ -1474,10 +1474,10 @@ bool ray_face_intersection(const float ray_start[3], (t3 && isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t2, t3, &dist, NULL, 0.1f) && dist < *fdist)) { *fdist = dist; - return 1; + return true; } else { - return 0; + return false; } } diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index a6a7664ec61..19ed49c727a 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -50,7 +50,6 @@ #include "BLI_threads.h" #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_system.h" #include "BLF_translation.h" @@ -58,6 +57,7 @@ #include "WM_api.h" +#include "BKE_appdir.h" #include "BKE_anim.h" #include "BKE_blender.h" #include "BKE_cloth.h" @@ -1043,8 +1043,6 @@ static void ptcache_rigidbody_interpolate(int index, void *rb_v, void **data, fl { RigidBodyWorld *rbw = rb_v; Object *ob = NULL; - ParticleKey keys[4]; - float dfra; if (rbw->objects) ob = rbw->objects[index]; @@ -1053,6 +1051,11 @@ static void ptcache_rigidbody_interpolate(int index, void *rb_v, void **data, fl RigidBodyOb *rbo = ob->rigidbody_object; if (rbo->type == RBO_TYPE_ACTIVE) { + ParticleKey keys[4]; + ParticleKey result; + float dfra; + + memset(keys, 0, sizeof(keys)); copy_v3_v3(keys[1].co, rbo->pos); copy_qt_qt(keys[1].rot, rbo->orn); @@ -1062,16 +1065,17 @@ static void ptcache_rigidbody_interpolate(int index, void *rb_v, void **data, fl memcpy(keys[2].rot, data + 3, 4 * sizeof(float)); } else { - BKE_ptcache_make_particle_key(keys+2, 0, data, cfra2); + BKE_ptcache_make_particle_key(&keys[2], 0, data, cfra2); } dfra = cfra2 - cfra1; - psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, keys, 1); - interp_qt_qtqt(keys->rot, keys[1].rot, keys[2].rot, (cfra - cfra1) / dfra); + /* note: keys[0] and keys[3] unused for type < 1 (crappy) */ + psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, &result, true); + interp_qt_qtqt(result.rot, keys[1].rot, keys[2].rot, (cfra - cfra1) / dfra); - copy_v3_v3(rbo->pos, keys->co); - copy_qt_qt(rbo->orn, keys->rot); + copy_v3_v3(rbo->pos, result.co); + copy_qt_qt(rbo->orn, result.rot); } } } @@ -1465,7 +1469,7 @@ static int ptcache_path(PTCacheID *pid, char *filename) /* use the temp path. this is weak but better then not using point cache at all */ /* temporary directory is assumed to exist and ALWAYS has a trailing slash */ - BLI_snprintf(filename, MAX_PTCACHE_PATH, "%s"PTCACHE_PATH, BLI_temp_dir_session()); + BLI_snprintf(filename, MAX_PTCACHE_PATH, "%s"PTCACHE_PATH, BKE_tempdir_session()); return BLI_add_slash(filename); /* new strlen() */ } @@ -2567,12 +2571,19 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra) if (pid->cache->flag & PTCACHE_DISK_CACHE) { ptcache_path(pid, path); - len = ptcache_filename(pid, filename, cfra, 0, 0); /* no path */ - dir = opendir(path); if (dir==NULL) return; - + + len = ptcache_filename(pid, filename, cfra, 0, 0); /* no path */ + /* append underscore terminator to ensure we don't match similar names + * from objects whose names start with the same prefix + */ + if (len < sizeof(filename) - 2) { + BLI_strncpy(filename + len, "_", sizeof(filename) - 2 - len); + len += 1; + } + BLI_snprintf(ext, sizeof(ext), "_%02u"PTCACHE_EXT, pid->stack_index); while ((de = readdir(dir)) != NULL) { diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index 3d61b0bdefb..3bf5c4cc47e 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -62,8 +62,6 @@ #include "BKE_pointcache.h" #include "BKE_rigidbody.h" -#include "RNA_access.h" - #ifdef WITH_BULLET /* ************************************** */ @@ -401,7 +399,7 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild) height = size[2]; } else if (rbo->shape == RB_SHAPE_SPHERE) { - /* take radius to the the largest dimension to try and encompass everything */ + /* take radius to the largest dimension to try and encompass everything */ radius = MAX3(size[0], size[1], size[2]); } @@ -483,7 +481,7 @@ void BKE_rigidbody_calc_volume(Object *ob, float *r_vol) height = size[2]; } else if (rbo->shape == RB_SHAPE_SPHERE) { - /* take radius to the the largest dimension to try and encompass everything */ + /* take radius to the largest dimension to try and encompass everything */ radius = max_fff(size[0], size[1], size[2]) * 0.5f; } @@ -1158,7 +1156,7 @@ static void rigidbody_update_ob_array(RigidBodyWorld *rbw) GroupObject *go; int i, n; - n = BLI_countlist(&rbw->group->gobject); + n = BLI_listbase_count(&rbw->group->gobject); if (rbw->numbodies != n) { rbw->numbodies = n; @@ -1499,7 +1497,7 @@ void BKE_rigidbody_rebuild_world(Scene *scene, float ctime) cache = rbw->pointcache; /* flag cache as outdated if we don't have a world or number of objects in the simulation has changed */ - if (rbw->physics_world == NULL || rbw->numbodies != BLI_countlist(&rbw->group->gobject)) { + if (rbw->physics_world == NULL || rbw->numbodies != BLI_listbase_count(&rbw->group->gobject)) { cache->flag |= PTCACHE_OUTDATED; } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 5bfd6e8a120..13e9b7fb0c4 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -63,12 +63,14 @@ #include "BKE_anim.h" #include "BKE_animsys.h" #include "BKE_action.h" +#include "BKE_armature.h" #include "BKE_colortools.h" #include "BKE_depsgraph.h" #include "BKE_editmesh.h" #include "BKE_fcurve.h" #include "BKE_freestyle.h" #include "BKE_global.h" +#include "BKE_gpencil.h" #include "BKE_group.h" #include "BKE_idprop.h" #include "BKE_image.h" @@ -98,6 +100,10 @@ # include <sys/time.h> #endif +const char *RE_engine_id_BLENDER_RENDER = "BLENDER_RENDER"; +const char *RE_engine_id_BLENDER_GAME = "BLENDER_GAME"; +const char *RE_engine_id_CYCLES = "CYCLES"; + void free_avicodecdata(AviCodecData *acd) { if (acd) { @@ -303,6 +309,19 @@ Scene *BKE_scene_copy(Scene *sce, int type) BKE_sequence_base_dupli_recursive(sce, scen, &scen->ed->seqbase, &sce->ed->seqbase, SEQ_DUPE_ALL); } } + + /* grease pencil */ + if (scen->gpd) { + if (type == SCE_COPY_FULL) { + scen->gpd = gpencil_data_duplicate(scen->gpd, false); + } + else if (type == SCE_COPY_EMPTY) { + scen->gpd = NULL; + } + else { + id_us_plus((ID *)scen->gpd); + } + } return scen; } @@ -595,7 +614,7 @@ Scene *BKE_scene_add(Main *bmain, const char *name) sce->r.ffcodecdata.audio_bitrate = 192; sce->r.ffcodecdata.audio_channels = 2; - BLI_strncpy(sce->r.engine, "BLENDER_RENDER", sizeof(sce->r.engine)); + BLI_strncpy(sce->r.engine, RE_engine_id_BLENDER_RENDER, sizeof(sce->r.engine)); sce->audio.distance_model = 2.0f; sce->audio.doppler_factor = 1.0f; @@ -1092,27 +1111,24 @@ void BKE_scene_base_select(Scene *sce, Base *selbase) } /* checks for cycle, returns 1 if it's all OK */ -int BKE_scene_validate_setscene(Main *bmain, Scene *sce) +bool BKE_scene_validate_setscene(Main *bmain, Scene *sce) { - Scene *scene; + Scene *sce_iter; int a, totscene; + + if (sce->set == NULL) return true; + totscene = BLI_listbase_count(&bmain->scene); - if (sce->set == NULL) return 1; - - totscene = 0; - for (scene = bmain->scene.first; scene; scene = scene->id.next) - totscene++; - - for (a = 0, scene = sce; scene->set; scene = scene->set, a++) { + for (a = 0, sce_iter = sce; sce_iter->set; sce_iter = sce_iter->set, a++) { /* more iterations than scenes means we have a cycle */ if (a > totscene) { /* the tested scene gets zero'ed, that's typically current scene */ sce->set = NULL; - return 0; + return false; } } - return 1; + return true; } /* This function is needed to cope with fractional frames - including two Blender rendering features @@ -1242,8 +1258,35 @@ static void scene_depsgraph_hack(EvaluationContext *eval_ctx, Scene *scene, Scen } } } +} +/* That's like really a bummer, because currently animation data for armatures + * might want to use pose, and pose might be missing on the object. + * This happens when changing visible layers, which leads to situations when + * pose is missing or marked for recalc, animation will change it and then + * object update will restore the pose. + * + * This could be solved by the new dependency graph, but for until then we'll + * do an extra pass on the objects to ensure it's all fine. + */ +#define POSE_ANIMATION_WORKAROUND + +#ifdef POSE_ANIMATION_WORKAROUND +static void scene_armature_depsgraph_workaround(Main *bmain) +{ + Object *ob; + if (BLI_listbase_is_empty(&bmain->armature) || !DAG_id_type_tagged(bmain, ID_OB)) { + return; + } + for (ob = bmain->object.first; ob; ob = ob->id.next) { + if (ob->type == OB_ARMATURE && ob->adt && ob->adt->recalc & ADT_RECALC_ANIM) { + if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC)) { + BKE_pose_rebuild(ob, ob->data); + } + } + } } +#endif static void scene_rebuild_rbw_recursive(Scene *scene, float ctime) { @@ -1736,6 +1779,10 @@ void BKE_scene_update_for_newframe_ex(EvaluationContext *eval_ctx, Main *bmain, BKE_mask_evaluate_all_masks(bmain, ctime, true); +#ifdef POSE_ANIMATION_WORKAROUND + scene_armature_depsgraph_workaround(bmain); +#endif + /* All 'standard' (i.e. without any dependencies) animation is handled here, * with an 'local' to 'macro' order of evaluation. This should ensure that * settings stored nestled within a hierarchy (i.e. settings in a Texture block @@ -1805,13 +1852,13 @@ bool BKE_scene_remove_render_layer(Main *bmain, Scene *scene, SceneRenderLayer * Scene *sce; if (act == -1) { - return 0; + return false; } else if ( (scene->r.layers.first == scene->r.layers.last) && (scene->r.layers.first == srl)) { /* ensure 1 layer is kept */ - return 0; + return false; } BLI_remlink(&scene->r.layers, srl); @@ -1833,7 +1880,7 @@ bool BKE_scene_remove_render_layer(Main *bmain, Scene *scene, SceneRenderLayer * } } - return 1; + return true; } /* render simplification */ @@ -1902,9 +1949,13 @@ bool BKE_scene_use_new_shading_nodes(Scene *scene) bool BKE_scene_uses_blender_internal(struct Scene *scene) { - return strcmp("BLENDER_RENDER", scene->r.engine) == 0; + return STREQ(scene->r.engine, RE_engine_id_BLENDER_RENDER); } +bool BKE_scene_uses_blender_game(struct Scene *scene) +{ + return STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME); +} void BKE_scene_base_flag_to_objects(struct Scene *scene) { diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index c9647b05ce7..ddc0d5874f8 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -257,26 +257,15 @@ Editing *BKE_sequencer_editing_get(Scene *scene, bool alloc) return scene->ed; } -static void seq_free_clipboard_recursive(Sequence *seq_parent) -{ - Sequence *seq, *nseq; - - for (seq = seq_parent->seqbase.first; seq; seq = nseq) { - nseq = seq->next; - seq_free_clipboard_recursive(seq); - } - - BKE_sequence_clipboard_pointers_free(seq_parent); - BKE_sequence_free_ex(NULL, seq_parent, false); -} - void BKE_sequencer_free_clipboard(void) { Sequence *seq, *nseq; + BKE_sequencer_base_clipboard_pointers_free(&seqbase_clipboard); + for (seq = seqbase_clipboard.first; seq; seq = nseq) { nseq = seq->next; - seq_free_clipboard_recursive(seq); + seq_free_sequence_recurse(NULL, seq); } BLI_listbase_clear(&seqbase_clipboard); } @@ -373,6 +362,33 @@ void BKE_sequence_clipboard_pointers_restore(Sequence *seq, Main *bmain) seqclipboard_ptr_restore(bmain, (ID **)&seq->mask); seqclipboard_ptr_restore(bmain, (ID **)&seq->sound); } + +/* recursive versions of funcions above */ +void BKE_sequencer_base_clipboard_pointers_free(ListBase *seqbase) +{ + Sequence *seq; + for (seq = seqbase->first; seq; seq = seq->next) { + BKE_sequence_clipboard_pointers_free(seq); + BKE_sequencer_base_clipboard_pointers_free(&seq->seqbase); + } +} +void BKE_sequencer_base_clipboard_pointers_store(ListBase *seqbase) +{ + Sequence *seq; + for (seq = seqbase->first; seq; seq = seq->next) { + BKE_sequence_clipboard_pointers_store(seq); + BKE_sequencer_base_clipboard_pointers_store(&seq->seqbase); + } +} +void BKE_sequencer_base_clipboard_pointers_restore(ListBase *seqbase, Main *bmain) +{ + Sequence *seq; + for (seq = seqbase->first; seq; seq = seq->next) { + BKE_sequence_clipboard_pointers_restore(seq, bmain); + BKE_sequencer_base_clipboard_pointers_restore(&seq->seqbase, bmain); + } +} + /* end clipboard pointer mess */ @@ -876,7 +892,6 @@ void BKE_sequencer_sort(Scene *scene) Editing *ed = BKE_sequencer_editing_get(scene, false); Sequence *seq, *seqt; - if (ed == NULL) return; @@ -1474,20 +1489,25 @@ static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, i int quality; int rectx, recty; int ok; - ImBuf *ibuf; + ImBuf *ibuf_tmp, *ibuf; if (!seq_proxy_get_fname(seq, cfra, proxy_render_size, name)) { return; } - ibuf = seq_render_strip(context, seq, cfra); + ibuf_tmp = seq_render_strip(context, seq, cfra); - rectx = (proxy_render_size * ibuf->x) / 100; - recty = (proxy_render_size * ibuf->y) / 100; + rectx = (proxy_render_size * ibuf_tmp->x) / 100; + recty = (proxy_render_size * ibuf_tmp->y) / 100; - if (ibuf->x != rectx || ibuf->y != recty) { + if (ibuf_tmp->x != rectx || ibuf_tmp->y != recty) { + ibuf = IMB_dupImBuf(ibuf_tmp); + IMB_freeImBuf(ibuf_tmp); IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty); } + else { + ibuf = ibuf_tmp; + } /* depth = 32 is intentionally left in, otherwise ALPHA channels * won't work... */ @@ -2509,6 +2529,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq int do_seq; // bool have_seq = false; /* UNUSED */ bool have_comp = false; + bool use_gpencil = true; Scene *scene; int is_thread_main = BLI_thread_is_main(); @@ -2533,6 +2554,10 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq BKE_scene_camera_switch_update(scene); camera = scene->camera; } + + if (seq->flag & SEQ_SCENE_NO_GPENCIL) { + use_gpencil = false; + } if (have_comp == false && camera == NULL) { scene->r.cfra = oldcfra; @@ -2566,7 +2591,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq ibuf = sequencer_view3d_cb(scene, camera, width, height, IB_rect, context->scene->r.seq_prev_type, (context->scene->r.seq_flag & R_SEQ_SOLID_TEX) != 0, - true, scene->r.alphamode, err_out); + use_gpencil, true, scene->r.alphamode, err_out); if (ibuf == NULL) { fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out); } @@ -3080,7 +3105,7 @@ ImBuf *BKE_sequencer_give_ibuf(const SeqRenderData *context, float cfra, int cha if (ed == NULL) return NULL; if ((chanshown < 0) && !BLI_listbase_is_empty(&ed->metastack)) { - int count = BLI_countlist(&ed->metastack); + int count = BLI_listbase_count(&ed->metastack); count = max_ii(count + chanshown, 0); seqbasep = ((MetaStack *)BLI_findlink(&ed->metastack, count))->oldbasep; } @@ -3395,7 +3420,7 @@ static bool update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *cha /* recurs downwards to see if this seq depends on the changed seq */ if (seq == NULL) - return 0; + return false; if (seq == changed_seq) free_imbuf = true; @@ -3513,28 +3538,16 @@ bool BKE_sequence_single_check(Sequence *seq) } /* check if the selected seq's reference unselected seq's */ -bool BKE_sequence_base_isolated_sel_check(ListBase *seqbase, bool one_only) +bool BKE_sequence_base_isolated_sel_check(ListBase *seqbase) { Sequence *seq; - /* is there a valid selection select */ + /* is there more than 1 select */ bool ok = false; - /* is there one selected already? */ - bool first = false; for (seq = seqbase->first; seq; seq = seq->next) { if (seq->flag & SELECT) { - if (one_only) { - ok = true; - break; - } - else { - if (first) { - ok = true; - break; - } - else - first = true; - } + ok = true; + break; } } @@ -4616,11 +4629,15 @@ Sequence *BKE_sequence_dupli_recursive(Scene *scene, Scene *scene_to, Sequence * return seqn; } -void BKE_sequence_base_dupli_recursive(Scene *scene, Scene *scene_to, ListBase *nseqbase, ListBase *seqbase, int dupe_flag) +void BKE_sequence_base_dupli_recursive( + Scene *scene, Scene *scene_to, ListBase *nseqbase, ListBase *seqbase, + int dupe_flag) { Sequence *seq; Sequence *seqn = NULL; Sequence *last_seq = BKE_sequencer_active_get(scene); + /* always include meta's strips */ + int dupe_flag_recursive = dupe_flag | SEQ_DUPE_ALL; for (seq = seqbase->first; seq; seq = seq->next) { seq->tmp = NULL; @@ -4633,8 +4650,11 @@ void BKE_sequence_base_dupli_recursive(Scene *scene, Scene *scene_to, ListBase * } BLI_addtail(nseqbase, seqn); - if (seq->type == SEQ_TYPE_META) - BKE_sequence_base_dupli_recursive(scene, scene_to, &seqn->seqbase, &seq->seqbase, dupe_flag); + if (seq->type == SEQ_TYPE_META) { + BKE_sequence_base_dupli_recursive( + scene, scene_to, &seqn->seqbase, &seq->seqbase, + dupe_flag_recursive); + } if (dupe_flag & SEQ_DUPE_CONTEXT) { if (seq == last_seq) { @@ -4664,3 +4684,70 @@ bool BKE_sequence_is_valid_check(Sequence *seq) return true; } +int BKE_sequencer_find_next_prev_edit( + Scene *scene, int cfra, const short side, + const bool do_skip_mute, const bool do_center, const bool do_unselected) +{ + Editing *ed = BKE_sequencer_editing_get(scene, false); + Sequence *seq; + + int dist, best_dist, best_frame = cfra; + int seq_frames[2], seq_frames_tot; + + /* in case where both is passed, frame just finds the nearest end while frame_left the nearest start */ + + best_dist = MAXFRAME * 2; + + if (ed == NULL) return cfra; + + for (seq = ed->seqbasep->first; seq; seq = seq->next) { + int i; + + if (do_skip_mute && (seq->flag & SEQ_MUTE)) { + continue; + } + + if (do_unselected && (seq->flag & SELECT)) + continue; + + if (do_center) { + seq_frames[0] = (seq->startdisp + seq->enddisp) / 2; + seq_frames_tot = 1; + } + else { + seq_frames[0] = seq->startdisp; + seq_frames[1] = seq->enddisp; + + seq_frames_tot = 2; + } + + for (i = 0; i < seq_frames_tot; i++) { + const int seq_frame = seq_frames[i]; + + dist = MAXFRAME * 2; + + switch (side) { + case SEQ_SIDE_LEFT: + if (seq_frame < cfra) { + dist = cfra - seq_frame; + } + break; + case SEQ_SIDE_RIGHT: + if (seq_frame > cfra) { + dist = seq_frame - cfra; + } + break; + case SEQ_SIDE_BOTH: + dist = abs(seq_frame - cfra); + break; + } + + if (dist < best_dist) { + best_frame = seq_frame; + best_dist = dist; + } + } + } + + return best_frame; +} diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index d2a4d15a2c6..d91818615f3 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -52,7 +52,6 @@ #include "BKE_deform.h" #include "BKE_mesh.h" /* for OMP limits. */ #include "BKE_subsurf.h" -#include "BKE_editmesh.h" #include "BLI_strict_flags.h" diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 90ac712e55a..4c46875bd48 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -60,6 +60,7 @@ #include "DNA_scene_types.h" #include "DNA_smoke_types.h" +#include "BKE_appdir.h" #include "BKE_animsys.h" #include "BKE_armature.h" #include "BKE_bvhutils.h" @@ -205,7 +206,7 @@ void smoke_reallocate_highres_fluid(SmokeDomainSettings *sds, float dx, int res[ /* smoke_turbulence_init uses non-threadsafe functions from fftw3 lib (like fftw_plan & co). */ BLI_lock_thread(LOCK_FFTW); - sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, BLI_temp_dir_session(), use_fire, use_colors); + sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, BKE_tempdir_session(), use_fire, use_colors); BLI_unlock_thread(LOCK_FFTW); @@ -953,7 +954,7 @@ static bool subframe_updateObject(Scene *scene, Object *ob, int update_mesh, int /* if other is dynamic paint canvas, don't update */ if (smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN)) - return 1; + return true; /* if object has parents, update them too */ if (parent_recursion) { @@ -965,7 +966,7 @@ static bool subframe_updateObject(Scene *scene, Object *ob, int update_mesh, int /* skip subframe if object is parented * to vertex of a dynamic paint canvas */ if (is_domain && (ob->partype == PARVERT1 || ob->partype == PARVERT3)) - return 0; + return false; /* also update constraint targets */ for (con = ob->constraints.first; con; con = con->next) { @@ -1011,7 +1012,7 @@ static bool subframe_updateObject(Scene *scene, Object *ob, int update_mesh, int BKE_pose_where_is(scene, ob); } - return 0; + return false; } /********************************************************** @@ -1424,7 +1425,7 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke static void sample_derivedmesh( SmokeFlowSettings *sfs, MVert *mvert, MTFace *tface, MFace *mface, - float *influence_map, float *velocity_map, int index, int base_res[3], float flow_center[3], + float *influence_map, float *velocity_map, int index, const int base_res[3], float flow_center[3], BVHTreeFromMesh *treeData, const float ray_start[3], const float *vert_vel, bool has_velocity, int defgrp_index, MDeformVert *dvert, float x, float y, float z) { @@ -2020,7 +2021,7 @@ BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value if (fuel && fuel[index] > FLT_EPSILON) { /* instead of using 1.0 for all new fuel add slight falloff * to reduce flow blockiness */ - float value = 1.0f - powf(1.0f - emission_value, 2.0f); + float value = 1.0f - pow2f(1.0f - emission_value); if (value > react[index]) { float f = fuel_flow / fuel[index]; diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 13575560669..941344cf21e 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -3349,7 +3349,7 @@ static void mesh_to_softbody(Scene *scene, Object *ob) build_bps_springlist(ob); /* scan for springs attached to bodypoints ONCE */ /* insert *other second order* springs if desired */ if (sb->secondspring > 0.0000001f) { - add_2nd_order_springs(ob, sb->secondspring); /* exploits the the first run of build_bps_springlist(ob);*/ + add_2nd_order_springs(ob, sb->secondspring); /* exploits the first run of build_bps_springlist(ob);*/ build_bps_springlist(ob); /* yes we need to do it again*/ } springs_from_mesh(ob); /* write the 'rest'-length of the springs */ @@ -3561,7 +3561,7 @@ static void curve_surf_to_softbody(Scene *scene, Object *ob) if (ob->softflag & OB_SB_EDGES) { if (ob->type==OB_CURVE) { - totspring= totvert - BLI_countlist(&cu->nurb); + totspring = totvert - BLI_listbase_count(&cu->nurb); } } diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index da6ead06d98..3c7b01f9052 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -36,6 +36,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" +#include "BLI_threads.h" #include "DNA_anim_types.h" #include "DNA_object_types.h" @@ -116,6 +117,12 @@ void BKE_sound_free(bSound *sound) } sound_free_waveform(sound); + + if (sound->mutex) { + BLI_mutex_free(sound->mutex); + sound->mutex = NULL; + } + #endif /* WITH_AUDASPACE */ } @@ -296,12 +303,6 @@ void sound_cache(bSound *sound) sound->playback_handle = sound->handle; } -void sound_cache_notifying(struct Main *main, bSound *sound) -{ - sound_cache(sound); - sound_update_sequencer(main, sound); -} - void sound_delete_cache(bSound *sound) { sound->flags &= ~SOUND_FLAGS_CACHING; @@ -680,22 +681,40 @@ void sound_free_waveform(bSound *sound) sound->waveform = NULL; } -void sound_read_waveform(bSound *sound) +void sound_read_waveform(bSound *sound, bool locked, short *stop) { AUD_SoundInfo info; - + SoundWaveform *waveform = NULL; + info = AUD_getInfo(sound->playback_handle); - + if (info.length > 0) { - SoundWaveform *waveform = MEM_mallocN(sizeof(SoundWaveform), "SoundWaveform"); int length = info.length * SOUND_WAVE_SAMPLES_PER_SECOND; - + + waveform = MEM_mallocN(sizeof(SoundWaveform), "SoundWaveform"); waveform->data = MEM_mallocN(length * sizeof(float) * 3, "SoundWaveform.samples"); - waveform->length = AUD_readSound(sound->playback_handle, waveform->data, length, SOUND_WAVE_SAMPLES_PER_SECOND); - + waveform->length = AUD_readSound(sound->playback_handle, waveform->data, length, SOUND_WAVE_SAMPLES_PER_SECOND, stop); + + if (*stop) { + MEM_freeN(waveform->data); + MEM_freeN(waveform); + if (locked) + BLI_mutex_lock(sound->mutex); + sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING; + if (locked) + BLI_mutex_unlock(sound->mutex); + return; + } + sound_free_waveform(sound); - sound->waveform = waveform; } + + if (locked) + BLI_mutex_lock(sound->mutex); + sound->waveform = waveform; + sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING; + if (locked) + BLI_mutex_unlock(sound->mutex); } void sound_update_scene(Main *bmain, struct Scene *scene) @@ -830,7 +849,7 @@ void sound_stop_scene(struct Scene *UNUSED(scene)) {} void sound_seek_scene(struct Main *UNUSED(bmain), struct Scene *UNUSED(scene)) {} float sound_sync_scene(struct Scene *UNUSED(scene)) { return NAN_FLT; } int sound_scene_playing(struct Scene *UNUSED(scene)) { return -1; } -void sound_read_waveform(struct bSound *UNUSED(sound)) {} +void sound_read_waveform(struct bSound *sound, bool locked, short *stop) { UNUSED_VARS(sound, locked, stop); } void sound_init_main(struct Main *UNUSED(bmain)) {} void sound_set_cfra(int UNUSED(cfra)) {} void sound_update_sequencer(struct Main *UNUSED(main), struct bSound *UNUSED(sound)) {} diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 0bd9517dcfd..c777fcd5e7b 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -41,7 +41,6 @@ #include "MEM_guardedalloc.h" -#include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" @@ -66,8 +65,6 @@ #include "BKE_scene.h" #include "BKE_subsurf.h" -#include "PIL_time.h" - #ifndef USE_DYNSIZE # include "BLI_array.h" #endif @@ -75,7 +72,6 @@ #include "GPU_draw.h" #include "GPU_extensions.h" #include "GPU_glew.h" -#include "GPU_material.h" #include "CCGSubSurf.h" @@ -411,7 +407,7 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, CCGFace **faceMap; MTFace *tf; MLoopUV *mluv; - CCGFaceIterator *fi; + CCGFaceIterator fi; int index, gridSize, gridFaces, /*edgeSize,*/ totface, x, y, S; MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, n); /* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away with @@ -438,11 +434,10 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, /* make a map from original faces to CCGFaces */ faceMap = MEM_mallocN(totface * sizeof(*faceMap), "facemapuv"); - for (fi = ccgSubSurf_getFaceIterator(uvss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { - CCGFace *f = ccgFaceIterator_getCurrent(fi); + for (ccgSubSurf_initFaceIterator(uvss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(&fi); faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f))] = f; } - ccgFaceIterator_free(fi); /* load coordinates from uvss into tface */ tf = tface; @@ -699,9 +694,9 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3]) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; - CCGVertIterator *vi; - CCGEdgeIterator *ei; - CCGFaceIterator *fi; + CCGVertIterator vi; + CCGEdgeIterator ei; + CCGFaceIterator fi; CCGKey key; int i, edgeSize = ccgSubSurf_getEdgeSize(ss); int gridSize = ccgSubSurf_getGridSize(ss); @@ -711,25 +706,23 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3]) if (!ccgSubSurf_getNumVerts(ss)) r_min[0] = r_min[1] = r_min[2] = r_max[0] = r_max[1] = r_max[2] = 0.0; - for (vi = ccgSubSurf_getVertIterator(ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { - CCGVert *v = ccgVertIterator_getCurrent(vi); + for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) { + CCGVert *v = ccgVertIterator_getCurrent(&vi); float *co = ccgSubSurf_getVertData(ss, v); minmax_v3_v3v3(co, r_min, r_max); } - ccgVertIterator_free(vi); - for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { - CCGEdge *e = ccgEdgeIterator_getCurrent(ei); + for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) { + CCGEdge *e = ccgEdgeIterator_getCurrent(&ei); CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); for (i = 0; i < edgeSize; i++) minmax_v3_v3v3(CCG_elem_offset_co(&key, edgeData, i), r_min, r_max); } - ccgEdgeIterator_free(ei); - for (fi = ccgSubSurf_getFaceIterator(ss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { - CCGFace *f = ccgFaceIterator_getCurrent(fi); + for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(&fi); int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); for (S = 0; S < numVerts; S++) { @@ -740,7 +733,6 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3]) minmax_v3_v3v3(CCG_grid_elem_co(&key, faceGridData, x, y), r_min, r_max); } } - ccgFaceIterator_free(fi); } static int ccgDM_getNumVerts(DerivedMesh *dm) @@ -1433,9 +1425,9 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) int edgeSize = ccgSubSurf_getEdgeSize(ss); int gridSize = ccgSubSurf_getGridSize(ss); int i; - CCGVertIterator *vi; - CCGEdgeIterator *ei; - CCGFaceIterator *fi; + CCGVertIterator vi; + CCGEdgeIterator ei; + CCGFaceIterator fi; CCGFace **faceMap2; CCGEdge **edgeMap2; CCGVert **vertMap2; @@ -1443,30 +1435,27 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) totvert = ccgSubSurf_getNumVerts(ss); vertMap2 = MEM_mallocN(totvert * sizeof(*vertMap2), "vertmap"); - for (vi = ccgSubSurf_getVertIterator(ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { - CCGVert *v = ccgVertIterator_getCurrent(vi); + for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) { + CCGVert *v = ccgVertIterator_getCurrent(&vi); vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))] = v; } - ccgVertIterator_free(vi); totedge = ccgSubSurf_getNumEdges(ss); edgeMap2 = MEM_mallocN(totedge * sizeof(*edgeMap2), "edgemap"); - for (ei = ccgSubSurf_getEdgeIterator(ss), i = 0; !ccgEdgeIterator_isStopped(ei); i++, ccgEdgeIterator_next(ei)) { - CCGEdge *e = ccgEdgeIterator_getCurrent(ei); + for (ccgSubSurf_initEdgeIterator(ss, &ei), i = 0; !ccgEdgeIterator_isStopped(&ei); i++, ccgEdgeIterator_next(&ei)) { + CCGEdge *e = ccgEdgeIterator_getCurrent(&ei); edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))] = e; } - ccgEdgeIterator_free(ei); totface = ccgSubSurf_getNumFaces(ss); faceMap2 = MEM_mallocN(totface * sizeof(*faceMap2), "facemap"); - for (fi = ccgSubSurf_getFaceIterator(ss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { - CCGFace *f = ccgFaceIterator_getCurrent(fi); + for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(&fi); faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f))] = f; } - ccgFaceIterator_free(fi); i = 0; for (index = 0; index < totface; index++) { @@ -1516,12 +1505,12 @@ static void ccgDM_foreachMappedVert( DMForeachFlag flag) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGVertIterator *vi; + CCGVertIterator vi; CCGKey key; CCG_key_top_level(&key, ccgdm->ss); - for (vi = ccgSubSurf_getVertIterator(ccgdm->ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { - CCGVert *v = ccgVertIterator_getCurrent(vi); + for (ccgSubSurf_initVertIterator(ccgdm->ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) { + CCGVert *v = ccgVertIterator_getCurrent(&vi); const int index = ccgDM_getVertMapIndex(ccgdm->ss, v); if (index != -1) { @@ -1530,8 +1519,6 @@ static void ccgDM_foreachMappedVert( func(userData, index, CCG_elem_co(&key, vd), no, NULL); } } - - ccgVertIterator_free(vi); } static void ccgDM_foreachMappedEdge( @@ -1541,14 +1528,14 @@ static void ccgDM_foreachMappedEdge( { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; - CCGEdgeIterator *ei; + CCGEdgeIterator ei; CCGKey key; int i, edgeSize = ccgSubSurf_getEdgeSize(ss); CCG_key_top_level(&key, ss); - for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { - CCGEdge *e = ccgEdgeIterator_getCurrent(ei); + for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) { + CCGEdge *e = ccgEdgeIterator_getCurrent(&ei); const int index = ccgDM_getEdgeMapIndex(ss, e); if (index != -1) { @@ -1558,8 +1545,6 @@ static void ccgDM_foreachMappedEdge( } } } - - ccgEdgeIterator_free(ei); } static void ccgDM_foreachMappedLoop( @@ -1597,28 +1582,26 @@ static void ccgDM_drawVerts(DerivedMesh *dm) CCGSubSurf *ss = ccgdm->ss; int edgeSize = ccgSubSurf_getEdgeSize(ss); int gridSize = ccgSubSurf_getGridSize(ss); - CCGVertIterator *vi; - CCGEdgeIterator *ei; - CCGFaceIterator *fi; + CCGVertIterator vi; + CCGEdgeIterator ei; + CCGFaceIterator fi; glBegin(GL_POINTS); - for (vi = ccgSubSurf_getVertIterator(ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { - CCGVert *v = ccgVertIterator_getCurrent(vi); + for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) { + CCGVert *v = ccgVertIterator_getCurrent(&vi); glVertex3fv(ccgSubSurf_getVertData(ss, v)); } - ccgVertIterator_free(vi); - for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { - CCGEdge *e = ccgEdgeIterator_getCurrent(ei); + for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) { + CCGEdge *e = ccgEdgeIterator_getCurrent(&ei); int x; for (x = 1; x < edgeSize - 1; x++) glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x)); } - ccgEdgeIterator_free(ei); - for (fi = ccgSubSurf_getFaceIterator(ss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { - CCGFace *f = ccgFaceIterator_getCurrent(fi); + for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(&fi); int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); glVertex3fv(ccgSubSurf_getFaceCenterData(f)); @@ -1630,7 +1613,6 @@ static void ccgDM_drawVerts(DerivedMesh *dm) for (x = 1; x < gridSize - 1; x++) glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y)); } - ccgFaceIterator_free(fi); glEnd(); } @@ -2289,7 +2271,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, static void ccgDM_drawFacesTex_common(DerivedMesh *dm, DMSetDrawOptionsTex drawParams, - DMSetDrawOptions drawParamsMapped, + DMSetDrawOptionsMappedTex drawParamsMapped, DMCompareDrawOptions compareDrawOptions, void *userData, DMDrawFlag flag) { @@ -2352,15 +2334,16 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, mat_nr_cache = mat_nr; } - tf = tf_base + gridOffset; - tf_stencil = tf_stencil_base + gridOffset; + + tf = tf_base ? tf_base + gridOffset : NULL; + tf_stencil = tf_stencil_base ? tf_stencil_base + gridOffset : NULL; gridOffset += gridFaces * gridFaces * numVerts; } if (drawParams) draw_option = drawParams(tf, (mcol != NULL), mat_nr); else if (index != ORIGINDEX_NONE) - draw_option = (drawParamsMapped) ? drawParamsMapped(userData, index) : DM_DRAW_OPTION_NORMAL; + draw_option = (drawParamsMapped) ? drawParamsMapped(userData, index, mat_nr) : DM_DRAW_OPTION_NORMAL; else draw_option = GPU_enable_material(mat_nr, NULL) ? DM_DRAW_OPTION_NORMAL : DM_DRAW_OPTION_SKIP; @@ -2529,7 +2512,7 @@ static void ccgDM_drawFacesTex(DerivedMesh *dm, } static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, - DMSetDrawOptions setDrawOptions, + DMSetDrawOptionsMappedTex setDrawOptions, DMCompareDrawOptions compareDrawOptions, void *userData, DMDrawFlag flag) { @@ -2585,6 +2568,7 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm, DMFlagMat *faceFlags = ccgdm->faceFlags; int useColors = flag & DM_DRAW_USE_COLORS; int gridFaces = gridSize - 1, totface; + int prev_mat_nr = -1; CCG_key_top_level(&key, ss); @@ -2625,9 +2609,16 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm, { DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; - if (index == ORIGINDEX_NONE) - draw_option = setMaterial(faceFlags ? faceFlags[origIndex].mat_nr + 1 : 1, NULL); /* XXX, no faceFlags no material */ - else if (setDrawOptions) + if (setMaterial) { + int mat_nr = faceFlags ? faceFlags[origIndex].mat_nr + 1 : 1; + + if (mat_nr != prev_mat_nr) { + setMaterial(mat_nr, NULL); /* XXX, no faceFlags no material */ + prev_mat_nr = mat_nr; + } + } + + if (setDrawOptions && (index != ORIGINDEX_NONE)) draw_option = setDrawOptions(userData, index); if (draw_option != DM_DRAW_OPTION_SKIP) { @@ -2744,15 +2735,15 @@ static void ccgDM_drawMappedEdges(DerivedMesh *dm, { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; - CCGEdgeIterator *ei; + CCGEdgeIterator ei; CCGKey key; int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss); CCG_key_top_level(&key, ss); ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); - for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { - CCGEdge *e = ccgEdgeIterator_getCurrent(ei); + for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) { + CCGEdge *e = ccgEdgeIterator_getCurrent(&ei); CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); int index = ccgDM_getEdgeMapIndex(ss, e); @@ -2770,8 +2761,6 @@ static void ccgDM_drawMappedEdges(DerivedMesh *dm, } glEnd(); } - - ccgEdgeIterator_free(ei); } static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, @@ -2782,14 +2771,14 @@ static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; CCGKey key; - CCGEdgeIterator *ei; + CCGEdgeIterator ei; int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss); CCG_key_top_level(&key, ss); ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); - for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { - CCGEdge *e = ccgEdgeIterator_getCurrent(ei); + for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) { + CCGEdge *e = ccgEdgeIterator_getCurrent(&ei); CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); int index = ccgDM_getEdgeMapIndex(ss, e); @@ -2808,8 +2797,6 @@ static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, } glEnd(); } - - ccgEdgeIterator_free(ei); } static void ccgDM_foreachMappedFaceCenter( @@ -2821,12 +2808,12 @@ static void ccgDM_foreachMappedFaceCenter( CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; CCGKey key; - CCGFaceIterator *fi; + CCGFaceIterator fi; CCG_key_top_level(&key, ss); - for (fi = ccgSubSurf_getFaceIterator(ss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { - CCGFace *f = ccgFaceIterator_getCurrent(fi); + for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(&fi); const int index = ccgDM_getFaceMapIndex(ss, f); if (index != -1) { @@ -2836,8 +2823,6 @@ static void ccgDM_foreachMappedFaceCenter( func(userData, index, CCG_elem_co(&key, vd), no); } } - - ccgFaceIterator_free(fi); } static void ccgDM_release(DerivedMesh *dm) @@ -3433,9 +3418,9 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, DerivedMesh *dm) { CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm"); - CCGVertIterator *vi; - CCGEdgeIterator *ei; - CCGFaceIterator *fi; + CCGVertIterator vi; + CCGEdgeIterator ei; + CCGFaceIterator fi; int index, totvert, totedge, totface; int i; int vertNum, edgeNum, faceNum; @@ -3568,30 +3553,27 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, totvert = ccgSubSurf_getNumVerts(ss); ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap"); - for (vi = ccgSubSurf_getVertIterator(ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { - CCGVert *v = ccgVertIterator_getCurrent(vi); + for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) { + CCGVert *v = ccgVertIterator_getCurrent(&vi); ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))].vert = v; } - ccgVertIterator_free(vi); totedge = ccgSubSurf_getNumEdges(ss); ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap"); - for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { - CCGEdge *e = ccgEdgeIterator_getCurrent(ei); + for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) { + CCGEdge *e = ccgEdgeIterator_getCurrent(&ei); ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e; } - ccgEdgeIterator_free(ei); totface = ccgSubSurf_getNumFaces(ss); ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap"); - for (fi = ccgSubSurf_getFaceIterator(ss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { - CCGFace *f = ccgFaceIterator_getCurrent(fi); + for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(&fi); ccgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f))].face = f; } - ccgFaceIterator_free(fi); ccgdm->reverseFaceMap = MEM_callocN(sizeof(int) * ccgSubSurf_getNumFinalFaces(ss), "reverseFaceMap"); @@ -3996,13 +3978,13 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3]) */ CCGSubSurf *ss = _getSubSurf(NULL, 1, 3, CCG_USE_ARENA); float edge_sum[3], face_sum[3]; - CCGVertIterator *vi; + CCGVertIterator vi; DerivedMesh *dm = CDDM_from_mesh(me); ss_sync_from_derivedmesh(ss, dm, NULL, 0); - for (vi = ccgSubSurf_getVertIterator(ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { - CCGVert *v = ccgVertIterator_getCurrent(vi); + for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) { + CCGVert *v = ccgVertIterator_getCurrent(&vi); int idx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); int N = ccgSubSurf_getVertNumEdges(v); int numFaces = ccgSubSurf_getVertNumFaces(v); @@ -4031,7 +4013,6 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3]) r_positions[idx][1] = (co[1] * N * N + edge_sum[1] * 4 + face_sum[1]) / (N * (N + 5)); r_positions[idx][2] = (co[2] * N * N + edge_sum[2] * 4 + face_sum[2]) / (N * (N + 5)); } - ccgVertIterator_free(vi); ccgSubSurf_free(ss); diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 8a272cd9d81..77629715edb 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -369,8 +369,8 @@ int BKE_text_reload(Text *text) buffer = MEM_mallocN(len, "text_buffer"); - // under windows fread can return less then len bytes because - // of CR stripping + /* under windows fread can return less than len bytes because + * of CR stripping */ len = fread(buffer, 1, len, fp); fclose(fp); @@ -425,8 +425,8 @@ Text *BKE_text_load_ex(Main *bmain, const char *file, const char *relpath, const fseek(fp, 0L, SEEK_SET); buffer = MEM_mallocN(len, "text_buffer"); - // under windows fread can return less then len bytes because - // of CR stripping + /* under windows fread can return less than len bytes because + * of CR stripping */ len = fread(buffer, 1, len, fp); fclose(fp); @@ -1515,7 +1515,7 @@ static bool max_undo_test(Text *text, int x) /* XXX error("Undo limit reached, buffer cleared\n"); */ MEM_freeN(text->undo_buf); init_undo_text(text); - return 0; + return false; } else { void *tmp = text->undo_buf; @@ -1526,7 +1526,7 @@ static bool max_undo_test(Text *text, int x) } } - return 1; + return true; } #if 0 /* UNUSED */ @@ -2474,6 +2474,7 @@ void txt_delete_word(Text *text) { txt_jump_right(text, true, true); txt_delete_sel(text); + txt_make_dirty(text); } void txt_backspace_char(Text *text) @@ -2522,6 +2523,7 @@ void txt_backspace_word(Text *text) { txt_jump_left(text, true, true); txt_delete_sel(text); + txt_make_dirty(text); } /* Max spaces to replace a tab with, currently hardcoded to TXT_TABSIZE = 4. @@ -2548,13 +2550,13 @@ static bool txt_add_char_intern(Text *text, unsigned int add, bool replace_tabs) if (add == '\n') { txt_split_curline(text); - return 1; + return true; } /* insert spaces rather than tabs */ if (add == '\t' && replace_tabs) { txt_convert_tab_to_spaces(text); - return 1; + return true; } txt_delete_sel(text); @@ -2603,7 +2605,7 @@ bool txt_replace_char(Text *text, unsigned int add) size_t del_size = 0, add_size; char ch[BLI_UTF8_MAX]; - if (!text->curl) return 0; + if (!text->curl) return false; /* If text is selected or we're at the end of the line just use txt_add_char */ if (text->curc == text->curl->len || txt_has_sel(text) || add == '\n') { @@ -2642,7 +2644,7 @@ bool txt_replace_char(Text *text, unsigned int add) text->curc += add_size; txt_pop_sel(text); } - return 1; + return true; } void txt_indent(Text *text) @@ -2977,37 +2979,37 @@ bool text_check_delim(const char ch) for (a = 0; a < (sizeof(delims) - 1); a++) { if (ch == delims[a]) - return 1; + return true; } - return 0; + return false; } bool text_check_digit(const char ch) { - if (ch < '0') return 0; - if (ch <= '9') return 1; - return 0; + if (ch < '0') return false; + if (ch <= '9') return true; + return false; } bool text_check_identifier(const char ch) { - if (ch < '0') return 0; - if (ch <= '9') return 1; - if (ch < 'A') return 0; - if (ch <= 'Z' || ch == '_') return 1; - if (ch < 'a') return 0; - if (ch <= 'z') return 1; - return 0; + if (ch < '0') return false; + if (ch <= '9') return true; + if (ch < 'A') return false; + if (ch <= 'Z' || ch == '_') return true; + if (ch < 'a') return false; + if (ch <= 'z') return true; + return false; } bool text_check_identifier_nodigit(const char ch) { - if (ch <= '9') return 0; - if (ch < 'A') return 0; - if (ch <= 'Z' || ch == '_') return 1; - if (ch < 'a') return 0; - if (ch <= 'z') return 1; - return 0; + if (ch <= '9') return false; + if (ch < 'A') return false; + if (ch <= 'Z' || ch == '_') return true; + if (ch < 'a') return false; + if (ch <= 'z') return true; + return false; } #ifndef WITH_PYTHON @@ -3025,8 +3027,8 @@ int text_check_identifier_nodigit_unicode(const unsigned int ch) bool text_check_whitespace(const char ch) { if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') - return 1; - return 0; + return true; + return false; } int text_find_identifier_start(const char *str, int i) diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index f938ed08142..3c02d5c19fc 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -37,7 +37,6 @@ #include "MEM_guardedalloc.h" -#include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_kdopbvh.h" #include "BLI_utildefines.h" @@ -328,7 +327,7 @@ bool do_colorband(const ColorBand *coba, float in, float out[4]) int ipotype; int a; - if (coba == NULL || coba->tot == 0) return 0; + if (coba == NULL || coba->tot == 0) return false; cbd1 = coba->data; @@ -464,7 +463,7 @@ bool do_colorband(const ColorBand *coba, float in, float out[4]) } } } - return 1; /* OK */ + return true; /* OK */ } void colorband_table_RGBA(ColorBand *coba, float **array, int *size) @@ -1302,7 +1301,7 @@ bool has_current_material_texture(Material *ma) node = nodeGetActiveID(ma->nodetree, ID_TE); if (node) - return 1; + return true; } return (ma != NULL); @@ -1596,17 +1595,17 @@ void BKE_free_oceantex(struct OceanTex *ot) bool BKE_texture_dependsOnTime(const struct Tex *texture) { if (texture->ima && BKE_image_is_animated(texture->ima)) { - return 1; + return true; } else if (texture->adt) { /* assume anything in adt means the texture is animated */ - return 1; + return true; } else if (texture->type == TEX_NOISE) { /* noise always varies with time */ - return 1; + return true; } - return 0; + return false; } /* ------------------------------------------------------------------------- */ diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 40d9dc0d7e0..d580c184a8b 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1456,6 +1456,35 @@ MovieTrackingPlaneMarker *BKE_tracking_plane_marker_ensure(MovieTrackingPlaneTra return plane_marker; } +void BKE_tracking_plane_marker_get_subframe_corners(MovieTrackingPlaneTrack *plane_track, + float framenr, + float corners[4][2]) +{ + MovieTrackingPlaneMarker *marker = BKE_tracking_plane_marker_get(plane_track, (int)framenr); + MovieTrackingPlaneMarker *marker_last = plane_track->markers + (plane_track->markersnr - 1); + int i; + if (marker != marker_last) { + MovieTrackingPlaneMarker *marker_next = marker + 1; + if (marker_next->framenr == marker->framenr + 1) { + float fac = (framenr - (int) framenr) / (marker_next->framenr - marker->framenr); + for (i = 0; i < 4; ++i) { + interp_v2_v2v2(corners[i], marker->corners[i], + marker_next->corners[i], fac); + } + } + else { + for (i = 0; i < 4; ++i) { + copy_v2_v2(corners[i], marker->corners[i]); + } + } + } + else { + for (i = 0; i < 4; ++i) { + copy_v2_v2(corners[i], marker->corners[i]); + } + } +} + /*********************** Object *************************/ MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char *name) @@ -1475,7 +1504,7 @@ MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char BLI_addtail(&tracking->objects, object); tracking->tot_object++; - tracking->objectnr = BLI_countlist(&tracking->objects) - 1; + tracking->objectnr = BLI_listbase_count(&tracking->objects) - 1; object->scale = 1.0f; object->keyframe1 = 1; @@ -2410,30 +2439,30 @@ static void tracking_dopesheet_channels_sort(MovieTracking *tracking, int sort_m if (inverse) { if (sort_method == TRACKING_DOPE_SORT_NAME) { - BLI_sortlist(&dopesheet->channels, channels_alpha_inverse_sort); + BLI_listbase_sort(&dopesheet->channels, channels_alpha_inverse_sort); } else if (sort_method == TRACKING_DOPE_SORT_LONGEST) { - BLI_sortlist(&dopesheet->channels, channels_longest_segment_inverse_sort); + BLI_listbase_sort(&dopesheet->channels, channels_longest_segment_inverse_sort); } else if (sort_method == TRACKING_DOPE_SORT_TOTAL) { - BLI_sortlist(&dopesheet->channels, channels_total_track_inverse_sort); + BLI_listbase_sort(&dopesheet->channels, channels_total_track_inverse_sort); } else if (sort_method == TRACKING_DOPE_SORT_AVERAGE_ERROR) { - BLI_sortlist(&dopesheet->channels, channels_average_error_inverse_sort); + BLI_listbase_sort(&dopesheet->channels, channels_average_error_inverse_sort); } } else { if (sort_method == TRACKING_DOPE_SORT_NAME) { - BLI_sortlist(&dopesheet->channels, channels_alpha_sort); + BLI_listbase_sort(&dopesheet->channels, channels_alpha_sort); } else if (sort_method == TRACKING_DOPE_SORT_LONGEST) { - BLI_sortlist(&dopesheet->channels, channels_longest_segment_sort); + BLI_listbase_sort(&dopesheet->channels, channels_longest_segment_sort); } else if (sort_method == TRACKING_DOPE_SORT_TOTAL) { - BLI_sortlist(&dopesheet->channels, channels_total_track_sort); + BLI_listbase_sort(&dopesheet->channels, channels_total_track_sort); } else if (sort_method == TRACKING_DOPE_SORT_AVERAGE_ERROR) { - BLI_sortlist(&dopesheet->channels, channels_average_error_sort); + BLI_listbase_sort(&dopesheet->channels, channels_average_error_sort); } } } diff --git a/source/blender/blenkernel/intern/tracking_auto.c b/source/blender/blenkernel/intern/tracking_auto.c new file mode 100644 index 00000000000..22a380ea835 --- /dev/null +++ b/source/blender/blenkernel/intern/tracking_auto.c @@ -0,0 +1,568 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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) 2011 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * Keir Mierle + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/intern/tracking_auto.c + * \ingroup bke + */ + +#include <stdlib.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_movieclip_types.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "BLI_threads.h" +#include "BLI_utildefines.h" +#include "BLI_math.h" + +#include "BKE_movieclip.h" +#include "BKE_tracking.h" + +#include "libmv-capi.h" +#include "tracking_private.h" + +typedef struct AutoTrackOptions { + int clip_index; /** Index of the clip this track belogs to. */ + int track_index; /* Index of the track in AutoTrack tracks structure. */ + MovieTrackingTrack *track; /* Pointer to an original track/ */ + libmv_TrackRegionOptions track_region_options; /* Options for the region + tracker. */ + bool use_keyframe_match; /* Keyframe pattern matching. */ + + /* TODO(sergey): A bit awkward to keep it in here, only used to + * place a disabled marker once the tracking fails, + * Wither find a more clear way to do it or call it track context + * or state, not options. + */ + bool is_failed; + int failed_frame; +} AutoTrackOptions; + +typedef struct AutoTrackContext { + MovieClip *clips[MAX_ACCESSOR_CLIP]; + int num_clips; + + MovieClipUser user; + int frame_width, frame_height; + + struct libmv_AutoTrack *autotrack; + TrackingImageAccessor *image_accessor; + + int num_tracks; /* Number of tracks being tracked. */ + AutoTrackOptions *options; /* Per-tracking track options. */ + + bool backwards; + bool sequence; + int first_frame; + int sync_frame; + bool first_sync; + SpinLock spin_lock; +} AutoTrackContext; + +static void normalized_to_libmv_frame(const float normalized[2], + const int frame_dimensions[2], + float result[2]) +{ + result[0] = normalized[0] * frame_dimensions[0] - 0.5f; + result[1] = normalized[1] * frame_dimensions[1] - 0.5f; +} + +static void normalized_relative_to_libmv_frame(const float normalized[2], + const float origin[2], + const int frame_dimensions[2], + float result[2]) +{ + result[0] = (normalized[0] + origin[0]) * frame_dimensions[0] - 0.5f; + result[1] = (normalized[1] + origin[1]) * frame_dimensions[1] - 0.5f; +} + +static void libmv_frame_to_normalized(const float frame_coord[2], + const int frame_dimensions[2], + float result[2]) +{ + result[0] = (frame_coord[0] + 0.5f) / frame_dimensions[0]; + result[1] = (frame_coord[1] + 0.5f) / frame_dimensions[1]; +} + +static void libmv_frame_to_normalized_relative(const float frame_coord[2], + const float origin[2], + const int frame_dimensions[2], + float result[2]) +{ + result[0] = (frame_coord[0] - origin[0]) / frame_dimensions[0]; + result[1] = (frame_coord[1] - origin[1]) / frame_dimensions[1]; +} + +static void dna_marker_to_libmv_marker(/*const*/ MovieTrackingTrack *track, + /*const*/ MovieTrackingMarker *marker, + int clip, + int track_index, + int frame_width, + int frame_height, + bool backwards, + libmv_Marker *libmv_marker) +{ + const int frame_dimensions[2] = {frame_width, frame_height}; + int i; + libmv_marker->clip = clip; + libmv_marker->frame = marker->framenr; + libmv_marker->track = track_index; + + normalized_to_libmv_frame(marker->pos, + frame_dimensions, + libmv_marker->center); + for (i = 0; i < 4; ++i) { + normalized_relative_to_libmv_frame(marker->pattern_corners[i], + marker->pos, + frame_dimensions, + libmv_marker->patch[i]); + } + + normalized_relative_to_libmv_frame(marker->search_min, + marker->pos, + frame_dimensions, + libmv_marker->search_region_min); + + normalized_relative_to_libmv_frame(marker->search_max, + marker->pos, + frame_dimensions, + libmv_marker->search_region_max); + + /* TODO(sergey): All the markers does have 1.0 weight. */ + libmv_marker->weight = 1.0f; + + if (marker->flag & MARKER_TRACKED) { + libmv_marker->source = LIBMV_MARKER_SOURCE_TRACKED; + } + else { + libmv_marker->source = LIBMV_MARKER_SOURCE_MANUAL; + } + libmv_marker->status = LIBMV_MARKER_STATUS_UNKNOWN; + libmv_marker->model_type = LIBMV_MARKER_MODEL_TYPE_POINT; + libmv_marker->model_id = 0; + + /* TODO(sergey): We currently don't support reference marker from + * different clip. + */ + libmv_marker->reference_clip = clip; + + if (track->pattern_match == TRACK_MATCH_KEYFRAME) { + MovieTrackingMarker *keyframe_marker = + tracking_get_keyframed_marker(track, + marker->framenr, + backwards); + libmv_marker->reference_frame = keyframe_marker->framenr; + } + else { + libmv_marker->reference_frame = backwards ? + marker->framenr - 1 : + marker->framenr; + } + + libmv_marker->disabled_channels = + ((track->flag & TRACK_DISABLE_RED) ? LIBMV_MARKER_CHANNEL_R : 0) | + ((track->flag & TRACK_DISABLE_GREEN) ? LIBMV_MARKER_CHANNEL_G : 0) | + ((track->flag & TRACK_DISABLE_BLUE) ? LIBMV_MARKER_CHANNEL_B : 0); +} + +static void libmv_marker_to_dna_marker(libmv_Marker *libmv_marker, + int frame_width, + int frame_height, + MovieTrackingMarker *marker) +{ + const int frame_dimensions[2] = {frame_width, frame_height}; + int i; + marker->framenr = libmv_marker->frame; + + libmv_frame_to_normalized(libmv_marker->center, + frame_dimensions, + marker->pos); + for (i = 0; i < 4; ++i) { + libmv_frame_to_normalized_relative(libmv_marker->patch[i], + libmv_marker->center, + frame_dimensions, + marker->pattern_corners[i]); + } + + libmv_frame_to_normalized_relative(libmv_marker->search_region_min, + libmv_marker->center, + frame_dimensions, + marker->search_min); + + libmv_frame_to_normalized_relative(libmv_marker->search_region_max, + libmv_marker->center, + frame_dimensions, + marker->search_max); + + marker->flag = 0; + if (libmv_marker->source == LIBMV_MARKER_SOURCE_TRACKED) { + marker->flag |= MARKER_TRACKED; + } + else { + marker->flag &= ~MARKER_TRACKED; + } +} + +static bool check_track_trackable(MovieClip *clip, + MovieTrackingTrack *track, + MovieClipUser *user) +{ + if (TRACK_SELECTED(track) && + (track->flag & (TRACK_LOCKED | TRACK_HIDDEN)) == 0) + { + MovieTrackingMarker *marker; + int frame; + frame = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr); + marker = BKE_tracking_marker_get(track, frame); + return (marker->flag & MARKER_DISABLED) == 0; + } + return false; +} + +/* Returns false if marker crossed margin area from frame bounds. */ +static bool tracking_check_marker_margin(libmv_Marker *libmv_marker, + int margin, + int frame_width, + int frame_height) +{ + float patch_min[2], patch_max[2]; + float margin_left, margin_top, margin_right, margin_bottom; + + INIT_MINMAX2(patch_min, patch_max); + minmax_v2v2_v2(patch_min, patch_max, libmv_marker->patch[0]); + minmax_v2v2_v2(patch_min, patch_max, libmv_marker->patch[1]); + minmax_v2v2_v2(patch_min, patch_max, libmv_marker->patch[2]); + minmax_v2v2_v2(patch_min, patch_max, libmv_marker->patch[3]); + + margin_left = max_ff(libmv_marker->center[0] - patch_min[0], margin); + margin_top = max_ff(patch_max[1] - libmv_marker->center[1], margin); + margin_right = max_ff(patch_max[0] - libmv_marker->center[0], margin); + margin_bottom = max_ff(libmv_marker->center[1] - patch_min[1], margin); + + if (libmv_marker->center[0] < margin_left || + libmv_marker->center[0] > frame_width - margin_right || + libmv_marker->center[1] < margin_bottom || + libmv_marker->center[1] > frame_height - margin_top) + { + return false; + } + + return true; +} + +AutoTrackContext *BKE_autotrack_context_new(MovieClip *clip, + MovieClipUser *user, + const bool backwards, + const bool sequence) +{ + AutoTrackContext *context = MEM_callocN(sizeof(AutoTrackContext), + "autotrack context"); + MovieTracking *tracking = &clip->tracking; + MovieTrackingTrack *track; + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); + int i, track_index, frame_width, frame_height; + + BKE_movieclip_get_size(clip, user, &frame_width, &frame_height); + + /* TODO(sergey): Currently using only a single clip. */ + context->clips[0] = clip; + context->num_clips = 1; + + context->user = *user; + context->user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL; + context->user.render_flag = 0; + context->frame_width = frame_width; + context->frame_height = frame_height; + context->backwards = backwards; + context->sequence = sequence; + context->first_frame = user->framenr; + context->sync_frame = user->framenr; + context->first_sync = true; + + BLI_spin_init(&context->spin_lock); + + context->image_accessor = + tracking_image_accessor_new(context->clips, 1, user->framenr); + context->autotrack = + libmv_autoTrackNew(context->image_accessor->libmv_accessor); + + /* Fill in Autotrack with all markers we know. */ + track_index = 0; + for (track = tracksbase->first; + track; + track = track->next) + { + if (check_track_trackable(clip, track, user)) { + context->num_tracks++; + } + + for (i = 0; i < track->markersnr; ++i) { + MovieTrackingMarker *marker = track->markers + i; + if ((marker->flag & MARKER_DISABLED) == 0) { + libmv_Marker libmv_marker; + dna_marker_to_libmv_marker(track, + marker, + 0, + track_index, + frame_width, + frame_height, + backwards, + &libmv_marker); + libmv_autoTrackAddMarker(context->autotrack, + &libmv_marker); + } + } + track_index++; + } + + /* Create per-track tracking options. */ + context->options = + MEM_callocN(sizeof(AutoTrackOptions) * context->num_tracks, + "auto track options"); + i = track_index = 0; + for (track = tracksbase->first; + track; + track = track->next) + { + if (check_track_trackable(clip, track, user)) { + AutoTrackOptions *options = &context->options[i++]; + /* TODO(sergey): Single clip only for now. */ + options->clip_index = 0; + options->track_index = track_index; + options->track = track; + tracking_configure_tracker(track, + NULL, + &options->track_region_options); + options->use_keyframe_match = + track->pattern_match == TRACK_MATCH_KEYFRAME; + } + ++track_index; + } + + return context; +} + +bool BKE_autotrack_context_step(AutoTrackContext *context) +{ + int frame_delta = context->backwards ? -1 : 1; + bool ok = false; + int track; + +#pragma omp parallel for if(context->num_tracks > 1) + for (track = 0; track < context->num_tracks; ++track) { + AutoTrackOptions *options = &context->options[track]; + libmv_Marker libmv_current_marker, + libmv_reference_marker, + libmv_tracked_marker; + libmv_TrackRegionResult libmv_result; + int frame = BKE_movieclip_remap_scene_to_clip_frame( + context->clips[options->clip_index], + context->user.framenr); + bool has_marker; + + BLI_spin_lock(&context->spin_lock); + has_marker = libmv_autoTrackGetMarker(context->autotrack, + options->clip_index, + frame, + options->track_index, + &libmv_current_marker); + BLI_spin_unlock(&context->spin_lock); + + if (has_marker) { + if (!tracking_check_marker_margin(&libmv_current_marker, + options->track->margin, + context->frame_width, + context->frame_height)) + { + continue; + } + + libmv_tracked_marker = libmv_current_marker; + libmv_tracked_marker.frame = frame + frame_delta; + + if (options->use_keyframe_match) { + libmv_tracked_marker.reference_frame = + libmv_current_marker.reference_frame; + libmv_autoTrackGetMarker(context->autotrack, + options->clip_index, + libmv_tracked_marker.reference_frame, + options->track_index, + &libmv_reference_marker); + } + else { + libmv_tracked_marker.reference_frame = frame; + libmv_reference_marker = libmv_current_marker; + } + + if (libmv_autoTrackMarker(context->autotrack, + &options->track_region_options, + &libmv_tracked_marker, + &libmv_result)) + { + BLI_spin_lock(&context->spin_lock); + libmv_autoTrackAddMarker(context->autotrack, + &libmv_tracked_marker); + BLI_spin_unlock(&context->spin_lock); + } + else { + options->is_failed = true; + options->failed_frame = frame + frame_delta; + } + ok = true; + } + } + + BLI_spin_lock(&context->spin_lock); + context->user.framenr += frame_delta; + BLI_spin_unlock(&context->spin_lock); + + return ok; +} + +void BKE_autotrack_context_sync(AutoTrackContext *context) +{ + int newframe, frame_delta = context->backwards ? -1 : 1; + int clip, frame; + + BLI_spin_lock(&context->spin_lock); + newframe = context->user.framenr; + for (frame = context->sync_frame; + frame != (context->backwards ? newframe - 1 : newframe + 1); + frame += frame_delta) + { + MovieTrackingMarker marker; + libmv_Marker libmv_marker; + int clip = 0; + int track; + for (track = 0; track < context->num_tracks; ++track) { + AutoTrackOptions *options = &context->options[track]; + int track_frame = BKE_movieclip_remap_scene_to_clip_frame( + context->clips[options->clip_index], frame); + if (options->is_failed && options->failed_frame == track_frame) { + MovieTrackingMarker *prev_marker = + BKE_tracking_marker_get_exact(options->track, frame); + if (prev_marker) { + marker = *prev_marker; + marker.framenr = context->backwards ? + track_frame - 1 : + track_frame + 1; + marker.flag |= MARKER_DISABLED; + BKE_tracking_marker_insert(options->track, &marker); + continue; + } + } + if (libmv_autoTrackGetMarker(context->autotrack, + clip, + track_frame, + options->track_index, + &libmv_marker)) + { + libmv_marker_to_dna_marker(&libmv_marker, + context->frame_width, + context->frame_height, + &marker); + if (context->first_sync && frame == context->sync_frame) { + tracking_marker_insert_disabled(options->track, + &marker, + !context->backwards, + false); + } + BKE_tracking_marker_insert(options->track, &marker); + tracking_marker_insert_disabled(options->track, + &marker, + context->backwards, + false); + } + } + } + BLI_spin_unlock(&context->spin_lock); + + for (clip = 0; clip < context->num_clips; ++clip) { + MovieTracking *tracking = &context->clips[clip]->tracking; + BKE_tracking_dopesheet_tag_update(tracking); + } + + context->sync_frame = newframe; + context->first_sync = false; +} + +void BKE_autotrack_context_sync_user(AutoTrackContext *context, + MovieClipUser *user) +{ + user->framenr = context->sync_frame; +} + +void BKE_autotrack_context_finish(AutoTrackContext *context) +{ + int clip_index; + + for (clip_index = 0; clip_index < context->num_clips; ++clip_index) { + MovieClip *clip = context->clips[clip_index]; + ListBase *plane_tracks_base = + BKE_tracking_get_active_plane_tracks(&clip->tracking); + MovieTrackingPlaneTrack *plane_track; + + for (plane_track = plane_tracks_base->first; + plane_track; + plane_track = plane_track->next) + { + if ((plane_track->flag & PLANE_TRACK_AUTOKEY) == 0) { + int track; + for (track = 0; track < context->num_tracks; ++track) { + MovieTrackingTrack *old_track; + bool do_update = false; + int j; + + old_track = context->options[track].track; + for (j = 0; j < plane_track->point_tracksnr; j++) { + if (plane_track->point_tracks[j] == old_track) { + do_update = true; + break; + } + } + + if (do_update) { + BKE_tracking_track_plane_from_existing_motion( + plane_track, + context->first_frame); + break; + } + } + } + } + } +} + +void BKE_autotrack_context_free(AutoTrackContext *context) +{ + libmv_autoTrackDestroy(context->autotrack); + tracking_image_accessor_destroy(context->image_accessor); + MEM_freeN(context->options); + BLI_spin_end(&context->spin_lock); + MEM_freeN(context); +} diff --git a/source/blender/blenkernel/intern/tracking_detect.c b/source/blender/blenkernel/intern/tracking_detect.c index 62039b761e8..6df51b5441a 100644 --- a/source/blender/blenkernel/intern/tracking_detect.c +++ b/source/blender/blenkernel/intern/tracking_detect.c @@ -40,7 +40,6 @@ #include "BKE_tracking.h" #include "IMB_imbuf_types.h" -#include "IMB_imbuf.h" #include "libmv-capi.h" diff --git a/source/blender/blenkernel/intern/tracking_region_tracker.c b/source/blender/blenkernel/intern/tracking_region_tracker.c index c41106f37cb..dd7def16ca8 100644 --- a/source/blender/blenkernel/intern/tracking_region_tracker.c +++ b/source/blender/blenkernel/intern/tracking_region_tracker.c @@ -35,11 +35,8 @@ #include "MEM_guardedalloc.h" #include "DNA_movieclip_types.h" -#include "DNA_object_types.h" /* SELECT */ #include "BLI_utildefines.h" -#include "BLI_math.h" -#include "BLI_ghash.h" #include "BLI_threads.h" #include "BKE_tracking.h" @@ -51,170 +48,6 @@ #include "libmv-capi.h" #include "tracking_private.h" -typedef struct TrackContext { - /* the reference marker and cutout search area */ - MovieTrackingMarker reference_marker; - - /* keyframed patch. This is the search area */ - float *search_area; - int search_area_height; - int search_area_width; - int framenr; - - float *mask; -} TrackContext; - -typedef struct MovieTrackingContext { - MovieClipUser user; - MovieClip *clip; - int clip_flag; - - int frames, first_frame; - bool first_time; - - MovieTrackingSettings settings; - TracksMap *tracks_map; - - bool backwards, sequence; - int sync_frame; -} MovieTrackingContext; - -static void track_context_free(void *customdata) -{ - TrackContext *track_context = (TrackContext *)customdata; - - if (track_context->search_area) - MEM_freeN(track_context->search_area); - - if (track_context->mask) - MEM_freeN(track_context->mask); -} - -/* Create context for motion 2D tracking, copies all data needed - * for thread-safe tracking, allowing clip modifications during - * tracking. - */ -MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user, - const bool backwards, const bool sequence) -{ - MovieTrackingContext *context = MEM_callocN(sizeof(MovieTrackingContext), "trackingContext"); - MovieTracking *tracking = &clip->tracking; - MovieTrackingSettings *settings = &tracking->settings; - ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - MovieTrackingTrack *track; - MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); - int num_tracks = 0; - - context->clip = clip; - context->settings = *settings; - context->backwards = backwards; - context->sync_frame = user->framenr; - context->first_time = true; - context->first_frame = user->framenr; - context->sequence = sequence; - - /* count */ - track = tracksbase->first; - while (track) { - if (TRACK_SELECTED(track) && (track->flag & (TRACK_LOCKED | TRACK_HIDDEN)) == 0) { - int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr); - MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); - - if ((marker->flag & MARKER_DISABLED) == 0) - num_tracks++; - } - - track = track->next; - } - - /* create tracking contextx for all tracks which would be tracked */ - if (num_tracks) { - int width, height; - - context->tracks_map = tracks_map_new(object->name, object->flag & TRACKING_OBJECT_CAMERA, - num_tracks, sizeof(TrackContext)); - - BKE_movieclip_get_size(clip, user, &width, &height); - - /* create tracking data */ - track = tracksbase->first; - while (track) { - if (TRACK_SELECTED(track) && (track->flag & (TRACK_HIDDEN | TRACK_LOCKED)) == 0) { - int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr); - MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); - - if ((marker->flag & MARKER_DISABLED) == 0) { - TrackContext track_context; - memset(&track_context, 0, sizeof(TrackContext)); - tracks_map_insert(context->tracks_map, track, &track_context); - } - } - - track = track->next; - } - } - - /* store needed clip flags passing to get_buffer functions - * - MCLIP_USE_PROXY is needed to because timecode affects on movie clip - * only in case Proxy/Timecode flag is set, so store this flag to use - * timecodes properly but reset render size to SIZE_FULL so correct resolution - * would be used for images - * - MCLIP_USE_PROXY_CUSTOM_DIR is needed because proxy/timecode files might - * be stored in a different location - * ignore all the rest possible flags for now - */ - context->clip_flag = clip->flag & MCLIP_TIMECODE_FLAGS; - - context->user = *user; - context->user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL; - context->user.render_flag = 0; - - if (!sequence) - BLI_begin_threaded_malloc(); - - return context; -} - -/* Free context used for tracking. */ -void BKE_tracking_context_free(MovieTrackingContext *context) -{ - if (!context->sequence) - BLI_end_threaded_malloc(); - - tracks_map_free(context->tracks_map, track_context_free); - - MEM_freeN(context); -} - -/* Synchronize tracks between clip editor and tracking context, - * by merging them together so all new created tracks and tracked - * ones presents in the movie clip. - */ -void BKE_tracking_context_sync(MovieTrackingContext *context) -{ - MovieTracking *tracking = &context->clip->tracking; - int newframe; - - tracks_map_merge(context->tracks_map, tracking); - - if (context->backwards) - newframe = context->user.framenr + 1; - else - newframe = context->user.framenr - 1; - - context->sync_frame = newframe; - - BKE_tracking_dopesheet_tag_update(tracking); -} - -/* Synchronize clip user's frame number with a frame number from tracking context, - * used to update current frame displayed in the clip editor while tracking. - */ -void BKE_tracking_context_sync_user(const MovieTrackingContext *context, MovieClipUser *user) -{ - user->framenr = context->sync_frame; -} - /* **** utility functions for tracking **** */ /* convert from float and byte RGBA to grayscale. Supports different coefficients for RGB. */ @@ -280,7 +113,7 @@ static float *track_get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, return gray_pixels; } -/* Get image boffer for a given frame +/* Get image buffer for a given frame * * Frame is in clip space. */ @@ -296,51 +129,6 @@ static ImBuf *tracking_context_get_frame_ibuf(MovieClip *clip, MovieClipUser *us return ibuf; } -/* Get previous keyframed marker. */ -static MovieTrackingMarker *tracking_context_get_keyframed_marker(MovieTrackingTrack *track, - int curfra, bool backwards) -{ - MovieTrackingMarker *marker_keyed = NULL; - MovieTrackingMarker *marker_keyed_fallback = NULL; - int a = BKE_tracking_marker_get(track, curfra) - track->markers; - - while (a >= 0 && a < track->markersnr) { - int next = backwards ? a + 1 : a - 1; - bool is_keyframed = false; - MovieTrackingMarker *cur_marker = &track->markers[a]; - MovieTrackingMarker *next_marker = NULL; - - if (next >= 0 && next < track->markersnr) - next_marker = &track->markers[next]; - - if ((cur_marker->flag & MARKER_DISABLED) == 0) { - /* If it'll happen so we didn't find a real keyframe marker, - * fallback to the first marker in current tracked segment - * as a keyframe. - */ - if (next_marker && next_marker->flag & MARKER_DISABLED) { - if (marker_keyed_fallback == NULL) - marker_keyed_fallback = cur_marker; - } - - is_keyframed |= (cur_marker->flag & MARKER_TRACKED) == 0; - } - - if (is_keyframed) { - marker_keyed = cur_marker; - - break; - } - - a = next; - } - - if (marker_keyed == NULL) - marker_keyed = marker_keyed_fallback; - - return marker_keyed; -} - /* Get image buffer for previous marker's keyframe. */ static ImBuf *tracking_context_get_keyframed_ibuf(MovieClip *clip, MovieClipUser *user, int clip_flag, MovieTrackingTrack *track, int curfra, bool backwards, @@ -349,7 +137,7 @@ static ImBuf *tracking_context_get_keyframed_ibuf(MovieClip *clip, MovieClipUser MovieTrackingMarker *marker_keyed; int keyed_framenr; - marker_keyed = tracking_context_get_keyframed_marker(track, curfra, backwards); + marker_keyed = tracking_get_keyframed_marker(track, curfra, backwards); if (marker_keyed == NULL) { return NULL; } @@ -381,50 +169,9 @@ static ImBuf *tracking_context_get_reference_ibuf(MovieClip *clip, MovieClipUser return ibuf; } -/* Update track's reference patch (patch from which track is tracking from) - * - * Returns false if reference image buffer failed to load. - */ -static bool track_context_update_reference(MovieTrackingContext *context, TrackContext *track_context, - MovieTrackingTrack *track, MovieTrackingMarker *marker, int curfra, - int frame_width, int frame_height) -{ - MovieTrackingMarker *reference_marker = NULL; - ImBuf *reference_ibuf = NULL; - int width, height; - - /* calculate patch for keyframed position */ - reference_ibuf = tracking_context_get_reference_ibuf(context->clip, &context->user, context->clip_flag, - track, curfra, context->backwards, &reference_marker); - - if (!reference_ibuf) - return false; - - track_context->reference_marker = *reference_marker; - - if (track_context->search_area) { - MEM_freeN(track_context->search_area); - } - - track_context->search_area = track_get_search_floatbuf(reference_ibuf, track, reference_marker, &width, &height); - track_context->search_area_height = height; - track_context->search_area_width = width; - - if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0) { - if (track_context->mask) - MEM_freeN(track_context->mask); - - track_context->mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker); - } - - IMB_freeImBuf(reference_ibuf); - - return true; -} - /* Fill in libmv tracker options structure with settings need to be used to perform track. */ -static void tracking_configure_tracker(const MovieTrackingTrack *track, float *mask, - libmv_TrackRegionOptions *options) +void tracking_configure_tracker(const MovieTrackingTrack *track, float *mask, + libmv_TrackRegionOptions *options) { options->motion_model = track->motion_model; @@ -442,102 +189,6 @@ static void tracking_configure_tracker(const MovieTrackingTrack *track, float *m options->image1_mask = NULL; } -/* returns false if marker crossed margin area from frame bounds */ -static bool tracking_check_marker_margin(MovieTrackingTrack *track, MovieTrackingMarker *marker, - int frame_width, int frame_height) -{ - float pat_min[2], pat_max[2]; - float margin_left, margin_top, margin_right, margin_bottom; - float normalized_track_margin[2]; - - /* margin from frame boundaries */ - BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); - - normalized_track_margin[0] = (float)track->margin / frame_width; - normalized_track_margin[1] = (float)track->margin / frame_height; - - margin_left = max_ff(-pat_min[0], normalized_track_margin[0]); - margin_top = max_ff( pat_max[1], normalized_track_margin[1]); - margin_right = max_ff( pat_max[0], normalized_track_margin[0]); - margin_bottom = max_ff(-pat_min[1], normalized_track_margin[1]); - - /* do not track markers which are too close to boundary */ - if (marker->pos[0] < margin_left || marker->pos[0] > 1.0f - margin_right || - marker->pos[1] < margin_bottom || marker->pos[1] > 1.0f - margin_top) - { - return false; - } - - return true; -} - -/* Scale search area of marker based on scale changes of pattern area, - * - * TODO(sergey): currently based on pattern bounding box scale change, - * smarter approach here is welcome. - */ -static void tracking_scale_marker_search(const MovieTrackingMarker *old_marker, MovieTrackingMarker *new_marker) -{ - float old_pat_min[2], old_pat_max[2]; - float new_pat_min[2], new_pat_max[2]; - float scale_x, scale_y; - - BKE_tracking_marker_pattern_minmax(old_marker, old_pat_min, old_pat_max); - BKE_tracking_marker_pattern_minmax(new_marker, new_pat_min, new_pat_max); - - scale_x = (new_pat_max[0] - new_pat_min[0]) / (old_pat_max[0] - old_pat_min[0]); - scale_y = (new_pat_max[1] - new_pat_min[1]) / (old_pat_max[1] - old_pat_min[1]); - - new_marker->search_min[0] *= scale_x; - new_marker->search_min[1] *= scale_y; - - new_marker->search_max[0] *= scale_x; - new_marker->search_max[1] *= scale_y; -} - -/* Insert new marker which was tracked from old_marker to a new image, - * will also ensure tracked segment is surrounded by disabled markers. - */ -static void tracking_insert_new_marker(MovieTrackingContext *context, MovieTrackingTrack *track, - const MovieTrackingMarker *old_marker, int curfra, bool tracked, - int frame_width, int frame_height, - const double dst_pixel_x[5], const double dst_pixel_y[5]) -{ - MovieTrackingMarker new_marker; - int frame_delta = context->backwards ? -1 : 1; - int nextfra = curfra + frame_delta; - - new_marker = *old_marker; - - if (tracked) { - tracking_set_marker_coords_from_tracking(frame_width, frame_height, &new_marker, dst_pixel_x, dst_pixel_y); - new_marker.flag |= MARKER_TRACKED; - new_marker.framenr = nextfra; - - tracking_scale_marker_search(old_marker, &new_marker); - - if (context->first_time) { - /* check if there's no keyframe/tracked markers before tracking marker. - * if so -- create disabled marker before currently tracking "segment" - */ - - tracking_marker_insert_disabled(track, old_marker, !context->backwards, false); - } - - /* insert currently tracked marker */ - BKE_tracking_marker_insert(track, &new_marker); - - /* make currently tracked segment be finished with disabled marker */ - tracking_marker_insert_disabled(track, &new_marker, context->backwards, false); - } - else { - new_marker.framenr = nextfra; - new_marker.flag |= MARKER_DISABLED; - - BKE_tracking_marker_insert(track, &new_marker); - } -} - /* Peform tracking from a reference_marker to destination_ibuf. * Uses marker as an initial position guess. * @@ -601,130 +252,6 @@ static bool configure_and_run_tracker(ImBuf *destination_ibuf, MovieTrackingTrac return tracked; } -/* Track all the tracks from context one more frame, - * returns FALSe if nothing was tracked. - */ -bool BKE_tracking_context_step(MovieTrackingContext *context) -{ - ImBuf *destination_ibuf; - int frame_delta = context->backwards ? -1 : 1; - int curfra = BKE_movieclip_remap_scene_to_clip_frame(context->clip, context->user.framenr); - int a, map_size; - bool ok = false; - - int frame_width, frame_height; - - map_size = tracks_map_get_size(context->tracks_map); - - /* Nothing to track, avoid unneeded frames reading to save time and memory. */ - if (!map_size) - return false; - - /* Get an image buffer for frame we're tracking to. */ - context->user.framenr += frame_delta; - - destination_ibuf = BKE_movieclip_get_ibuf_flag(context->clip, &context->user, - context->clip_flag, MOVIECLIP_CACHE_SKIP); - if (!destination_ibuf) - return false; - - frame_width = destination_ibuf->x; - frame_height = destination_ibuf->y; - -#pragma omp parallel for private(a) shared(destination_ibuf, ok) if (map_size > 1) - for (a = 0; a < map_size; a++) { - TrackContext *track_context = NULL; - MovieTrackingTrack *track; - MovieTrackingMarker *marker; - - tracks_map_get_indexed_element(context->tracks_map, a, &track, (void **)&track_context); - - marker = BKE_tracking_marker_get_exact(track, curfra); - - if (marker && (marker->flag & MARKER_DISABLED) == 0) { - bool tracked = false, need_readjust; - double dst_pixel_x[5], dst_pixel_y[5]; - - if (track->pattern_match == TRACK_MATCH_KEYFRAME) - need_readjust = context->first_time; - else - need_readjust = true; - - /* do not track markers which are too close to boundary */ - if (tracking_check_marker_margin(track, marker, frame_width, frame_height)) { - if (need_readjust) { - if (track_context_update_reference(context, track_context, track, marker, - curfra, frame_width, frame_height) == false) - { - /* happens when reference frame fails to be loaded */ - continue; - } - } - - tracked = configure_and_run_tracker(destination_ibuf, track, - &track_context->reference_marker, marker, - track_context->search_area, - track_context->search_area_width, - track_context->search_area_height, - track_context->mask, - dst_pixel_x, dst_pixel_y); - } - - BLI_spin_lock(&context->tracks_map->spin_lock); - tracking_insert_new_marker(context, track, marker, curfra, tracked, - frame_width, frame_height, dst_pixel_x, dst_pixel_y); - BLI_spin_unlock(&context->tracks_map->spin_lock); - - ok = true; - } - } - - IMB_freeImBuf(destination_ibuf); - - context->first_time = false; - context->frames++; - - return ok; -} - -void BKE_tracking_context_finish(MovieTrackingContext *context) -{ - MovieClip *clip = context->clip; - ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking); - MovieTrackingPlaneTrack *plane_track; - int map_size = tracks_map_get_size(context->tracks_map); - - for (plane_track = plane_tracks_base->first; - plane_track; - plane_track = plane_track->next) - { - if ((plane_track->flag & PLANE_TRACK_AUTOKEY) == 0) { - int i; - for (i = 0; i < map_size; i++) { - TrackContext *track_context = NULL; - MovieTrackingTrack *track, *old_track; - bool do_update = false; - int j; - - tracks_map_get_indexed_element(context->tracks_map, i, &track, (void **)&track_context); - - old_track = BLI_ghash_lookup(context->tracks_map->hash, track); - for (j = 0; j < plane_track->point_tracksnr; j++) { - if (plane_track->point_tracks[j] == old_track) { - do_update = true; - break; - } - } - - if (do_update) { - BKE_tracking_track_plane_from_existing_motion(plane_track, context->first_frame); - break; - } - } - } - } -} - static bool refine_marker_reference_frame_get(MovieTrackingTrack *track, MovieTrackingMarker *marker, bool backwards, diff --git a/source/blender/blenkernel/intern/tracking_solver.c b/source/blender/blenkernel/intern/tracking_solver.c index 056220e27d8..d5e2f24e9ed 100644 --- a/source/blender/blenkernel/intern/tracking_solver.c +++ b/source/blender/blenkernel/intern/tracking_solver.c @@ -356,7 +356,7 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieClip *clip MovieReconstructContext *context = MEM_callocN(sizeof(MovieReconstructContext), "MovieReconstructContext data"); ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); float aspy = 1.0f / tracking->camera.pixel_aspect; - int num_tracks = BLI_countlist(tracksbase); + int num_tracks = BLI_listbase_count(tracksbase); int sfra = INT_MAX, efra = INT_MIN; MovieTrackingTrack *track; @@ -391,7 +391,7 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieClip *clip last_marker--; } - if (first < track->markersnr - 1) + if (first <= track->markersnr - 1) sfra = min_ii(sfra, first_marker->framenr); if (last >= 0) @@ -509,6 +509,11 @@ bool BKE_tracking_reconstruction_finish(MovieReconstructContext *context, MovieT MovieTrackingReconstruction *reconstruction; MovieTrackingObject *object; + if (!libmv_reconstructionIsValid(context->reconstruction)) { + printf("Failed solve the motion: most likely there are no good keyframes\n"); + return false; + } + tracks_map_merge(context->tracks_map, tracking); BKE_tracking_dopesheet_tag_update(tracking); diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c index 0a8293630c7..17e4a3c73c3 100644 --- a/source/blender/blenkernel/intern/tracking_util.c +++ b/source/blender/blenkernel/intern/tracking_util.c @@ -47,8 +47,13 @@ #include "BLF_translation.h" +#include "BKE_movieclip.h" #include "BKE_tracking.h" +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" +#include "IMB_moviecache.h" + #include "tracking_private.h" #include "libmv-capi.h" @@ -390,8 +395,7 @@ void tracking_marker_insert_disabled(MovieTrackingTrack *track, const MovieTrack } -/* Fill in Libmv C-API camera intrinsics options from tracking structure. - */ +/* Fill in Libmv C-API camera intrinsics options from tracking structure. */ void tracking_cameraIntrinscisOptionsFromTracking(MovieTracking *tracking, int calibration_width, int calibration_height, libmv_CameraIntrinsicsOptions *camera_intrinsics_options) @@ -453,3 +457,441 @@ void tracking_trackingCameraFromIntrinscisOptions(MovieTracking *tracking, BLI_assert(!"Unknown distortion model"); } } + +/* Get previous keyframed marker. */ +MovieTrackingMarker *tracking_get_keyframed_marker(MovieTrackingTrack *track, + int current_frame, + bool backwards) +{ + MovieTrackingMarker *marker_keyed = NULL; + MovieTrackingMarker *marker_keyed_fallback = NULL; + int a = BKE_tracking_marker_get(track, current_frame) - track->markers; + + while (a >= 0 && a < track->markersnr) { + int next = backwards ? a + 1 : a - 1; + bool is_keyframed = false; + MovieTrackingMarker *cur_marker = &track->markers[a]; + MovieTrackingMarker *next_marker = NULL; + + if (next >= 0 && next < track->markersnr) + next_marker = &track->markers[next]; + + if ((cur_marker->flag & MARKER_DISABLED) == 0) { + /* If it'll happen so we didn't find a real keyframe marker, + * fallback to the first marker in current tracked segment + * as a keyframe. + */ + if (next_marker && next_marker->flag & MARKER_DISABLED) { + if (marker_keyed_fallback == NULL) + marker_keyed_fallback = cur_marker; + } + + is_keyframed |= (cur_marker->flag & MARKER_TRACKED) == 0; + } + + if (is_keyframed) { + marker_keyed = cur_marker; + + break; + } + + a = next; + } + + if (marker_keyed == NULL) + marker_keyed = marker_keyed_fallback; + + return marker_keyed; +} + +/*********************** Frame accessr *************************/ + +typedef struct AccessCacheKey { + int clip_index; + int frame; + int downscale; + libmv_InputMode input_mode; + int64_t transform_key; +} AccessCacheKey; + +static unsigned int accesscache_hashhash(const void *key_v) +{ + const AccessCacheKey *key = (const AccessCacheKey *) key_v; + /* TODP(sergey): Need better hasing here for faster frame access. */ + return key->clip_index << 16 | key->frame; +} + +static bool accesscache_hashcmp(const void *a_v, const void *b_v) +{ + const AccessCacheKey *a = (const AccessCacheKey *) a_v; + const AccessCacheKey *b = (const AccessCacheKey *) b_v; + +#define COMPARE_FIELD(field) + { \ + if (a->clip_index != b->clip_index) { \ + return false; \ + } \ + } (void) 0 + + COMPARE_FIELD(clip_index); + COMPARE_FIELD(frame); + COMPARE_FIELD(downscale); + COMPARE_FIELD(input_mode); + COMPARE_FIELD(transform_key); + +#undef COMPARE_FIELD + + return true; +} + +static void accesscache_put(TrackingImageAccessor *accessor, + int clip_index, + int frame, + libmv_InputMode input_mode, + int downscale, + int64_t transform_key, + ImBuf *ibuf) +{ + AccessCacheKey key; + key.clip_index = clip_index; + key.frame = frame; + key.input_mode = input_mode; + key.downscale = downscale; + key.transform_key = transform_key; + IMB_moviecache_put(accessor->cache, &key, ibuf); +} + +static ImBuf *accesscache_get(TrackingImageAccessor *accessor, + int clip_index, + int frame, + libmv_InputMode input_mode, + int downscale, + int64_t transform_key) +{ + AccessCacheKey key; + key.clip_index = clip_index; + key.frame = frame; + key.input_mode = input_mode; + key.downscale = downscale; + key.transform_key = transform_key; + return IMB_moviecache_get(accessor->cache, &key); +} + +static ImBuf *accessor_get_preprocessed_ibuf(TrackingImageAccessor *accessor, + int clip_index, + int frame) +{ + MovieClip *clip; + MovieClipUser user; + ImBuf *ibuf; + int scene_frame; + + BLI_assert(clip_index < accessor->num_clips); + + clip = accessor->clips[clip_index]; + scene_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, frame); + BKE_movieclip_user_set_frame(&user, scene_frame); + user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL; + user.render_flag = 0; + ibuf = BKE_movieclip_get_ibuf(clip, &user); + + return ibuf; +} + +static ImBuf *make_grayscale_ibuf_copy(ImBuf *ibuf) +{ + ImBuf *grayscale = IMB_allocImBuf(ibuf->x, ibuf->y, 32, 0); + size_t size; + int i; + + BLI_assert(ibuf->channels == 3 || ibuf->channels == 4); + + /* TODO(sergey): Bummer, currently IMB API only allows to create 4 channels + * float buffer, so we do it manually here. + * + * Will generalize it later. + */ + size = (size_t)grayscale->x * (size_t)grayscale->y * sizeof(float); + grayscale->channels = 1; + if ((grayscale->rect_float = MEM_mapallocN(size, "tracking grayscale image"))) { + grayscale->mall |= IB_rectfloat; + grayscale->flags |= IB_rectfloat; + } + + for (i = 0; i < grayscale->x * grayscale->y; ++i) { + const float *pixel = ibuf->rect_float + ibuf->channels * i; + + grayscale->rect_float[i] = 0.2126f * pixel[0] + + 0.7152f * pixel[1] + + 0.0722f * pixel[2]; + } + + return grayscale; +} + +static void ibuf_to_float_image(const ImBuf *ibuf, libmv_FloatImage *float_image) +{ + BLI_assert(ibuf->rect_float != NULL); + float_image->buffer = ibuf->rect_float; + float_image->width = ibuf->x; + float_image->height = ibuf->y; + float_image->channels = ibuf->channels; +} + +static ImBuf *float_image_to_ibuf(libmv_FloatImage *float_image) +{ + ImBuf *ibuf = IMB_allocImBuf(float_image->width, float_image->height, 32, 0); + size_t size = (size_t)ibuf->x * (size_t)ibuf->y * + float_image->channels * sizeof(float); + ibuf->channels = float_image->channels; + if ((ibuf->rect_float = MEM_mapallocN(size, "tracking grayscale image"))) { + ibuf->mall |= IB_rectfloat; + ibuf->flags |= IB_rectfloat; + } + memcpy(ibuf->rect_float, float_image->buffer, size); + return ibuf; +} + +static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor, + int clip_index, + int frame, + libmv_InputMode input_mode, + int downscale, + const libmv_Region *region, + const libmv_FrameTransform *transform) +{ + ImBuf *ibuf, *orig_ibuf, *final_ibuf; + int64_t transform_key = 0; + + if (transform != NULL) { + transform_key = libmv_frameAccessorgetTransformKey(transform); + } + + /* First try to get fully processed image from the cache. */ + ibuf = accesscache_get(accessor, + clip_index, + frame, + input_mode, + downscale, + transform_key); + if (ibuf != NULL) { + return ibuf; + } + + /* And now we do postprocessing of the original frame. */ + orig_ibuf = accessor_get_preprocessed_ibuf(accessor, clip_index, frame); + + if (orig_ibuf == NULL) { + return NULL; + } + + if (region != NULL) { + int width = region->max[0] - region->min[0], + height = region->max[1] - region->min[1]; + + /* If the requested region goes outside of the actual frame we still + * return the requested region size, but only fill it's partially with + * the data we can. + */ + int clamped_origin_x = max_ii((int)region->min[0], 0), + clamped_origin_y = max_ii((int)region->min[1], 0); + int dst_offset_x = clamped_origin_x - (int)region->min[0], + dst_offset_y = clamped_origin_y - (int)region->min[1]; + int clamped_width = width - dst_offset_x, + clamped_height = height - dst_offset_y; + clamped_width = min_ii(clamped_width, orig_ibuf->x - clamped_origin_x); + clamped_height = min_ii(clamped_height, orig_ibuf->y - clamped_origin_y); + + final_ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat); + + if (orig_ibuf->rect_float != NULL) { + IMB_rectcpy(final_ibuf, orig_ibuf, + dst_offset_x, dst_offset_y, + clamped_origin_x, clamped_origin_y, + clamped_width, clamped_height); + } + else { + int y; + /* TODO(sergey): We don't do any color space or alpha conversion + * here. Probably Libmv is better to work in the linear space, + * but keep sRGB space here for compatibility for now. + */ + for (y = 0; y < clamped_height; ++y) { + int x; + for (x = 0; x < clamped_width; ++x) { + int src_x = x + clamped_origin_x, + src_y = y + clamped_origin_y; + int dst_x = x + dst_offset_x, + dst_y = y + dst_offset_y; + int dst_index = (dst_y * width + dst_x) * 4, + src_index = (src_y * orig_ibuf->x + src_x) * 4; + rgba_uchar_to_float(final_ibuf->rect_float + dst_index, + (unsigned char *)orig_ibuf->rect + + src_index); + } + } + } + } + else { + /* Libmv only works with float images, + * + * This would likely make it so loads of float buffers are being stored + * in the cache which is nice on the one hand (faster re-use of the + * frames) but on the other hand it bumps the memory usage up. + */ + BLI_lock_thread(LOCK_MOVIECLIP); + IMB_float_from_rect(orig_ibuf); + BLI_unlock_thread(LOCK_MOVIECLIP); + final_ibuf = orig_ibuf; + } + + if (downscale > 0) { + if (final_ibuf == orig_ibuf) { + final_ibuf = IMB_dupImBuf(orig_ibuf); + } + IMB_scaleImBuf(final_ibuf, + ibuf->x / (1 << downscale), + ibuf->y / (1 << downscale)); + } + + if (transform != NULL) { + libmv_FloatImage input_image, output_image; + ibuf_to_float_image(final_ibuf, &input_image); + libmv_frameAccessorgetTransformRun(transform, + &input_image, + &output_image); + if (final_ibuf != orig_ibuf) { + IMB_freeImBuf(final_ibuf); + } + final_ibuf = float_image_to_ibuf(&output_image); + libmv_floatImageDestroy(&output_image); + } + + if (input_mode == LIBMV_IMAGE_MODE_RGBA) { + BLI_assert(ibuf->channels == 3 || ibuf->channels == 4); + /* pass */ + } + else /* if (input_mode == LIBMV_IMAGE_MODE_MONO) */ { + if (final_ibuf->channels != 1) { + ImBuf *grayscale_ibuf = make_grayscale_ibuf_copy(final_ibuf); + if (final_ibuf != orig_ibuf) { + /* We dereference original frame later. */ + IMB_freeImBuf(final_ibuf); + } + final_ibuf = grayscale_ibuf; + } + } + + /* it's possible processing still didn't happen at this point, + * but we really need a copy of the buffer to be transformed + * and to be put to the cache. + */ + if (final_ibuf == orig_ibuf) { + final_ibuf = IMB_dupImBuf(orig_ibuf); + } + + IMB_freeImBuf(orig_ibuf); + + /* We put postprocessed frame to the cache always for now, + * not the smartest thing in the world, but who cares at this point. + */ + + /* TODO(sergey): Disable cache for now, because we don't store region + * in the cache key and can't check whether cached version is usable for + * us or not. + * + * Need to think better about what to cache and when. + */ + if (false) { + accesscache_put(accessor, + clip_index, + frame, + input_mode, + downscale, + transform_key, + final_ibuf); + } + + return final_ibuf; +} + +static libmv_CacheKey accessor_get_image_callback( + struct libmv_FrameAccessorUserData *user_data, + int clip_index, + int frame, + libmv_InputMode input_mode, + int downscale, + const libmv_Region *region, + const libmv_FrameTransform *transform, + float **destination, + int *width, + int *height, + int *channels) +{ + TrackingImageAccessor *accessor = (TrackingImageAccessor *) user_data; + ImBuf *ibuf; + + BLI_assert(clip_index >= 0 && clip_index < accessor->num_clips); + + ibuf = accessor_get_ibuf(accessor, + clip_index, + frame, + input_mode, + downscale, + region, + transform); + + if (ibuf) { + *destination = ibuf->rect_float; + *width = ibuf->x; + *height = ibuf->y; + *channels = ibuf->channels; + } + else { + *destination = NULL; + *width = 0; + *height = 0; + *channels = 0; + } + + return ibuf; +} + +static void accessor_release_image_callback(libmv_CacheKey cache_key) +{ + ImBuf *ibuf = (ImBuf *) cache_key; + IMB_freeImBuf(ibuf); +} + +TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR_CLIP], + int num_clips, + int start_frame) +{ + TrackingImageAccessor *accessor = + MEM_callocN(sizeof(TrackingImageAccessor), "tracking image accessor"); + + BLI_assert(num_clips <= MAX_ACCESSOR_CLIP); + + accessor->cache = IMB_moviecache_create("frame access cache", + sizeof(AccessCacheKey), + accesscache_hashhash, + accesscache_hashcmp); + + memcpy(accessor->clips, clips, num_clips * sizeof(MovieClip *)); + accessor->num_clips = num_clips; + accessor->start_frame = start_frame; + + accessor->libmv_accessor = + libmv_FrameAccessorNew((libmv_FrameAccessorUserData *) accessor, + accessor_get_image_callback, + accessor_release_image_callback); + + return accessor; +} + +void tracking_image_accessor_destroy(TrackingImageAccessor *accessor) +{ + IMB_moviecache_free(accessor->cache); + libmv_FrameAccessorDestroy(accessor->libmv_accessor); + MEM_freeN(accessor); +} diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 8e3c92314e6..8113e2bf9ef 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -38,8 +38,8 @@ #include "DNA_scene_types.h" #include "DNA_texture_types.h" -#include "BLI_listbase.h" #include "BLI_utildefines.h" +#include "BLI_listbase.h" #include "BKE_animsys.h" #include "BKE_global.h" @@ -49,6 +49,8 @@ #include "BKE_node.h" #include "BKE_world.h" +#include "GPU_material.h" + void BKE_world_free_ex(World *wrld, bool do_id_user) { MTex *mtex; @@ -69,6 +71,9 @@ void BKE_world_free_ex(World *wrld, bool do_id_user) MEM_freeN(wrld->nodetree); } + if (wrld->gpumaterial.first) + GPU_material_free(&wrld->gpumaterial); + BKE_icon_delete((struct ID *)wrld); wrld->id.icon_id = 0; } @@ -134,6 +139,8 @@ World *BKE_world_copy(World *wrld) if (wrld->preview) wrldn->preview = BKE_previewimg_copy(wrld->preview); + BLI_listbase_clear(&wrldn->gpumaterial); + return wrldn; } @@ -158,6 +165,8 @@ World *localize_world(World *wrld) wrldn->preview = NULL; + BLI_listbase_clear(&wrldn->gpumaterial); + return wrldn; } diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c index aef44993912..8a6a0438b84 100644 --- a/source/blender/blenkernel/intern/writeavi.c +++ b/source/blender/blenkernel/intern/writeavi.c @@ -80,7 +80,9 @@ static void filepath_avi(char *string, RenderData *rd); # include "BKE_writeffmpeg.h" #endif -#include "BKE_writeframeserver.h" +#ifdef WITH_FRAMESERVER +# include "BKE_writeframeserver.h" +#endif bMovieHandle *BKE_movie_handle_get(const char imtype) { diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index ca21180000d..d4f5da2e36f 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -57,7 +57,6 @@ #include "BKE_sound.h" #include "BKE_writeffmpeg.h" -#include "IMB_imbuf_types.h" #include "IMB_imbuf.h" #include "ffmpeg_compat.h" @@ -484,7 +483,6 @@ static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char AVDictionary **dictionary) { IDProperty *prop; - void *iter; IDProperty *curr; /* TODO(sergey): This is actually rather stupid, because changing @@ -495,7 +493,7 @@ static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char * * For as long we don't allow editing properties in the interface * it's all good. bug if we allow editing them, we'll need to - * repace it with some smarter code which would port settings + * replace it with some smarter code which would port settings * from deprecated to new one. */ ffmpeg_set_expert_options(rd); @@ -509,9 +507,7 @@ static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char return; } - iter = IDP_GetGroupIterator(prop); - - while ((curr = IDP_GroupIterNext(iter)) != NULL) { + for (curr = prop->data.group.first; curr; curr = curr->next) { if (ffmpeg_proprty_valid(c, prop_name, curr)) set_ffmpeg_property_option(c, curr, dictionary); } @@ -696,7 +692,7 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex } if (codec->sample_fmts) { - /* check if the prefered sample format for this codec is supported. + /* check if the preferred sample format for this codec is supported. * this is because, depending on the version of libav, and with the whole ffmpeg/libav fork situation, * you have various implementations around. float samples in particular are not always supported. */ diff --git a/source/blender/blenkernel/tracking_private.h b/source/blender/blenkernel/tracking_private.h index 6efa1533e3e..591ee4d0d01 100644 --- a/source/blender/blenkernel/tracking_private.h +++ b/source/blender/blenkernel/tracking_private.h @@ -95,4 +95,32 @@ void tracking_cameraIntrinscisOptionsFromTracking(struct MovieTracking *tracking void tracking_trackingCameraFromIntrinscisOptions(struct MovieTracking *tracking, const struct libmv_CameraIntrinsicsOptions *camera_intrinsics_options); +struct libmv_TrackRegionOptions; + +void tracking_configure_tracker(const MovieTrackingTrack *track, float *mask, + struct libmv_TrackRegionOptions *options); + +struct MovieTrackingMarker *tracking_get_keyframed_marker( + struct MovieTrackingTrack *track, + int current_frame, + bool backwards); + +/*********************** Frame accessr *************************/ + +struct libmv_FrameAccessor; + +#define MAX_ACCESSOR_CLIP 64 +typedef struct TrackingImageAccessor { + struct MovieCache *cache; + struct MovieClip *clips[MAX_ACCESSOR_CLIP]; + int num_clips; + int start_frame; + struct libmv_FrameAccessor *libmv_accessor; +} TrackingImageAccessor; + +TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR_CLIP], + int num_clips, + int start_frame); +void tracking_image_accessor_destroy(TrackingImageAccessor *accessor); + #endif /* __TRACKING_PRIVATE_H__ */ diff --git a/source/blender/blenlib/BLI_bitmap.h b/source/blender/blenlib/BLI_bitmap.h index 594bf89b667..e9a828c678c 100644 --- a/source/blender/blenlib/BLI_bitmap.h +++ b/source/blender/blenlib/BLI_bitmap.h @@ -47,7 +47,7 @@ typedef unsigned int BLI_bitmap; /* size (in bytes) used to hold '_tot' bits */ #define BLI_BITMAP_SIZE(_tot) \ - (_BITMAP_NUM_BLOCKS(_tot) * sizeof(BLI_bitmap)) + ((size_t)(_BITMAP_NUM_BLOCKS(_tot)) * sizeof(BLI_bitmap)) /* allocate memory for a bitmap with '_tot' bits; free * with MEM_freeN() */ @@ -59,6 +59,11 @@ typedef unsigned int BLI_bitmap; #define BLI_BITMAP_NEW_ALLOCA(_tot) \ ((BLI_bitmap *)memset(alloca(BLI_BITMAP_SIZE(_tot)), 0, BLI_BITMAP_SIZE(_tot))) +/* Allocate using given MemArena */ +#define BLI_BITMAP_NEW_MEMARENA(_mem, _tot) \ + (CHECK_TYPE_INLINE(_mem, MemArena *), \ + ((BLI_bitmap *)BLI_memarena_calloc(_mem, BLI_BITMAP_SIZE(_tot)))) + /* get the value of a single bit at '_index' */ #define BLI_BITMAP_TEST(_bitmap, _index) \ (CHECK_TYPE_INLINE(_bitmap, BLI_bitmap *), \ diff --git a/source/blender/blenlib/BLI_callbacks.h b/source/blender/blenlib/BLI_callbacks.h index 2f963cfac51..7cf524749c2 100644 --- a/source/blender/blenlib/BLI_callbacks.h +++ b/source/blender/blenlib/BLI_callbacks.h @@ -41,6 +41,7 @@ typedef enum { BLI_CB_EVT_FRAME_CHANGE_POST, BLI_CB_EVT_RENDER_PRE, BLI_CB_EVT_RENDER_POST, + BLI_CB_EVT_RENDER_WRITE, BLI_CB_EVT_RENDER_STATS, BLI_CB_EVT_RENDER_INIT, BLI_CB_EVT_RENDER_COMPLETE, diff --git a/source/blender/blenlib/BLI_compiler_typecheck.h b/source/blender/blenlib/BLI_compiler_typecheck.h index 551569b066d..46c57772f64 100644 --- a/source/blender/blenlib/BLI_compiler_typecheck.h +++ b/source/blender/blenlib/BLI_compiler_typecheck.h @@ -51,9 +51,9 @@ })) #else -# define CHECK_TYPE(var, type) -# define CHECK_TYPE_PAIR(var_a, var_b) -# define CHECK_TYPE_PAIR_INLINE(var_a, var_b) (void)0 +# define CHECK_TYPE(var, type) { EXPR_NOP(var); }(void)0 +# define CHECK_TYPE_PAIR(var_a, var_b) { (EXPR_NOP(var_a), EXPR_NOP(var_b)); }(void)0 +# define CHECK_TYPE_PAIR_INLINE(var_a, var_b) (EXPR_NOP(var_a), EXPR_NOP(var_b)) #endif /* can be used in simple macros */ @@ -66,10 +66,15 @@ ((void)(((type)0) != (0 ? (val) : ((type)0)))) #endif -#define CHECK_TYPE_NONCONST(var) { \ - void *non_const = 0 ? (var) : NULL; \ - (void)non_const; \ -} (void)0 +#if defined(__GNUC__) || defined(__clang__) +# define CHECK_TYPE_NONCONST(var) __extension__ ({ \ + void *non_const = 0 ? (var) : NULL; \ + (void)non_const; \ +}) +#else +# define CHECK_TYPE_NONCONST(var) EXPR_NOP(var) +#endif + /** * CHECK_TYPE_ANY: handy macro, eg: diff --git a/source/blender/blenlib/BLI_edgehash.h b/source/blender/blenlib/BLI_edgehash.h index a0455489d24..ded4b163f71 100644 --- a/source/blender/blenlib/BLI_edgehash.h +++ b/source/blender/blenlib/BLI_edgehash.h @@ -26,7 +26,6 @@ /** \file BLI_edgehash.h * \ingroup bli * \author Daniel Dunbar - * \brief A general unordered 2-int pair hash table ADT. */ #include "BLI_compiler_attrs.h" @@ -55,6 +54,9 @@ bool BLI_edgehash_reinsert(EdgeHash *eh, unsigned int v0, unsigned in void *BLI_edgehash_lookup(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT; void *BLI_edgehash_lookup_default(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val_default) ATTR_WARN_UNUSED_RESULT; void **BLI_edgehash_lookup_p(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT; +bool BLI_edgehash_remove(EdgeHash *eh, unsigned int v0, unsigned int v1, EdgeHashFreeFP valfreefp); + +void *BLI_edgehash_popkey(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT; bool BLI_edgehash_haskey(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT; int BLI_edgehash_size(EdgeHash *eh) ATTR_WARN_UNUSED_RESULT; void BLI_edgehash_clear_ex(EdgeHash *eh, EdgeHashFreeFP valfreefp, diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h index af2605894e3..e9f83e786de 100644 --- a/source/blender/blenlib/BLI_ghash.h +++ b/source/blender/blenlib/BLI_ghash.h @@ -30,7 +30,6 @@ /** \file BLI_ghash.h * \ingroup bli - * \brief A general (pointer -> pointer) hash table ADT */ #include "BLI_sys_types.h" /* for bool */ @@ -41,6 +40,7 @@ extern "C" { #endif typedef unsigned int (*GHashHashFP) (const void *key); +/** returns false when equal */ typedef bool (*GHashCmpFP) (const void *a, const void *b); typedef void (*GHashKeyFreeFP) (void *key); typedef void (*GHashValFreeFP) (void *val); diff --git a/source/blender/blenlib/BLI_md5.h b/source/blender/blenlib/BLI_hash_md5.h index 6a760f53e45..544ae753793 100644 --- a/source/blender/blenlib/BLI_md5.h +++ b/source/blender/blenlib/BLI_hash_md5.h @@ -18,30 +18,26 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef __BLI_MD5_H__ -#define __BLI_MD5_H__ +#ifndef __BLI_HASH_MD5_H__ +#define __BLI_HASH_MD5_H__ -/** \file BLI_md5.h +/** \file BLI_hash_md5.h * \ingroup bli */ -#include <stdio.h> -#include <stdlib.h> - /* Compute MD5 message digest for LEN bytes beginning at BUFFER. The * result is always in little endian byte order, so that a byte-wise * output yields to the wanted ASCII representation of the message * digest. */ -void *md5_buffer(const char *buffer, size_t len, void *resblock); +void *BLI_hash_md5_buffer(const char *buffer, size_t len, void *resblock); /* Compute MD5 message digest for bytes read from STREAM. The * resulting message digest number will be written into the 16 bytes * beginning at RESBLOCK. */ -int md5_stream(FILE *stream, void *resblock); - -char *md5_to_hexdigest(void *resblock, char r_hex_digest[33]); +int BLI_hash_md5_stream(FILE *stream, void *resblock); -#endif +char *BLI_hash_md5_to_hexdigest(void *resblock, char r_hex_digest[33]); +#endif /* __BLI_HASH_MD5_H__ */ diff --git a/source/blender/blenlib/BLI_hash_mm2a.h b/source/blender/blenlib/BLI_hash_mm2a.h new file mode 100644 index 00000000000..007dec4f4d6 --- /dev/null +++ b/source/blender/blenlib/BLI_hash_mm2a.h @@ -0,0 +1,45 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BLI_HASH_MM2A_H__ +#define __BLI_HASH_MM2A_H__ + +/** \file BLI_hash_mm2a.h + * \ingroup bli + */ + +#include "BLI_sys_types.h" + +typedef struct BLI_HashMurmur2A { + uint32_t hash; + uint32_t tail; + uint32_t count; + uint32_t size; +} BLI_HashMurmur2A; + +void BLI_hash_mm2a_init(BLI_HashMurmur2A *mm2, uint32_t seed); + +void BLI_hash_mm2a_add(BLI_HashMurmur2A *mm2, const unsigned char *data, size_t len); + +void BLI_hash_mm2a_add_int(BLI_HashMurmur2A *mm2, int data); + +uint32_t BLI_hash_mm2a_end(BLI_HashMurmur2A *mm2); + +#endif /* __BLI_HASH_MM2A_H__ */ diff --git a/source/blender/blenlib/BLI_heap.h b/source/blender/blenlib/BLI_heap.h index ac9edfd46a2..ea361097b7b 100644 --- a/source/blender/blenlib/BLI_heap.h +++ b/source/blender/blenlib/BLI_heap.h @@ -37,6 +37,7 @@ typedef void (*HeapFreeFP)(void *ptr); * are recycled, so memory usage will not shrink. */ Heap *BLI_heap_new_ex(unsigned int tot_reserve) ATTR_WARN_UNUSED_RESULT; Heap *BLI_heap_new(void) ATTR_WARN_UNUSED_RESULT; +void BLI_heap_clear(Heap *heap, HeapFreeFP ptrfreefp) ATTR_NONNULL(1); void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp) ATTR_NONNULL(1); /* Insert heap node with a value (often a 'cost') and pointer into the heap, diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index fb388977ddf..2e01f743f9e 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -67,12 +67,15 @@ void *BLI_poptail(ListBase *listbase) ATTR_NONNULL(1); void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1); void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1); void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1); -void BLI_sortlist(struct ListBase *listbase, int (*cmp)(const void *, const void *)) ATTR_NONNULL(1, 2); -void BLI_sortlist_r(ListBase *listbase, void *thunk, int (*cmp)(void *, const void *, const void *)) ATTR_NONNULL(1, 3); +void BLI_listbase_sort(struct ListBase *listbase, int (*cmp)(const void *, const void *)) ATTR_NONNULL(1, 2); +void BLI_listbase_sort_r(ListBase *listbase, void *thunk, int (*cmp)(void *, const void *, const void *)) ATTR_NONNULL(1, 3); void BLI_freelist(struct ListBase *listbase) ATTR_NONNULL(1); -int BLI_countlist(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +int BLI_listbase_count_ex(const struct ListBase *listbase, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1); +void BLI_listbase_swaplinks(struct ListBase *listbase, void *vlinka, void *vlinkb) ATTR_NONNULL(1, 2); + void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL(1, 2); void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1, 2); void BLI_listbase_reverse(struct ListBase *lb) ATTR_NONNULL(1); diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h index 07de074e717..13718e83621 100644 --- a/source/blender/blenlib/BLI_math_base.h +++ b/source/blender/blenlib/BLI_math_base.h @@ -48,13 +48,16 @@ #define M_PI_2 1.57079632679489661923 #endif #ifndef M_SQRT2 -#define M_SQRT2 1.41421356237309504880 +#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ #endif #ifndef M_SQRT1_2 -#define M_SQRT1_2 0.70710678118654752440 +#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ #endif #ifndef M_SQRT3 -#define M_SQRT3 1.7320508075688772 +#define M_SQRT3 1.73205080756887729352 /* sqrt(3) */ +#endif +#ifndef M_SQRT1_3 +#define M_SQRT1_3 0.57735026918962576450 /* 1/sqrt(3) */ #endif #ifndef M_1_PI #define M_1_PI 0.318309886183790671538 @@ -157,6 +160,11 @@ static const int NAN_INT = 0x7FC00000; /******************************* Float ******************************/ +MINLINE float pow2f(float x); +MINLINE float pow3f(float x); +MINLINE float pow4f(float x); +MINLINE float pow7f(float x); + MINLINE float sqrt3f(float f); MINLINE double sqrt3d(double d); diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index ba32b29becc..32678bdf680 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -77,6 +77,7 @@ float volume_tetrahedron_signed_v3(const float v1[3], const float v2[3], const f bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]); bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]); bool is_poly_convex_v2(const float verts[][2], unsigned int nr); +int is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]); /********************************* Distance **********************************/ diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index 732f4b66f38..45972d03175 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -125,7 +125,8 @@ void mul_m3_fl(float R[3][3], float f); void mul_m4_fl(float R[4][4], float f); void mul_mat3_m4_fl(float R[4][4], float f); -void negate_m3(float R[4][4]); +void negate_m3(float R[3][3]); +void negate_mat3_m4(float R[4][4]); void negate_m4(float R[4][4]); bool invert_m3_ex(float m[3][3], const float epsilon); @@ -144,7 +145,10 @@ void mul_v4d_m4v4d(double r[4], float M[4][4], double v[4]); /****************************** Linear Algebra *******************************/ void transpose_m3(float R[3][3]); +void transpose_m3_m3(float R[3][3], float A[3][3]); +void transpose_m3_m4(float R[3][3], float A[4][4]); void transpose_m4(float R[4][4]); +void transpose_m4_m4(float R[4][4], float A[4][4]); int compare_m4m4(float mat1[4][4], float mat2[4][4], float limit); diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h index 3d82480d050..bade390d056 100644 --- a/source/blender/blenlib/BLI_path_util.h +++ b/source/blender/blenlib/BLI_path_util.h @@ -40,40 +40,6 @@ extern "C" { struct ListBase; struct direntry; -const char *BLI_getDefaultDocumentFolder(void); - -const char *BLI_get_folder(int folder_id, const char *subfolder); -const char *BLI_get_folder_create(int folder_id, const char *subfolder); -const char *BLI_get_user_folder_notest(int folder_id, const char *subfolder); -const char *BLI_get_folder_version(const int id, const int ver, const bool do_check); - -/* folder_id */ - -/* general, will find based on user/local/system priority */ -#define BLENDER_DATAFILES 2 - -/* user-specific */ -#define BLENDER_USER_CONFIG 31 -#define BLENDER_USER_DATAFILES 32 -#define BLENDER_USER_SCRIPTS 33 -#define BLENDER_USER_AUTOSAVE 34 - -/* system */ -#define BLENDER_SYSTEM_DATAFILES 52 -#define BLENDER_SYSTEM_SCRIPTS 53 -#define BLENDER_SYSTEM_PYTHON 54 - -/* for BLI_get_folder_version only */ -#define BLENDER_RESOURCE_PATH_USER 0 -#define BLENDER_RESOURCE_PATH_LOCAL 1 -#define BLENDER_RESOURCE_PATH_SYSTEM 2 - -#define BLENDER_STARTUP_FILE "startup.blend" -#define BLENDER_USERPREF_FILE "userpref.blend" -#define BLENDER_QUIT_FILE "quit.blend" -#define BLENDER_BOOKMARK_FILE "bookmarks.txt" -#define BLENDER_HISTORY_FILE "recent-files.txt" - #ifdef WIN32 #define SEP '\\' #define ALTSEP '/' @@ -185,19 +151,6 @@ bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char void BLI_char_switch(char *string, char from, char to) ATTR_NONNULL(); -/* Initialize path to program executable */ -void BLI_init_program_path(const char *argv0); -/* Initialize path to temporary directory. - * NOTE: On Window userdir will be set to the temporary directory! */ -void BLI_temp_dir_init(char *userdir); - -const char *BLI_program_path(void); -const char *BLI_program_dir(void); -const char *BLI_temp_dir_session(void); -const char *BLI_temp_dir_base(void); -void BLI_system_temporary_dir(char *dir); -void BLI_temp_dir_session_purge(void); - #ifdef WITH_ICONV void BLI_string_to_utf8(char *original, char *utf_8, const char *code); #endif diff --git a/source/blender/blenlib/BLI_polyfill2d.h b/source/blender/blenlib/BLI_polyfill2d.h index 5c5cea8f67d..798055f9240 100644 --- a/source/blender/blenlib/BLI_polyfill2d.h +++ b/source/blender/blenlib/BLI_polyfill2d.h @@ -37,4 +37,7 @@ void BLI_polyfill_calc( const int coords_sign, unsigned int (*r_tris)[3]); +/* default size of polyfill arena */ +#define BLI_POLYFILL_ARENA_SIZE MEM_SIZE_OPTIMAL(1 << 14) + #endif /* __BLI_POLYFILL2D_H__ */ diff --git a/source/blender/blenlib/BLI_polyfill2d_beautify.h b/source/blender/blenlib/BLI_polyfill2d_beautify.h new file mode 100644 index 00000000000..c3bb29af21e --- /dev/null +++ b/source/blender/blenlib/BLI_polyfill2d_beautify.h @@ -0,0 +1,39 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BLI_POLYFILL2D_BEAUTIFY_H__ +#define __BLI_POLYFILL2D_BEAUTIFY_H__ + +struct EdgeHash; +struct Heap; +struct MemArena; + +void BLI_polyfill_beautify( + const float (*coords)[2], + const unsigned int coords_tot, + unsigned int (*tris)[3], + + /* structs for reuse */ + struct MemArena *arena, struct Heap *eheap, struct EdgeHash *eh); + +/* avoid realloc's when creating new structures for polyfill ngons */ +#define BLI_POLYFILL_ALLOC_NGON_RESERVE 64 + +#endif /* __BLI_POLYFILL2D_BEAUTIFY_H__ */ diff --git a/source/blender/blenlib/BLI_smallhash.h b/source/blender/blenlib/BLI_smallhash.h index b80044bccff..e096354e5b1 100644 --- a/source/blender/blenlib/BLI_smallhash.h +++ b/source/blender/blenlib/BLI_smallhash.h @@ -52,7 +52,7 @@ typedef struct SmallHash { } SmallHash; typedef struct { - SmallHash *sh; + const SmallHash *sh; unsigned int i; } SmallHashIter; @@ -61,13 +61,16 @@ void BLI_smallhash_init_ex(SmallHash *sh, void BLI_smallhash_init(SmallHash *sh) ATTR_NONNULL(1); void BLI_smallhash_release(SmallHash *sh) ATTR_NONNULL(1); void BLI_smallhash_insert(SmallHash *sh, uintptr_t key, void *item) ATTR_NONNULL(1); +bool BLI_smallhash_reinsert(SmallHash *sh, uintptr_t key, void *item) ATTR_NONNULL(1); bool BLI_smallhash_remove(SmallHash *sh, uintptr_t key) ATTR_NONNULL(1); -void *BLI_smallhash_lookup(SmallHash *sh, uintptr_t key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; -void **BLI_smallhash_lookup_p(SmallHash *sh, uintptr_t key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; -bool BLI_smallhash_haskey(SmallHash *sh, uintptr_t key) ATTR_NONNULL(1); -int BLI_smallhash_count(SmallHash *sh) ATTR_NONNULL(1); +void *BLI_smallhash_lookup(const SmallHash *sh, uintptr_t key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; +void **BLI_smallhash_lookup_p(const SmallHash *sh, uintptr_t key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; +bool BLI_smallhash_haskey(const SmallHash *sh, uintptr_t key) ATTR_NONNULL(1); +int BLI_smallhash_count(const SmallHash *sh) ATTR_NONNULL(1); void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; -void *BLI_smallhash_iternew(SmallHash *sh, SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; +void **BLI_smallhash_iternext_p(SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; +void *BLI_smallhash_iternew(const SmallHash *sh, SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; +void **BLI_smallhash_iternew_p(const SmallHash *sh, SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; /* void BLI_smallhash_print(SmallHash *sh); */ /* UNUSED */ #ifdef DEBUG diff --git a/source/blender/blenlib/BLI_sort.h b/source/blender/blenlib/BLI_sort.h index 516f917a351..cb6b87bda38 100644 --- a/source/blender/blenlib/BLI_sort.h +++ b/source/blender/blenlib/BLI_sort.h @@ -35,7 +35,8 @@ #include <stdlib.h> -#ifdef __GLIBC__ +/* glibc 2.8+ */ +#if defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)) # define BLI_qsort_r qsort_r #endif diff --git a/source/blender/blenlib/BLI_system.h b/source/blender/blenlib/BLI_system.h index 8cdc9e4e6c5..cb8cb6f5a0d 100644 --- a/source/blender/blenlib/BLI_system.h +++ b/source/blender/blenlib/BLI_system.h @@ -27,6 +27,10 @@ int BLI_cpu_support_sse2(void); +#if defined(NDEBUG) || !defined(__BLI_UTILDEFINES_H__) +void BLI_system_backtrace(FILE *fp); +#endif + /* getpid */ #ifdef WIN32 # define BLI_SYSTEM_PID_H <process.h> @@ -35,4 +39,3 @@ int BLI_cpu_support_sse2(void); #endif #endif /* __BLI_SYSTEM_H__ */ - diff --git a/source/blender/blenlib/BLI_task.h b/source/blender/blenlib/BLI_task.h index c9cbaf997fb..8f85bc4ec31 100644 --- a/source/blender/blenlib/BLI_task.h +++ b/source/blender/blenlib/BLI_task.h @@ -88,6 +88,9 @@ void BLI_task_pool_cancel(TaskPool *pool); /* stop all worker threads */ void BLI_task_pool_stop(TaskPool *pool); +/* set number of threads allowed to be used by this pool */ +void BLI_pool_set_num_threads(TaskPool *pool, int num_threads); + /* for worker threads, test if canceled */ bool BLI_task_pool_canceled(TaskPool *pool); @@ -100,6 +103,19 @@ ThreadMutex *BLI_task_pool_user_mutex(TaskPool *pool); /* number of tasks done, for stats, don't use this to make decisions */ size_t BLI_task_pool_tasks_done(TaskPool *pool); +/* Parallel for routines */ +typedef void (*TaskParallelRangeFunc)(void *userdata, int iter); +void BLI_task_parallel_range_ex( + int start, int stop, + void *userdata, + TaskParallelRangeFunc func, + const int range_threshold, + const bool use_dynamic_scheduling); +void BLI_task_parallel_range( + int start, int stop, + void *userdata, + TaskParallelRangeFunc func); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index 736578361b3..53896bb31b6 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -32,6 +32,10 @@ * \ingroup bli */ +#ifdef __cplusplus +extern "C" { +#endif + /* avoid many includes for now */ #include "BLI_sys_types.h" #include "BLI_compiler_compat.h" @@ -51,7 +55,7 @@ _49_, _50_, _51_, _52_, _53_, _54_, _55_, _56_, _57_, _58_, _59_, _60_, _61_, _62_, _63_, _64_, \ count, ...) count #define _VA_NARGS_EXPAND(args) _VA_NARGS_RETURN_COUNT args -#define _VA_NARGS_COUNT_MAX32(...) _VA_NARGS_EXPAND((__VA_ARGS__, \ +#define _VA_NARGS_COUNT_MAX64(...) _VA_NARGS_EXPAND((__VA_ARGS__, \ 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, \ 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, \ 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, \ @@ -61,7 +65,7 @@ #define _VA_NARGS_OVERLOAD_MACRO(name, count) _VA_NARGS_OVERLOAD_MACRO1(name, count) /* --- expose for re-use --- */ #define VA_NARGS_CALL_OVERLOAD(name, ...) \ - _VA_NARGS_GLUE(_VA_NARGS_OVERLOAD_MACRO(name, _VA_NARGS_COUNT_MAX32(__VA_ARGS__)), (__VA_ARGS__)) + _VA_NARGS_GLUE(_VA_NARGS_OVERLOAD_MACRO(name, _VA_NARGS_COUNT_MAX64(__VA_ARGS__)), (__VA_ARGS__)) /* useful for finding bad use of min/max */ #if 0 @@ -179,8 +183,10 @@ /* ELEM#(v, ...): is the first arg equal any others? */ /* internal helpers*/ +#define _VA_ELEM2(v, a) \ + ((v) == (a)) #define _VA_ELEM3(v, a, b) \ - (((v) == (a)) || ((v) == (b))) + (_VA_ELEM2(v, a) || ((v) == (b))) #define _VA_ELEM4(v, a, b, c) \ (_VA_ELEM3(v, a, b) || ((v) == (c))) #define _VA_ELEM5(v, a, b, c, d) \ @@ -213,6 +219,8 @@ /* reusable ELEM macro */ #define ELEM(...) VA_NARGS_CALL_OVERLOAD(_VA_ELEM, __VA_ARGS__) +/* no-op for expressions we don't want to instansiate, but must remian valid */ +#define EXPR_NOP(expr) (void)(0 ? ((void)(expr), 1) : 0) /* shift around elements */ #define SHIFT3(type, a, b, c) { \ @@ -335,6 +343,60 @@ if ((a) < (b)) (a) = (b); \ } (void)0 +#define CLAMP2(vec, b, c) { \ + CLAMP((vec)[0], b, c); \ + CLAMP((vec)[1], b, c); \ +} (void)0 + +#define CLAMP2_MIN(vec, b) { \ + CLAMP_MIN((vec)[0], b); \ + CLAMP_MIN((vec)[1], b); \ +} (void)0 + +#define CLAMP2_MAX(vec, b) { \ + CLAMP_MAX((vec)[0], b); \ + CLAMP_MAX((vec)[1], b); \ +} (void)0 + +#define CLAMP3(vec, b, c) { \ + CLAMP((vec)[0], b, c); \ + CLAMP((vec)[1], b, c); \ + CLAMP((vec)[2], b, c); \ +} (void)0 + +#define CLAMP3_MIN(vec, b) { \ + CLAMP_MIN((vec)[0], b); \ + CLAMP_MIN((vec)[1], b); \ + CLAMP_MIN((vec)[2], b); \ +} (void)0 + +#define CLAMP3_MAX(vec, b) { \ + CLAMP_MAX((vec)[0], b); \ + CLAMP_MAX((vec)[1], b); \ + CLAMP_MAX((vec)[2], b); \ +} (void)0 + +#define CLAMP4(vec, b, c) { \ + CLAMP((vec)[0], b, c); \ + CLAMP((vec)[1], b, c); \ + CLAMP((vec)[2], b, c); \ + CLAMP((vec)[3], b, c); \ +} (void)0 + +#define CLAMP4_MIN(vec, b) { \ + CLAMP_MIN((vec)[0], b); \ + CLAMP_MIN((vec)[1], b); \ + CLAMP_MIN((vec)[2], b); \ + CLAMP_MIN((vec)[3], b); \ +} (void)0 + +#define CLAMP4_MAX(vec, b) { \ + CLAMP_MAX((vec)[0], b); \ + CLAMP_MAX((vec)[1], b); \ + CLAMP_MAX((vec)[2], b); \ + CLAMP_MAX((vec)[3], b); \ +} (void)0 + #define IS_EQ(a, b) ( \ CHECK_TYPE_INLINE(a, double), CHECK_TYPE_INLINE(b, double), \ ((fabs((double)((a) - (b))) >= (double) FLT_EPSILON) ? false : true)) @@ -437,6 +499,56 @@ # define UNUSED_FUNCTION(x) UNUSED_ ## x #endif +/** + * UNUSED_VARS#(a, ...): quiet unused warnings + * + * <pre> + * for i in range(16): + * args = [(chr(ord('a') + (c % 26)) + (chr(ord('0') + (c // 26)))) for c in range(i + 1)] + * print("#define _VA_UNUSED_VARS_%d(%s) \\" % (i + 1, ", ".join(args))) + * print("\t((void)(%s)%s)" % + * (args[0], ((", _VA_UNUSED_VARS_" + str(i) + "(%s)") if i else "%s") % ", ".join((args[1:])))) + * </pre> + * + */ + +#define _VA_UNUSED_VARS_1(a0) \ + ((void)(a0)) +#define _VA_UNUSED_VARS_2(a0, b0) \ + ((void)(a0), _VA_UNUSED_VARS_1(b0)) +#define _VA_UNUSED_VARS_3(a0, b0, c0) \ + ((void)(a0), _VA_UNUSED_VARS_2(b0, c0)) +#define _VA_UNUSED_VARS_4(a0, b0, c0, d0) \ + ((void)(a0), _VA_UNUSED_VARS_3(b0, c0, d0)) +#define _VA_UNUSED_VARS_5(a0, b0, c0, d0, e0) \ + ((void)(a0), _VA_UNUSED_VARS_4(b0, c0, d0, e0)) +#define _VA_UNUSED_VARS_6(a0, b0, c0, d0, e0, f0) \ + ((void)(a0), _VA_UNUSED_VARS_5(b0, c0, d0, e0, f0)) +#define _VA_UNUSED_VARS_7(a0, b0, c0, d0, e0, f0, g0) \ + ((void)(a0), _VA_UNUSED_VARS_6(b0, c0, d0, e0, f0, g0)) +#define _VA_UNUSED_VARS_8(a0, b0, c0, d0, e0, f0, g0, h0) \ + ((void)(a0), _VA_UNUSED_VARS_7(b0, c0, d0, e0, f0, g0, h0)) +#define _VA_UNUSED_VARS_9(a0, b0, c0, d0, e0, f0, g0, h0, i0) \ + ((void)(a0), _VA_UNUSED_VARS_8(b0, c0, d0, e0, f0, g0, h0, i0)) +#define _VA_UNUSED_VARS_10(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0) \ + ((void)(a0), _VA_UNUSED_VARS_9(b0, c0, d0, e0, f0, g0, h0, i0, j0)) +#define _VA_UNUSED_VARS_11(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0) \ + ((void)(a0), _VA_UNUSED_VARS_10(b0, c0, d0, e0, f0, g0, h0, i0, j0, k0)) +#define _VA_UNUSED_VARS_12(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0) \ + ((void)(a0), _VA_UNUSED_VARS_11(b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0)) +#define _VA_UNUSED_VARS_13(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0) \ + ((void)(a0), _VA_UNUSED_VARS_12(b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0)) +#define _VA_UNUSED_VARS_14(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0) \ + ((void)(a0), _VA_UNUSED_VARS_13(b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0)) +#define _VA_UNUSED_VARS_15(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0) \ + ((void)(a0), _VA_UNUSED_VARS_14(b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0)) +#define _VA_UNUSED_VARS_16(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0) \ + ((void)(a0), _VA_UNUSED_VARS_15(b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0)) + + +/* reusable ELEM macro */ +#define UNUSED_VARS(...) VA_NARGS_CALL_OVERLOAD(_VA_UNUSED_VARS_, __VA_ARGS__) + /*little macro so inline keyword works*/ #if defined(_MSC_VER) # define BLI_INLINE static __forceinline @@ -454,6 +566,7 @@ * for aborting need to define WITH_ASSERT_ABORT */ #ifndef NDEBUG +extern void BLI_system_backtrace(FILE *fp); # ifdef WITH_ASSERT_ABORT # define _BLI_DUMMY_ABORT abort # else @@ -463,6 +576,7 @@ # define BLI_assert(a) \ (void)((!(a)) ? ( \ ( \ + BLI_system_backtrace(stderr), \ fprintf(stderr, \ "BLI_assert failed: %s:%d, %s(), at \'%s\'\n", \ __FILE__, __LINE__, __func__, STRINGIFY(a)), \ @@ -502,4 +616,8 @@ # define UNLIKELY(x) (x) #endif +#ifdef __cplusplus +} +#endif + #endif /* __BLI_UTILDEFINES_H__ */ diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 9efa20da13e..c8f0e1bf26b 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -29,8 +29,8 @@ set(INC . # ../blenkernel # dont add this back! ../makesdna - ../../../intern/ghost ../../../intern/guardedalloc + ../../../intern/atomic ../../../extern/wcwidth ) @@ -65,6 +65,8 @@ set(SRC intern/freetypefont.c intern/graph.c intern/gsqueue.c + intern/hash_md5.c + intern/hash_mm2a.c intern/jitter.c intern/lasso.c intern/listbase.c @@ -80,10 +82,10 @@ set(SRC intern/math_rotation.c intern/math_vector.c intern/math_vector_inline.c - intern/md5.c intern/noise.c intern/path_util.c intern/polyfill2d.c + intern/polyfill2d_beautify.c intern/quadric.c intern/rand.c intern/rct.c @@ -134,6 +136,8 @@ set(SRC BLI_ghash.h BLI_graph.h BLI_gsqueue.h + BLI_hash_md5.h + BLI_hash_mm2a.h BLI_heap.h BLI_jitter.h BLI_kdopbvh.h @@ -153,12 +157,12 @@ set(SRC BLI_math_matrix.h BLI_math_rotation.h BLI_math_vector.h - BLI_md5.h BLI_memarena.h BLI_mempool.h BLI_noise.h BLI_path_util.h BLI_polyfill2d.h + BLI_polyfill2d_beautify.h BLI_quadric.h BLI_rand.h BLI_rect.h @@ -187,13 +191,6 @@ set(SRC PIL_time_utildefines.h ) -if(WITH_BINRELOC) - list(APPEND INC_SYS - ${BINRELOC_INCLUDE_DIRS} - ) - add_definitions(-DWITH_BINRELOC) -endif() - if(WITH_MEM_VALGRIND) add_definitions(-DWITH_MEM_VALGRIND) endif() diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript index b712d2032bf..8b4054e00b5 100644 --- a/source/blender/blenlib/SConscript +++ b/source/blender/blenlib/SConscript @@ -34,8 +34,8 @@ cflags='' incs = [ '.', '#/extern/wcwidth', - '#/intern/ghost', '#/intern/guardedalloc', + '#/intern/atomic', '../makesdna', env['BF_FREETYPE_INC'], env['BF_ZLIB_INC'], @@ -44,10 +44,6 @@ incs = ' '.join(incs) defs = [] -if env['WITH_BF_BINRELOC']: - incs += ' ../../../extern/binreloc/include' - defs.append('WITH_BINRELOC') - if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'): incs += ' ' + env['BF_PTHREADS_INC'] incs += ' ../../../intern/utfconv' diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index 6747e5c4e7e..c87b60f08db 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -28,7 +28,8 @@ /** \file blender/blenlib/intern/BLI_ghash.c * \ingroup bli * - * A general (pointer -> pointer) hash table ADT + * A general (pointer -> pointer) chaining hash table + * for 'Abstract Data Types' (known as an ADT Hash Table). * * \note edgehash.c is based on this, make sure they stay in sync. */ diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c index 55dee4e8677..66dfa87b7b9 100644 --- a/source/blender/blenlib/intern/BLI_heap.c +++ b/source/blender/blenlib/intern/BLI_heap.c @@ -49,7 +49,6 @@ struct Heap { unsigned int bufsize; MemArena *arena; HeapNode *freenodes; - HeapNode *nodes; HeapNode **tree; }; @@ -139,9 +138,9 @@ Heap *BLI_heap_new(void) void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp) { - unsigned int i; - if (ptrfreefp) { + unsigned int i; + for (i = 0; i < heap->size; i++) { ptrfreefp(heap->tree[i]->ptr); } @@ -152,6 +151,21 @@ void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp) MEM_freeN(heap); } +void BLI_heap_clear(Heap *heap, HeapFreeFP ptrfreefp) +{ + if (ptrfreefp) { + unsigned int i; + + for (i = 0; i < heap->size; i++) { + ptrfreefp(heap->tree[i]->ptr); + } + } + + heap->size = 0; + BLI_memarena_clear(heap->arena); + heap->freenodes = NULL; +} + HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr) { HeapNode *node; @@ -163,7 +177,7 @@ HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr) if (heap->freenodes) { node = heap->freenodes; - heap->freenodes = (HeapNode *)(((HeapNode *)heap->freenodes)->ptr); + heap->freenodes = heap->freenodes->ptr; } else { node = (HeapNode *)BLI_memarena_alloc(heap->arena, sizeof(*node)); @@ -206,13 +220,8 @@ void *BLI_heap_popmin(Heap *heap) heap->tree[0]->ptr = heap->freenodes; heap->freenodes = heap->tree[0]; - if (UNLIKELY(heap->size == 1)) { - heap->size--; - } - else { - heap_swap(heap, 0, heap->size - 1); - heap->size--; - + if (--heap->size) { + heap_swap(heap, 0, heap->size); heap_down(heap, 0); } diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index d28215ee8ed..b76b925e6cc 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -986,7 +986,7 @@ bool BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const /* check if index exists */ if (index > tree->totleaf) - return 0; + return false; node = tree->nodearray + index; @@ -1001,7 +1001,7 @@ bool BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const node->bv[(2 * axis_iter) + 1] += tree->epsilon; /* maximum */ } - return 1; + return true; } /* call BLI_bvhtree_update_node() first for every node/point/triangle */ diff --git a/source/blender/blenlib/intern/BLI_linklist.c b/source/blender/blenlib/intern/BLI_linklist.c index a0b61e7945c..6b79cf97e86 100644 --- a/source/blender/blenlib/intern/BLI_linklist.c +++ b/source/blender/blenlib/intern/BLI_linklist.c @@ -32,6 +32,8 @@ #include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" #include "BLI_linklist.h" #include "BLI_memarena.h" #include "BLI_mempool.h" @@ -96,7 +98,7 @@ void BLI_linklist_prepend_nlink(LinkNode **listp, void *ptr, LinkNode *nlink) void BLI_linklist_prepend(LinkNode **listp, void *ptr) { - LinkNode *nlink = MEM_mallocN(sizeof(*nlink), "nlink"); + LinkNode *nlink = MEM_mallocN(sizeof(*nlink), __func__); BLI_linklist_prepend_nlink(listp, ptr, nlink); } @@ -135,7 +137,7 @@ void BLI_linklist_append_nlink(LinkNode **listp, void *ptr, LinkNode *nlink) void BLI_linklist_append(LinkNode **listp, void *ptr) { - LinkNode *nlink = MEM_mallocN(sizeof(*nlink), "nlink"); + LinkNode *nlink = MEM_mallocN(sizeof(*nlink), __func__); BLI_linklist_append_nlink(listp, ptr, nlink); } @@ -177,7 +179,7 @@ void *BLI_linklist_pop_pool(struct LinkNode **listp, struct BLI_mempool *mempool void BLI_linklist_insert_after(LinkNode **listp, void *ptr) { - LinkNode *nlink = MEM_mallocN(sizeof(*nlink), "nlink"); + LinkNode *nlink = MEM_mallocN(sizeof(*nlink), __func__); LinkNode *node = *listp; nlink->link = ptr; diff --git a/source/blender/blenlib/intern/convexhull2d.c b/source/blender/blenlib/intern/convexhull2d.c index 361e4b4eadb..5f64088f433 100644 --- a/source/blender/blenlib/intern/convexhull2d.c +++ b/source/blender/blenlib/intern/convexhull2d.c @@ -187,8 +187,8 @@ static int pointref_cmp_yx(const void *a_, const void *b_) * \param points An array of 2D points. * \param n The number of points in points. * \param r_points An array of the convex hull vertex indices (max is n). - * _must_ be allocated as ``n * 2`` because of how its used internally, - * even though the final result will be no more then \a n in size. + * _must_ be allocated as ``n * 2`` because of how its used internally, + * even though the final result will be no more than \a n in size. * \returns the number of points in r_points. */ int BLI_convexhull_2d(const float (*points)[2], const int n, int r_points[]) diff --git a/source/blender/blenlib/intern/easing.c b/source/blender/blenlib/intern/easing.c index 80f02d54eaa..90c8528338e 100644 --- a/source/blender/blenlib/intern/easing.c +++ b/source/blender/blenlib/intern/easing.c @@ -139,7 +139,7 @@ float BLI_easing_cubic_ease_in_out(float time, float begin, float change, float #ifdef USE_ELASTIC_BLEND /** - * When the amplitude is less then the change, we need to blend + * When the amplitude is less than the change, we need to blend * \a f when we're close to the crossing point (int time), else we get an ugly sharp falloff. */ static float elastic_blend(float time, float change, float duration, float amplitude, float s, float f) diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c index 4ed82f8a473..82d57dad753 100644 --- a/source/blender/blenlib/intern/edgehash.c +++ b/source/blender/blenlib/intern/edgehash.c @@ -23,12 +23,13 @@ /** \file blender/blenlib/intern/edgehash.c * \ingroup bli * - * A general (pointer -> pointer) hash table ADT + * An (edge -> pointer) chaining hash table. + * Using unordered int-pairs as keys. * - * \note Based on 'BLI_ghash.c', make sure these stay in sync. + * \note Based on 'BLI_ghash.c', which is a more generalized hash-table + * make sure these stay in sync. */ - #include <stdlib.h> #include <string.h> #include <limits.h> @@ -146,7 +147,7 @@ BLI_INLINE void edgehash_buckets_reserve(EdgeHash *eh, const unsigned int nentri /** * Internal lookup function. - * Takes a hash argument to avoid calling #ghash_keyhash multiple times. + * Takes a hash argument to avoid calling #edgehash_keyhash multiple times. */ BLI_INLINE EdgeEntry *edgehash_lookup_entry_ex(EdgeHash *eh, unsigned int v0, unsigned int v1, const unsigned int hash) @@ -256,6 +257,35 @@ BLI_INLINE void edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1, } /** + * Remove the entry and return it, caller must free from eh->epool. + */ +static EdgeEntry *edgehash_remove_ex(EdgeHash *eh, unsigned int v0, unsigned int v1, EdgeHashFreeFP valfreefp, + unsigned int hash) +{ + EdgeEntry *e; + EdgeEntry *e_prev = NULL; + + BLI_assert(v0 < v1); + + for (e = eh->buckets[hash]; e; e = e->next) { + if (UNLIKELY(v0 == e->v0 && v1 == e->v1)) { + EdgeEntry *e_next = e->next; + + if (valfreefp) valfreefp(e->val); + + if (e_prev) e_prev->next = e_next; + else eh->buckets[hash] = e_next; + + eh->nentries--; + return e; + } + e_prev = e; + } + + return NULL; +} + +/** * Run free callbacks for freeing entries. */ static void edgehash_free_cb(EdgeHash *eh, EdgeHashFreeFP valfreefp) @@ -366,6 +396,57 @@ void *BLI_edgehash_lookup_default(EdgeHash *eh, unsigned int v0, unsigned int v1 } /** + * Remove \a key from \a eh, or return false if the key wasn't found. + * + * \param key The key to remove. + * \param valfreefp Optional callback to free the value. + * \return true if \a key was removed from \a eh. + */ +bool BLI_edgehash_remove(EdgeHash *eh, unsigned int v0, unsigned int v1, EdgeHashFreeFP valfreefp) +{ + unsigned int hash; + EdgeEntry *e; + + EDGE_ORD(v0, v1); /* ensure v0 is smaller */ + hash = edgehash_keyhash(eh, v0, v1); + e = edgehash_remove_ex(eh, v0, v1, valfreefp, hash); + if (e) { + BLI_mempool_free(eh->epool, e); + return true; + } + else { + return false; + } +} + +/* same as above but return the value, + * no free value argument since it will be returned */ +/** + * Remove \a key from \a eh, returning the value or NULL if the key wasn't found. + * + * \param key The key to remove. + * \return the value of \a key int \a eh or NULL. + */ +void *BLI_edgehash_popkey(EdgeHash *eh, unsigned int v0, unsigned int v1) +{ + unsigned int hash; + EdgeEntry *e; + + EDGE_ORD(v0, v1); /* ensure v0 is smaller */ + hash = edgehash_keyhash(eh, v0, v1); + e = edgehash_remove_ex(eh, v0, v1, NULL, hash); + IS_EDGEHASH_ASSERT(eh); + if (e) { + void *val = e->val; + BLI_mempool_free(eh->epool, e); + return val; + } + else { + return NULL; + } +} + +/** * Return boolean true/false if edge (v0,v1) in hash. */ bool BLI_edgehash_haskey(EdgeHash *eh, unsigned int v0, unsigned int v1) @@ -404,6 +485,14 @@ void BLI_edgehash_clear_ex(EdgeHash *eh, EdgeHashFreeFP valfreefp, BLI_mempool_clear_ex(eh->epool, nentries_reserve ? (int)nentries_reserve : -1); } +/** + * Wraps #BLI_edgehash_clear_ex with zero entries reserved. + */ +void BLI_edgehash_clear(EdgeHash *eh, EdgeHashFreeFP valfreefp) +{ + BLI_edgehash_clear_ex(eh, valfreefp, 0); +} + void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP valfreefp) { BLI_assert((int)eh->nentries == BLI_mempool_count(eh->epool)); @@ -440,7 +529,7 @@ void BLI_edgehash_flag_clear(EdgeHash *eh, unsigned int flag) /** * Create a new EdgeHashIterator. The hash table must not be mutated * while the iterator is in use, and the iterator will step exactly - * BLI_edgehash_size(gh) times before becoming done. + * BLI_edgehash_size(eh) times before becoming done. */ EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh) { diff --git a/source/blender/blenlib/intern/graph.c b/source/blender/blenlib/intern/graph.c index d4d87dfdbf6..81cc9fde01f 100644 --- a/source/blender/blenlib/intern/graph.c +++ b/source/blender/blenlib/intern/graph.c @@ -170,11 +170,11 @@ bool BLI_hasAdjacencyList(BGraph *graph) for (node = graph->nodes.first; node; node = node->next) { if (node->arcs == NULL) { - return 0; + return false; } } - return 1; + return true; } void BLI_replaceNodeInArc(BGraph *graph, BArc *arc, BNode *node_src, BNode *node_replaced) @@ -337,7 +337,7 @@ static bool detectCycle(BNode *node, BArc *src_arc) } } else { - value = 1; + value = true; } return value; @@ -354,7 +354,7 @@ bool BLI_isGraphCyclic(BGraph *graph) BLI_flagNodes(graph, 0); /* detectCycles in subgraphs */ - for (node = graph->nodes.first; node && value == 0; node = node->next) { + for (node = graph->nodes.first; node && value == false; node = node->next) { /* only for nodes in subgraphs that haven't been visited yet */ if (node->flag == 0) { value = value || detectCycle(node, NULL); diff --git a/source/blender/blenlib/intern/md5.c b/source/blender/blenlib/intern/hash_md5.c index 3d1a9cdb7a4..4eec38278e9 100644 --- a/source/blender/blenlib/intern/md5.c +++ b/source/blender/blenlib/intern/hash_md5.c @@ -22,20 +22,20 @@ * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>. */ -/** \file blender/blenlib/intern/md5.c +/** \file blender/blenlib/intern/hash_md5.c * \ingroup bli * * Functions to compute MD5 message digest of files or memory blocks * according to the definition of MD5 in RFC 1321 from April 1992. */ -#include "BLI_md5.h" /* own include */ - #include <stdlib.h> #include <string.h> #include <stdio.h> #include <sys/types.h> +#include "BLI_hash_md5.h" /* own include */ + #if defined HAVE_LIMITS_H || defined _LIBC # include <limits.h> #endif @@ -77,7 +77,8 @@ #endif -/* Following code is low level, upon which are built up the functions 'md5_stream' and 'md5_buffer'. */ +/* Following code is low level, upon which are built up the functions + * 'BLI_hash_md5_stream' and 'BLI_hash_md5_buffer'. */ /* Structure to save state of computation between the single steps. */ struct md5_ctx @@ -284,7 +285,7 @@ static void *md5_read_ctx(const struct md5_ctx *ctx, void *resbuf) * The resulting message digest number will be written into the 16 bytes beginning at 'resblock'. * \return Non-zero if an error occurred. */ -int md5_stream(FILE *stream, void *resblock) +int BLI_hash_md5_stream(FILE *stream, void *resblock) { #define BLOCKSIZE 4096 /* Important: must be a multiple of 64. */ struct md5_ctx ctx; @@ -356,7 +357,7 @@ int md5_stream(FILE *stream, void *resblock) * The result is always in little endian byte order, so that a byte-wise output yields to the wanted * ASCII representation of the message digest. */ -void *md5_buffer(const char *buffer, size_t len, void *resblock) +void *BLI_hash_md5_buffer(const char *buffer, size_t len, void *resblock) { struct md5_ctx ctx; char restbuf[64 + 72]; @@ -390,7 +391,7 @@ void *md5_buffer(const char *buffer, size_t len, void *resblock) return md5_read_ctx(&ctx, resblock); } -char *md5_to_hexdigest(void *resblock, char r_hex_digest[33]) +char *BLI_hash_md5_to_hexdigest(void *resblock, char r_hex_digest[33]) { static const char hex_map[17] = "0123456789abcdef"; const unsigned char *p; diff --git a/source/blender/blenlib/intern/hash_mm2a.c b/source/blender/blenlib/intern/hash_mm2a.c new file mode 100644 index 00000000000..8b4242fa5be --- /dev/null +++ b/source/blender/blenlib/intern/hash_mm2a.c @@ -0,0 +1,107 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * ***** END GPL LICENSE BLOCK ***** + * + * Copyright (C) 2014 Blender Foundation. + * + */ + +/** \file blender/blenlib/intern/hash_mm2a.c + * \ingroup bli + * + * Functions to compute Murmur2A hash key. + * + * A very fast hash generating int32 result, with few collisions and good repartition. + * + * See also: + * reference implementation: https://smhasher.googlecode.com/svn-history/r130/trunk/MurmurHash2.cpp + * and http://programmers.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed + * + * \warning Do not store that hash in files or such, it is not endian-agnostic, so you should only use it + * for temporary data. + */ + +#include "BLI_hash_mm2a.h" /* own include */ + +/* Helpers. */ +#define MM2A_M 0x5bd1e995 + +#define MM2A_MIX(h, k) \ +{ \ + (k) *= MM2A_M; \ + (k) ^= (k) >> 24; \ + (k) *= MM2A_M; \ + (h) = ((h) * MM2A_M) ^ (k); \ +} (void)0 + +static void mm2a_mix_tail(BLI_HashMurmur2A *mm2, const unsigned char **data, size_t *len) +{ + while (*len && ((*len < 4) || mm2->count)) { + mm2->tail |= (uint32_t)(**data) << (mm2->count * 8); + + mm2->count++; + (*len)--; + (*data)++; + + if (mm2->count == 4) { + MM2A_MIX(mm2->hash, mm2->tail); + mm2->tail = 0; + mm2->count = 0; + } + } +} + +void BLI_hash_mm2a_init(BLI_HashMurmur2A *mm2, uint32_t seed) +{ + mm2->hash = seed; + mm2->tail = 0; + mm2->count = 0; + mm2->size = 0; +} + +void BLI_hash_mm2a_add(BLI_HashMurmur2A *mm2, const unsigned char *data, size_t len) +{ + mm2->size += (uint32_t)len; + + mm2a_mix_tail(mm2, &data, &len); + + for (; len >= 4; data += 4, len -= 4) { + uint32_t k = *(uint32_t *)data; + + MM2A_MIX(mm2->hash, k); + } + + mm2a_mix_tail(mm2, &data, &len); +} + +void BLI_hash_mm2a_add_int(BLI_HashMurmur2A *mm2, int data) +{ + BLI_hash_mm2a_add(mm2, (const unsigned char *)&data, sizeof(data)); +} + +uint32_t BLI_hash_mm2a_end(BLI_HashMurmur2A *mm2) +{ + MM2A_MIX(mm2->hash, mm2->tail); + MM2A_MIX(mm2->hash, mm2->size); + + mm2->hash ^= mm2->hash >> 13; + mm2->hash *= MM2A_M; + mm2->hash ^= mm2->hash >> 15; + + return mm2->hash; +} diff --git a/source/blender/blenlib/intern/lasso.c b/source/blender/blenlib/intern/lasso.c index e89f7fd795b..23704538413 100644 --- a/source/blender/blenlib/intern/lasso.c +++ b/source/blender/blenlib/intern/lasso.c @@ -33,7 +33,6 @@ #include "DNA_vec_types.h" #include "BLI_math.h" -#include "BLI_rect.h" #include "BLI_strict_flags.h" #include "BLI_lasso.h" /* own include */ diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index d9cf8971246..bd3e1e0bbb0 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -130,6 +130,44 @@ bool BLI_remlink_safe(ListBase *listbase, void *vlink) } /** + * Swaps \a vlinka and \a vlinkb in the list. Assumes they are both already in the list! + */ +void BLI_listbase_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb) +{ + Link *linka = vlinka; + Link *linkb = vlinkb; + + if (!linka || !linkb) + return; + + if (linkb->next == linka) { + SWAP(Link *, linka, linkb); + } + + if (linka->next == linkb) { + linka->next = linkb->next; + linkb->prev = linka->prev; + linka->prev = linkb; + linkb->next = linka; + } + else { /* Non-contiguous items, we can safely swap. */ + SWAP(Link *, linka->prev, linkb->prev); + SWAP(Link *, linka->next, linkb->next); + } + + /* Update neighbors of linka and linkb. */ + if (linka->prev) linka->prev->next = linka; + if (linka->next) linka->next->prev = linka; + if (linkb->prev) linkb->prev->next = linkb; + if (linkb->next) linkb->next->prev = linkb; + + if (listbase->last == linka) listbase->last = linkb; + else if (listbase->last == linkb) listbase->last = linka; + if (listbase->first == linka) listbase->first = linkb; + else if (listbase->first == linkb) listbase->first = linka; +} + +/** * Removes the head from \a listbase and returns it. */ void *BLI_pophead(ListBase *listbase) @@ -173,7 +211,7 @@ void BLI_freelinkN(ListBase *listbase, void *vlink) * (which should return 1 iff its first arg should come after its second arg). * This uses insertion sort, so NOT ok for large list. */ -void BLI_sortlist(ListBase *listbase, int (*cmp)(const void *, const void *)) +void BLI_listbase_sort(ListBase *listbase, int (*cmp)(const void *, const void *)) { Link *current = NULL; Link *previous = NULL; @@ -195,7 +233,7 @@ void BLI_sortlist(ListBase *listbase, int (*cmp)(const void *, const void *)) } } -void BLI_sortlist_r(ListBase *listbase, void *thunk, int (*cmp)(void *, const void *, const void *)) +void BLI_listbase_sort_r(ListBase *listbase, void *thunk, int (*cmp)(void *, const void *, const void *)) { Link *current = NULL; Link *previous = NULL; @@ -334,22 +372,35 @@ void BLI_freelistN(ListBase *listbase) BLI_listbase_clear(listbase); } +/** + * Returns the number of elements in \a listbase, up until (and including count_max) + * + * \note Use to avoid redundant looping. + */ +int BLI_listbase_count_ex(const ListBase *listbase, const int count_max) +{ + Link *link; + int count = 0; + + for (link = listbase->first; link && count != count_max; link = link->next) { + count++; + } + + return count; +} /** * Returns the number of elements in \a listbase. */ -int BLI_countlist(const ListBase *listbase) +int BLI_listbase_count(const ListBase *listbase) { Link *link; int count = 0; - - if (listbase) { - link = listbase->first; - while (link) { - count++; - link = link->next; - } + + for (link = listbase->first; link; link = link->next) { + count++; } + return count; } diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c index e6217329145..39116d6f30f 100644 --- a/source/blender/blenlib/intern/math_base_inline.c +++ b/source/blender/blenlib/intern/math_base_inline.c @@ -44,6 +44,24 @@ # define UNLIKELY(x) (x) #endif +/* powf is really slow for raising to integer powers. */ +MINLINE float pow2f(float x) +{ + return x * x; +} +MINLINE float pow3f(float x) +{ + return pow2f(x) * x; +} +MINLINE float pow4f(float x) +{ + return pow2f(pow2f(x)); +} +MINLINE float pow7f(float x) +{ + return pow2f(pow3f(x)) * x; +} + MINLINE float sqrt3f(float f) { if (UNLIKELY(f == 0.0f)) return 0.0f; diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index da0855ad022..42aa24d284d 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -912,12 +912,12 @@ bool isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[ if (line_point_side_v2(v1, v2, pt) >= 0.0f) { if (line_point_side_v2(v2, v3, pt) >= 0.0f) { if (line_point_side_v2(v3, v1, pt) >= 0.0f) { - return 1; + return true; } } } - return 0; + return false; } int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2]) @@ -983,28 +983,28 @@ bool isect_line_tri_v3(const float p1[3], const float p2[3], cross_v3_v3v3(p, d, e2); a = dot_v3v3(e1, p); - if (a == 0.0f) return 0; + if (a == 0.0f) return false; f = 1.0f / a; sub_v3_v3v3(s, p1, v0); u = f * dot_v3v3(s, p); - if ((u < 0.0f) || (u > 1.0f)) return 0; + if ((u < 0.0f) || (u > 1.0f)) return false; cross_v3_v3v3(q, s, e1); v = f * dot_v3v3(d, q); - if ((v < 0.0f) || ((u + v) > 1.0f)) return 0; + if ((v < 0.0f) || ((u + v) > 1.0f)) return false; *r_lambda = f * dot_v3v3(e2, q); - if ((*r_lambda < 0.0f) || (*r_lambda > 1.0f)) return 0; + if ((*r_lambda < 0.0f) || (*r_lambda > 1.0f)) return false; if (r_uv) { r_uv[0] = u; r_uv[1] = v; } - return 1; + return true; } /* like isect_line_tri_v3, but allows epsilon tolerance around triangle */ @@ -1022,28 +1022,28 @@ bool isect_line_tri_epsilon_v3(const float p1[3], const float p2[3], cross_v3_v3v3(p, d, e2); a = dot_v3v3(e1, p); - if (a == 0.0f) return 0; + if (a == 0.0f) return false; f = 1.0f / a; sub_v3_v3v3(s, p1, v0); u = f * dot_v3v3(s, p); - if ((u < -epsilon) || (u > 1.0f + epsilon)) return 0; + if ((u < -epsilon) || (u > 1.0f + epsilon)) return false; cross_v3_v3v3(q, s, e1); v = f * dot_v3v3(d, q); - if ((v < -epsilon) || ((u + v) > 1.0f + epsilon)) return 0; + if ((v < -epsilon) || ((u + v) > 1.0f + epsilon)) return false; *r_lambda = f * dot_v3v3(e2, q); - if ((*r_lambda < 0.0f) || (*r_lambda > 1.0f)) return 0; + if ((*r_lambda < 0.0f) || (*r_lambda > 1.0f)) return false; if (r_uv) { r_uv[0] = u; r_uv[1] = v; } - return 1; + return true; } /* moved from effect.c @@ -1064,28 +1064,28 @@ bool isect_ray_tri_v3(const float p1[3], const float d[3], a = dot_v3v3(e1, p); /* note: these values were 0.000001 in 2.4x but for projection snapping on * a human head (1BU == 1m), subsurf level 2, this gave many errors - campbell */ - if ((a > -0.00000001f) && (a < 0.00000001f)) return 0; + if ((a > -0.00000001f) && (a < 0.00000001f)) return false; f = 1.0f / a; sub_v3_v3v3(s, p1, v0); u = f * dot_v3v3(s, p); - if ((u < 0.0f) || (u > 1.0f)) return 0; + if ((u < 0.0f) || (u > 1.0f)) return false; cross_v3_v3v3(q, s, e1); v = f * dot_v3v3(d, q); - if ((v < 0.0f) || ((u + v) > 1.0f)) return 0; + if ((v < 0.0f) || ((u + v) > 1.0f)) return false; *r_lambda = f * dot_v3v3(e2, q); - if ((*r_lambda < 0.0f)) return 0; + if ((*r_lambda < 0.0f)) return false; if (r_uv) { r_uv[0] = u; r_uv[1] = v; } - return 1; + return true; } /** @@ -1107,7 +1107,7 @@ bool isect_ray_plane_v3(const float p1[3], const float d[3], a = dot_v3v3(e1, p); /* note: these values were 0.000001 in 2.4x but for projection snapping on * a human head (1BU == 1m), subsurf level 2, this gave many errors - campbell */ - if ((a > -0.00000001f) && (a < 0.00000001f)) return 0; + if ((a > -0.00000001f) && (a < 0.00000001f)) return false; f = 1.0f / a; sub_v3_v3v3(s, p1, v0); @@ -1119,9 +1119,9 @@ bool isect_ray_plane_v3(const float p1[3], const float d[3], /* v = f * dot_v3v3(d, q); */ /*UNUSED*/ *r_lambda = f * dot_v3v3(e2, q); - if (clip && (*r_lambda < 0.0f)) return 0; + if (clip && (*r_lambda < 0.0f)) return false; - return 1; + return true; } bool isect_ray_tri_epsilon_v3(const float p1[3], const float d[3], @@ -1142,22 +1142,22 @@ bool isect_ray_tri_epsilon_v3(const float p1[3], const float d[3], sub_v3_v3v3(s, p1, v0); u = f * dot_v3v3(s, p); - if ((u < -epsilon) || (u > 1.0f + epsilon)) return 0; + if ((u < -epsilon) || (u > 1.0f + epsilon)) return false; cross_v3_v3v3(q, s, e1); v = f * dot_v3v3(d, q); - if ((v < -epsilon) || ((u + v) > 1.0f + epsilon)) return 0; + if ((v < -epsilon) || ((u + v) > 1.0f + epsilon)) return false; *r_lambda = f * dot_v3v3(e2, q); - if ((*r_lambda < 0.0f)) return 0; + if ((*r_lambda < 0.0f)) return false; if (uv) { uv[0] = u; uv[1] = v; } - return 1; + return true; } bool isect_ray_tri_threshold_v3(const float p1[3], const float d[3], @@ -1173,14 +1173,14 @@ bool isect_ray_tri_threshold_v3(const float p1[3], const float d[3], cross_v3_v3v3(p, d, e2); a = dot_v3v3(e1, p); - if ((a > -0.000001f) && (a < 0.000001f)) return 0; + if ((a > -0.000001f) && (a < 0.000001f)) return false; f = 1.0f / a; sub_v3_v3v3(s, p1, v0); cross_v3_v3v3(q, s, e1); *r_lambda = f * dot_v3v3(e2, q); - if ((*r_lambda < 0.0f)) return 0; + if ((*r_lambda < 0.0f)) return false; u = f * dot_v3v3(s, p); v = f * dot_v3v3(d, q); @@ -1204,7 +1204,7 @@ bool isect_ray_tri_threshold_v3(const float p1[3], const float d[3], mul_v3_fl(e2, dv); if (len_squared_v3(e1) + len_squared_v3(e2) > threshold * threshold) { - return 0; + return false; } if (r_uv) { @@ -1212,7 +1212,7 @@ bool isect_ray_tri_threshold_v3(const float p1[3], const float d[3], r_uv[1] = v; } - return 1; + return true; } /** @@ -1363,7 +1363,7 @@ bool isect_sweeping_sphere_tri_v3(const float p1[3], const float p2[3], const fl if (t0 > t1) SWAP(float, t0, t1); - if (t0 > 1.0f || t1 < 0.0f) return 0; + if (t0 > 1.0f || t1 < 0.0f) return false; /* clamp to [0, 1] */ CLAMP(t0, 0.0f, 1.0f); @@ -1542,7 +1542,7 @@ bool isect_axial_line_tri_v3(const int axis, const float p1[3], const float p2[3 if ((f > -0.000001f) && (f < 0.000001f)) return false; v = (p[a2] * e1[a1] - p[a1] * e1[a2]) / f; - if ((v < 0.0f) || (v > 1.0f)) return 0; + if ((v < 0.0f) || (v > 1.0f)) return false; f = e1[a1]; if ((f > -0.000001f) && (f < 0.000001f)) { @@ -1553,7 +1553,7 @@ bool isect_axial_line_tri_v3(const int axis, const float p1[3], const float p2[3 else u = (-p[a1] - v * e2[a1]) / f; - if ((u < 0.0f) || ((u + v) > 1.0f)) return 0; + if ((u < 0.0f) || ((u + v) > 1.0f)) return false; *r_lambda = (p[a0] + u * e1[a0] + v * e2[a0]) / (p2[a0] - p1[a0]); @@ -1756,8 +1756,8 @@ bool isect_ray_aabb(const IsectRayAABBData *data, const float bb_min[3], if (tzmin > tmin) tmin = tzmin; - /* XXX jwilkins: tmax does not need to be updated since we don't use it - * keeping this here for future reference */ + /* Note: tmax does not need to be updated since we don't use it + * keeping this here for future reference - jwilkins */ //if (tzmax < tmax) tmax = tzmax; if (tmin_out) @@ -1840,7 +1840,7 @@ float line_plane_factor_v3(const float plane_co[3], const float plane_no[3], return (dot != 0.0f) ? -dot_v3v3(plane_no, h) / dot : 0.0f; } -/** Ensure the distance between these points is no greater then 'dist'. +/** Ensure the distance between these points is no greater than 'dist'. * If it is, scale then both into the center. */ void limit_dist_v3(float v1[3], float v2[3], const float dist) @@ -4016,3 +4016,31 @@ bool is_poly_convex_v2(const float verts[][2], unsigned int nr) return true; } + +/** + * Check if either of the diagonals along this quad create flipped triangles + * (normals pointing away from eachother). + * - (1 << 0): (v1-v3) is flipped. + * - (1 << 1): (v2-v4) is flipped. + */ +int is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]) +{ + float d_12[3], d_23[3], d_34[3], d_41[3]; + float cross_a[3], cross_b[3]; + int ret = 0; + + sub_v3_v3v3(d_12, v1, v2); + sub_v3_v3v3(d_23, v2, v3); + sub_v3_v3v3(d_34, v3, v4); + sub_v3_v3v3(d_41, v4, v1); + + cross_v3_v3v3(cross_a, d_12, d_23); + cross_v3_v3v3(cross_b, d_34, d_41); + ret |= ((dot_v3v3(cross_a, cross_b) < 0.0f) << 0); + + cross_v3_v3v3(cross_a, d_23, d_34); + cross_v3_v3v3(cross_b, d_41, d_12); + ret |= ((dot_v3v3(cross_a, cross_b) < 0.0f) << 1); + + return ret; +} diff --git a/source/blender/blenlib/intern/math_interp.c b/source/blender/blenlib/intern/math_interp.c index 4feb954a31a..a0c47be8d48 100644 --- a/source/blender/blenlib/intern/math_interp.c +++ b/source/blender/blenlib/intern/math_interp.c @@ -467,7 +467,7 @@ void BLI_ewa_filter(const int width, const int height, /* scaling dxt/dyt by full resolution can cause overflow because of huge A/B/C and esp. F values, * scaling by aspect ratio alone does the opposite, so try something in between instead... */ const float ff2 = (float)width, ff = sqrtf(ff2), q = (float)height / ff; - const float Ux = du[0] * ff, Vx = dv[0] * q, Uy = du[1] * ff, Vy = dv[1] * q; + const float Ux = du[0] * ff, Vx = du[1] * q, Uy = dv[0] * ff, Vy = dv[1] * q; float A = Vx * Vx + Vy * Vy; float B = -2.0f * (Ux * Vx + Uy * Vy); float C = Ux * Ux + Uy * Uy; diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index af42af88582..1b4bbafdb04 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -639,7 +639,16 @@ void mul_mat3_m4_fl(float m[4][4], float f) m[i][j] *= f; } -void negate_m3(float m[4][4]) +void negate_m3(float m[3][3]) +{ + int i, j; + + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + m[i][j] *= -1.0f; +} + +void negate_mat3_m4(float m[4][4]) { int i, j; @@ -839,9 +848,10 @@ bool invert_m4_m4(float inverse[4][4], float mat[4][4]) } } - temp = tempmat[i][i]; - if (temp == 0) - return 0; /* No non-zero pivot */ + if (UNLIKELY(tempmat[i][i] == 0.0f)) { + return false; /* No non-zero pivot */ + } + temp = (double)tempmat[i][i]; for (k = 0; k < 4; k++) { tempmat[i][k] = (float)((double)tempmat[i][k] / temp); inverse[i][k] = (float)((double)inverse[i][k] / temp); @@ -856,7 +866,7 @@ bool invert_m4_m4(float inverse[4][4], float mat[4][4]) } } } - return 1; + return true; } /****************************** Linear Algebra *******************************/ @@ -876,6 +886,37 @@ void transpose_m3(float mat[3][3]) mat[2][1] = t; } +void transpose_m3_m3(float rmat[3][3], float mat[3][3]) +{ + BLI_assert(rmat != mat); + + rmat[0][0] = mat[0][0]; + rmat[0][1] = mat[1][0]; + rmat[0][2] = mat[2][0]; + rmat[1][0] = mat[0][1]; + rmat[1][1] = mat[1][1]; + rmat[1][2] = mat[2][1]; + rmat[2][0] = mat[0][2]; + rmat[2][1] = mat[1][2]; + rmat[2][2] = mat[2][2]; +} + +/* seems obscure but in-fact a common operation */ +void transpose_m3_m4(float rmat[3][3], float mat[4][4]) +{ + BLI_assert(&rmat[0][0] != &mat[0][0]); + + rmat[0][0] = mat[0][0]; + rmat[0][1] = mat[1][0]; + rmat[0][2] = mat[2][0]; + rmat[1][0] = mat[0][1]; + rmat[1][1] = mat[1][1]; + rmat[1][2] = mat[2][1]; + rmat[2][0] = mat[0][2]; + rmat[2][1] = mat[1][2]; + rmat[2][2] = mat[2][2]; +} + void transpose_m4(float mat[4][4]) { float t; @@ -902,6 +943,28 @@ void transpose_m4(float mat[4][4]) mat[3][2] = t; } +void transpose_m4_m4(float rmat[4][4], float mat[4][4]) +{ + BLI_assert(rmat != mat); + + rmat[0][0] = mat[0][0]; + rmat[0][1] = mat[1][0]; + rmat[0][2] = mat[2][0]; + rmat[0][3] = mat[3][0]; + rmat[1][0] = mat[0][1]; + rmat[1][1] = mat[1][1]; + rmat[1][2] = mat[2][1]; + rmat[1][3] = mat[3][1]; + rmat[2][0] = mat[0][2]; + rmat[2][1] = mat[1][2]; + rmat[2][2] = mat[2][2]; + rmat[2][3] = mat[3][2]; + rmat[3][0] = mat[0][3]; + rmat[3][1] = mat[1][3]; + rmat[3][2] = mat[2][3]; + rmat[3][3] = mat[3][3]; +} + int compare_m4m4(float mat1[4][4], float mat2[4][4], float limit) { if (compare_v4v4(mat1[0], mat2[0], limit)) @@ -1087,11 +1150,11 @@ bool is_orthogonal_m3(float m[3][3]) for (i = 0; i < 3; i++) { for (j = 0; j < i; j++) { if (fabsf(dot_v3v3(m[i], m[j])) > 1.5f * FLT_EPSILON) - return 0; + return false; } } - return 1; + return true; } bool is_orthogonal_m4(float m[4][4]) @@ -1101,12 +1164,12 @@ bool is_orthogonal_m4(float m[4][4]) for (i = 0; i < 4; i++) { for (j = 0; j < i; j++) { if (fabsf(dot_v4v4(m[i], m[j])) > 1.5f * FLT_EPSILON) - return 0; + return false; } } - return 1; + return true; } bool is_orthonormal_m3(float m[3][3]) @@ -1116,12 +1179,12 @@ bool is_orthonormal_m3(float m[3][3]) for (i = 0; i < 3; i++) if (fabsf(dot_v3v3(m[i], m[i]) - 1) > 1.5f * FLT_EPSILON) - return 0; + return false; - return 1; + return true; } - return 0; + return false; } bool is_orthonormal_m4(float m[4][4]) @@ -1131,12 +1194,12 @@ bool is_orthonormal_m4(float m[4][4]) for (i = 0; i < 4; i++) if (fabsf(dot_v4v4(m[i], m[i]) - 1) > 1.5f * FLT_EPSILON) - return 0; + return false; - return 1; + return true; } - return 0; + return false; } bool is_uniform_scaled_m3(float m[3][3]) @@ -1145,8 +1208,7 @@ bool is_uniform_scaled_m3(float m[3][3]) float t[3][3]; float l1, l2, l3, l4, l5, l6; - copy_m3_m3(t, m); - transpose_m3(t); + transpose_m3_m3(t, m); l1 = len_squared_v3(m[0]); l2 = len_squared_v3(m[1]); @@ -1387,7 +1449,7 @@ float mat3_to_scale(float mat[3][3]) { /* unit length vector */ float unit_vec[3]; - copy_v3_fl(unit_vec, (float)(1.0 / M_SQRT3)); + copy_v3_fl(unit_vec, (float)M_SQRT1_3); mul_m3_v3(mat, unit_vec); return len_v3(unit_vec); } @@ -1396,7 +1458,7 @@ float mat4_to_scale(float mat[4][4]) { /* unit length vector */ float unit_vec[3]; - copy_v3_fl(unit_vec, (float)(1.0 / M_SQRT3)); + copy_v3_fl(unit_vec, (float)M_SQRT1_3); mul_mat3_m4_v3(mat, unit_vec); return len_v3(unit_vec); } @@ -1413,9 +1475,7 @@ void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]) /* note: this is a workaround for negative matrix not working for rotation conversion, FIXME */ normalize_m3_m3(mat3_n, mat3); if (is_negative_m3(mat3)) { - negate_v3(mat3_n[0]); - negate_v3(mat3_n[1]); - negate_v3(mat3_n[2]); + negate_m3(mat3_n); } /* rotation */ @@ -1425,11 +1485,19 @@ void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]) /* scale */ /* note: mat4_to_size(ob->size, mat) fails for negative scale */ invert_m3_m3(imat3_n, mat3_n); + + /* better not edit mat3 */ +#if 0 mul_m3_m3m3(mat3, imat3_n, mat3); size[0] = mat3[0][0]; size[1] = mat3[1][1]; size[2] = mat3[2][2]; +#else + size[0] = dot_m3_v3_row_x(imat3_n, mat3[0]); + size[1] = dot_m3_v3_row_y(imat3_n, mat3[1]); + size[2] = dot_m3_v3_row_z(imat3_n, mat3[2]); +#endif } void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4]) @@ -1454,9 +1522,7 @@ void mat4_to_loc_quat(float loc[3], float quat[4], float wmat[4][4]) /* so scale doesn't interfere with rotation [#24291] */ /* note: this is a workaround for negative matrix not working for rotation conversion, FIXME */ if (is_negative_m3(mat3)) { - negate_v3(mat3_n[0]); - negate_v3(mat3_n[1]); - negate_v3(mat3_n[2]); + negate_m3(mat3_n); } mat3_to_quat(quat, mat3_n); @@ -2183,14 +2249,14 @@ void svd_m4(float U[4][4], float s[4], float V[4][4], float A_[4][4]) } } -void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon) +void pseudoinverse_m4_m4(float Ainv[4][4], float A_[4][4], float epsilon) { /* compute moon-penrose pseudo inverse of matrix, singular values * below epsilon are ignored for stability (truncated SVD) */ - float V[4][4], W[4], Wm[4][4], U[4][4]; + float A[4][4], V[4][4], W[4], Wm[4][4], U[4][4]; int i; - transpose_m4(A); + transpose_m4_m4(A, A_); svd_m4(V, W, U, A); transpose_m4(U); transpose_m4(V); diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index 9a6515daf68..3ac031d7b90 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -1867,7 +1867,7 @@ float angle_wrap_deg(float angle) /* returns an angle compatible with angle_compat */ float angle_compat_rad(float angle, float angle_compat) { - return angle + (floorf(((angle_compat - angle) / (float)M_PI) + 0.5f)) * (float)M_PI; + return angle_compat + angle_wrap_rad(angle - angle_compat); } /* axis conversion */ diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index d5af980e373..0a30a35ba7c 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -45,12 +45,6 @@ #include "BLI_string_utf8.h" #include "BLI_fnmatch.h" -#include "../blenkernel/BKE_blender.h" /* BLENDER_VERSION, bad level include (no function call) */ - -#include "GHOST_Path-api.h" - -#include "MEM_guardedalloc.h" - #ifdef WIN32 # include "utf_winfunc.h" # include "utfconv.h" @@ -62,21 +56,12 @@ # include <windows.h> # include <shlobj.h> # include "BLI_winstuff.h" -#else /* non windows */ -# ifdef WITH_BINRELOC -# include "binreloc.h" -# endif -# include <unistd.h> /* mkdtemp on OSX (and probably all *BSD?), not worth making specific check for this OS. */ +# include "MEM_guardedalloc.h" #endif /* WIN32 */ /* local */ #define UNIQUE_NAME_MAX 128 -static char bprogname[FILE_MAX]; /* full path to program executable */ -static char bprogdir[FILE_MAX]; /* full path to directory in which executable is located */ -static char btempdir_base[FILE_MAX]; /* persistent temporary directory */ -static char btempdir_session[FILE_MAX] = ""; /* volatile temporary directory */ - /* implementation */ /** @@ -954,8 +939,6 @@ bool BLI_path_abs(char *path, const char *basepath) BLI_strncpy(path, tmp, FILE_MAX); } - BLI_cleanup_path(NULL, path); - #ifdef WIN32 /* skip first two chars, which in case of * absolute path will be drive:/blabla and @@ -965,7 +948,10 @@ bool BLI_path_abs(char *path, const char *basepath) */ BLI_char_switch(path + 2, '/', '\\'); #endif - + + /* ensure this is after correcting for path switch */ + BLI_cleanup_path(NULL, path); + return wasrelative; } @@ -1038,446 +1024,6 @@ void BLI_getlastdir(const char *dir, char *last, const size_t maxlen) } } -/* This is now only used to really get the user's default document folder */ -/* On Windows I chose the 'Users/<MyUserName>/Documents' since it's used - * as default location to save documents */ -const char *BLI_getDefaultDocumentFolder(void) -{ -#ifndef WIN32 - const char * const xdg_documents_dir = getenv("XDG_DOCUMENTS_DIR"); - - if (xdg_documents_dir) - return xdg_documents_dir; - - return getenv("HOME"); -#else /* Windows */ - static char documentfolder[MAXPATHLEN]; - HRESULT hResult; - - /* Check for %HOME% env var */ - if (uput_getenv("HOME", documentfolder, MAXPATHLEN)) { - if (BLI_is_dir(documentfolder)) return documentfolder; - } - - /* add user profile support for WIN 2K / NT. - * This is %APPDATA%, which translates to either - * %USERPROFILE%\Application Data or since Vista - * to %USERPROFILE%\AppData\Roaming - */ - hResult = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, documentfolder); - - if (hResult == S_OK) { - if (BLI_is_dir(documentfolder)) return documentfolder; - } - - return NULL; -#endif /* WIN32 */ -} - -/* NEW stuff, to be cleaned up when fully migrated */ -/* ************************************************************* */ -/* ************************************************************* */ - -// #define PATH_DEBUG - -/* returns a formatted representation of the specified version number. Non-reentrant! */ -static char *blender_version_decimal(const int ver) -{ - static char version_str[5]; - sprintf(version_str, "%d.%02d", ver / 100, ver % 100); - return version_str; -} - -/** - * Concatenates path_base, (optional) path_sep and (optional) folder_name into targetpath, - * returning true if result points to a directory. - */ -static bool test_path(char *targetpath, const char *path_base, const char *path_sep, const char *folder_name) -{ - char tmppath[FILE_MAX]; - - if (path_sep) BLI_join_dirfile(tmppath, sizeof(tmppath), path_base, path_sep); - else BLI_strncpy(tmppath, path_base, sizeof(tmppath)); - - /* rare cases folder_name is omitted (when looking for ~/.blender/2.xx dir only) */ - if (folder_name) - BLI_make_file_string("/", targetpath, tmppath, folder_name); - else - BLI_strncpy(targetpath, tmppath, sizeof(tmppath)); - /* FIXME: why is "//" on front of tmppath expanded to "/" (by BLI_join_dirfile) - * if folder_name is specified but not otherwise? */ - - if (BLI_is_dir(targetpath)) { -#ifdef PATH_DEBUG - printf("\t%s found: %s\n", __func__, targetpath); -#endif - return true; - } - else { -#ifdef PATH_DEBUG - printf("\t%s missing: %s\n", __func__, targetpath); -#endif - //targetpath[0] = '\0'; - return false; - } -} - -/** - * Puts the value of the specified environment variable into *path if it exists - * and points at a directory. Returns true if this was done. - */ -static bool test_env_path(char *path, const char *envvar) -{ - const char *env = envvar ? getenv(envvar) : NULL; - if (!env) return false; - - if (BLI_is_dir(env)) { - BLI_strncpy(path, env, FILE_MAX); -#ifdef PATH_DEBUG - printf("\t%s env %s found: %s\n", __func__, envvar, env); -#endif - return true; - } - else { - path[0] = '\0'; -#ifdef PATH_DEBUG - printf("\t%s env %s missing: %s\n", __func__, envvar, env); -#endif - return false; - } -} - -/** - * Constructs in \a targetpath the name of a directory relative to a version-specific - * subdirectory in the parent directory of the Blender executable. - * - * \param targetpath String to return path - * \param folder_name Optional folder name within version-specific directory - * \param subfolder_name Optional subfolder name within folder_name - * \param ver To construct name of version-specific directory within bprogdir - * \return true if such a directory exists. - */ -static bool get_path_local(char *targetpath, const char *folder_name, const char *subfolder_name, const int ver) -{ - char relfolder[FILE_MAX]; - -#ifdef PATH_DEBUG - printf("%s...\n", __func__); -#endif - - if (folder_name) { - if (subfolder_name) { - BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name); - } - else { - BLI_strncpy(relfolder, folder_name, sizeof(relfolder)); - } - } - else { - relfolder[0] = '\0'; - } - - /* try EXECUTABLE_DIR/2.5x/folder_name - new default directory for local blender installed files */ -#ifdef __APPLE__ - static char osx_resourses[FILE_MAX]; /* due new codesign situation in OSX > 10.9.5 we must move the blender_version dir with contents to Resources */ - sprintf(osx_resourses, "%s../Resources", bprogdir); - return test_path(targetpath, osx_resourses, blender_version_decimal(ver), relfolder); -#else - return test_path(targetpath, bprogdir, blender_version_decimal(ver), relfolder); -#endif -} - -/** - * Is this an install with user files kept together with the Blender executable and its - * installation files. - */ -static bool is_portable_install(void) -{ - /* detect portable install by the existence of config folder */ - const int ver = BLENDER_VERSION; - char path[FILE_MAX]; - - return get_path_local(path, "config", NULL, ver); -} - -/** - * Returns the path of a folder within the user-files area. - * - * - * \param targetpath String to return path - * \param folder_name default name of folder within user area - * \param subfolder_name optional name of subfolder within folder - * \param envvar name of environment variable which, if defined, overrides folder_name - * \param ver Blender version, used to construct a subdirectory name - * \return true if it was able to construct such a path. - */ -static bool get_path_user(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver) -{ - char user_path[FILE_MAX]; - const char *user_base_path; - - /* for portable install, user path is always local */ - if (is_portable_install()) - return get_path_local(targetpath, folder_name, subfolder_name, ver); - - user_path[0] = '\0'; - - if (test_env_path(user_path, envvar)) { - if (subfolder_name) { - return test_path(targetpath, user_path, NULL, subfolder_name); - } - else { - BLI_strncpy(targetpath, user_path, FILE_MAX); - return true; - } - } - - user_base_path = (const char *)GHOST_getUserDir(ver, blender_version_decimal(ver)); - if (user_base_path) - BLI_strncpy(user_path, user_base_path, FILE_MAX); - - if (!user_path[0]) - return false; - -#ifdef PATH_DEBUG - printf("%s: %s\n", __func__, user_path); -#endif - - if (subfolder_name) { - return test_path(targetpath, user_path, folder_name, subfolder_name); - } - else { - return test_path(targetpath, user_path, NULL, folder_name); - } -} - -/** - * Returns the path of a folder within the Blender installation directory. - * - * \param targetpath String to return path - * \param folder_name default name of folder within installation area - * \param subfolder_name optional name of subfolder within folder - * \param envvar name of environment variable which, if defined, overrides folder_name - * \param ver Blender version, used to construct a subdirectory name - * \return true if it was able to construct such a path. - */ -static bool get_path_system(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver) -{ - char system_path[FILE_MAX]; - const char *system_base_path; - char cwd[FILE_MAX]; - char relfolder[FILE_MAX]; - - if (folder_name) { - if (subfolder_name) { - BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name); - } - else { - BLI_strncpy(relfolder, folder_name, sizeof(relfolder)); - } - } - else { - relfolder[0] = '\0'; - } - - /* first allow developer only overrides to the system path - * these are only used when running blender from source */ - - /* try CWD/release/folder_name */ - if (BLI_current_working_dir(cwd, sizeof(cwd))) { - if (test_path(targetpath, cwd, "release", relfolder)) { - return true; - } - } - - /* try EXECUTABLE_DIR/release/folder_name */ - if (test_path(targetpath, bprogdir, "release", relfolder)) - return true; - - /* end developer overrides */ - - - - system_path[0] = '\0'; - - if (test_env_path(system_path, envvar)) { - if (subfolder_name) { - return test_path(targetpath, system_path, NULL, subfolder_name); - } - else { - BLI_strncpy(targetpath, system_path, FILE_MAX); - return true; - } - } - - system_base_path = (const char *)GHOST_getSystemDir(ver, blender_version_decimal(ver)); - if (system_base_path) - BLI_strncpy(system_path, system_base_path, FILE_MAX); - - if (!system_path[0]) - return false; - -#ifdef PATH_DEBUG - printf("%s: %s\n", __func__, system_path); -#endif - - if (subfolder_name) { - /* try $BLENDERPATH/folder_name/subfolder_name */ - return test_path(targetpath, system_path, folder_name, subfolder_name); - } - else { - /* try $BLENDERPATH/folder_name */ - return test_path(targetpath, system_path, NULL, folder_name); - } -} - -/* get a folder out of the 'folder_id' presets for paths */ -/* returns the path if found, NULL string if not */ -const char *BLI_get_folder(int folder_id, const char *subfolder) -{ - const int ver = BLENDER_VERSION; - static char path[FILE_MAX] = ""; - - switch (folder_id) { - case BLENDER_DATAFILES: /* general case */ - if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver)) break; - if (get_path_local(path, "datafiles", subfolder, ver)) break; - if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES", ver)) break; - return NULL; - - case BLENDER_USER_DATAFILES: - if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver)) break; - return NULL; - - case BLENDER_SYSTEM_DATAFILES: - if (get_path_local(path, "datafiles", subfolder, ver)) break; - if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES", ver)) break; - return NULL; - - case BLENDER_USER_AUTOSAVE: - if (get_path_user(path, "autosave", subfolder, "BLENDER_USER_DATAFILES", ver)) break; - return NULL; - - case BLENDER_USER_CONFIG: - if (get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG", ver)) break; - return NULL; - - case BLENDER_USER_SCRIPTS: - if (get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS", ver)) break; - return NULL; - - case BLENDER_SYSTEM_SCRIPTS: - if (get_path_local(path, "scripts", subfolder, ver)) break; - if (get_path_system(path, "scripts", subfolder, "BLENDER_SYSTEM_SCRIPTS", ver)) break; - return NULL; - - case BLENDER_SYSTEM_PYTHON: - if (get_path_local(path, "python", subfolder, ver)) break; - if (get_path_system(path, "python", subfolder, "BLENDER_SYSTEM_PYTHON", ver)) break; - return NULL; - - default: - BLI_assert(0); - break; - } - - return path; -} - -/** - * Returns the path to a folder in the user area without checking that it actually exists first. - */ -const char *BLI_get_user_folder_notest(int folder_id, const char *subfolder) -{ - const int ver = BLENDER_VERSION; - static char path[FILE_MAX] = ""; - - switch (folder_id) { - case BLENDER_USER_DATAFILES: - get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver); - break; - case BLENDER_USER_CONFIG: - get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG", ver); - break; - case BLENDER_USER_AUTOSAVE: - get_path_user(path, "autosave", subfolder, "BLENDER_USER_AUTOSAVE", ver); - break; - case BLENDER_USER_SCRIPTS: - get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS", ver); - break; - default: - BLI_assert(0); - break; - } - - if ('\0' == path[0]) { - return NULL; - } - return path; -} - -/** - * Returns the path to a folder in the user area, creating it if it doesn't exist. - */ -const char *BLI_get_folder_create(int folder_id, const char *subfolder) -{ - const char *path; - - /* only for user folders */ - if (!ELEM(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_SCRIPTS, BLENDER_USER_AUTOSAVE)) - return NULL; - - path = BLI_get_folder(folder_id, subfolder); - - if (!path) { - path = BLI_get_user_folder_notest(folder_id, subfolder); - if (path) BLI_dir_create_recursive(path); - } - - return path; -} - -/** - * Returns the path of the top-level version-specific local, user or system directory. - * If do_check, then the result will be NULL if the directory doesn't exist. - */ -const char *BLI_get_folder_version(const int id, const int ver, const bool do_check) -{ - static char path[FILE_MAX] = ""; - bool ok; - switch (id) { - case BLENDER_RESOURCE_PATH_USER: - ok = get_path_user(path, NULL, NULL, NULL, ver); - break; - case BLENDER_RESOURCE_PATH_LOCAL: - ok = get_path_local(path, NULL, NULL, ver); - break; - case BLENDER_RESOURCE_PATH_SYSTEM: - ok = get_path_system(path, NULL, NULL, NULL, ver); - break; - default: - path[0] = '\0'; /* in case do_check is false */ - ok = false; - BLI_assert(!"incorrect ID"); - break; - } - - if (!ok && do_check) { - return NULL; - } - - return path; -} - -/* End new stuff */ -/* ************************************************************* */ -/* ************************************************************* */ - - - -#ifdef PATH_DEBUG -# undef PATH_DEBUG -#endif /** * Sets the specified environment variable to the specified value, @@ -1580,7 +1126,7 @@ void BLI_make_existing_file(const char *name) char di[FILE_MAX]; BLI_split_dir_part(name, di, sizeof(di)); - /* make if if the dir doesn't exist */ + /* make if the dir doesn't exist */ BLI_dir_create_recursive(di); } @@ -1707,11 +1253,10 @@ bool BLI_testextensie_n(const char *str, ...) while ((ext = (const char *) va_arg(args, void *))) { if (testextensie_ex(str, str_len, ext, strlen(ext))) { ret = true; - goto finally; + break; } } -finally: va_end(args); return ret; @@ -2153,310 +1698,6 @@ void BLI_path_native_slash(char *path) #endif } -/** - * Tries appending each of the semicolon-separated extensions in the PATHEXT - * environment variable (Windows-only) onto *name in turn until such a file is found. - * Returns success/failure. - */ -static int add_win32_extension(char *name) -{ - int retval = 0; - int type; - - type = BLI_exists(name); - if ((type == 0) || S_ISDIR(type)) { -#ifdef _WIN32 - char filename[FILE_MAX]; - char ext[FILE_MAX]; - const char *extensions = getenv("PATHEXT"); - if (extensions) { - char *temp; - do { - strcpy(filename, name); - temp = strstr(extensions, ";"); - if (temp) { - strncpy(ext, extensions, temp - extensions); - ext[temp - extensions] = 0; - extensions = temp + 1; - strcat(filename, ext); - } - else { - strcat(filename, extensions); - } - - type = BLI_exists(filename); - if (type && (!S_ISDIR(type))) { - retval = 1; - strcpy(name, filename); - break; - } - } while (temp); - } -#endif - } - else { - retval = 1; - } - - return (retval); -} - -/** - * Checks if name is a fully qualified filename to an executable. - * If not it searches $PATH for the file. On Windows it also - * adds the correct extension (.com .exe etc) from - * $PATHEXT if necessary. Also on Windows it translates - * the name to its 8.3 version to prevent problems with - * spaces and stuff. Final result is returned in fullname. - * - * \param fullname The full path and full name of the executable - * (must be FILE_MAX minimum) - * \param name The name of the executable (usually argv[0]) to be checked - */ -static void bli_where_am_i(char *fullname, const size_t maxlen, const char *name) -{ - char filename[FILE_MAX]; - const char *path = NULL, *temp; - -#ifdef _WIN32 - const char *separator = ";"; -#else - const char *separator = ":"; -#endif - - -#ifdef WITH_BINRELOC - /* linux uses binreloc since argv[0] is not reliable, call br_init( NULL ) first */ - path = br_find_exe(NULL); - if (path) { - BLI_strncpy(fullname, path, maxlen); - free((void *)path); - return; - } -#endif - -#ifdef _WIN32 - wchar_t *fullname_16 = MEM_mallocN(maxlen * sizeof(wchar_t), "ProgramPath"); - if (GetModuleFileNameW(0, fullname_16, maxlen)) { - conv_utf_16_to_8(fullname_16, fullname, maxlen); - if (!BLI_exists(fullname)) { - printf("path can't be found: \"%.*s\"\n", (int)maxlen, fullname); - MessageBox(NULL, "path contains invalid characters or is too long (see console)", "Error", MB_OK); - } - MEM_freeN(fullname_16); - return; - } - - MEM_freeN(fullname_16); -#endif - - /* unix and non linux */ - if (name && name[0]) { - - BLI_strncpy(fullname, name, maxlen); - if (name[0] == '.') { - char wdir[FILE_MAX] = ""; - BLI_current_working_dir(wdir, sizeof(wdir)); /* backup cwd to restore after */ - - // not needed but avoids annoying /./ in name - if (name[1] == SEP) - BLI_join_dirfile(fullname, maxlen, wdir, name + 2); - else - BLI_join_dirfile(fullname, maxlen, wdir, name); - - add_win32_extension(fullname); /* XXX, doesnt respect length */ - } - else if (BLI_last_slash(name)) { - // full path - BLI_strncpy(fullname, name, maxlen); - add_win32_extension(fullname); - } - else { - // search for binary in $PATH - path = getenv("PATH"); - if (path) { - do { - temp = strstr(path, separator); - if (temp) { - strncpy(filename, path, temp - path); - filename[temp - path] = 0; - path = temp + 1; - } - else { - strncpy(filename, path, sizeof(filename)); - } - BLI_path_append(fullname, maxlen, name); - if (add_win32_extension(filename)) { - BLI_strncpy(fullname, filename, maxlen); - break; - } - } while (temp); - } - } -#if defined(DEBUG) - if (strcmp(name, fullname)) { - printf("guessing '%s' == '%s'\n", name, fullname); - } -#endif - } -} - -void BLI_init_program_path(const char *argv0) -{ - bli_where_am_i(bprogname, sizeof(bprogname), argv0); - BLI_split_dir_part(bprogname, bprogdir, sizeof(bprogdir)); -} - -/** - * Path to executable - */ -const char *BLI_program_path(void) -{ - return bprogname; -} - -/** - * Path to directory of executable - */ -const char *BLI_program_dir(void) -{ - return bprogdir; -} - -/** - * Gets the temp directory when blender first runs. - * If the default path is not found, use try $TEMP - * - * Also make sure the temp dir has a trailing slash - * - * \param fullname The full path to the temporary temp directory - * \param basename The full path to the persistent temp directory (may be NULL) - * \param maxlen The size of the fullname buffer - * \param userdir Directory specified in user preferences - */ -static void BLI_where_is_temp(char *fullname, char *basename, const size_t maxlen, char *userdir) -{ - /* Clear existing temp dir, if needed. */ - BLI_temp_dir_session_purge(); - - fullname[0] = '\0'; - if (basename) { - basename[0] = '\0'; - } - - if (userdir && BLI_is_dir(userdir)) { - BLI_strncpy(fullname, userdir, maxlen); - } - - -#ifdef WIN32 - if (fullname[0] == '\0') { - const char *tmp = getenv("TEMP"); /* Windows */ - if (tmp && BLI_is_dir(tmp)) { - BLI_strncpy(fullname, tmp, maxlen); - } - } -#else - /* Other OS's - Try TMP and TMPDIR */ - if (fullname[0] == '\0') { - const char *tmp = getenv("TMP"); - if (tmp && BLI_is_dir(tmp)) { - BLI_strncpy(fullname, tmp, maxlen); - } - } - - if (fullname[0] == '\0') { - const char *tmp = getenv("TMPDIR"); - if (tmp && BLI_is_dir(tmp)) { - BLI_strncpy(fullname, tmp, maxlen); - } - } -#endif - - if (fullname[0] == '\0') { - BLI_strncpy(fullname, "/tmp/", maxlen); - } - else { - /* add a trailing slash if needed */ - BLI_add_slash(fullname); -#ifdef WIN32 - if (userdir && userdir != fullname) { - BLI_strncpy(userdir, fullname, maxlen); /* also set user pref to show %TEMP%. /tmp/ is just plain confusing for Windows users. */ - } -#endif - } - - /* Now that we have a valid temp dir, add system-generated unique sub-dir. */ - if (basename) { - /* 'XXXXXX' is kind of tag to be replaced by mktemp-familly by an uuid. */ - char *tmp_name = BLI_strdupcat(fullname, "blender_XXXXXX"); - const size_t ln = strlen(tmp_name) + 1; - if (ln <= maxlen) { -#ifdef WIN32 - if (_mktemp_s(tmp_name, ln) == 0) { - BLI_dir_create_recursive(tmp_name); - } -#else - mkdtemp(tmp_name); -#endif - } - if (BLI_is_dir(tmp_name)) { - BLI_strncpy(basename, fullname, maxlen); - BLI_strncpy(fullname, tmp_name, maxlen); - BLI_add_slash(fullname); - } - else { - printf("Warning! Could not generate a temp file name for '%s', falling back to '%s'\n", tmp_name, fullname); - } - - MEM_freeN(tmp_name); - } -} - -/** - * Sets btempdir_base to userdir if specified and is a valid directory, otherwise - * chooses a suitable OS-specific temporary directory. - * Sets btempdir_session to a mkdtemp-generated sub-dir of btempdir_base. - */ -void BLI_temp_dir_init(char *userdir) -{ - BLI_where_is_temp(btempdir_session, btempdir_base, FILE_MAX, userdir); -; -} - -/** - * Path to temporary directory (with trailing slash) - */ -const char *BLI_temp_dir_session(void) -{ - return btempdir_session[0] ? btempdir_session : BLI_temp_dir_base(); -} - -/** - * Path to persistent temporary directory (with trailing slash) - */ -const char *BLI_temp_dir_base(void) -{ - return btempdir_base; -} - -/** - * Path to the system temporary directory (with trailing slash) - */ -void BLI_system_temporary_dir(char *dir) -{ - BLI_where_is_temp(dir, NULL, FILE_MAX, NULL); -} - -/** - * Delete content of this instance's temp dir. - */ -void BLI_temp_dir_session_purge(void) -{ - if (btempdir_session[0] && BLI_is_dir(btempdir_session)) { - BLI_delete(btempdir_session, true, true); - } -} #ifdef WITH_ICONV diff --git a/source/blender/blenlib/intern/polyfill2d_beautify.c b/source/blender/blenlib/intern/polyfill2d_beautify.c new file mode 100644 index 00000000000..c4e333d0094 --- /dev/null +++ b/source/blender/blenlib/intern/polyfill2d_beautify.c @@ -0,0 +1,499 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenlib/intern/polyfill2d_beautify.c + * \ingroup bli + * + * This function is to improve the tessellation resulting from polyfill2d, + * creating optimal topology. + * + * The functionality here matches #BM_mesh_beautify_fill, + * but its far simpler to perform this operation in 2d, + * on a simple polygon representation where we _know_: + * + * - The polygon is primitive with no holes with a continuous boundary. + * - Tris have consistent winding. + * - 2d (saves some hassles projecting face pairs on an axis for every edge-rotation) + * also saves us having to store all previous edge-states (see #EdRotState in bmesh_beautify.c) + * + * \note + * + * No globals - keep threadsafe. + */ + +#include "BLI_utildefines.h" +#include "BLI_math.h" + +#include "BLI_memarena.h" +#include "BLI_edgehash.h" +#include "BLI_heap.h" + +#include "BLI_polyfill2d_beautify.h" /* own include */ + +#include "BLI_strict_flags.h" + +struct PolyEdge { + /** ordered vert indices (smaller first) */ + unsigned int verts[2]; + /** ordered face indices (depends on winding compared to the edge verts) + * - (verts[0], verts[1]) == faces[0] + * - (verts[1], verts[0]) == faces[1] + */ + unsigned int faces[2]; + /** + * The face-index which isn't used by either of the edges verts [0 - 2]. + * could be calculated each time, but cleaner to store for reuse. + */ + unsigned int faces_other_v[2]; +}; + + +#ifndef NDEBUG +/** + * Only to check for error-cases. + */ +static void polyfill_validate_tri(unsigned int (*tris)[3], unsigned int tri_index, EdgeHash *ehash) +{ + const unsigned int *tri = tris[tri_index]; + int j_curr; + + BLI_assert(!ELEM(tri[0], tri[1], tri[2]) && + !ELEM(tri[1], tri[0], tri[2]) && + !ELEM(tri[2], tri[0], tri[1])); + + for (j_curr = 0; j_curr < 3; j_curr++) { + struct PolyEdge *e; + unsigned int e_v1 = tri[(j_curr ) ]; + unsigned int e_v2 = tri[(j_curr + 1) % 3]; + e = BLI_edgehash_lookup(ehash, e_v1, e_v2); + if (e) { + if (e->faces[0] == tri_index) { + BLI_assert(e->verts[0] == e_v1); + BLI_assert(e->verts[1] == e_v2); + } + else if (e->faces[1] == tri_index) { + BLI_assert(e->verts[0] == e_v2); + BLI_assert(e->verts[1] == e_v1); + } + else { + BLI_assert(0); + } + + BLI_assert(e->faces[0] != e->faces[1]); + BLI_assert(ELEM(e_v1, UNPACK3(tri))); + BLI_assert(ELEM(e_v2, UNPACK3(tri))); + BLI_assert(ELEM(e_v1, UNPACK2(e->verts))); + BLI_assert(ELEM(e_v2, UNPACK2(e->verts))); + BLI_assert(e_v1 != tris[e->faces[0]][e->faces_other_v[0]]); + BLI_assert(e_v1 != tris[e->faces[1]][e->faces_other_v[1]]); + BLI_assert(e_v2 != tris[e->faces[0]][e->faces_other_v[0]]); + BLI_assert(e_v2 != tris[e->faces[1]][e->faces_other_v[1]]); + + BLI_assert(ELEM(tri_index, UNPACK2(e->faces))); + } + } +} +#endif + +BLI_INLINE bool is_boundary_edge(unsigned int i_a, unsigned int i_b, const unsigned int coord_last) +{ + BLI_assert(i_a < i_b); + return ((i_a + 1 == i_b) || UNLIKELY((i_a == 0) && (i_b == coord_last))); +} +/** + * Assuming we have 2 triangles sharing an edge (2 - 4), + * check if the edge running from (1 - 3) gives better results. + * + * \return (negative number means the edge can be rotated, lager == better). + */ +static float quad_v2_rotate_beauty_calc( + const float v1[2], const float v2[2], const float v3[2], const float v4[2]) +{ + /* not a loop (only to be able to break out) */ + do { + bool is_zero_a, is_zero_b; + + const float area_2x_234 = cross_tri_v2(v2, v3, v4); + const float area_2x_241 = cross_tri_v2(v2, v4, v1); + + const float area_2x_123 = cross_tri_v2(v1, v2, v3); + const float area_2x_134 = cross_tri_v2(v1, v3, v4); + + { + BLI_assert((ELEM(v1, v2, v3, v4) == false) && + (ELEM(v2, v1, v3, v4) == false) && + (ELEM(v3, v1, v2, v4) == false) && + (ELEM(v4, v1, v2, v3) == false)); + + is_zero_a = (fabsf(area_2x_234) <= FLT_EPSILON); + is_zero_b = (fabsf(area_2x_241) <= FLT_EPSILON); + + if (is_zero_a && is_zero_b) { + break; + } + } + + if (is_zero_a == false && is_zero_b == false) { + /* both tri's are valid, check we make a concave quad */ + if (!is_quad_convex_v2(v1, v2, v3, v4)) { + break; + } + } + else { + /* one of the tri's was degenerate, chech we're not rotating + * into a different degenerate shape or flipping the face */ + if ((fabsf(area_2x_123) <= FLT_EPSILON) || (fabsf(area_2x_134) <= FLT_EPSILON)) { + /* one of the new rotations is degenerate */ + break; + } + + if ((area_2x_123 >= 0.0f) != (area_2x_134 >= 0.0f)) { + /* rotation would cause flipping */ + break; + } + } + + { + /* testing rule: the area divided by the perimeter, + * check if (1-3) beats the existing (2-4) edge rotation */ + float area_a, area_b; + float prim_a, prim_b; + float fac_24, fac_13; + + float len_12, len_23, len_34, len_41, len_24, len_13; + +#define AREA_FROM_CROSS(val) (fabsf(val) / 2.0f) + + /* edges around the quad */ + len_12 = len_v2v2(v1, v2); + len_23 = len_v2v2(v2, v3); + len_34 = len_v2v2(v3, v4); + len_41 = len_v2v2(v4, v1); + /* edges crossing the quad interior */ + len_13 = len_v2v2(v1, v3); + len_24 = len_v2v2(v2, v4); + + /* edge (2-4), current state */ + area_a = AREA_FROM_CROSS(area_2x_234); + area_b = AREA_FROM_CROSS(area_2x_241); + prim_a = len_23 + len_34 + len_24; + prim_b = len_24 + len_41 + len_12; + fac_24 = (area_a / prim_a) + (area_b / prim_b); + + /* edge (1-3), new state */ + area_a = AREA_FROM_CROSS(area_2x_123); + area_b = AREA_FROM_CROSS(area_2x_134); + prim_a = len_12 + len_23 + len_13; + prim_b = len_34 + len_41 + len_13; + fac_13 = (area_a / prim_a) + (area_b / prim_b); + +#undef AREA_FROM_CROSS + + /* negative number if (1-3) is an improved state */ + return fac_24 - fac_13; + } + } while (false); + + return FLT_MAX; +} + +static float polyedge_rotate_beauty_calc( + const float (*coords)[2], + const unsigned int (*tris)[3], + const struct PolyEdge *e) +{ + const float *v1, *v2, *v3, *v4; + + v1 = coords[tris[e->faces[0]][e->faces_other_v[0]]]; + v3 = coords[tris[e->faces[1]][e->faces_other_v[1]]]; + v2 = coords[e->verts[0]]; + v4 = coords[e->verts[1]]; + + return quad_v2_rotate_beauty_calc(v1, v2, v3, v4); +} + +static void polyedge_beauty_cost_update_single( + const float (*coords)[2], + const unsigned int (*tris)[3], + const struct PolyEdge *edges, + struct PolyEdge *e, + Heap *eheap, HeapNode **eheap_table) +{ + const unsigned int i = (unsigned int)(e - edges); + + if (eheap_table[i]) { + BLI_heap_remove(eheap, eheap_table[i]); + eheap_table[i] = NULL; + } + + { + /* recalculate edge */ + const float cost = polyedge_rotate_beauty_calc(coords, tris, e); + if (cost < 0.0f) { + eheap_table[i] = BLI_heap_insert(eheap, cost, e); + } + else { + eheap_table[i] = NULL; + } + } +} + +static void polyedge_beauty_cost_update( + const float (*coords)[2], + const unsigned int (*tris)[3], + const struct PolyEdge *edges, + struct PolyEdge *e, + Heap *eheap, HeapNode **eheap_table, + EdgeHash *ehash) +{ + const unsigned int *tri_0 = tris[e->faces[0]]; + const unsigned int *tri_1 = tris[e->faces[1]]; + unsigned int i; + + struct PolyEdge *e_arr[4] = { + BLI_edgehash_lookup(ehash, + tri_0[(e->faces_other_v[0] ) % 3], + tri_0[(e->faces_other_v[0] + 1) % 3]), + BLI_edgehash_lookup(ehash, + tri_0[(e->faces_other_v[0] + 2) % 3], + tri_0[(e->faces_other_v[0] ) % 3]), + BLI_edgehash_lookup(ehash, + tri_1[(e->faces_other_v[1] ) % 3], + tri_1[(e->faces_other_v[1] + 1) % 3]), + BLI_edgehash_lookup(ehash, + tri_1[(e->faces_other_v[1] + 2) % 3], + tri_1[(e->faces_other_v[1] ) % 3]), + }; + + + for (i = 0; i < 4; i++) { + if (e_arr[i]) { + BLI_assert(!(ELEM(e_arr[i]->faces[0], UNPACK2(e->faces)) && + ELEM(e_arr[i]->faces[1], UNPACK2(e->faces)))); + + polyedge_beauty_cost_update_single( + coords, tris, edges, + e_arr[i], + eheap, eheap_table); + } + } +} + +static void polyedge_rotate( + unsigned int (*tris)[3], + struct PolyEdge *e, + EdgeHash *ehash) +{ + unsigned int e_v1_new = tris[e->faces[0]][e->faces_other_v[0]]; + unsigned int e_v2_new = tris[e->faces[1]][e->faces_other_v[1]]; + +#ifndef NDEBUG + polyfill_validate_tri(tris, e->faces[0], ehash); + polyfill_validate_tri(tris, e->faces[1], ehash); +#endif + + BLI_assert(e_v1_new != e_v2_new); + BLI_assert(!ELEM(e_v2_new, UNPACK3(tris[e->faces[0]]))); + BLI_assert(!ELEM(e_v1_new, UNPACK3(tris[e->faces[1]]))); + + tris[e->faces[0]][(e->faces_other_v[0] + 1) % 3] = e_v2_new; + tris[e->faces[1]][(e->faces_other_v[1] + 1) % 3] = e_v1_new; + + e->faces_other_v[0] = (e->faces_other_v[0] + 2) % 3; + e->faces_other_v[1] = (e->faces_other_v[1] + 2) % 3; + + BLI_assert((tris[e->faces[0]][e->faces_other_v[0]] != e_v1_new) && + (tris[e->faces[0]][e->faces_other_v[0]] != e_v2_new)); + BLI_assert((tris[e->faces[1]][e->faces_other_v[1]] != e_v1_new) && + (tris[e->faces[1]][e->faces_other_v[1]] != e_v2_new)); + + BLI_edgehash_remove(ehash, e->verts[0], e->verts[1], NULL); + BLI_edgehash_insert(ehash, e_v1_new, e_v2_new, e); + + if (e_v1_new < e_v2_new) { + e->verts[0] = e_v1_new; + e->verts[1] = e_v2_new; + } + else { + /* maintain winding info */ + e->verts[0] = e_v2_new; + e->verts[1] = e_v1_new; + + SWAP(unsigned int, e->faces[0], e->faces[1]); + SWAP(unsigned int, e->faces_other_v[0], e->faces_other_v[1]); + } + + /* update adjacent data */ + { + unsigned int e_side = 0; + + for (e_side = 0; e_side < 2; e_side++) { + /* 't_other' which we need to swap out is always the same edge-order */ + const unsigned int t_other = (((e->faces_other_v[e_side]) + 2)) % 3; + unsigned int t_index = e->faces[e_side]; + unsigned int t_index_other = e->faces[!e_side]; + unsigned int *tri = tris[t_index]; + + struct PolyEdge *e_other; + unsigned int e_v1 = tri[(t_other ) ]; + unsigned int e_v2 = tri[(t_other + 1) % 3]; + + e_other = BLI_edgehash_lookup(ehash, e_v1, e_v2); + if (e_other) { + BLI_assert(t_index != e_other->faces[0] && t_index != e_other->faces[1]); + if (t_index_other == e_other->faces[0]) { + e_other->faces[0] = t_index; + e_other->faces_other_v[0] = (t_other + 2) % 3; + BLI_assert(!ELEM(tri[e_other->faces_other_v[0]], e_v1, e_v2)); + } + else if (t_index_other == e_other->faces[1]) { + e_other->faces[1] = t_index; + e_other->faces_other_v[1] = (t_other + 2) % 3; + BLI_assert(!ELEM(tri[e_other->faces_other_v[1]], e_v1, e_v2)); + } + else { + BLI_assert(0); + } + } + } + } + +#ifndef NDEBUG + polyfill_validate_tri(tris, e->faces[0], ehash); + polyfill_validate_tri(tris, e->faces[1], ehash); +#endif + + BLI_assert(!ELEM(tris[e->faces[0]][e->faces_other_v[0]], UNPACK2(e->verts))); + BLI_assert(!ELEM(tris[e->faces[1]][e->faces_other_v[1]], UNPACK2(e->verts))); +} + +/** + * The intention is that this calculates the output of #BLI_polyfill_calc + * + * + * \note assumes the \a coords form a boundary, + * so any edges running along contiguous (wrapped) indices, + * are ignored since the edges wont share 2 faces. + */ +void BLI_polyfill_beautify( + const float (*coords)[2], + const unsigned int coords_tot, + unsigned int (*tris)[3], + + /* structs for reuse */ + MemArena *arena, Heap *eheap, EdgeHash *ehash) +{ + const unsigned int coord_last = coords_tot - 1; + const unsigned int tris_tot = coords_tot - 2; + /* internal edges only (between 2 tris) */ + const unsigned int edges_tot = tris_tot - 1; + unsigned int edges_tot_used = 0; + unsigned int i; + + HeapNode **eheap_table; + + struct PolyEdge *edges = BLI_memarena_alloc(arena, edges_tot * sizeof(*edges)); + + BLI_assert(BLI_heap_size(eheap) == 0); + BLI_assert(BLI_edgehash_size(ehash) == 0); + + /* first build edges */ + for (i = 0; i < tris_tot; i++) { + unsigned int j_prev, j_curr, j_next; + j_prev = 2; + j_next = 1; + for (j_curr = 0; j_curr < 3; j_next = j_prev, j_prev = j_curr++) { + int e_index; + + unsigned int e_pair[2] = { + tris[i][j_prev], + tris[i][j_curr], + }; + + if (e_pair[0] > e_pair[1]) { + SWAP(unsigned int, e_pair[0], e_pair[1]); + e_index = 1; + } + else { + e_index = 0; + } + + if (!is_boundary_edge(e_pair[0], e_pair[1], coord_last)) { + struct PolyEdge *e = BLI_edgehash_lookup(ehash, e_pair[0], e_pair[1]); + if (e == NULL) { + e = &edges[edges_tot_used++]; + BLI_edgehash_insert(ehash, e_pair[0], e_pair[1], e); + memcpy(e->verts, e_pair, sizeof(e->verts)); +#ifndef NDEBUG + e->faces[!e_index] = (unsigned int)-1; +#endif + } + else { + + /* ensure each edge only ever has 2x users */ +#ifndef NDEBUG + BLI_assert(e->faces[e_index] == (unsigned int)-1); + BLI_assert((e->verts[0] == e_pair[0]) && + (e->verts[1] == e_pair[1])); +#endif + } + + e->faces[e_index] = i; + e->faces_other_v[e_index] = j_next; + } + } + } + + /* now perform iterative rotations */ + eheap_table = BLI_memarena_alloc(arena, sizeof(HeapNode *) * (size_t)edges_tot); + + // for (i = 0; i < tris_tot; i++) { polyfill_validate_tri(tris, i, eh); } + + /* build heap */ + for (i = 0; i < edges_tot; i++) { + struct PolyEdge *e = &edges[i]; + const float cost = polyedge_rotate_beauty_calc(coords, (const unsigned int (*)[3])tris, e); + if (cost < 0.0f) { + eheap_table[i] = BLI_heap_insert(eheap, cost, e); + } + else { + eheap_table[i] = NULL; + } + } + + while (BLI_heap_is_empty(eheap) == false) { + struct PolyEdge *e = BLI_heap_popmin(eheap); + i = (unsigned int)(e - edges); + eheap_table[i] = NULL; + + polyedge_rotate(tris, e, ehash); + + /* recalculate faces connected on the heap */ + polyedge_beauty_cost_update( + coords, (const unsigned int (*)[3])tris, edges, + e, + eheap, eheap_table, ehash); + } + + BLI_heap_clear(eheap, NULL); + BLI_edgehash_clear_ex(ehash, NULL, BLI_POLYFILL_ALLOC_NGON_RESERVE); + + /* MEM_freeN(eheap_table); */ /* arena */ +} diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c index cf0d8cff870..8a96daeeb91 100644 --- a/source/blender/blenlib/intern/scanfill.c +++ b/source/blender/blenlib/intern/scanfill.c @@ -173,13 +173,13 @@ static bool boundisect(PolyFill *pf2, PolyFill *pf1) /* has pf2 been touched (intersected) by pf1 ? with bounding box */ /* test first if polys exist */ - if (pf1->edges == 0 || pf2->edges == 0) return 0; + if (pf1->edges == 0 || pf2->edges == 0) return false; - if (pf2->max_xy[0] < pf1->min_xy[0]) return 0; - if (pf2->max_xy[1] < pf1->min_xy[1]) return 0; + if (pf2->max_xy[0] < pf1->min_xy[0]) return false; + if (pf2->max_xy[1] < pf1->min_xy[1]) return false; - if (pf2->min_xy[0] > pf1->max_xy[0]) return 0; - if (pf2->min_xy[1] > pf1->max_xy[1]) return 0; + if (pf2->min_xy[0] > pf1->max_xy[0]) return false; + if (pf2->min_xy[1] > pf1->max_xy[1]) return false; /* join */ if (pf2->max_xy[0] < pf1->max_xy[0]) pf2->max_xy[0] = pf1->max_xy[0]; @@ -188,7 +188,7 @@ static bool boundisect(PolyFill *pf2, PolyFill *pf1) if (pf2->min_xy[0] > pf1->min_xy[0]) pf2->min_xy[0] = pf1->min_xy[0]; if (pf2->min_xy[1] > pf1->min_xy[1]) pf2->min_xy[1] = pf1->min_xy[1]; - return 1; + return true; } @@ -225,13 +225,13 @@ static bool testedgeside(const float v1[2], const float v2[2], const float v3[2] (v1[1] - v2[1]) * (v1[0] - v3[0]); if (inp < 0.0f) { - return 0; + return false; } else if (inp == 0.0f) { - if (v1[0] == v3[0] && v1[1] == v3[1]) return 0; - if (v2[0] == v3[0] && v2[1] == v3[1]) return 0; + if (v1[0] == v3[0] && v1[1] == v3[1]) return false; + if (v2[0] == v3[0] && v2[1] == v3[1]) return false; } - return 1; + return true; } static bool addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed) @@ -261,7 +261,7 @@ static bool addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed) for (ed = sc->edge_first; ed; ed = ed->next) { if (ed->v2 == eed->v2) { - return 0; + return false; } fac = ed->v2->xy[1] - y; @@ -279,7 +279,7 @@ static bool addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed) if (ed) BLI_insertlinkbefore((ListBase *)&(sc->edge_first), ed, eed); else BLI_addtail((ListBase *)&(sc->edge_first), eed); - return 1; + return true; } @@ -341,10 +341,10 @@ static bool boundinsideEV(ScanFillEdge *eed, ScanFillVert *eve) maxy = eed->v1->xy[1]; } if (eve->xy[1] >= miny && eve->xy[1] <= maxy) { - return 1; + return true; } } - return 0; + return false; } @@ -807,7 +807,7 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const #if 0 if (flag & BLI_SCANFILL_CALC_QUADTRI_FASTPATH) { - const int totverts = BLI_countlist(&sf_ctx->fillvertbase); + const int totverts = BLI_listbase_count(&sf_ctx->fillvertbase); if (totverts == 3) { eve = sf_ctx->fillvertbase.first; diff --git a/source/blender/blenlib/intern/scanfill_utils.c b/source/blender/blenlib/intern/scanfill_utils.c index 9fc1db1f1e4..6ddea300404 100644 --- a/source/blender/blenlib/intern/scanfill_utils.c +++ b/source/blender/blenlib/intern/scanfill_utils.c @@ -76,7 +76,7 @@ typedef struct ScanFillIsect { #if 0 -void BKE_scanfill_obj_dump(ScanFillContext *sf_ctx) +void BLI_scanfill_obj_dump(ScanFillContext *sf_ctx) { FILE *f = fopen("test.obj", "w"); unsigned int i = 1; @@ -96,7 +96,7 @@ void BKE_scanfill_obj_dump(ScanFillContext *sf_ctx) #endif #if 0 -void BKE_scanfill_view3d_dump(ScanFillContext *sf_ctx) +void BLI_scanfill_view3d_dump(ScanFillContext *sf_ctx) { ScanFillEdge *eed; @@ -265,7 +265,7 @@ static bool scanfill_preprocess_self_isect( } if (BLI_listbase_is_single(e_ls) == false) { - BLI_sortlist_r(e_ls, eed->v2->co, edge_isect_ls_sort_cb); + BLI_listbase_sort_r(e_ls, eed->v2->co, edge_isect_ls_sort_cb); } /* move original edge to filledgebase and add replacement @@ -508,8 +508,8 @@ bool BLI_scanfill_calc_self_isect( sf_ctx->poly_nr = SF_POLY_UNSET; #if 0 - BKE_scanfill_view3d_dump(sf_ctx); - BKE_scanfill_obj_dump(sf_ctx); + BLI_scanfill_view3d_dump(sf_ctx); + BLI_scanfill_obj_dump(sf_ctx); #endif return changed; diff --git a/source/blender/blenlib/intern/smallhash.c b/source/blender/blenlib/intern/smallhash.c index 0cf9f69b9ae..ba336ab6c4b 100644 --- a/source/blender/blenlib/intern/smallhash.c +++ b/source/blender/blenlib/intern/smallhash.c @@ -118,7 +118,7 @@ BLI_INLINE void smallhash_buckets_reserve(SmallHash *sh, const unsigned int nent } } -BLI_INLINE SmallHashEntry *smallhash_lookup(SmallHash *sh, const uintptr_t key) +BLI_INLINE SmallHashEntry *smallhash_lookup(const SmallHash *sh, const uintptr_t key) { SmallHashEntry *e; unsigned int h = smallhash_key(key); @@ -246,6 +246,26 @@ void BLI_smallhash_insert(SmallHash *sh, uintptr_t key, void *val) e->val = val; } +/** + * Inserts a new value to a key that may already be in ghash. + * + * Avoids #BLI_smallhash_remove, #BLI_smallhash_insert calls (double lookups) + * + * \returns true if a new key has been added. + */ +bool BLI_smallhash_reinsert(SmallHash *sh, uintptr_t key, void *item) +{ + SmallHashEntry *e = smallhash_lookup(sh, key); + if (e) { + e->val = item; + return false; + } + else { + BLI_smallhash_insert(sh, key, item); + return true; + } +} + #ifdef USE_REMOVE bool BLI_smallhash_remove(SmallHash *sh, uintptr_t key) { @@ -264,33 +284,33 @@ bool BLI_smallhash_remove(SmallHash *sh, uintptr_t key) } #endif -void *BLI_smallhash_lookup(SmallHash *sh, uintptr_t key) +void *BLI_smallhash_lookup(const SmallHash *sh, uintptr_t key) { SmallHashEntry *e = smallhash_lookup(sh, key); return e ? e->val : NULL; } -void **BLI_smallhash_lookup_p(SmallHash *sh, uintptr_t key) +void **BLI_smallhash_lookup_p(const SmallHash *sh, uintptr_t key) { SmallHashEntry *e = smallhash_lookup(sh, key); return e ? &e->val : NULL; } -bool BLI_smallhash_haskey(SmallHash *sh, uintptr_t key) +bool BLI_smallhash_haskey(const SmallHash *sh, uintptr_t key) { SmallHashEntry *e = smallhash_lookup(sh, key); return (e != NULL); } -int BLI_smallhash_count(SmallHash *sh) +int BLI_smallhash_count(const SmallHash *sh) { return (int)sh->nentries; } -void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key) +BLI_INLINE SmallHashEntry *smallhash_iternext(SmallHashIter *iter, uintptr_t *key) { while (iter->i < iter->sh->nbuckets) { if (smallhash_val_is_used(iter->sh->buckets[iter->i].val)) { @@ -298,7 +318,7 @@ void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key) *key = iter->sh->buckets[iter->i].key; } - return iter->sh->buckets[iter->i++].val; + return &iter->sh->buckets[iter->i++]; } iter->i++; @@ -307,7 +327,21 @@ void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key) return NULL; } -void *BLI_smallhash_iternew(SmallHash *sh, SmallHashIter *iter, uintptr_t *key) +void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key) +{ + SmallHashEntry *e = smallhash_iternext(iter, key); + + return e ? e->val : NULL; +} + +void **BLI_smallhash_iternext_p(SmallHashIter *iter, uintptr_t *key) +{ + SmallHashEntry *e = smallhash_iternext(iter, key); + + return e ? &e->val : NULL; +} + +void *BLI_smallhash_iternew(const SmallHash *sh, SmallHashIter *iter, uintptr_t *key) { iter->sh = sh; iter->i = 0; @@ -315,6 +349,15 @@ void *BLI_smallhash_iternew(SmallHash *sh, SmallHashIter *iter, uintptr_t *key) return BLI_smallhash_iternext(iter, key); } +void **BLI_smallhash_iternew_p(const SmallHash *sh, SmallHashIter *iter, uintptr_t *key) +{ + iter->sh = sh; + iter->i = 0; + + return BLI_smallhash_iternext_p(iter, key); +} + + /** \name Debugging & Introspection * \{ */ diff --git a/source/blender/blenlib/intern/sort.c b/source/blender/blenlib/intern/sort.c index 9fad7505f79..c5922feb0ed 100644 --- a/source/blender/blenlib/intern/sort.c +++ b/source/blender/blenlib/intern/sort.c @@ -32,7 +32,9 @@ #include <stdlib.h> -#ifndef __GLIBC__ +#if defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)) +/* do nothing! */ +#else #include "BLI_utildefines.h" diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index f3ecc799e1e..c062d62bca5 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -280,7 +280,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) closedir(dir); } else { - printf("%s non-existant directory\n", dirname); + printf("%s non-existent directory\n", dirname); } } diff --git a/source/blender/blenlib/intern/system.c b/source/blender/blenlib/intern/system.c index e6389bc68f3..51b8efbb79f 100644 --- a/source/blender/blenlib/intern/system.c +++ b/source/blender/blenlib/intern/system.c @@ -22,9 +22,18 @@ * \ingroup bli */ +#include <stdio.h> +#include <stdlib.h> #include "BLI_system.h" +/* for backtrace */ +#if defined(__linux__) || defined(__APPLE__) +# include <execinfo.h> +#elif defined(_MSV_VER) +# include <DbgHelp.h> +#endif + int BLI_cpu_support_sse2(void) { #if defined(__x86_64__) || defined(_M_X64) @@ -57,3 +66,69 @@ int BLI_cpu_support_sse2(void) #endif } +/** + * Write a backtrace into a file for systems which support it. + */ +void BLI_system_backtrace(FILE *fp) +{ + /* ------------- */ + /* Linux / Apple */ +#if defined(__linux__) || defined(__APPLE__) + +#define SIZE 100 + void *buffer[SIZE]; + int nptrs; + char **strings; + int i; + + /* include a backtrace for good measure */ + nptrs = backtrace(buffer, SIZE); + strings = backtrace_symbols(buffer, nptrs); + for (i = 0; i < nptrs; i++) { + fputs(strings[i], fp); + fputc('\n', fp); + } + + free(strings); +#undef SIZE + + /* -------- */ + /* Windows */ +#elif defined(_MSC_VER) + + (void)fp; +#if 0 +#define MAXSYMBOL 256 + unsigned short i; + void *stack[SIZE]; + unsigned short nframes; + SYMBOL_INFO *symbolinfo; + HANDLE process; + + process = GetCurrentProcess(); + + SymInitialize(process, NULL, true); + + nframes = CaptureStackBackTrace(0, SIZE, stack, NULL); + symbolinfo = MEM_callocN(sizeof(SYMBOL_INFO) + MAXSYMBOL * sizeof(char), "crash Symbol table"); + symbolinfo->MaxNameLen = MAXSYMBOL - 1; + symbolinfo->SizeOfStruct = sizeof(SYMBOL_INFO); + + for (i = 0; i < nframes; i++) { + SymFromAddr(process, ( DWORD64 )( stack[ i ] ), 0, symbolinfo); + + fprintf(fp, "%u: %s - 0x%0X\n", nframes - i - 1, symbolinfo->Name, symbolinfo->Address); + } + + MEM_freeN(symbolinfo); +#undef MAXSYMBOL +#endif + + /* ------------------ */ + /* non msvc/osx/linux */ +#else + (void)fp; +#endif + +} +/* end BLI_system_backtrace */ diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c index 8d867b9f295..d187a8d1968 100644 --- a/source/blender/blenlib/intern/task.c +++ b/source/blender/blenlib/intern/task.c @@ -29,9 +29,12 @@ #include "MEM_guardedalloc.h" #include "BLI_listbase.h" +#include "BLI_math.h" #include "BLI_task.h" #include "BLI_threads.h" +#include "atomic_ops.h" + /* Types */ typedef struct Task { @@ -48,6 +51,8 @@ struct TaskPool { volatile size_t num; volatile size_t done; + size_t num_threads; + size_t currently_running_tasks; ThreadMutex num_mutex; ThreadCondition num_cond; @@ -83,6 +88,7 @@ static void task_pool_num_decrease(TaskPool *pool, size_t done) BLI_assert(pool->num >= done); pool->num -= done; + atomic_sub_z(&pool->currently_running_tasks, done); pool->done += done; if (pool->num == 0) @@ -103,19 +109,37 @@ static void task_pool_num_increase(TaskPool *pool) static bool task_scheduler_thread_wait_pop(TaskScheduler *scheduler, Task **task) { + bool found_task = false; BLI_mutex_lock(&scheduler->queue_mutex); while (!scheduler->queue.first && !scheduler->do_exit) BLI_condition_wait(&scheduler->queue_cond, &scheduler->queue_mutex); - if (!scheduler->queue.first) { - BLI_mutex_unlock(&scheduler->queue_mutex); - BLI_assert(scheduler->do_exit); - return false; - } - - *task = scheduler->queue.first; - BLI_remlink(&scheduler->queue, *task); + do { + Task *current_task; + if (!scheduler->queue.first) { + BLI_mutex_unlock(&scheduler->queue_mutex); + BLI_assert(scheduler->do_exit); + return false; + } + for (current_task = scheduler->queue.first; + current_task != NULL; + current_task = current_task->next) + { + TaskPool *pool = current_task->pool; + if (pool->num_threads == 0 || + pool->currently_running_tasks < pool->num_threads) + { + *task = current_task; + found_task = true; + atomic_add_z(&pool->currently_running_tasks, 1); + BLI_remlink(&scheduler->queue, *task); + break; + } + } + if (!found_task) + BLI_condition_wait(&scheduler->queue_cond, &scheduler->queue_mutex); + } while (!found_task); BLI_mutex_unlock(&scheduler->queue_mutex); @@ -287,6 +311,8 @@ TaskPool *BLI_task_pool_create(TaskScheduler *scheduler, void *userdata) pool->scheduler = scheduler; pool->num = 0; + pool->num_threads = 0; + pool->currently_running_tasks = 0; pool->do_cancel = false; BLI_mutex_init(&pool->num_mutex); @@ -350,12 +376,16 @@ void BLI_task_pool_work_and_wait(TaskPool *pool) /* find task from this pool. if we get a task from another pool, * we can get into deadlock */ - for (task = scheduler->queue.first; task; task = task->next) { - if (task->pool == pool) { - work_task = task; - found_task = true; - BLI_remlink(&scheduler->queue, task); - break; + if (pool->num_threads == 0 || + pool->currently_running_tasks < pool->num_threads) + { + for (task = scheduler->queue.first; task; task = task->next) { + if (task->pool == pool) { + work_task = task; + found_task = true; + BLI_remlink(&scheduler->queue, task); + break; + } } } @@ -364,6 +394,7 @@ void BLI_task_pool_work_and_wait(TaskPool *pool) /* if found task, do it, otherwise wait until other tasks are done */ if (found_task) { /* run task */ + atomic_add_z(&pool->currently_running_tasks, 1); work_task->run(pool, work_task->taskdata, 0); /* delete task */ @@ -386,6 +417,12 @@ void BLI_task_pool_work_and_wait(TaskPool *pool) BLI_mutex_unlock(&pool->num_mutex); } +void BLI_pool_set_num_threads(TaskPool *pool, int num_threads) +{ + /* NOTE: Don't try to modify threads while tasks are running! */ + pool->num_threads = num_threads; +} + void BLI_task_pool_cancel(TaskPool *pool) { pool->do_cancel = true; @@ -428,3 +465,131 @@ size_t BLI_task_pool_tasks_done(TaskPool *pool) return pool->done; } +/* Parallel range routines */ + +/** + * + * Main functions: + * - #BLI_task_parallel_range + * + * TODO: + * - #BLI_task_parallel_foreach_listbase (#ListBase - double linked list) + * - #BLI_task_parallel_foreach_link (#Link - single linked list) + * - #BLI_task_parallel_foreach_ghash/gset (#GHash/#GSet - hash & set) + * - #BLI_task_parallel_foreach_mempool (#BLI_mempool - iterate over mempools) + * + * Possible improvements: + * + * - Chunk iterations to reduce number of spin locks. + */ + +typedef struct ParallelRangeState { + int start, stop; + void *userdata; + TaskParallelRangeFunc func; + + int iter; + int chunk_size; + SpinLock lock; +} ParallelRangeState; + +BLI_INLINE bool parallel_range_next_iter_get( + ParallelRangeState * __restrict state, + int * __restrict iter, int * __restrict count) +{ + bool result = false; + if (state->iter < state->stop) { + BLI_spin_lock(&state->lock); + if (state->iter < state->stop) { + *count = min_ii(state->chunk_size, state->stop - state->iter); + *iter = state->iter; + state->iter += *count; + result = true; + } + BLI_spin_unlock(&state->lock); + } + return result; +} + +static void parallel_range_func( + TaskPool * __restrict pool, + void *UNUSED(taskdata), + int UNUSED(threadid)) +{ + ParallelRangeState * __restrict state = BLI_task_pool_userdata(pool); + int iter, count; + while (parallel_range_next_iter_get(state, &iter, &count)) { + int i; + for (i = 0; i < count; ++i) { + state->func(state->userdata, iter + i); + } + } +} + +void BLI_task_parallel_range_ex( + int start, int stop, + void *userdata, + TaskParallelRangeFunc func, + const int range_threshold, + const bool use_dynamic_scheduling) +{ + TaskScheduler *task_scheduler; + TaskPool *task_pool; + ParallelRangeState state; + int i, num_threads, num_tasks; + + BLI_assert(start < stop); + + /* If it's not enough data to be crunched, don't bother with tasks at all, + * do everything from the main thread. + */ + if (stop - start < range_threshold) { + for (i = start; i < stop; ++i) { + func(userdata, i); + } + return; + } + + task_scheduler = BLI_task_scheduler_get(); + task_pool = BLI_task_pool_create(task_scheduler, &state); + num_threads = BLI_task_scheduler_num_threads(task_scheduler); + + /* The idea here is to prevent creating task for each of the loop iterations + * and instead have tasks which are evenly distributed across CPU cores and + * pull next iter to be crunched using the queue. + */ + num_tasks = num_threads * 2; + + BLI_spin_init(&state.lock); + state.start = start; + state.stop = stop; + state.userdata = userdata; + state.func = func; + state.iter = start; + if (use_dynamic_scheduling) { + state.chunk_size = 32; + } + else { + state.chunk_size = (stop - start) / (num_tasks); + } + + for (i = 0; i < num_tasks; i++) { + BLI_task_pool_push(task_pool, + parallel_range_func, + NULL, false, + TASK_PRIORITY_HIGH); + } + + BLI_task_pool_work_and_wait(task_pool); + BLI_task_pool_free(task_pool); + + BLI_spin_end(&state.lock); +} + +void BLI_task_parallel_range( + int start, int stop, + void *userdata, + TaskParallelRangeFunc func) +{ + BLI_task_parallel_range_ex(start, stop, userdata, func, 64, false); +} diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index d9bcfc2e8f9..95440158277 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -308,6 +308,9 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain, const char *filename, MemFil /* makes lookup of existing video clips in old main */ blo_make_movieclip_pointer_map(fd, oldmain); + + /* make lookups of existing sound data in old main */ + blo_make_sound_pointer_map(fd, oldmain); /* removed packed data from this trick - it's internal data that needs saves */ @@ -318,7 +321,10 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain, const char *filename, MemFil /* ensures relinked movie clips are not freed */ blo_end_movieclip_pointer_map(fd, oldmain); - + + /* ensures relinked sounds are not freed */ + blo_end_sound_pointer_map(fd, oldmain); + /* move libraries from old main to new main */ if (bfd && mainlist.first != mainlist.last) { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ede2e08b396..cd1d63aac5b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -141,13 +141,9 @@ #include "BKE_treehash.h" #include "BKE_sound.h" -#include "IMB_imbuf.h" // for proxy / timecode versioning stuff #include "NOD_common.h" #include "NOD_socket.h" -#include "NOD_composite.h" -#include "NOD_shader.h" -#include "NOD_texture.h" #include "BLO_readfile.h" #include "BLO_undofile.h" @@ -157,7 +153,6 @@ #include "readfile.h" -#include "PIL_time.h" #include <errno.h> @@ -256,6 +251,12 @@ void blo_reportf_wrap(ReportList *reports, ReportType type, const char *format, } } +/* for reporting linking messages */ +static const char *library_parent_filepath(Library *lib) +{ + return lib->parent ? lib->parent->filepath : "<direct>"; +} + static OldNewMap *oldnewmap_new(void) { OldNewMap *onm= MEM_callocN(sizeof(*onm), "OldNewMap"); @@ -1122,6 +1123,8 @@ void blo_freefiledata(FileData *fd) oldnewmap_free(fd->imamap); if (fd->movieclipmap) oldnewmap_free(fd->movieclipmap); + if (fd->soundmap) + oldnewmap_free(fd->soundmap); if (fd->packedmap) oldnewmap_free(fd->packedmap); if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP)) @@ -1149,6 +1152,9 @@ bool BLO_is_a_library(const char *path, char *dir, char *group) int len; char *fd; + /* if path leads to a directory we can be sure we're not in a library */ + if (BLI_is_dir(path)) return 0; + strcpy(dir, path); len = strlen(dir); if (len < 7) return 0; @@ -1212,6 +1218,13 @@ static void *newmclipadr(FileData *fd, void *adr) /* used to restore movie return NULL; } +static void *newsoundadr(FileData *fd, void *adr) /* used to restore sound data after undo */ +{ + if (fd->soundmap && adr) + return oldnewmap_lookup_and_inc(fd->soundmap, adr, true); + return NULL; +} + static void *newpackedadr(FileData *fd, void *adr) /* used to restore packed data after undo */ { if (fd->packedmap && adr) @@ -1428,6 +1441,37 @@ void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain) } } +void blo_make_sound_pointer_map(FileData *fd, Main *oldmain) +{ + bSound *sound = oldmain->sound.first; + + fd->soundmap = oldnewmap_new(); + + for (; sound; sound = sound->id.next) { + if (sound->waveform) + oldnewmap_insert(fd->soundmap, sound->waveform, sound->waveform, 0); + } +} + +/* set old main sound caches to zero if it has been restored */ +/* this works because freeing old main only happens after this call */ +void blo_end_sound_pointer_map(FileData *fd, Main *oldmain) +{ + OldNew *entry = fd->soundmap->entries; + bSound *sound = oldmain->sound.first; + int i; + + /* used entries were restored, so we put them to zero */ + for (i = 0; i < fd->soundmap->nentries; i++, entry++) { + if (entry->nr > 0) + entry->newp = NULL; + } + + for (; sound; sound = sound->id.next) { + sound->waveform = newsoundadr(fd, sound->waveform); + } +} + /* XXX disabled this feature - packed files also belong in temp saves and quit.blend, to make restore work */ static void insert_packedmap(FileData *fd, PackedFile *pf) @@ -3210,6 +3254,7 @@ static void direct_link_world(FileData *fd, World *wrld) } wrld->preview = direct_link_preview_image(fd, wrld->preview); + BLI_listbase_clear(&wrld->gpumaterial); } @@ -3304,7 +3349,7 @@ static void direct_link_image(FileData *fd, Image *ima) { /* for undo system, pointers could be restored */ if (fd->imamap) - ima->cache = newmclipadr(fd, ima->cache); + ima->cache = newimaadr(fd, ima->cache); else ima->cache = NULL; @@ -5114,6 +5159,36 @@ static void lib_link_sequence_modifiers(FileData *fd, Scene *scene, ListBase *lb } } +/* check for cyclic set-scene, + * libs can cause this case which is normally prevented, see (T#####) */ +#define USE_SETSCENE_CHECK + +#ifdef USE_SETSCENE_CHECK +/** + * A version of #BKE_scene_validate_setscene with special checks for linked libs. + */ +static bool scene_validate_setscene__liblink(Scene *sce, const int totscene) +{ + Scene *sce_iter; + int a; + + if (sce->set == NULL) return 1; + + for (a = 0, sce_iter = sce; sce_iter->set; sce_iter = sce_iter->set, a++) { + if (sce_iter->id.flag & LIB_NEED_LINK) { + return 1; + } + + if (a > totscene) { + sce->set = NULL; + return 0; + } + } + + return 1; +} +#endif + static void lib_link_scene(FileData *fd, Main *main) { Scene *sce; @@ -5123,6 +5198,11 @@ static void lib_link_scene(FileData *fd, Main *main) TimeMarker *marker; FreestyleModuleConfig *fmc; FreestyleLineSet *fls; + +#ifdef USE_SETSCENE_CHECK + bool need_check_set = false; + int totscene = 0; +#endif for (sce = main->scene.first; sce; sce = sce->id.next) { if (sce->id.flag & LIB_NEED_LINK) { @@ -5268,12 +5348,45 @@ static void lib_link_scene(FileData *fd, Main *main) /* Motion Tracking */ sce->clip = newlibadr_us(fd, sce->id.lib, sce->clip); - - sce->id.flag -= LIB_NEED_LINK; + +#ifdef USE_SETSCENE_CHECK + if (sce->set != NULL) { + /* link flag for scenes with set would be reset later, + * so this way we only check cyclic for newly linked scenes. + */ + need_check_set = true; + } + else { + /* postpone un-setting the flag until we've checked the set-scene */ + sce->id.flag &= ~LIB_NEED_LINK; + } +#else + sce->id.flag &= ~LIB_NEED_LINK; +#endif + } + +#ifdef USE_SETSCENE_CHECK + totscene++; +#endif + } + +#ifdef USE_SETSCENE_CHECK + if (need_check_set) { + for (sce = main->scene.first; sce; sce = sce->id.next) { + if (sce->id.flag & LIB_NEED_LINK) { + sce->id.flag &= ~LIB_NEED_LINK; + if (!scene_validate_setscene__liblink(sce, totscene)) { + printf("Found cyclic background scene when linking %s\n", sce->id.name + 2); + } + } } } +#endif } +#undef USE_SETSCENE_CHECK + + static void link_recurs_seq(FileData *fd, ListBase *lb) { Sequence *seq; @@ -5379,7 +5492,7 @@ static void direct_link_scene(FileData *fd, Scene *sce) } if (sce->ed) { - ListBase *old_seqbasep = &((Editing *)sce->ed)->seqbase; + ListBase *old_seqbasep = &sce->ed->seqbase; ed = sce->ed = newdataadr(fd, sce->ed); @@ -5393,6 +5506,7 @@ static void direct_link_scene(FileData *fd, Scene *sce) seq->seq1= newdataadr(fd, seq->seq1); seq->seq2= newdataadr(fd, seq->seq2); seq->seq3= newdataadr(fd, seq->seq3); + /* a patch: after introduction of effects with 3 input strips */ if (seq->seq3 == NULL) seq->seq3 = seq->seq2; @@ -5562,6 +5676,9 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) win->eventstate = NULL; win->curswin = NULL; win->tweak = NULL; +#ifdef WIN32 + win->ime_data = NULL; +#endif BLI_listbase_clear(&win->queue); BLI_listbase_clear(&win->handlers); @@ -5617,6 +5734,21 @@ static void lib_link_windowmanager(FileData *fd, Main *main) /* ****************** READ GREASE PENCIL ***************** */ +/* relink's grease pencil data's refs */ +static void lib_link_gpencil(FileData *fd, Main *main) +{ + bGPdata *gpd; + + for (gpd = main->gpencil.first; gpd; gpd = gpd->id.next) { + if (gpd->id.flag & LIB_NEED_LINK) { + gpd->id.flag -= LIB_NEED_LINK; + + if (gpd->adt) + lib_link_animdata(fd, &gpd->id, gpd->adt); + } + } +} + /* relinks grease-pencil data - used for direct_link and old file linkage */ static void direct_link_gpencil(FileData *fd, bGPdata *gpd) { @@ -5628,6 +5760,10 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd) if (gpd == NULL) return; + /* relink animdata */ + gpd->adt = newdataadr(fd, gpd->adt); + direct_link_animdata(fd, gpd->adt); + /* relink layers */ link_list(fd, &gpd->layers); @@ -6698,14 +6834,26 @@ static void direct_link_sound(FileData *fd, bSound *sound) { sound->handle = NULL; sound->playback_handle = NULL; - sound->waveform = NULL; - // versioning stuff, if there was a cache, then we enable caching: + /* versioning stuff, if there was a cache, then we enable caching: */ if (sound->cache) { sound->flags |= SOUND_FLAGS_CACHING; sound->cache = NULL; } + if (fd->soundmap) { + sound->waveform = newsoundadr(fd, sound->waveform); + } + else { + sound->waveform = NULL; + } + + if (sound->mutex) + sound->mutex = BLI_mutex_alloc(); + + /* clear waveform loading flag */ + sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING; + sound->packedfile = direct_link_packedfile(fd, sound->packedfile); sound->newpackedfile = direct_link_packedfile(fd, sound->newpackedfile); } @@ -7587,6 +7735,7 @@ static void lib_link_all(FileData *fd, Main *main) lib_link_movieclip(fd, main); lib_link_mask(fd, main); lib_link_linestyle(fd, main); + lib_link_gpencil(fd, main); lib_link_mesh(fd, main); /* as last: tpage images with users at zero */ @@ -8692,6 +8841,12 @@ static void expand_linestyle(FileData *fd, Main *mainvar, FreestyleLineStyle *li } } +static void expand_gpencil(FileData *fd, Main *mainvar, bGPdata *gpd) +{ + if (gpd->adt) + expand_animdata(fd, mainvar, gpd->adt); +} + void BLO_main_expander(void (*expand_doit_func)(void *, Main *, void *)) { expand_doit = expand_doit_func; @@ -8786,6 +8941,9 @@ void BLO_expand_main(void *fdhandle, Main *mainvar) case ID_LS: expand_linestyle(fd, mainvar, (FreestyleLineStyle *)id); break; + case ID_GD: + expand_gpencil(fd, mainvar, (bGPdata *)id); + break; } do_it = true; @@ -9218,8 +9376,10 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) if (mainptr->curlib->packedfile) { PackedFile *pf = mainptr->curlib->packedfile; - blo_reportf_wrap(basefd->reports, RPT_INFO, TIP_("Read packed library: '%s'"), - mainptr->curlib->name); + blo_reportf_wrap( + basefd->reports, RPT_INFO, TIP_("Read packed library: '%s', parent '%s'"), + mainptr->curlib->name, + library_parent_filepath(mainptr->curlib)); fd = blo_openblendermemory(pf->data, pf->size, basefd->reports); @@ -9227,8 +9387,11 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) BLI_strncpy(fd->relabase, mainptr->curlib->filepath, sizeof(fd->relabase)); } else { - blo_reportf_wrap(basefd->reports, RPT_INFO, TIP_("Read library: '%s', '%s'"), - mainptr->curlib->filepath, mainptr->curlib->name); + blo_reportf_wrap( + basefd->reports, RPT_INFO, TIP_("Read library: '%s', '%s', parent '%s'"), + mainptr->curlib->filepath, + mainptr->curlib->name, + library_parent_filepath(mainptr->curlib)); fd = blo_openblenderfile(mainptr->curlib->filepath, basefd->reports); } /* allow typing in a new lib path */ @@ -9299,10 +9462,13 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) append_id_part(fd, mainptr, id, &realid); if (!realid) { - blo_reportf_wrap(fd->reports, RPT_WARNING, - TIP_("LIB ERROR: %s: '%s' missing from '%s'"), - BKE_idcode_to_name(GS(id->name)), - id->name + 2, mainptr->curlib->filepath); + blo_reportf_wrap( + fd->reports, RPT_WARNING, + TIP_("LIB ERROR: %s: '%s' missing from '%s', parent '%s'"), + BKE_idcode_to_name(GS(id->name)), + id->name + 2, + mainptr->curlib->filepath, + library_parent_filepath(mainptr->curlib)); } change_idid_adr(mainlist, basefd, id, realid); @@ -9331,9 +9497,13 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) idn = id->next; if (id->flag & LIB_READ) { BLI_remlink(lbarray[a], id); - blo_reportf_wrap(basefd->reports, RPT_WARNING, - TIP_("LIB ERROR: %s: '%s' unread lib block missing from '%s'"), - BKE_idcode_to_name(GS(id->name)), id->name + 2, mainptr->curlib->filepath); + blo_reportf_wrap( + basefd->reports, RPT_WARNING, + TIP_("LIB ERROR: %s: '%s' unread lib block missing from '%s', parent '%s'"), + BKE_idcode_to_name(GS(id->name)), + id->name + 2, + mainptr->curlib->filepath, + library_parent_filepath(mainptr->curlib)); change_idid_adr(mainlist, basefd, id, NULL); MEM_freeN(id); diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h index d56f58d1b37..2b40accbf21 100644 --- a/source/blender/blenloader/intern/readfile.h +++ b/source/blender/blenloader/intern/readfile.h @@ -88,6 +88,7 @@ typedef struct FileData { struct OldNewMap *libmap; struct OldNewMap *imamap; struct OldNewMap *movieclipmap; + struct OldNewMap *soundmap; struct OldNewMap *packedmap; struct BHeadSort *bheadmap; @@ -133,6 +134,8 @@ void blo_make_image_pointer_map(FileData *fd, Main *oldmain); void blo_end_image_pointer_map(FileData *fd, Main *oldmain); void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain); void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain); +void blo_make_sound_pointer_map(FileData *fd, Main *oldmain); +void blo_end_sound_pointer_map(FileData *fd, Main *oldmain); void blo_make_packed_pointer_map(FileData *fd, Main *oldmain); void blo_end_packed_pointer_map(FileData *fd, Main *oldmain); void blo_add_library_pointer_map(ListBase *mainlist, FileData *fd); diff --git a/source/blender/blenloader/intern/runtime.c b/source/blender/blenloader/intern/runtime.c index d6fd2f92443..ec496e1c866 100644 --- a/source/blender/blenloader/intern/runtime.c +++ b/source/blender/blenloader/intern/runtime.c @@ -51,7 +51,6 @@ #include "BLO_readfile.h" #include "BLO_runtime.h" -#include "BKE_blender.h" #include "BKE_report.h" /* Runtime reading */ diff --git a/source/blender/blenloader/intern/undofile.c b/source/blender/blenloader/intern/undofile.c index 12f4a295a34..f70d889828f 100644 --- a/source/blender/blenloader/intern/undofile.c +++ b/source/blender/blenloader/intern/undofile.c @@ -40,7 +40,6 @@ #include "DNA_listBase.h" #include "BLI_blenlib.h" -#include "BLI_linklist.h" #include "BLO_undofile.h" diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index 40b756a3f7c..b71a4029690 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -25,11 +25,10 @@ * \ingroup blenloader */ -#include "zlib.h" - #ifndef WIN32 # include <unistd.h> /* for read close */ #else +# include <zlib.h> /* odd include order-issue */ # include <io.h> // for open close read # include "winsock2.h" # include "BLI_winstuff.h" @@ -90,14 +89,9 @@ #include "NOD_socket.h" #include "BLO_readfile.h" -#include "BLO_undofile.h" - -#include "RE_engine.h" #include "readfile.h" -#include "PIL_time.h" - #include <errno.h> /* 2.50 patch */ diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c index 7c6b6ec7249..7e5127aa407 100644 --- a/source/blender/blenloader/intern/versioning_260.c +++ b/source/blender/blenloader/intern/versioning_260.c @@ -25,8 +25,6 @@ * \ingroup blenloader */ -#include "zlib.h" - #include "BLI_utildefines.h" /* allow readfile to use deprecated functionality */ diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index d8da0a12b50..372a0b06d01 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -49,13 +49,11 @@ #include "DNA_genfile.h" -#include "BLI_blenlib.h" -#include "BLI_math.h" - #include "BKE_main.h" #include "BKE_node.h" #include "BLI_math.h" +#include "BLI_listbase.h" #include "BLI_string.h" #include "BLO_readfile.h" @@ -114,6 +112,19 @@ static void do_version_constraints_radians_degrees_270_5(ListBase *lb) } } +static void do_version_constraints_stretch_to_limits(ListBase *lb) +{ + bConstraint *con; + + for (con = lb->first; con; con = con->next) { + if (con->type == CONSTRAINT_TYPE_STRETCHTO) { + bStretchToConstraint *data = (bStretchToConstraint *)con->data; + data->bulge_min = 1.0f; + data->bulge_max = 1.0f; + } + } +} + void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) { if (!MAIN_VERSION_ATLEAST(main, 270, 0)) { @@ -297,7 +308,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) { Scene *scene; for (scene = main->scene.first; scene; scene = scene->id.next) { - int num_layers = BLI_countlist(&scene->r.layers); + int num_layers = BLI_listbase_count(&scene->r.layers); scene->r.actlay = min_ff(scene->r.actlay, num_layers - 1); } } @@ -390,7 +401,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) } } } - + if (!MAIN_VERSION_ATLEAST(main, 272, 1)) { Brush *br; for (br = main->brush.first; br; br = br->id.next) { @@ -399,10 +410,29 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) } } - if (!DNA_struct_elem_find(fd->filesdna, "Image", "float", "gen_color")) { - Image *image; - for (image = main->image.first; image != NULL; image = image->id.next) { - image->gen_color[3] = 1.0f; + if (!MAIN_VERSION_ATLEAST(main, 272, 2)) { + if (!DNA_struct_elem_find(fd->filesdna, "Image", "float", "gen_color")) { + Image *image; + for (image = main->image.first; image != NULL; image = image->id.next) { + image->gen_color[3] = 1.0f; + } + } + + if (!DNA_struct_elem_find(fd->filesdna, "bStretchToConstraint", "float", "bulge_min")) { + Object *ob; + + /* Update Transform constraint (again :|). */ + for (ob = main->object.first; ob; ob = ob->id.next) { + do_version_constraints_stretch_to_limits(&ob->constraints); + + if (ob->pose) { + /* Bones constraints! */ + bPoseChannel *pchan; + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + do_version_constraints_stretch_to_limits(&pchan->constraints); + } + } + } } } } diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c index 1afcac313a2..4732f8578ed 100644 --- a/source/blender/blenloader/intern/versioning_defaults.c +++ b/source/blender/blenloader/intern/versioning_defaults.c @@ -147,6 +147,24 @@ void BLO_update_defaults_startup_blend(Main *bmain) br->imagepaint_tool = PAINT_TOOL_MASK; br->ob_mode |= OB_MODE_TEXTURE_PAINT; } + + /* remove polish brush (flatten/contrast does the same) */ + br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Polish"); + if (br) { + BKE_libblock_free(bmain, br); + } + + /* remove brush brush (huh?) from some modes (draw brushes do the same) */ + br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Brush"); + if (br) { + BKE_libblock_free(bmain, br); + } + + /* remove draw brush from texpaint (draw brushes do the same) */ + br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Draw"); + if (br) { + br->ob_mode &= ~OB_MODE_TEXTURE_PAINT; + } } } diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c index 557cc147f19..1a1bc3a55be 100644 --- a/source/blender/blenloader/intern/versioning_legacy.c +++ b/source/blender/blenloader/intern/versioning_legacy.c @@ -30,13 +30,12 @@ */ -#include "zlib.h" - #include <limits.h> #ifndef WIN32 # include <unistd.h> // for read close #else +# include <zlib.h> /* odd include order-issue */ # include <io.h> // for open close read # include "winsock2.h" # include "BLI_winstuff.h" @@ -94,14 +93,9 @@ #include "BKE_scene.h" #include "BKE_sequencer.h" -#include "IMB_imbuf.h" // for proxy / timecode versioning stuff - #include "NOD_socket.h" #include "BLO_readfile.h" -#include "BLO_undofile.h" - -#include "RE_engine.h" #include "readfile.h" @@ -3085,7 +3079,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) BLI_addtail(&ob->particlesystem, psys); md = modifier_new(eModifierType_ParticleSystem); - BLI_snprintf(md->name, sizeof(md->name), "ParticleSystem %i", BLI_countlist(&ob->particlesystem)); + BLI_snprintf(md->name, sizeof(md->name), "ParticleSystem %i", BLI_listbase_count(&ob->particlesystem)); psmd = (ParticleSystemModifierData*) md; psmd->psys = psys; BLI_addtail(&ob->modifiers, md); diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 59f12657703..bf82a4fa551 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -79,9 +79,8 @@ #include <string.h> #include <stdlib.h> -#include "zlib.h" - #ifdef WIN32 +# include <zlib.h> /* odd include order-issue */ # include "winsock2.h" # include <io.h> # include "BLI_winstuff.h" @@ -163,11 +162,9 @@ #include "BKE_mesh.h" #ifdef USE_NODE_COMPAT_CUSTOMNODES -#include "NOD_common.h" #include "NOD_socket.h" /* for sock->default_value data */ #endif -#include "RNA_access.h" #include "BLO_writefile.h" #include "BLO_readfile.h" @@ -2060,7 +2057,8 @@ static void write_lattices(WriteData *wd, ListBase *idbase) static void write_previews(WriteData *wd, PreviewImage *prv) { - if (prv) { + /* Never write previews in undo steps! */ + if (prv && !wd->current) { short w = prv->w[1]; short h = prv->h[1]; unsigned int *rect = prv->rect[1]; @@ -2468,6 +2466,8 @@ static void write_gpencils(WriteData *wd, ListBase *lb) /* write gpd data block to file */ writestruct(wd, ID_GD, "bGPdata", 1, gpd); + if (gpd->adt) write_animdata(wd, gpd->adt); + /* write grease-pencil layers to file */ writelist(wd, DATA, "bGPDlayer", &gpd->layers); for (gpl= gpd->layers.first; gpl; gpl= gpl->next) { diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index 50d3ac30ddc..23737866bf2 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -74,6 +74,8 @@ set(SRC operators/bmo_utils.c operators/bmo_wireframe.c + intern/bmesh_callback_generic.c + intern/bmesh_callback_generic.h intern/bmesh_construct.c intern/bmesh_construct.h intern/bmesh_core.c diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index 4efc6aa16f8..87b1818fa5d 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -243,6 +243,7 @@ extern "C" { #include "intern/bmesh_error.h" #include "intern/bmesh_core.h" +#include "intern/bmesh_callback_generic.h" #include "intern/bmesh_construct.h" #include "intern/bmesh_delete.h" #include "intern/bmesh_edgeloop.h" diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index 39359b97a4e..120ff4997dc 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -256,6 +256,12 @@ enum { #define BM_ALL (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE) #define BM_ALL_NOLOOP (BM_VERT | BM_EDGE | BM_FACE) +#define BM_CHECK_TYPE_ELEM(ele) \ + CHECK_TYPE_ANY(ele, void *, BMFace *, BMEdge *, BMVert *, BMLoop *, BMElem *, BMElemF *, BMHeader *) + +#define BM_CHECK_TYPE_ELEM_ASSIGN(ele) \ + (BM_CHECK_TYPE_ELEM(ele), CHECK_TYPE_NONCONST(ele)), ele + /* BMHeader->hflag (char) */ enum { BM_ELEM_SELECT = (1 << 0), diff --git a/source/blender/bmesh/intern/bmesh_callback_generic.c b/source/blender/bmesh/intern/bmesh_callback_generic.c new file mode 100644 index 00000000000..84fcc67f3c4 --- /dev/null +++ b/source/blender/bmesh/intern/bmesh_callback_generic.c @@ -0,0 +1,55 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/bmesh/intern/bmesh_callback_generic.c + * \ingroup bmesh + * + * BM element callback functions. + */ + +#include "BLI_utildefines.h" + +#include "bmesh.h" + +#include "intern/bmesh_callback_generic.h" + +bool BM_elem_cb_check_hflag_ex(BMElem *ele, void *user_data) +{ + const unsigned int hflag_pair = GET_INT_FROM_POINTER(user_data); + const char hflag_p = (hflag_pair & 0xff); + const char hflag_n = (hflag_pair >> 8); + + return ((BM_elem_flag_test(ele, hflag_p) != 0) && + (BM_elem_flag_test(ele, hflag_n) == 0)); +} + +bool BM_elem_cb_check_hflag_enabled(BMElem *ele, void *user_data) +{ + const char hflag = GET_INT_FROM_POINTER(user_data); + + return (BM_elem_flag_test(ele, hflag) != 0); +} + +bool BM_elem_cb_check_hflag_disabled(BMElem *ele, void *user_data) +{ + const char hflag = GET_INT_FROM_POINTER(user_data); + + return (BM_elem_flag_test(ele, hflag) == 0); +} diff --git a/source/blender/bmesh/intern/bmesh_callback_generic.h b/source/blender/bmesh/intern/bmesh_callback_generic.h new file mode 100644 index 00000000000..8c46128f3b0 --- /dev/null +++ b/source/blender/bmesh/intern/bmesh_callback_generic.h @@ -0,0 +1,44 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BMESH_CALLBACK_GENERIC_H__ +#define __BMESH_CALLBACK_GENERIC_H__ + +/** \file blender/bmesh/intern/bmesh_callback_generic.h + * \ingroup bmesh + */ + +bool BM_elem_cb_check_hflag_enabled(BMElem *, void *user_data); +bool BM_elem_cb_check_hflag_disabled(BMElem *, void *user_data); +bool BM_elem_cb_check_hflag_ex(BMElem *, void *user_data); + +#define BM_elem_cb_check_hflag_ex_simple(type, hflag_p, hflag_n) \ + (bool (*)(type, void *))BM_elem_cb_check_hflag_ex, \ + SET_UINT_IN_POINTER(((hflag_p) | (hflag_n << 8))) + +#define BM_elem_cb_check_hflag_enabled_simple(type, hflag_p) \ + (bool (*)(type, void *))BM_elem_cb_check_hflag_enabled, \ + SET_UINT_IN_POINTER((hflag_p)) + +#define BM_elem_cb_check_hflag_disabled_simple(type, hflag_n) \ + (bool (*)(type, void *))BM_elem_cb_check_hflag_disabled, \ + SET_UINT_IN_POINTER(hflag_n) + +#endif /* __BMESH_CALLBACK_GENERIC_H__ */ diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.c b/source/blender/bmesh/intern/bmesh_edgeloop.c index e83a1d5b00a..aa1f511e8d7 100644 --- a/source/blender/bmesh/intern/bmesh_edgeloop.c +++ b/source/blender/bmesh/intern/bmesh_edgeloop.c @@ -662,7 +662,7 @@ void BM_edgeloop_flip(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store) void BM_edgeloop_expand(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store, int el_store_len) { - /* first double until we are more then half as big */ + /* first double until we are more than half as big */ while ((el_store->len * 2) < el_store_len) { LinkData *node_curr = el_store->verts.first; while (node_curr) { diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c index 476878ad38c..4dc27d75a55 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.c +++ b/source/blender/bmesh/intern/bmesh_iterators.c @@ -56,7 +56,7 @@ const char bm_iter_itype_htype_map[BM_ITYPE_MAX] = { /** * Utility function. */ -int BM_iter_mesh_count(BMesh *bm, const char itype) +int BM_iter_mesh_count(const char itype, BMesh *bm) { int count; diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h index 44be7072e71..49e511bdcb5 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.h +++ b/source/blender/bmesh/intern/bmesh_iterators.h @@ -84,30 +84,40 @@ typedef enum BMIterType { extern const char bm_iter_itype_htype_map[BM_ITYPE_MAX]; #define BM_ITER_MESH(ele, iter, bm, itype) \ - for (ele = BM_iter_new(iter, bm, itype, NULL); ele; ele = BM_iter_step(iter)) + for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL); \ + ele; \ + BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter)) #define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar) \ - for (ele = BM_iter_new(iter, bm, itype, NULL), indexvar = 0; ele; ele = BM_iter_step(iter), (indexvar)++) + for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL), indexvar = 0; \ + ele; \ + BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter), (indexvar)++) /* a version of BM_ITER_MESH which keeps the next item in storage * so we can delete the current item, see bug [#36923] */ #ifdef DEBUG # define BM_ITER_MESH_MUTABLE(ele, ele_next, iter, bm, itype) \ - for (ele = BM_iter_new(iter, bm, itype, NULL); \ - ele ? ((void)((iter)->count = BM_iter_mesh_count(bm, itype)), \ - (void)(ele_next = BM_iter_step(iter)), 1) : 0; \ - ele = ele_next) + for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL); \ + ele ? ((void)((iter)->count = BM_iter_mesh_count(itype, bm)), \ + (void)(ele_next = BM_iter_step(iter)), 1) : 0; \ + BM_CHECK_TYPE_ELEM_ASSIGN(ele) = ele_next) #else # define BM_ITER_MESH_MUTABLE(ele, ele_next, iter, bm, itype) \ - for (ele = BM_iter_new(iter, bm, itype, NULL); ele ? ((ele_next = BM_iter_step(iter)), 1) : 0; ele = ele_next) + for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL); \ + ele ? ((BM_CHECK_TYPE_ELEM_ASSIGN(ele_next) = BM_iter_step(iter)), 1) : 0; \ + ele = ele_next) #endif #define BM_ITER_ELEM(ele, iter, data, itype) \ - for (ele = BM_iter_new(iter, NULL, itype, data); ele; ele = BM_iter_step(iter)) + for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, NULL, itype, data); \ + ele; \ + BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter)) #define BM_ITER_ELEM_INDEX(ele, iter, data, itype, indexvar) \ - for (ele = BM_iter_new(iter, NULL, itype, data), indexvar = 0; ele; ele = BM_iter_step(iter), (indexvar)++) + for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, NULL, itype, data), indexvar = 0; \ + ele; \ + BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter), (indexvar)++) /* iterator type structs */ struct BMIter__elem_of_mesh { @@ -185,7 +195,6 @@ typedef struct BMIter { char itype; } BMIter; -int BM_iter_mesh_count(BMesh *bm, const char itype); void *BM_iter_at_index(BMesh *bm, const char itype, void *data, int index) ATTR_WARN_UNUSED_RESULT; int BM_iter_as_array(BMesh *bm, const char itype, void *data, void **array, const int len); void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len, @@ -196,9 +205,9 @@ void *BMO_iter_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *sl int *r_len, /* optional args to avoid an alloc (normally stack array) */ void **stack_array, int stack_array_size); - int BM_iter_elem_count_flag(const char itype, void *data, const char hflag, const bool value); int BMO_iter_elem_count_flag(BMesh *bm, const char itype, void *data, const short oflag, const bool value); +int BM_iter_mesh_count(const char itype, BMesh *bm); int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const bool value); /* private for bmesh_iterators_inline.c */ diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c index 709a174731f..158c2aa4263 100644 --- a/source/blender/bmesh/intern/bmesh_log.c +++ b/source/blender/bmesh/intern/bmesh_log.c @@ -582,7 +582,7 @@ void BM_log_free(BMLog *log) /* Get the number of log entries */ int BM_log_length(const BMLog *log) { - return BLI_countlist(&log->entries); + return BLI_listbase_count(&log->entries); } /* Apply a consistent ordering to BMesh vertices */ diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index 05f3ff5b60b..3630bb78b8a 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -788,7 +788,7 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface) { BMEditSelection *selected; - me->totselect = BLI_countlist(&(bm->selected)); + me->totselect = BLI_listbase_count(&(bm->selected)); if (me->mselect) MEM_freeN(me->mselect); @@ -850,15 +850,7 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface) * bmesh and the mesh are out of sync */ (oldverts != NULL)) /* not used here, but 'oldverts' is used later for applying 'ofs' */ { - bool act_is_basis = false; - - /* find if this key is a basis for any others */ - for (currkey = me->key->block.first; currkey; currkey = currkey->next) { - if (bm->shapenr - 1 == currkey->relative) { - act_is_basis = true; - break; - } - } + const bool act_is_basis = BKE_keyblock_is_basis(me->key, bm->shapenr - 1); /* active key is a base */ if (act_is_basis && (cd_shape_keyindex_offset != -1)) { diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index 72d25413f09..6687902f77b 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -1149,7 +1149,7 @@ BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, * </pre> * * \param e The edge to split. - * \param v One of the vertices in \a e and defines the the "from" end of the splitting operation, + * \param v One of the vertices in \a e and defines the "from" end of the splitting operation, * the new vertex will be \a fac of the way from \a v to the other end. * \param r_e The newly created edge. * \return The new vertex. diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index aba805cccd7..114358884b7 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -173,8 +173,9 @@ static BMOpDefine bmo_region_extend_def = { "region_extend", /* slots_in */ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */ - {"use_constrict", BMO_OP_SLOT_BOOL}, /* find boundary inside the regions, not outside. */ + {"use_contract", BMO_OP_SLOT_BOOL}, /* find boundary inside the regions, not outside. */ {"use_faces", BMO_OP_SLOT_BOOL}, /* extend from faces instead of edges */ + {"use_face_step", BMO_OP_SLOT_BOOL}, /* step over connected faces */ {{'\0'}}, }, /* slots_out */ diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h index 287aafc8f9f..d966d882c67 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api.h +++ b/source/blender/bmesh/intern/bmesh_operator_api.h @@ -395,6 +395,8 @@ void BMO_slot_buffer_from_disabled_hflag(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char htype, const char hflag); +void BMO_slot_buffer_from_array(BMOperator *op, BMOpSlot *slot, BMHeader **ele_buffer, int ele_buffer_len); + void BMO_slot_buffer_from_single(BMOperator *op, BMOpSlot *slot, BMHeader *ele); void *BMO_slot_buffer_get_single(BMOpSlot *slot); @@ -477,7 +479,9 @@ int BMO_iter_map_value_int(BMOIter *iter); bool BMO_iter_map_value_bool(BMOIter *iter); #define BMO_ITER(ele, iter, slot_args, slot_name, restrict_flag) \ - for (ele = BMO_iter_new(iter, slot_args, slot_name, restrict_flag); ele; ele = BMO_iter_step(iter)) + for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMO_iter_new(iter, slot_args, slot_name, restrict_flag); \ + ele; \ + BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMO_iter_step(iter)) /******************* Inlined Functions********************/ typedef void (*opexec)(BMesh *bm, BMOperator *op); diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index b041c010c22..ba154b04838 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -900,6 +900,21 @@ void BMO_slot_buffer_from_single(BMOperator *op, BMOpSlot *slot, BMHeader *ele) *slot->data.buf = ele; } +void BMO_slot_buffer_from_array(BMOperator *op, BMOpSlot *slot, BMHeader **ele_buffer, int ele_buffer_len) +{ + BMO_ASSERT_SLOT_IN_OP(slot, op); + BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF); + BLI_assert(slot->len == 0 || slot->len == ele_buffer_len); + + if (slot->data.buf == NULL) { + slot->data.buf = BLI_memarena_alloc(op->arena, sizeof(*slot->data.buf) * ele_buffer_len); + } + + slot->len = ele_buffer_len; + memcpy(slot->data.buf, ele_buffer, ele_buffer_len * sizeof(*slot->data.buf)); +} + + void *BMO_slot_buffer_get_single(BMOpSlot *slot) { BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF); @@ -1636,6 +1651,7 @@ static int BMO_opcode_from_opname_check(const char *opname) * * **Element Buffer** (#BMO_OP_SLOT_ELEMENT_BUF) * - `e` - single element vert/edge/face (use with #BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE). + * - `eb` - elem buffer, take an array and a length. * - `av` - all verts * - `ae` - all edges * - `af` - all faces @@ -1756,12 +1772,23 @@ bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, state = true; break; } - case 'e': /* single vert/edge/face */ + case 'e': { - BMHeader *ele = va_arg(vlist, void *); BMOpSlot *slot = BMO_slot_get(op->slots_in, slot_name); - BMO_slot_buffer_from_single(op, slot, ele); + if (NEXT_CHAR(fmt) == 'b') { + BMHeader **ele_buffer = va_arg(vlist, void *); + int ele_buffer_len = va_arg(vlist, int); + + BMO_slot_buffer_from_array(op, slot, ele_buffer, ele_buffer_len); + fmt++; + } + else { + /* single vert/edge/face */ + BMHeader *ele = va_arg(vlist, void *); + + BMO_slot_buffer_from_single(op, slot, ele); + } state = true; break; diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h index b3d97947cab..8557bcd91b7 100644 --- a/source/blender/bmesh/intern/bmesh_operators.h +++ b/source/blender/bmesh/intern/bmesh_operators.h @@ -33,10 +33,10 @@ /*quad innervert values*/ enum { - SUBD_INNERVERT, - SUBD_PATH, - SUBD_FAN, - SUBD_STRAIGHT_CUT + SUBD_CORNER_INNERVERT, + SUBD_CORNER_PATH, + SUBD_CORNER_FAN, + SUBD_CORNER_STRAIGHT_CUT }; /* aligned with PROP_SMOOTH and friends */ diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index a8e1acd9c71..f2c426133c2 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -37,6 +37,7 @@ #include "BLI_math.h" #include "BLI_memarena.h" #include "BLI_polyfill2d.h" +#include "BLI_polyfill2d_beautify.h" #include "bmesh.h" #include "bmesh_tools.h" @@ -422,6 +423,43 @@ void BM_edge_normals_update(BMEdge *e) BM_vert_normal_update(e->v2); } +bool BM_vert_normal_update_ex(BMVert *v, const char hflag, float r_no[3]) +{ + /* TODO, we can normalize each edge only once, then compare with previous edge */ + + BMIter liter; + BMLoop *l; + int len = 0; + + zero_v3(r_no); + + BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { + if (BM_elem_flag_test(l->f, hflag)) { + float vec1[3], vec2[3], fac; + + /* Same calculation used in BM_mesh_normals_update */ + sub_v3_v3v3(vec1, l->v->co, l->prev->v->co); + sub_v3_v3v3(vec2, l->next->v->co, l->v->co); + normalize_v3(vec1); + normalize_v3(vec2); + + fac = saacos(-dot_v3v3(vec1, vec2)); + + madd_v3_v3fl(r_no, l->f->no, fac); + + len++; + } + } + + if (len) { + normalize_v3(r_no); + return true; + } + else { + return false; + } +} + /** * update a vert normal (but not the faces incident on it) */ @@ -431,12 +469,13 @@ void BM_vert_normal_update(BMVert *v) BMIter liter; BMLoop *l; - float vec1[3], vec2[3], fac; int len = 0; zero_v3(v->no); BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { + float vec1[3], vec2[3], fac; + /* Same calculation used in BM_mesh_normals_update */ sub_v3_v3v3(vec1, l->v->co, l->prev->v->co); sub_v3_v3v3(vec2, l->next->v->co, l->v->co); @@ -704,20 +743,21 @@ bool BM_face_point_inside_test(BMFace *f, const float co[3]) * * \note use_tag tags new flags and edges. */ -void BM_face_triangulate(BMesh *bm, BMFace *f, - BMFace **r_faces_new, - int *r_faces_new_tot, - MemArena *sf_arena, - const int quad_method, - const int ngon_method, - const bool use_tag) +void BM_face_triangulate( + BMesh *bm, BMFace *f, + BMFace **r_faces_new, + int *r_faces_new_tot, + const int quad_method, + const int ngon_method, + const bool use_tag, + MemArena *pf_arena, + + /* use for MOD_TRIANGULATE_NGON_BEAUTY only! */ + struct Heap *pf_heap, struct EdgeHash *pf_ehash) { BMLoop *l_iter, *l_first, *l_new; BMFace *f_new; - int orig_f_len = f->len; int nf_i = 0; - BMEdge **edge_array; - int edge_array_len; bool use_beauty = (ngon_method == MOD_TRIANGULATE_NGON_BEAUTY); BLI_assert(BM_face_is_normal_valid(f)); @@ -743,38 +783,39 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, break; } case MOD_TRIANGULATE_QUAD_SHORTEDGE: - { - BMLoop *l_v3, *l_v4; - float d1, d2; - - l_v1 = l_first; - l_v2 = l_first->next->next; - l_v3 = l_first->next; - l_v4 = l_first->prev; - - d1 = len_squared_v3v3(l_v1->v->co, l_v2->v->co); - d2 = len_squared_v3v3(l_v3->v->co, l_v4->v->co); - - if (d2 < d1) { - l_v1 = l_v3; - l_v2 = l_v4; - } - break; - } case MOD_TRIANGULATE_QUAD_BEAUTY: default: { BMLoop *l_v3, *l_v4; - float cost; + bool split_24; l_v1 = l_first->next; l_v2 = l_first->next->next; l_v3 = l_first->prev; l_v4 = l_first; - cost = BM_verts_calc_rotate_beauty(l_v1->v, l_v2->v, l_v3->v, l_v4->v, 0, 0); + if (quad_method == MOD_TRIANGULATE_QUAD_SHORTEDGE) { + float d1, d2; + d1 = len_squared_v3v3(l_v4->v->co, l_v2->v->co); + d2 = len_squared_v3v3(l_v1->v->co, l_v3->v->co); + split_24 = ((d2 - d1) > 0.0f); + } + else { + /* first check if the quad is concave on either diagonal */ + const int flip_flag = is_quad_flip_v3(l_v1->v->co, l_v2->v->co, l_v3->v->co, l_v4->v->co); + if (UNLIKELY(flip_flag & (1 << 0))) { + split_24 = true; + } + else if (UNLIKELY(flip_flag & (1 << 1))) { + split_24 = false; + } + else { + split_24 = (BM_verts_calc_rotate_beauty(l_v1->v, l_v2->v, l_v3->v, l_v4->v, 0, 0) > 0.0f); + } + } - if (cost < 0.0f) { + /* named confusingly, l_v1 is in fact the second vertex */ + if (split_24) { l_v1 = l_v4; //l_v2 = l_v2; } @@ -816,11 +857,12 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, } BLI_polyfill_calc_arena((const float (*)[2])projverts, f->len, -1, tris, - sf_arena); + pf_arena); if (use_beauty) { - edge_array = BLI_array_alloca(edge_array, orig_f_len - 3); - edge_array_len = 0; + BLI_polyfill_beautify( + (const float (*)[2])projverts, f->len, tris, + pf_arena, pf_heap, pf_ehash); } /* loop over calculated triangles and create new geometry */ @@ -857,7 +899,7 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, } /* we know any edge that we create and _isnt_ */ - if (use_beauty || use_tag) { + if (use_tag) { /* new faces loops */ l_iter = l_first = l_new; do { @@ -867,92 +909,19 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, bool is_new_edge = (l_iter == l_iter->radial_next); if (is_new_edge) { - if (use_beauty) { - edge_array[edge_array_len] = e; - edge_array_len++; - } - - if (use_tag) { - BM_elem_flag_enable(e, BM_ELEM_TAG); - - } + BM_elem_flag_enable(e, BM_ELEM_TAG); } /* note, never disable tag's */ } while ((l_iter = l_iter->next) != l_first); } } - if ((!use_beauty) || (!r_faces_new)) { + { /* we can't delete the real face, because some of the callers expect it to remain valid. * so swap data and delete the last created tri */ bmesh_face_swap_data(f, f_new); BM_face_kill(bm, f_new); } - - if (use_beauty) { - BLI_assert(edge_array_len <= orig_f_len - 3); - - BM_mesh_beautify_fill(bm, edge_array, edge_array_len, 0, 0, 0, 0); - - if (r_faces_new) { - /* beautify deletes and creates new faces - * we need to re-populate the r_faces_new array - * with the new faces - */ - int i; - - -#define FACE_USED_TEST(f) (BM_elem_index_get(f) == -2) -#define FACE_USED_SET(f) BM_elem_index_set(f, -2) - - nf_i = 0; - for (i = 0; i < edge_array_len; i++) { - BMFace *f_a, *f_b; - BMEdge *e = edge_array[i]; -#ifndef NDEBUG - const bool ok = BM_edge_face_pair(e, &f_a, &f_b); - BLI_assert(ok); -#else - BM_edge_face_pair(e, &f_a, &f_b); -#endif - - if (FACE_USED_TEST(f_a) == false) { - FACE_USED_SET(f_a); /* set_dirty */ - - if (nf_i < edge_array_len) { - r_faces_new[nf_i++] = f_a; - } - else { - f_new = f_a; - break; - } - } - - if (FACE_USED_TEST(f_b) == false) { - FACE_USED_SET(f_b); /* set_dirty */ - - if (nf_i < edge_array_len) { - r_faces_new[nf_i++] = f_b; - } - else { - f_new = f_b; - break; - } - } - } - -#undef FACE_USED_TEST -#undef FACE_USED_SET - - /* nf_i doesn't include the last face */ - BLI_assert(nf_i <= orig_f_len - 3); - - /* we can't delete the real face, because some of the callers expect it to remain valid. - * so swap data and delete the last created tri */ - bmesh_face_swap_data(f, f_new); - BM_face_kill(bm, f_new); - } - } } bm->elem_index_dirty |= BM_FACE; diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h index 91e649edb16..b25a7dbaa55 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.h +++ b/source/blender/bmesh/intern/bmesh_polygon.h @@ -27,6 +27,9 @@ * \ingroup bmesh */ +struct EdgeHash; +struct Heap; + #include "BLI_compiler_attrs.h" void BM_bmesh_calc_tessellation(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptris_tot); @@ -49,18 +52,22 @@ void BM_face_normal_update(BMFace *f) ATTR_NONNULL(); void BM_edge_normals_update(BMEdge *e) ATTR_NONNULL(); +bool BM_vert_normal_update_ex(BMVert *v, const char hflag, float r_no[3]); void BM_vert_normal_update(BMVert *v) ATTR_NONNULL(); void BM_vert_normal_update_all(BMVert *v) ATTR_NONNULL(); void BM_face_normal_flip(BMesh *bm, BMFace *f) ATTR_NONNULL(); bool BM_face_point_inside_test(BMFace *f, const float co[3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -void BM_face_triangulate(BMesh *bm, BMFace *f, - BMFace **r_faces_new, - int *r_faces_new_tot, - struct MemArena *sf_arena, - const int quad_method, const int ngon_method, - const bool use_tag) ATTR_NONNULL(1, 2); +void BM_face_triangulate( + BMesh *bm, BMFace *f, + BMFace **r_faces_new, + int *r_faces_new_tot, + const int quad_method, const int ngon_method, + const bool use_tag, + struct MemArena *pf_arena, + struct Heap *pf_heap, struct EdgeHash *pf_ehash + ) ATTR_NONNULL(1, 2); void BM_face_splits_check_legal(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) ATTR_NONNULL(); void BM_face_splits_check_optimal(BMFace *f, BMLoop *(*loops)[2], int len) ATTR_NONNULL(); diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 40e0356e14c..901b96c3ae0 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -202,6 +202,26 @@ bool BM_vert_pair_share_face_check( return false; } +bool BM_vert_pair_share_face_check_cb( + BMVert *v_a, BMVert *v_b, + bool (*test_fn)(BMFace *, void *user_data), void *user_data) +{ + if (v_a->e && v_b->e) { + BMIter iter; + BMFace *f; + + BM_ITER_ELEM (f, &iter, v_a, BM_FACES_OF_VERT) { + if (test_fn(f, user_data)) { + if (BM_vert_in_face(f, v_b)) { + return true; + } + } + } + } + + return false; +} + /** * Given 2 verts, find the smallest face they share and give back both loops. */ @@ -250,6 +270,36 @@ static float bm_face_calc_split_dot(BMLoop *l_a, BMLoop *l_b) } /** + * Check if a point is inside the corner defined by a loop + * (within the 2 planes defined by the loops corner & face normal). + * + * \return less than 0.0 when inside. + */ +float BM_loop_point_side_of_loop_test(const BMLoop *l, const float co[3]) +{ + const float *axis = l->f->no; + return (angle_signed_on_axis_v3v3v3_v3(l->prev->v->co, l->v->co, co, axis) - + angle_signed_on_axis_v3v3v3_v3(l->prev->v->co, l->v->co, l->next->v->co, axis)); +} + +/** + * Check if a point is inside the edge defined by a loop + * (within the plane defined by the loops edge & face normal). + * + * \return less than 0.0 when inside. + */ +float BM_loop_point_side_of_edge_test(const BMLoop *l, const float co[3]) +{ + const float *axis = l->f->no; + float dir[3]; + float plane[3]; + sub_v3_v3v3(dir, l->v->co, l->next->v->co); + cross_v3_v3v3(plane, axis, dir); + return (dot_v3v3(plane, co) - + dot_v3v3(plane, l->v->co)); +} + +/** * Given 2 verts, find a face they share that has the lowest angle across these verts and give back both loops. * * This can be better then #BM_vert_pair_share_face_by_len because concave splits are ranked lowest. @@ -448,7 +498,7 @@ bool BM_verts_in_face(BMFace *f, BMVert **varr, int len) } /** - * Returns whether or not a given edge is is part of a given face. + * Returns whether or not a given edge is part of a given face. */ bool BM_edge_in_face(BMEdge *e, BMFace *f) { @@ -1353,7 +1403,7 @@ float BM_vert_calc_shell_factor(BMVert *v) } /* alternate version of #BM_vert_calc_shell_factor which only * uses 'hflag' faces, but falls back to all if none found. */ -float BM_vert_calc_shell_factor_ex(BMVert *v, const char hflag) +float BM_vert_calc_shell_factor_ex(BMVert *v, const float no[3], const char hflag) { BMIter iter; BMLoop *l; @@ -1364,7 +1414,7 @@ float BM_vert_calc_shell_factor_ex(BMVert *v, const char hflag) BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) { if (BM_elem_flag_test(l->f, hflag)) { /* <-- main difference to BM_vert_calc_shell_factor! */ const float face_angle = BM_loop_calc_face_angle(l); - accum_shell += shell_v3v3_normalized_to_dist(v->no, l->f->no) * face_angle; + accum_shell += shell_v3v3_normalized_to_dist(no, l->f->no) * face_angle; accum_angle += face_angle; tot_sel++; } @@ -1777,7 +1827,7 @@ bool BM_face_exists_multi_edge(BMEdge **earr, int len) * * \note The face may contain other verts \b not in \a varr. * - * \note Its possible there are more then one overlapping faces, + * \note Its possible there are more than one overlapping faces, * in this case the first one found will be assigned to \a r_f_overlap. * * \param varr Array of unordered verts. diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h index 0d47633dc73..3dee4540c4c 100644 --- a/source/blender/bmesh/intern/bmesh_queries.h +++ b/source/blender/bmesh/intern/bmesh_queries.h @@ -52,6 +52,9 @@ BMLoop *BM_vert_find_first_loop(BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL( bool BM_vert_pair_share_face_check( BMVert *v_a, BMVert *v_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +bool BM_vert_pair_share_face_check_cb( + BMVert *v_a, BMVert *v_b, + bool (*test_fn)(BMFace *f, void *user_data), void *user_data) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3); BMFace *BM_vert_pair_share_face_by_len( BMVert *v_a, BMVert *v_b, BMLoop **r_l_a, BMLoop **r_l_b, @@ -80,6 +83,8 @@ bool BM_edge_is_convex(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL( bool BM_loop_is_convex(const BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BLI_INLINE bool BM_loop_is_adjacent(const BMLoop *l_a, const BMLoop *l_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +float BM_loop_point_side_of_loop_test(const BMLoop *l, const float co[3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +float BM_loop_point_side_of_edge_test(const BMLoop *l, const float co[3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); float BM_loop_calc_face_angle(BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); void BM_loop_calc_face_normal(BMLoop *l, float r_normal[3]) ATTR_NONNULL(); @@ -94,7 +99,7 @@ void BM_edge_calc_face_tangent(const BMEdge *e, const BMLoop *e_loop, float r float BM_vert_calc_edge_angle(BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); float BM_vert_calc_shell_factor(BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -float BM_vert_calc_shell_factor_ex(BMVert *v, const char hflag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +float BM_vert_calc_shell_factor_ex(BMVert *v, const float no[3], const char hflag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); float BM_vert_calc_mean_tagged_edge_length(BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BMLoop *BM_face_find_shortest_loop(BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); diff --git a/source/blender/bmesh/intern/bmesh_queries_inline.h b/source/blender/bmesh/intern/bmesh_queries_inline.h index 6162af46837..1ca56beb746 100644 --- a/source/blender/bmesh/intern/bmesh_queries_inline.h +++ b/source/blender/bmesh/intern/bmesh_queries_inline.h @@ -36,7 +36,7 @@ BLI_INLINE bool BM_vert_in_edge(const BMEdge *e, const BMVert *v) } /** - * Returns whether or not a given edge is is part of a given loop. + * Returns whether or not a given edge is part of a given loop. */ BLI_INLINE bool BM_edge_in_loop(const BMEdge *e, const BMLoop *l) { diff --git a/source/blender/bmesh/intern/bmesh_walkers.c b/source/blender/bmesh/intern/bmesh_walkers.c index 6a5efbe70ac..20b56632099 100644 --- a/source/blender/bmesh/intern/bmesh_walkers.c +++ b/source/blender/bmesh/intern/bmesh_walkers.c @@ -180,7 +180,7 @@ void *BMW_walk(BMWalker *walker) * \brief Current Walker State * * Returns the first state from the walker state - * worklist. This state is the the next in the + * worklist. This state is the next in the * worklist for processing. */ void *BMW_current_state(BMWalker *walker) diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c index 406dd412d6d..b7bf80b0e3f 100644 --- a/source/blender/bmesh/intern/bmesh_walkers_impl.c +++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c @@ -33,7 +33,6 @@ #include "BKE_customdata.h" #include "bmesh.h" -#include "intern/bmesh_private.h" #include "intern/bmesh_walkers_private.h" /* pop into stack memory (common operation) */ @@ -738,7 +737,7 @@ static void *bmw_LoopWalker_step(BMWalker *walker) (owalk.is_single == false && vert_edge_tot > 2) || /* initial edge was a boundary, so is this edge and vertex is only apart of this face - * this lets us walk over the the boundary of an ngon which is handy */ + * this lets us walk over the boundary of an ngon which is handy */ (owalk.is_single == true && vert_edge_tot == 2 && BM_edge_is_boundary(e))) { /* find next boundary edge in the fan */ diff --git a/source/blender/bmesh/operators/bmo_connect_pair.c b/source/blender/bmesh/operators/bmo_connect_pair.c index a0acf6ed2c5..b82823ecded 100644 --- a/source/blender/bmesh/operators/bmo_connect_pair.c +++ b/source/blender/bmesh/operators/bmo_connect_pair.c @@ -82,7 +82,7 @@ typedef struct PathContext { typedef struct PathLink { struct PathLink *next; BMElem *ele; /* edge or vert */ - BMElem *ele_from; /* edge or face we game from (not 'next->ele') */ + BMElem *ele_from; /* edge or face we came from (not 'next->ele') */ } PathLink; typedef struct PathLinkState { @@ -141,7 +141,7 @@ static void state_calc_co_pair(const PathContext *pc, /** * Ideally we wouldn't need this and for most cases we don't. - * But when a face has vertices that are on the boundary more then once this becomes tricky. + * But when a face has vertices that are on the boundary more than once this becomes tricky. */ static bool state_link_find(PathLinkState *state, BMElem *ele) { @@ -230,23 +230,45 @@ static PathLinkState *state_dupe_add( static PathLinkState *state_step__face_edges( PathContext *pc, PathLinkState *state, const PathLinkState *state_orig, - BMLoop *l_iter, BMLoop *l_last) + BMLoop *l_iter, BMLoop *l_last, + float *r_dist_best) { + BMLoop *l_iter_best = NULL; + float dist_best = *r_dist_best; + do { if (state_isect_co_pair(pc, l_iter->v->co, l_iter->next->v->co)) { - BMElem *ele_next = (BMElem *)l_iter->e; - BMElem *ele_next_from = (BMElem *)l_iter->f; + float dist_test; + float co_isect[3]; - if (FACE_WALK_TEST((BMFace *)ele_next_from) && - (state_link_find(state, ele_next) == false)) - { - if (state_orig->link_last != state->link_last) { - state = state_dupe_add(pc, state, state_orig); + state_calc_co_pair(pc, l_iter->v->co, l_iter->next->v->co, co_isect); + dist_test = len_squared_v3v3(state->co_prev, co_isect); + if (dist_test < dist_best) { + BMElem *ele_next = (BMElem *)l_iter->e; + BMElem *ele_next_from = (BMElem *)l_iter->f; + + if (FACE_WALK_TEST((BMFace *)ele_next_from) && + (state_link_find(state, ele_next) == false)) + { + dist_best = dist_test; + l_iter_best = l_iter; } - state_link_add(pc, state, ele_next, ele_next_from); } } } while ((l_iter = l_iter->next) != l_last); + + if ((l_iter = l_iter_best)) { + BMElem *ele_next = (BMElem *)l_iter->e; + BMElem *ele_next_from = (BMElem *)l_iter->f; + + if (state_orig->link_last != state->link_last) { + state = state_dupe_add(pc, state, state_orig); + } + state_link_add(pc, state, ele_next, ele_next_from); + } + + *r_dist_best = dist_best; + return state; } @@ -254,23 +276,40 @@ static PathLinkState *state_step__face_edges( static PathLinkState *state_step__face_verts( PathContext *pc, PathLinkState *state, const PathLinkState *state_orig, - BMLoop *l_iter, BMLoop *l_last) + BMLoop *l_iter, BMLoop *l_last, float *r_dist_best) { + BMLoop *l_iter_best = NULL; + float dist_best = *r_dist_best; + do { if (state_isect_co_exact(pc, l_iter->v->co)) { - BMElem *ele_next = (BMElem *)l_iter->v; - BMElem *ele_next_from = (BMElem *)l_iter->f; + const float dist_test = len_squared_v3v3(state->co_prev, l_iter->v->co); + if (dist_test < dist_best) { + BMElem *ele_next = (BMElem *)l_iter->v; + BMElem *ele_next_from = (BMElem *)l_iter->f; - if (FACE_WALK_TEST((BMFace *)ele_next_from) && - state_link_find(state, ele_next) == false) - { - if (state_orig->link_last != state->link_last) { - state = state_dupe_add(pc, state, state_orig); + if (FACE_WALK_TEST((BMFace *)ele_next_from) && + state_link_find(state, ele_next) == false) + { + dist_best = dist_test; + l_iter_best = l_iter; } - state_link_add(pc, state, ele_next, ele_next_from); } } } while ((l_iter = l_iter->next) != l_last); + + if ((l_iter = l_iter_best)) { + BMElem *ele_next = (BMElem *)l_iter->v; + BMElem *ele_next_from = (BMElem *)l_iter->f; + + if (state_orig->link_last != state->link_last) { + state = state_dupe_add(pc, state, state_orig); + } + state_link_add(pc, state, ele_next, ele_next_from); + } + + *r_dist_best = dist_best; + return state; } @@ -290,20 +329,12 @@ static bool state_step(PathContext *pc, PathLinkState *state) if ((l_start->f != ele_from) && FACE_WALK_TEST(l_start->f)) { + float dist_best = FLT_MAX; /* very similar to block below */ - if (BM_vert_in_face(l_start->f, pc->v_b)) { - if (state_orig.link_last != state->link_last) { - state = state_dupe_add(pc, state, &state_orig); - } - - state_link_add(pc, state, (BMElem *)pc->v_b, (BMElem *)l_start->f); - } - else { - state = state_step__face_edges(pc, state, &state_orig, - l_start->next, l_start); - state = state_step__face_verts(pc, state, &state_orig, - l_start->next->next, l_start); - } + state = state_step__face_edges(pc, state, &state_orig, + l_start->next, l_start, &dist_best); + state = state_step__face_verts(pc, state, &state_orig, + l_start->next->next, l_start, &dist_best); } } } @@ -319,24 +350,14 @@ static bool state_step(PathContext *pc, PathLinkState *state) if ((l_start->f != ele_from) && FACE_WALK_TEST(l_start->f)) { + float dist_best = FLT_MAX; /* very similar to block above */ - if (BM_vert_in_face(l_start->f, pc->v_b)) { - BMElem *ele_next = (BMElem *)pc->v_b; - BMElem *ele_next_from = (BMElem *)l_start->f; - - if (state_orig.link_last != state->link_last) { - state = state_dupe_add(pc, state, &state_orig); - } - state_link_add(pc, state, ele_next, ele_next_from); - } - else { - state = state_step__face_edges(pc, state, &state_orig, - l_start->next, l_start->prev); - if (l_start->f->len > 3) { - /* adjacent verts are handled in state_step__vert_edges */ - state = state_step__face_verts(pc, state, &state_orig, - l_start->next->next, l_start->prev); - } + state = state_step__face_edges(pc, state, &state_orig, + l_start->next, l_start->prev, &dist_best); + if (l_start->f->len > 3) { + /* adjacent verts are handled in state_step__vert_edges */ + state = state_step__face_verts(pc, state, &state_orig, + l_start->next->next, l_start->prev, &dist_best); } } } @@ -351,31 +372,19 @@ static bool state_step(PathContext *pc, PathLinkState *state) if (((BMElem *)e != ele_from) && VERT_WALK_TEST(v_other)) { - if (v_other == pc->v_b) { - BMElem *ele_next = (BMElem *)pc->v_b; + if (state_isect_co_exact(pc, v_other->co)) { + BMElem *ele_next = (BMElem *)v_other; BMElem *ele_next_from = (BMElem *)e; - - if (state_orig.link_last != state->link_last) { - state = state_dupe_add(pc, state, &state_orig); - } - state_link_add(pc, state, ele_next, ele_next_from); - } - else { - if (state_isect_co_exact(pc, v_other->co)) { - BMElem *ele_next = (BMElem *)v_other; - BMElem *ele_next_from = (BMElem *)e; - if (state_link_find(state, ele_next) == false) { - if (state_orig.link_last != state->link_last) { - state = state_dupe_add(pc, state, &state_orig); - } - state_link_add(pc, state, ele_next, ele_next_from); + if (state_link_find(state, ele_next) == false) { + if (state_orig.link_last != state->link_last) { + state = state_dupe_add(pc, state, &state_orig); } + state_link_add(pc, state, ele_next, ele_next_from); } } } } } - } else { BLI_assert(0); @@ -455,6 +464,10 @@ void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op) negate_v3(basis_nor_b); } add_v3_v3v3(basis_nor, basis_nor_a, basis_nor_b); + + if (UNLIKELY(fabsf(dot_v3v3(basis_nor, basis_dir)) < FLT_EPSILON)) { + ortho_v3_v3(basis_nor, basis_dir); + } } #endif @@ -482,6 +495,9 @@ void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op) while (pc.state_lb.first) { PathLinkState *state, *state_next; found_all = true; +#ifdef DEBUG_PRINT + printf("\n%s: stepping %d\n", __func__, BLI_listbase_count(&pc.state_lb)); +#endif for (state = pc.state_lb.first; state; state = state_next) { state_next = state->next; if (state->link_last->ele == (BMElem *)pc.v_b) { @@ -562,12 +578,10 @@ void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op) #if 1 if (found_all) { - /* leave 'check_degenerate' off, if a user tries to cut with 2 verts, - * always connect even when resulting faces are degenerate [#39418] */ BMOperator op_sub; BMO_op_initf(bm, &op_sub, 0, - "connect_verts verts=%fv faces_exclude=%s", - VERT_OUT, op, "faces_exclude"); + "connect_verts verts=%fv faces_exclude=%s check_degenerate=%b", + VERT_OUT, op, "faces_exclude", true); BMO_op_exec(bm, &op_sub); BMO_slot_copy(&op_sub, slots_out, "edges.out", op, slots_out, "edges.out"); diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c index dd814fa8bfb..1c054e89e39 100644 --- a/source/blender/bmesh/operators/bmo_create.c +++ b/source/blender/bmesh/operators/bmo_create.c @@ -39,7 +39,7 @@ /* This is what runs when pressing the F key * doing the best thing here isn't always easy create vs dissolve, its nice to support - * but it it _really_ gives issues we might have to not call dissolve. - campbell + * but it _really_ gives issues we might have to not call dissolve. - campbell */ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) { diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c index cd5592f08c9..a5a6480c187 100644 --- a/source/blender/bmesh/operators/bmo_dupe.c +++ b/source/blender/bmesh/operators/bmo_dupe.c @@ -109,7 +109,7 @@ static BMEdge *bmo_edge_copy(BMOperator *op, /* add to new/old edge map if necassary */ if (rlen < 2) { - /* not sure what non-manifold cases of greater then three + /* not sure what non-manifold cases of greater than three * radial should do. */ BMO_slot_map_elem_insert(op, slot_boundarymap_out, e_src, e_dst); } diff --git a/source/blender/bmesh/operators/bmo_similar.c b/source/blender/bmesh/operators/bmo_similar.c index f779828a00d..4b5eebb2a73 100644 --- a/source/blender/bmesh/operators/bmo_similar.c +++ b/source/blender/bmesh/operators/bmo_similar.c @@ -115,7 +115,7 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op) num_total = BM_mesh_elem_count(bm, BM_FACE); /* - * The first thing to do is to iterate through all the the selected items and mark them since + * The first thing to do is to iterate through all the selected items and mark them since * they will be in the selection anyway. * This will increase performance, (especially when the number of originally selected faces is high) * so the overall complexity will be less than $O(mn)$ where is the total number of selected faces, diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index 0d9ce4b2731..7b125186110 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -802,13 +802,13 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) patterns[1] = NULL; /* straight cut is patterns[1] == NULL */ switch (cornertype) { - case SUBD_PATH: + case SUBD_CORNER_PATH: patterns[1] = &quad_2edge_path; break; - case SUBD_INNERVERT: + case SUBD_CORNER_INNERVERT: patterns[1] = &quad_2edge_innervert; break; - case SUBD_FAN: + case SUBD_CORNER_FAN: patterns[1] = &quad_2edge_fan; break; } diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c index 986583cc21b..cb9ba5e361c 100644 --- a/source/blender/bmesh/operators/bmo_triangulate.c +++ b/source/blender/bmesh/operators/bmo_triangulate.c @@ -75,6 +75,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op) GHash *sf_vert_map; float normal[3]; const int scanfill_flag = BLI_SCANFILL_CALC_HOLES | BLI_SCANFILL_CALC_POLYS | BLI_SCANFILL_CALC_LOOSE; + unsigned int nors_tot; bool calc_winding = false; sf_vert_map = BLI_ghash_ptr_new_ex(__func__, BMO_slot_buffer_count(op->slots_in, "edges")); @@ -103,6 +104,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op) /* sf_edge = */ BLI_scanfill_edge_add(&sf_ctx, UNPACK2(sf_verts)); /* sf_edge->tmp.p = e; */ /* UNUSED */ } + nors_tot = BLI_ghash_size(sf_vert_map); BLI_ghash_free(sf_vert_map, NULL, NULL); @@ -111,7 +113,6 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op) * Since we don't know winding, just accumulate */ ScanFillVert *sf_vert; struct SortNormal *nors; - const unsigned int nors_tot = BLI_ghash_size(sf_vert_map); unsigned int i; bool is_degenerate = true; @@ -182,7 +183,11 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op) calc_winding = false; } - normalize_v3(normal); + /* in this case we almost certainly have degenerate geometry, + * better set a fallback value as a last resort */ + if (UNLIKELY(normalize_v3(normal) == 0.0f)) { + normal[2] = 1.0f; + } BLI_scanfill_calc_ex(&sf_ctx, scanfill_flag, normal); diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index a06d40c8c0f..e7b65a10790 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -177,42 +177,94 @@ void bmo_rotate_edges_exec(BMesh *bm, BMOperator *op) #define SEL_FLAG 1 #define SEL_ORIG 2 -static void bmo_region_extend_extend(BMesh *bm, BMOperator *op, const bool use_faces) +static void bmo_face_flag_set_flush(BMesh *bm, BMFace *f, const short oflag, const bool value) +{ + BMLoop *l_iter; + BMLoop *l_first; + + BMO_elem_flag_set(bm, f, oflag, value); + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + BMO_elem_flag_set(bm, l_iter->e, oflag, value); + BMO_elem_flag_set(bm, l_iter->v, oflag, value); + } while ((l_iter = l_iter->next) != l_first); +} + + +static void bmo_region_extend_expand( + BMesh *bm, BMOperator *op, + const bool use_faces, const bool use_faces_step) { - BMVert *v; - BMEdge *e; - BMIter eiter; BMOIter siter; if (!use_faces) { + BMVert *v; + BMO_ITER (v, &siter, op->slots_in, "geom", BM_VERT) { - BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) { - if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) - if (!BMO_elem_flag_test(bm, e, SEL_ORIG)) + bool found = false; + + { + BMIter eiter; + BMEdge *e; + + BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) { + if (!BMO_elem_flag_test(bm, e, SEL_ORIG)) { + found = true; break; + } + } } - if (e) { - BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) { - if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) { - BMO_elem_flag_enable(bm, e, SEL_FLAG); - BMO_elem_flag_enable(bm, BM_edge_other_vert(e, v), SEL_FLAG); + if (found) { + if (!use_faces_step) { + BMIter eiter; + BMEdge *e; + + BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) { + if (!BMO_elem_flag_test(bm, e, SEL_FLAG)) { + BMO_elem_flag_enable(bm, e, SEL_FLAG); + BMO_elem_flag_enable(bm, BM_edge_other_vert(e, v), SEL_FLAG); + } + } + } + else { + BMIter fiter; + BMFace *f; + + BM_ITER_ELEM (f, &fiter, v, BM_FACES_OF_VERT) { + if (!BMO_elem_flag_test(bm, f, SEL_FLAG)) { + bmo_face_flag_set_flush(bm, f, SEL_FLAG, true); + } } } } } } else { - BMIter liter, fiter; - BMFace *f, *f2; - BMLoop *l; + BMFace *f; BMO_ITER (f, &siter, op->slots_in, "geom", BM_FACE) { + BMIter liter; + BMLoop *l; + BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - BM_ITER_ELEM (f2, &fiter, l->e, BM_FACES_OF_EDGE) { - if (!BM_elem_flag_test(f2, BM_ELEM_HIDDEN)) { - if (!BMO_elem_flag_test(bm, f2, SEL_ORIG)) { - BMO_elem_flag_enable(bm, f2, SEL_FLAG); + if (!use_faces_step) { + BMIter fiter; + BMFace *f_other; + + BM_ITER_ELEM (f_other, &fiter, l->e, BM_FACES_OF_EDGE) { + if (!BMO_elem_flag_test(bm, f_other, SEL_ORIG | SEL_FLAG)) { + BMO_elem_flag_enable(bm, f_other, SEL_FLAG); + } + } + } + else { + BMIter fiter; + BMFace *f_other; + + BM_ITER_ELEM (f_other, &fiter, l->v, BM_FACES_OF_VERT) { + if (!BMO_elem_flag_test(bm, f_other, SEL_ORIG | SEL_FLAG)) { + BMO_elem_flag_enable(bm, f_other, SEL_FLAG); } } } @@ -221,43 +273,79 @@ static void bmo_region_extend_extend(BMesh *bm, BMOperator *op, const bool use_f } } -static void bmo_region_extend_constrict(BMesh *bm, BMOperator *op, const bool use_faces) +static void bmo_region_extend_contract( + BMesh *bm, BMOperator *op, + const bool use_faces, const bool use_faces_step) { - BMVert *v; - BMEdge *e; - BMIter eiter; BMOIter siter; if (!use_faces) { + BMVert *v; + BMO_ITER (v, &siter, op->slots_in, "geom", BM_VERT) { - BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) { - if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) - if (!BMO_elem_flag_test(bm, e, SEL_ORIG)) + bool found = false; + + if (!use_faces_step) { + BMIter eiter; + BMEdge *e; + + BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) { + if (!BMO_elem_flag_test(bm, e, SEL_ORIG)) { + found = true; break; + } + } } + else { + BMIter fiter; + BMFace *f; + + BM_ITER_ELEM (f, &fiter, v, BM_FACES_OF_VERT) { + if (!BMO_elem_flag_test(bm, f, SEL_ORIG)) { + found = true; + break; + } + } + } + + if (found) { + BMIter eiter; + BMEdge *e; - if (e) { BMO_elem_flag_enable(bm, v, SEL_FLAG); BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) { - if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) { - BMO_elem_flag_enable(bm, e, SEL_FLAG); - } + BMO_elem_flag_enable(bm, e, SEL_FLAG); } - } } } else { - BMIter liter, fiter; - BMFace *f, *f2; - BMLoop *l; + BMFace *f; BMO_ITER (f, &siter, op->slots_in, "geom", BM_FACE) { + BMIter liter; + BMLoop *l; + BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - BM_ITER_ELEM (f2, &fiter, l->e, BM_FACES_OF_EDGE) { - if (!BM_elem_flag_test(f2, BM_ELEM_HIDDEN)) { - if (!BMO_elem_flag_test(bm, f2, SEL_ORIG)) { + + if (!use_faces_step) { + BMIter fiter; + BMFace *f_other; + + BM_ITER_ELEM (f_other, &fiter, l->e, BM_FACES_OF_EDGE) { + if (!BMO_elem_flag_test(bm, f_other, SEL_ORIG)) { + BMO_elem_flag_enable(bm, f, SEL_FLAG); + break; + } + } + } + else { + BMIter fiter; + BMFace *f_other; + + BM_ITER_ELEM (f_other, &fiter, l->v, BM_FACES_OF_VERT) { + if (!BMO_elem_flag_test(bm, f_other, SEL_ORIG)) { BMO_elem_flag_enable(bm, f, SEL_FLAG); break; } @@ -271,14 +359,17 @@ static void bmo_region_extend_constrict(BMesh *bm, BMOperator *op, const bool us void bmo_region_extend_exec(BMesh *bm, BMOperator *op) { const bool use_faces = BMO_slot_bool_get(op->slots_in, "use_faces"); - const bool constrict = BMO_slot_bool_get(op->slots_in, "use_constrict"); + const bool use_face_step = BMO_slot_bool_get(op->slots_in, "use_face_step"); + const bool constrict = BMO_slot_bool_get(op->slots_in, "use_contract"); BMO_slot_buffer_flag_enable(bm, op->slots_in, "geom", BM_ALL_NOLOOP, SEL_ORIG); - if (constrict) - bmo_region_extend_constrict(bm, op, use_faces); - else - bmo_region_extend_extend(bm, op, use_faces); + if (constrict) { + bmo_region_extend_contract(bm, op, use_faces, use_face_step); + } + else { + bmo_region_extend_expand(bm, op, use_faces, use_face_step); + } BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, SEL_FLAG); } diff --git a/source/blender/bmesh/operators/bmo_wireframe.c b/source/blender/bmesh/operators/bmo_wireframe.c index 62409fc3987..ac81dde93c0 100644 --- a/source/blender/bmesh/operators/bmo_wireframe.c +++ b/source/blender/bmesh/operators/bmo_wireframe.c @@ -26,8 +26,6 @@ * Creates a solid wireframe from connected faces. */ -#include "MEM_guardedalloc.h" - #include "DNA_material_types.h" #include "BLI_sys_types.h" diff --git a/source/blender/bmesh/tools/bmesh_beautify.c b/source/blender/bmesh/tools/bmesh_beautify.c index 6639e767e77..1c6dc6f5c0e 100644 --- a/source/blender/bmesh/tools/bmesh_beautify.c +++ b/source/blender/bmesh/tools/bmesh_beautify.c @@ -125,9 +125,6 @@ static void erot_state_alternate(const BMEdge *e, EdRotState *e_state) /* -------------------------------------------------------------------- */ /* Calculate the improvement of rotating the edge */ -/** - * \return a negative value means the edge can be rotated. - */ static float bm_edge_calc_rotate_beauty__area( const float v1[3], const float v2[3], const float v3[3], const float v4[3]) { @@ -272,6 +269,12 @@ static float bm_edge_calc_rotate_beauty__angle( return FLT_MAX; } +/** + * Assuming we have 2 triangles sharing an edge (2 - 4), + * check if the edge running from (1 - 3) gives better results. + * + * \return (negative number means the edge can be rotated, lager == better). + */ float BM_verts_calc_rotate_beauty( const BMVert *v1, const BMVert *v2, const BMVert *v3, const BMVert *v4, const short flag, const short method) @@ -400,9 +403,10 @@ static void bm_edge_update_beauty_cost(BMEdge *e, Heap *eheap, HeapNode **eheap_ /** * \note This function sets the edge indices to invalid values. */ -void BM_mesh_beautify_fill(BMesh *bm, BMEdge **edge_array, const int edge_array_len, - const short flag, const short method, - const short oflag_edge, const short oflag_face) +void BM_mesh_beautify_fill( + BMesh *bm, BMEdge **edge_array, const int edge_array_len, + const short flag, const short method, + const short oflag_edge, const short oflag_face) { Heap *eheap; /* edge heap */ HeapNode **eheap_table; /* edge index aligned table pointing to the eheap */ diff --git a/source/blender/bmesh/tools/bmesh_beautify.h b/source/blender/bmesh/tools/bmesh_beautify.h index 7cc17008b50..0d6aa23b81d 100644 --- a/source/blender/bmesh/tools/bmesh_beautify.h +++ b/source/blender/bmesh/tools/bmesh_beautify.h @@ -31,12 +31,14 @@ enum { VERT_RESTRICT_TAG = (1 << 0), }; -void BM_mesh_beautify_fill(BMesh *bm, BMEdge **edge_array, const int edge_array_len, - const short flag, const short method, - const short oflag_edge, const short oflag_face); +void BM_mesh_beautify_fill( + BMesh *bm, BMEdge **edge_array, const int edge_array_len, + const short flag, const short method, + const short oflag_edge, const short oflag_face); -float BM_verts_calc_rotate_beauty(const BMVert *v1, const BMVert *v2, - const BMVert *v3, const BMVert *v4, - const short flag, const short method); +float BM_verts_calc_rotate_beauty( + const BMVert *v1, const BMVert *v2, + const BMVert *v3, const BMVert *v4, + const short flag, const short method); #endif /* __BMESH_BEAUTIFY_H__ */ diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 4a9fb677257..c3d1ca86fbf 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -787,7 +787,7 @@ static void offset_on_edge_between(BevelParams *bp, EdgeHalf *e1, EdgeHalf *e2, * be on emid if that does a better job of keeping offsets at the user spec. * Viewed from the vertex normal side, the CCW order of the edges is e1, emid, e2. * The offset lines may not meet exactly: the lines may be angled so that they can't meet. - * In that case, pick the the offset_on_edge_between. */ + * In that case, pick the offset_on_edge_between. */ static void offset_in_two_planes(BevelParams *bp, EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, BMVert *v, float meetco[3]) { @@ -1387,7 +1387,7 @@ static void set_bound_vert_seams(BevVert *bv) } /* Make a circular list of BoundVerts for bv, each of which has the coordinates - * of a vertex on the the boundary of the beveled vertex bv->v. + * of a vertex on the boundary of the beveled vertex bv->v. * This may adjust some EdgeHalf widths, and there might have to be * a subsequent pass to make the widths as consistent as possible. * The first time through, construct will be true and we are making the BoundVerts @@ -2229,7 +2229,6 @@ static VMesh *make_cube_corner_adj_vmesh(BevelParams *bp) BoundVert *bndv; int i, j, k, ns2; float co[3], coc[3]; - float w; if (r == PRO_SQUARE_R) return make_cube_corner_straight(mem_arena, nseg); @@ -2262,10 +2261,8 @@ static VMesh *make_cube_corner_adj_vmesh(BevelParams *bp) bndv = bndv->next; } /* center vertex */ - w = (float)(1.0 / M_SQRT3); - co[0] = w; - co[1] = w; - co[2] = w; + copy_v3_fl(co, M_SQRT1_3); + if (nseg > 2) { if (r > 1.5f) mul_v3_fl(co, 1.4f); @@ -2935,6 +2932,10 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) } bv->offset *= weight; } + else if (bp->use_weights) { + weight = BM_elem_float_data_get(&bm->vdata, v, CD_BWEIGHT); + bv->offset *= weight; + } } BLI_ghash_insert(bp->vert_hash, v, bv); diff --git a/source/blender/bmesh/tools/bmesh_bisect_plane.c b/source/blender/bmesh/tools/bmesh_bisect_plane.c index 463304f27f7..e6e33c905da 100644 --- a/source/blender/bmesh/tools/bmesh_bisect_plane.c +++ b/source/blender/bmesh/tools/bmesh_bisect_plane.c @@ -112,7 +112,7 @@ static int bm_vert_sortval_cb(const void *v_a_v, const void *v_b_v) static void bm_face_bisect_verts(BMesh *bm, BMFace *f, const float plane[4], const short oflag_center) { - /* unlikely more then 2 verts are needed */ + /* unlikely more than 2 verts are needed */ const unsigned int f_len_orig = (unsigned int)f->len; BMVert **vert_split_arr = BLI_array_alloca(vert_split_arr, f_len_orig); STACK_DECLARE(vert_split_arr); diff --git a/source/blender/bmesh/tools/bmesh_path.c b/source/blender/bmesh/tools/bmesh_path.c index 060d0dd969b..8ae3507a738 100644 --- a/source/blender/bmesh/tools/bmesh_path.c +++ b/source/blender/bmesh/tools/bmesh_path.c @@ -95,7 +95,7 @@ static void verttag_add_adjacent(Heap *heap, BMVert *v_a, BMVert **verts_prev, f LinkNode *BM_mesh_calc_path_vert( BMesh *bm, BMVert *v_src, BMVert *v_dst, const bool use_length, - void *user_data, bool (*test_fn)(BMVert *, void *user_data)) + bool (*test_fn)(BMVert *, void *user_data), void *user_data) { LinkNode *path = NULL; /* BM_ELEM_TAG flag is used to store visited edges */ @@ -221,7 +221,7 @@ static void edgetag_add_adjacent(Heap *heap, BMEdge *e1, BMEdge **edges_prev, fl LinkNode *BM_mesh_calc_path_edge( BMesh *bm, BMEdge *e_src, BMEdge *e_dst, const bool use_length, - void *user_data, bool (*filter_fn)(BMEdge *, void *user_data)) + bool (*filter_fn)(BMEdge *, void *user_data), void *user_data) { LinkNode *path = NULL; /* BM_ELEM_TAG flag is used to store visited edges */ @@ -347,7 +347,7 @@ static void facetag_add_adjacent(Heap *heap, BMFace *f_a, BMFace **faces_prev, f LinkNode *BM_mesh_calc_path_face( BMesh *bm, BMFace *f_src, BMFace *f_dst, const bool use_length, - void *user_data, bool (*test_fn)(BMFace *, void *user_data)) + bool (*test_fn)(BMFace *, void *user_data), void *user_data) { LinkNode *path = NULL; /* BM_ELEM_TAG flag is used to store visited edges */ diff --git a/source/blender/bmesh/tools/bmesh_path.h b/source/blender/bmesh/tools/bmesh_path.h index a13290b875e..c39e08e83ef 100644 --- a/source/blender/bmesh/tools/bmesh_path.h +++ b/source/blender/bmesh/tools/bmesh_path.h @@ -29,14 +29,17 @@ struct LinkNode *BM_mesh_calc_path_vert( BMesh *bm, BMVert *v_src, BMVert *v_dst, const bool use_length, - void *user_data, bool (*filter_fn)(BMVert *, void *)); + bool (*filter_fn)(BMVert *, void *), void *user_data) +ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3, 5); struct LinkNode *BM_mesh_calc_path_edge( BMesh *bm, BMEdge *e_src, BMEdge *e_dst, const bool use_length, - void *user_data, bool (*filter_fn)(BMEdge *, void *)); + bool (*filter_fn)(BMEdge *, void *), void *user_data) +ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3, 5); struct LinkNode *BM_mesh_calc_path_face( BMesh *bm, BMFace *f_src, BMFace *f_dst, const bool use_length, - void *user_data, bool (*test_fn)(BMFace *, void *)); + bool (*test_fn)(BMFace *, void *), void *user_data) +ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3, 5); #endif /* __BMESH_PATH_H__ */ diff --git a/source/blender/bmesh/tools/bmesh_region_match.c b/source/blender/bmesh/tools/bmesh_region_match.c index 050d5ae4808..bb7000e5534 100644 --- a/source/blender/bmesh/tools/bmesh_region_match.c +++ b/source/blender/bmesh/tools/bmesh_region_match.c @@ -656,7 +656,7 @@ static bool bm_uuidwalk_facestep_begin( bool ok = false; BLI_assert(BLI_ghash_size(uuidwalk->cache.faces_from_uuid) == 0); - BLI_assert(BLI_countlist(&fstep->items) == 0); + BLI_assert(BLI_listbase_is_empty(&fstep->items)); f_link_prev_p = &fstep->faces; for (f_link = fstep->faces; f_link; f_link = f_link_next) { @@ -695,7 +695,7 @@ static bool bm_uuidwalk_facestep_begin( BLI_ghash_clear(uuidwalk->cache.faces_from_uuid, NULL, NULL); - BLI_sortlist(&fstep->items, facestep_sort); + BLI_listbase_sort(&fstep->items, facestep_sort); return ok; } @@ -781,7 +781,7 @@ static BMFace **bm_mesh_region_match_pair( UUIDFaceStep *fstep_src = w_src->faces_step.first; UUIDFaceStep *fstep_dst = w_dst->faces_step.first; - BLI_assert(BLI_countlist(&w_src->faces_step) == BLI_countlist(&w_dst->faces_step)); + BLI_assert(BLI_listbase_count(&w_src->faces_step) == BLI_listbase_count(&w_dst->faces_step)); while (fstep_src) { @@ -874,7 +874,7 @@ static BMFace **bm_mesh_region_match_pair( const unsigned int faces_result_len = (unsigned int)BLI_ghash_size(w_dst->faces_uuid); unsigned int i; - faces_result = MEM_mallocN(sizeof(faces_result) * (faces_result_len + 1), __func__); + faces_result = MEM_mallocN(sizeof(*faces_result) * (faces_result_len + 1), __func__); GHASH_ITER_INDEX (gh_iter, w_dst->faces_uuid, i) { BMFace *f = BLI_ghashIterator_getKey(&gh_iter); faces_result[i] = f; diff --git a/source/blender/bmesh/tools/bmesh_triangulate.c b/source/blender/bmesh/tools/bmesh_triangulate.c index 446c03a543f..b76054f270f 100644 --- a/source/blender/bmesh/tools/bmesh_triangulate.c +++ b/source/blender/bmesh/tools/bmesh_triangulate.c @@ -27,13 +27,20 @@ * */ +#include "DNA_modifier_types.h" /* for MOD_TRIANGULATE_NGON_BEAUTY only */ + #include "MEM_guardedalloc.h" #include "BLI_utildefines.h" #include "BLI_alloca.h" #include "BLI_memarena.h" #include "BLI_listbase.h" -#include "BLI_scanfill.h" +#include "BLI_heap.h" +#include "BLI_edgehash.h" + +/* only for defines */ +#include "BLI_polyfill2d.h" +#include "BLI_polyfill2d_beautify.h" #include "bmesh.h" @@ -42,16 +49,25 @@ /** * a version of #BM_face_triangulate that maps to #BMOpSlot */ -static void bm_face_triangulate_mapping(BMesh *bm, BMFace *face, MemArena *sf_arena, - const int quad_method, const int ngon_method, - const bool use_tag, - BMOperator *op, BMOpSlot *slot_facemap_out) +static void bm_face_triangulate_mapping( + BMesh *bm, BMFace *face, + const int quad_method, const int ngon_method, + const bool use_tag, + BMOperator *op, BMOpSlot *slot_facemap_out, + + MemArena *pf_arena, + /* use for MOD_TRIANGULATE_NGON_BEAUTY only! */ + struct Heap *pf_heap, struct EdgeHash *pf_ehash) { int faces_array_tot = face->len - 3; BMFace **faces_array = BLI_array_alloca(faces_array, faces_array_tot); BLI_assert(face->len > 3); - BM_face_triangulate(bm, face, faces_array, &faces_array_tot, sf_arena, quad_method, ngon_method, use_tag); + BM_face_triangulate( + bm, face, faces_array, &faces_array_tot, + quad_method, ngon_method, use_tag, + pf_arena, + pf_heap, pf_ehash); if (faces_array_tot) { int i; @@ -63,22 +79,39 @@ static void bm_face_triangulate_mapping(BMesh *bm, BMFace *face, MemArena *sf_ar } -void BM_mesh_triangulate(BMesh *bm, const int quad_method, const int ngon_method, const bool tag_only, - BMOperator *op, BMOpSlot *slot_facemap_out) +void BM_mesh_triangulate( + BMesh *bm, const int quad_method, const int ngon_method, const bool tag_only, + BMOperator *op, BMOpSlot *slot_facemap_out) { BMIter iter; BMFace *face; - MemArena *sf_arena; + MemArena *pf_arena; + Heap *pf_heap; + EdgeHash *pf_ehash; - sf_arena = BLI_memarena_new(BLI_SCANFILL_ARENA_SIZE, __func__); + pf_arena = BLI_memarena_new(BLI_POLYFILL_ARENA_SIZE, __func__); + + if (ngon_method == MOD_TRIANGULATE_NGON_BEAUTY) { + pf_heap = BLI_heap_new_ex(BLI_POLYFILL_ALLOC_NGON_RESERVE); + pf_ehash = BLI_edgehash_new_ex(__func__, BLI_POLYFILL_ALLOC_NGON_RESERVE); + } + else { + pf_heap = NULL; + pf_ehash = NULL; + } if (slot_facemap_out) { /* same as below but call: bm_face_triangulate_mapping() */ BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) { if (face->len > 3) { if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) { - bm_face_triangulate_mapping(bm, face, sf_arena, quad_method, ngon_method, tag_only, - op, slot_facemap_out); + bm_face_triangulate_mapping( + bm, face, quad_method, + ngon_method, tag_only, + op, slot_facemap_out, + + pf_arena, + pf_heap, pf_ehash); } } } @@ -87,11 +120,20 @@ void BM_mesh_triangulate(BMesh *bm, const int quad_method, const int ngon_method BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) { if (face->len > 3) { if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) { - BM_face_triangulate(bm, face, NULL, NULL, sf_arena, quad_method, ngon_method, tag_only); + BM_face_triangulate( + bm, face, NULL, NULL, + quad_method, ngon_method, tag_only, + pf_arena, + pf_heap, pf_ehash); } } } } - BLI_memarena_free(sf_arena); + BLI_memarena_free(pf_arena); + + if (ngon_method == MOD_TRIANGULATE_NGON_BEAUTY) { + BLI_heap_free(pf_heap, NULL); + BLI_edgehash_free(pf_ehash, NULL); + } } diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp index 2e92cd9c147..5ce62873377 100644 --- a/source/blender/collada/ArmatureExporter.cpp +++ b/source/blender/collada/ArmatureExporter.cpp @@ -168,7 +168,7 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene *sce, node.setNodeSid(node_sid); #if 0 - if (BLI_listbase_is_empty(&bone->childbase) || BLI_countlist(&(bone->childbase)) >= 2) { + if (BLI_listbase_is_empty(&bone->childbase) || BLI_listbase_count_ex(&bone->childbase, 2) == 2) { add_blender_leaf_bone( bone, ob_arm, node); } else { diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp index e2c36df564a..bdfb7021370 100644 --- a/source/blender/collada/ArmatureImporter.cpp +++ b/source/blender/collada/ArmatureImporter.cpp @@ -37,6 +37,7 @@ #include "BKE_object.h" #include "BKE_armature.h" #include "BLI_string.h" +#include "BLI_listbase.h" #include "ED_armature.h" #include "ArmatureImporter.h" @@ -49,7 +50,23 @@ static const char *bc_get_joint_name(T *node) return id.size() ? id.c_str() : node->getOriginalId().c_str(); } -ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, Scene *sce) : +static EditBone *get_edit_bone(bArmature * armature, char *name) { + EditBone *eBone; + + eBone = (EditBone *)armature->edbo->first; + for (eBone; eBone; eBone = eBone->next) { + if (!strcmp(name, eBone->name)) + return eBone; + } + + return NULL; + +} + + + +ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, Scene *sce, const ImportSettings *import_settings) : + import_settings(import_settings), unit_converter(conv), TransformReader(conv), scene(sce), @@ -57,6 +74,15 @@ ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, mesh_importer(mesh) { } +void ArmatureImporter::clear_extended_boneset() +{ + for (std::map<std::string, BoneExtended *>::iterator it = extended_bones.begin(); it != extended_bones.end(); ++it) { + if (it->second != NULL) + delete it->second; + } + extended_bones.clear(); +} + ArmatureImporter::~ArmatureImporter() { // free skin controller data if we forget to do this earlier @@ -64,6 +90,7 @@ ArmatureImporter::~ArmatureImporter() for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { it->second.free(); } + clear_extended_boneset(); } #if 0 @@ -83,16 +110,17 @@ JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node); } #endif -void ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBone *parent, int totchild, +int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBone *parent, int totchild, float parent_mat[4][4], bArmature *arm) { float mat[4][4]; float joint_inv_bind_mat[4][4]; + int chain_length = 0; //Checking if bone is already made. std::vector<COLLADAFW::Node *>::iterator it; it = std::find(finished_joints.begin(), finished_joints.end(), node); - if (it != finished_joints.end()) return; + if (it != finished_joints.end()) return chain_length; // JointData* jd = get_joint_data(node); @@ -143,96 +171,156 @@ void ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBo // set tail, don't set it to head because 0-length bones are not allowed add_v3_v3v3(bone->tail, bone->head, vec); - // set parent tail + /* find smallest bone length in armature (used later for leaf bone length) */ if (parent) { - // XXX increase this to prevent "very" small bones? - const float epsilon = 0.000001f; - - // derive leaf bone length + /* guess reasonable leaf bone length */ float length = len_v3v3(parent->head, bone->head); - if ((length < leaf_bone_length || totbone == 0) && length > epsilon) { + if ((length < leaf_bone_length || totbone == 0) && length > MINIMUM_BONE_LENGTH) { leaf_bone_length = length; } - - if (totchild == 1) { - copy_v3_v3(parent->tail, bone->head); - - // not setting BONE_CONNECTED because this would lock child bone location with respect to parent - bone->flag |= BONE_CONNECTED; - - - // treat zero-sized bone like a leaf bone - if (length <= epsilon) { - add_leaf_bone(parent_mat, parent, node); - } - } - } COLLADAFW::NodePointerArray& children = node->getChildNodes(); + + BoneExtended &be = add_bone_extended(bone, node); + be.set_leaf_bone(true); + for (unsigned int i = 0; i < children.getCount(); i++) { - create_bone(skin, children[i], bone, children.getCount(), mat, arm); + int cl = create_bone(skin, children[i], bone, children.getCount(), mat, arm); + if (cl > chain_length) + chain_length = cl; } - // in second case it's not a leaf bone, but we handle it the same way - if (!children.getCount() || children.getCount() > 1) { - add_leaf_bone(mat, bone, node); - } bone->length = len_v3v3(bone->head, bone->tail); joint_by_uid[node->getUniqueId()] = node; finished_joints.push_back(node); + + be.set_chain_length(chain_length + 1); + + return chain_length + 1; } -void ArmatureImporter::add_leaf_bone(float mat[4][4], EditBone *bone, COLLADAFW::Node *node) +/** + * Collada only knows Joints, hence bones at the end of a bone chain + * don't have a defined length. This function guesses reasonable + * tail locations for the affected bones (nodes which don't have any connected child) + * Hint: The extended_bones set gets populated in ArmatureImporter::create_bone +**/ +void ArmatureImporter::fix_leaf_bones(bArmature *armature, Bone *bone) { - LeafBone leaf; + /* armature has no bones */ + if (bone == NULL) + return; - leaf.bone = bone; - copy_m4_m4(leaf.mat, mat); - BLI_strncpy(leaf.name, bone->name, sizeof(leaf.name)); - - TagsMap::iterator etit; - ExtraTags *et = 0; - etit = uid_tags_map.find(node->getUniqueId().toAscii()); - if (etit != uid_tags_map.end()) { - et = etit->second; - //else return; + BoneExtended *be = extended_bones[bone->name]; + if (be != NULL && be->is_leaf_bone() ) { + /* Collada only knows Joints, Here we guess a reasonable leaf bone length */ + float leaf_length = (leaf_bone_length == FLT_MAX) ? 1.0 : leaf_bone_length; + + EditBone *ebone = get_edit_bone(armature, bone->name); + float vec[3]; + + if (this->import_settings->fix_orientation) { + if (ebone->parent != NULL) { + EditBone *parent = ebone->parent; + sub_v3_v3v3(vec, ebone->head, parent->tail); + if (len_squared_v3(vec) < MINIMUM_BONE_LENGTH) + { + sub_v3_v3v3(vec, parent->tail, parent->head); + } + } + else { + vec[2] = 0.1f; + sub_v3_v3v3(vec, ebone->tail, ebone->head); + } + } + else { + sub_v3_v3v3(vec, ebone->tail, ebone->head); + } - float x, y, z; - et->setData("tip_x", &x); - et->setData("tip_y", &y); - et->setData("tip_z", &z); - float vec[3] = {x, y, z}; - copy_v3_v3(leaf.bone->tail, leaf.bone->head); - add_v3_v3v3(leaf.bone->tail, leaf.bone->head, vec); - } - else { - leaf_bones.push_back(leaf); + normalize_v3_v3(vec, vec); + mul_v3_fl(vec, leaf_length); + add_v3_v3v3(ebone->tail, ebone->head, vec); } -} -void ArmatureImporter::fix_leaf_bones( ) -{ - // Collada only knows Joints, Here we guess a reasonable - // leaf bone length - float leaf_length = (leaf_bone_length == FLT_MAX) ? 1.0:leaf_bone_length; + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { + fix_leaf_bones(armature, child); + } - // just setting tail for leaf bones here - std::vector<LeafBone>::iterator it; - for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) { +} - LeafBone& leaf = *it; - // pointing up - float vec[3] = {0.0f, 0.0f, 0.1f}; - - sub_v3_v3v3(vec, leaf.bone->tail , leaf.bone->head); - mul_v3_fl(vec, leaf_length); - add_v3_v3v3(leaf.bone->tail, leaf.bone->head , vec); +void ArmatureImporter::connect_bone_chains(bArmature *armature, Bone *parentbone, int clip) +{ + BoneExtended *dominant_child = NULL; + int maxlen = 0; + Bone *child = (Bone *)parentbone->childbase.first; + if (child && (import_settings->find_chains || child->next==NULL) ) + { + for (child; child; child = child->next) { + BoneExtended *be = extended_bones[child->name]; + if (be != NULL) { + if (be->get_chain_length() <= clip) { + if (be->get_chain_length() > maxlen) { + dominant_child = be; + maxlen = be->get_chain_length(); + } + else if (be->get_chain_length() == maxlen) { + dominant_child = NULL; + } + } + } + } + } + BoneExtended *pbe = extended_bones[parentbone->name]; + if (dominant_child != NULL) { + /* Found a valid chain. Now connect current bone with that chain.*/ + EditBone *pebone = get_edit_bone(armature, parentbone->name); + EditBone *cebone = get_edit_bone(armature, dominant_child->get_name()); + if (pebone && !(cebone->flag & BONE_CONNECTED)) { + + float vec[3]; + sub_v3_v3v3(vec, cebone->head, pebone->head); + + /* + * It is possible that the child's head is located on the parents head. + * When this happens, then moving the parent's tail to the child's head + * would result in a zero sized bone and Blender would silently remove the bone. + * So we move the tail only when the resulting bone has a minimum length: + */ + + if (len_squared_v3(vec) > MINIMUM_BONE_LENGTH) + { + pebone->tail[0] = cebone->head[0]; + pebone->tail[1] = cebone->head[1]; + pebone->tail[2] = cebone->head[2]; + + if (pbe && pbe->get_chain_length() >= this->import_settings->min_chain_length) { + cebone->flag |= BONE_CONNECTED; + printf("Connecting chain: parent %s --> %s (child)\n", pebone->name, cebone->name); + pbe->set_leaf_bone(false); + } + } + } + for (Bone *child = (Bone *)parentbone->childbase.first; child; child = child->next) { + ArmatureImporter::connect_bone_chains(armature, child, UNLIMITED_CHAIN_MAX); + } + } + else if (maxlen>1 && maxlen > this->import_settings->min_chain_length) { + /* Try again with smaller chain length */ + ArmatureImporter::connect_bone_chains(armature, parentbone, maxlen - 1); } + else { + /* can't connect this Bone. Proceed with children ... */ + if (pbe) pbe->set_leaf_bone(true); + for (Bone *child = (Bone *)parentbone->childbase.first; child; child = child->next) { + ArmatureImporter::connect_bone_chains(armature, child, UNLIMITED_CHAIN_MAX); + } + } + } #if 0 @@ -351,21 +439,26 @@ void ArmatureImporter::create_armature_bones( ) continue; } + clear_extended_boneset(); + ED_armature_to_edit(armature); create_bone(NULL, *ri , NULL, (*ri)->getChildNodes().getCount(), NULL, armature); - //leaf bone tails are derived from the matrix, so no need of this. - fix_leaf_bones(); + /* exit armature edit mode to populate the Armature object */ + ED_armature_from_edit(armature); + ED_armature_edit_free(armature); + + /* and step back to edit mode to fix the leaf nodes */ + ED_armature_to_edit(armature); + + connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX); + fix_leaf_bones(armature, (Bone *)armature->bonebase.first); // exit armature edit mode unskinned_armature_map[(*ri)->getUniqueId()] = ob_arm; ED_armature_from_edit(armature); - - //This serves no purpose, as pose is automatically reset later, in BKE_where_is_bone() - //set_pose(ob_arm, *ri, NULL, NULL); - ED_armature_edit_free(armature); DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA); } @@ -459,9 +552,11 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin) } // enter armature edit mode - ED_armature_to_edit((bArmature *)ob_arm->data); + bArmature * armature = (bArmature *)ob_arm->data; + ED_armature_to_edit(armature); + + clear_extended_boneset(); - leaf_bones.clear(); totbone = 0; // bone_direction_row = 1; // TODO: don't default to Y but use asset and based on it decide on default row leaf_bone_length = FLT_MAX; @@ -480,20 +575,27 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin) // since root_joints may contain joints for multiple controllers, we need to filter if (skin.uses_joint_or_descendant(*ri)) { - create_bone(&skin, *ri, NULL, (*ri)->getChildNodes().getCount(), NULL, (bArmature *)ob_arm->data); + create_bone(&skin, *ri, NULL, (*ri)->getChildNodes().getCount(), NULL, armature); if (joint_parent_map.find((*ri)->getUniqueId()) != joint_parent_map.end() && !skin.get_parent()) skin.set_parent(joint_parent_map[(*ri)->getUniqueId()]); } } - fix_leaf_bones(); + /* exit armature edit mode to populate the Armature object */ + ED_armature_from_edit(armature); + ED_armature_edit_free(armature); + + /* and step back to edit mode to fix the leaf nodes */ + ED_armature_to_edit(armature); + + connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX); + fix_leaf_bones(armature, (Bone *)armature->bonebase.first); // exit armature edit mode - ED_armature_from_edit((bArmature *)ob_arm->data); - ED_armature_edit_free((bArmature *)ob_arm->data); + ED_armature_from_edit(armature); + ED_armature_edit_free(armature); DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA); - } void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[4][4]) @@ -538,10 +640,11 @@ void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, con } - -// root - if this joint is the top joint in hierarchy, if a joint -// is a child of a node (not joint), root should be true since -// this is where we build armature bones from +/** + * root - if this joint is the top joint in hierarchy, if a joint + * is a child of a node (not joint), root should be true since + * this is where we build armature bones from + **/ void ArmatureImporter::add_root_joint(COLLADAFW::Node *node, Object *parent) { root_joints.push_back(node); @@ -702,7 +805,7 @@ void ArmatureImporter::make_shape_keys() //insert basis key kb = BKE_keyblock_add_ctime(key, "Basis", false); - BKE_key_convert_from_mesh(source_me, kb); + BKE_keyblock_convert_from_mesh(source_me, kb); //insert other shape keys for (int i = 0 ; i < morphTargetIds.getCount() ; i++ ) { @@ -716,7 +819,7 @@ void ArmatureImporter::make_shape_keys() std::string morph_name = *this->mesh_importer->get_geometry_name(me->id.name); kb = BKE_keyblock_add_ctime(key, morph_name.c_str(), false); - BKE_key_convert_from_mesh(me, kb); + BKE_keyblock_convert_from_mesh(me, kb); //apply weights weight = morphWeights.getFloatValues()->getData()[i]; @@ -785,3 +888,71 @@ bool ArmatureImporter::get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint) return found; } + + +/** + * BoneExtended is a helper class needed for the Bone chain finder + * See ArmatureImporter::fix_leaf_bones() + * and ArmatureImporter::connect_bone_chains() + **/ + +BoneExtended::BoneExtended(EditBone *aBone) +{ + this->set_name(aBone->name); + this->chain_length = 0; + this->is_leaf = false; +} + +char *BoneExtended::get_name() +{ + return name; +} + +void BoneExtended::set_name(char *aName) +{ + BLI_strncpy(name, aName, MAXBONENAME); +} + +int BoneExtended::get_chain_length() +{ + return chain_length; +} + +void BoneExtended::set_chain_length(const int aLength) +{ + chain_length = aLength; +} + + +void BoneExtended::set_leaf_bone(bool state) +{ + is_leaf = state; +} + +bool BoneExtended::is_leaf_bone() +{ + return is_leaf; +} + +BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Node *node) +{ + + TagsMap::iterator etit; + ExtraTags *et = 0; + etit = uid_tags_map.find(node->getUniqueId().toAscii()); + if (etit != uid_tags_map.end()) { + float x, y, z; + + et = etit->second; + et->setData("tip_x", &x); + et->setData("tip_y", &y); + et->setData("tip_z", &z); + float vec[3] = { x, y, z }; + copy_v3_v3(bone->tail, bone->head); + add_v3_v3v3(bone->tail, bone->head, vec); + } + + BoneExtended *be = new BoneExtended(bone); + extended_bones[bone->name] = be; + return *be; +} diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h index beeac85cc4d..732fda80ff1 100644 --- a/source/blender/collada/ArmatureImporter.h +++ b/source/blender/collada/ArmatureImporter.h @@ -54,23 +54,41 @@ extern "C" { #include "collada_internal.h" #include "collada_utils.h" +#include "ImportSettings.h" + +#define UNLIMITED_CHAIN_MAX INT_MAX +#define MINIMUM_BONE_LENGTH 0.000001f + +class BoneExtended { + +private: + char name[MAXBONENAME]; + int chain_length; + bool is_leaf; + +public: + + BoneExtended(EditBone *aBone); + char *get_name(); + int get_chain_length(); + + void set_name(char *aName); + void set_chain_length(const int aLength); + void set_leaf_bone(bool state); + bool is_leaf_bone(); +}; class ArmatureImporter : private TransformReader { private: Scene *scene; UnitConverter *unit_converter; + const ImportSettings *import_settings; // std::map<int, JointData> joint_index_to_joint_info_map; // std::map<COLLADAFW::UniqueId, int> joint_id_to_joint_index_map; - struct LeafBone { - // COLLADAFW::Node *node; - EditBone *bone; - char name[32]; - float mat[4][4]; // bone matrix, derived from inv_bind_mat - }; - std::vector<LeafBone> leaf_bones; + std::map<std::string, BoneExtended *> extended_bones; // int bone_direction_row; // XXX not used float leaf_bone_length; int totbone; @@ -106,13 +124,15 @@ private: JointData *get_joint_data(COLLADAFW::Node *node); #endif - void create_bone(SkinInfo* skin, COLLADAFW::Node *node, EditBone *parent, int totchild, + int create_bone(SkinInfo* skin, COLLADAFW::Node *node, EditBone *parent, int totchild, float parent_mat[4][4], bArmature *arm); - void add_leaf_bone(float mat[4][4], EditBone *bone, COLLADAFW::Node * node); + BoneExtended &add_bone_extended(EditBone *bone, COLLADAFW::Node * node); + void clear_extended_boneset(); + + void fix_leaf_bones(bArmature *armature, Bone *bone); + void connect_bone_chains(bArmature *armature, Bone *bone, const int max_chain_length); - void fix_leaf_bones(); - void set_pose( Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[4][4]); @@ -137,7 +157,7 @@ private: TagsMap uid_tags_map; public: - ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, Scene *sce); + ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, Scene *sce, const ImportSettings *import_settings); ~ArmatureImporter(); void add_root_joint(COLLADAFW::Node *node, Object *parent); diff --git a/source/blender/collada/ControllerExporter.cpp b/source/blender/collada/ControllerExporter.cpp index bc1c4172f46..25fd9c81535 100644 --- a/source/blender/collada/ControllerExporter.cpp +++ b/source/blender/collada/ControllerExporter.cpp @@ -556,7 +556,7 @@ std::string ControllerExporter::add_inv_bind_mats_source(Object *ob_arm, ListBas COLLADASW::FloatSourceF source(mSW); source.setId(source_id); source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(totjoint); //BLI_countlist(defbase)); + source.setAccessorCount(totjoint); //BLI_listbase_count(defbase)); source.setAccessorStride(16); source.setParameterTypeName(&COLLADASW::CSWC::CSW_VALUE_TYPE_FLOAT4x4); diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index 8101e579098..20ef45b6b71 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -104,7 +104,7 @@ DocumentImporter::DocumentImporter(bContext *C, const ImportSettings *import_set import_settings(import_settings), mImportStage(General), mContext(C), - armature_importer(&unit_converter, &mesh_importer, CTX_data_scene(C)), + armature_importer(&unit_converter, &mesh_importer, CTX_data_scene(C), import_settings), mesh_importer(&unit_converter, &armature_importer, CTX_data_scene(C)), anim_importer(&unit_converter, &armature_importer, CTX_data_scene(C)) { diff --git a/source/blender/collada/ErrorHandler.cpp b/source/blender/collada/ErrorHandler.cpp index 7ac138ac807..854e8abd76d 100644 --- a/source/blender/collada/ErrorHandler.cpp +++ b/source/blender/collada/ErrorHandler.cpp @@ -47,7 +47,7 @@ ErrorHandler::~ErrorHandler() //-------------------------------------------------------------------- bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error) { - mError = true; + bool isError = true; if (error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXPARSER) { COLLADASaxFWL::SaxParserError *saxParserError = (COLLADASaxFWL::SaxParserError *) error; @@ -56,14 +56,14 @@ bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error) // Workaround to avoid wrong error if (parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_VALIDATION_MIN_OCCURS_UNMATCHED) { if (strcmp(parserError.getElement(), "effect") == 0) { - mError = false; + isError = false; } } if (parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_VALIDATION_SEQUENCE_PREVIOUS_SIBLING_NOT_PRESENT) { if (!((strcmp(parserError.getElement(), "extra") == 0) && (strcmp(parserError.getAdditionalText().c_str(), "sibling: fx_profile_abstract") == 0))) { - mError = false; + isError = false; } } @@ -75,11 +75,21 @@ bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error) } else if (error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXFWL) { COLLADASaxFWL::SaxFWLError *saxFWLError = (COLLADASaxFWL::SaxFWLError *) error; + /* + * Accept non critical errors as warnings (i.e. texture not found) + * This makes the importer more gracefull, so it now imports what makes sense. + */ + if (saxFWLError->getSeverity() == COLLADASaxFWL::IError::SEVERITY_ERROR_NONCRITICAL) { + isError = false; + } + std::cout << "Sax FWL Error: " << saxFWLError->getErrorMessage() << std::endl; } else { std::cout << "opencollada error: " << error->getFullErrorMessage() << std::endl; } - return false; + mError |= isError; + + return false; // let OpenCollada decide when to abort } diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp index 1bf245c39e0..28cee05ec4b 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -159,7 +159,7 @@ void GeometryExporter::operator()(Object *ob) //skip the basis kb = kb->next; for (; kb; kb = kb->next) { - BKE_key_convert_to_mesh(kb, me); + BKE_keyblock_convert_to_mesh(kb, me); export_key_mesh(ob, me, kb); } } diff --git a/source/blender/collada/ImportSettings.h b/source/blender/collada/ImportSettings.h index 3f3a9fb354e..51a13da7724 100644 --- a/source/blender/collada/ImportSettings.h +++ b/source/blender/collada/ImportSettings.h @@ -32,7 +32,9 @@ struct ImportSettings { public: bool import_units; - + bool find_chains; + bool fix_orientation; + int min_chain_length; char *filepath; }; diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp index 75928f9d189..71875d6274a 100644 --- a/source/blender/collada/SkinInfo.cpp +++ b/source/blender/collada/SkinInfo.cpp @@ -38,13 +38,16 @@ #include "BLI_math.h" #include "BLI_compiler_attrs.h" -#include "BKE_object.h" #include "DNA_armature_types.h" #include "DNA_modifier_types.h" #include "DNA_scene_types.h" + +#include "BKE_action.h" +#include "BKE_object.h" +#include "BKE_object_deform.h" + #include "ED_mesh.h" #include "ED_object.h" -#include "BKE_action.h" #include "SkinInfo.h" #include "collada_utils.h" @@ -263,7 +266,7 @@ void SkinInfo::link_armature(bContext *C, Object *ob, std::map<COLLADAFW::Unique name = bc_get_joint_name(joint_by_uid[(*it).joint_uid]); } - ED_vgroup_add_name(ob, (char *)name); + BKE_object_defgroup_add_name(ob, name); } // <vcount> - number of joints per vertex - joints_per_vertex diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp index ffbbb8623ac..f1d5f1a208a 100644 --- a/source/blender/collada/collada.cpp +++ b/source/blender/collada/collada.cpp @@ -44,13 +44,18 @@ extern "C" int collada_import(bContext *C, const char *filepath, - int import_units) + int import_units, + int find_chains, + int fix_orientation, + int min_chain_length) { ImportSettings import_settings; - import_settings.filepath = (char *)filepath; - - import_settings.import_units = import_units != 0; + import_settings.filepath = (char *)filepath; + import_settings.import_units = import_units != 0; + import_settings.find_chains = find_chains != 0; + import_settings.fix_orientation = fix_orientation != 0; + import_settings.min_chain_length = min_chain_length; DocumentImporter imp(C, &import_settings); if (imp.import()) return 1; diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h index 524c704cdee..6819a62fdf0 100644 --- a/source/blender/collada/collada.h +++ b/source/blender/collada/collada.h @@ -55,7 +55,10 @@ struct Scene; */ int collada_import(struct bContext *C, const char *filepath, - int import_units); + int import_units, + int find_chains, + int fix_orientation, + int min_chain_length); int collada_export(struct Scene *sce, const char *filepath, diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp index 567ee22b3d6..2aab9b6e7d3 100644 --- a/source/blender/collada/collada_internal.cpp +++ b/source/blender/collada/collada_internal.cpp @@ -94,8 +94,7 @@ void UnitConverter::dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math:: void UnitConverter::mat4_to_dae(float out[4][4], float in[4][4]) { - copy_m4_m4(out, in); - transpose_m4(out); + transpose_m4_m4(out, in); } void UnitConverter::mat4_to_dae_double(double out[4][4], float in[4][4]) diff --git a/source/blender/compositor/intern/COM_Debug.cpp b/source/blender/compositor/intern/COM_Debug.cpp index 470f8fd2ef7..af693ea9149 100644 --- a/source/blender/compositor/intern/COM_Debug.cpp +++ b/source/blender/compositor/intern/COM_Debug.cpp @@ -398,7 +398,7 @@ void DebugInfo::graphviz(const ExecutionSystem *system) char filename[FILE_MAX]; BLI_snprintf(basename, sizeof(basename), "compositor_%d.dot", m_file_index); - BLI_join_dirfile(filename, sizeof(filename), BLI_temp_dir_session(), basename); + BLI_join_dirfile(filename, sizeof(filename), BKE_tempdir_session(), basename); ++m_file_index; FILE *fp = BLI_fopen(filename, "wb"); diff --git a/source/blender/compositor/nodes/COM_MathNode.cpp b/source/blender/compositor/nodes/COM_MathNode.cpp index ef7046b8165..4cd6964ed3b 100644 --- a/source/blender/compositor/nodes/COM_MathNode.cpp +++ b/source/blender/compositor/nodes/COM_MathNode.cpp @@ -29,61 +29,61 @@ void MathNode::convertToOperations(NodeConverter &converter, const CompositorCon MathBaseOperation *operation = NULL; switch (this->getbNode()->custom1) { - case 0: /* Add */ + case NODE_MATH_ADD: operation = new MathAddOperation(); break; - case 1: /* Subtract */ + case NODE_MATH_SUB: operation = new MathSubtractOperation(); break; - case 2: /* Multiply */ + case NODE_MATH_MUL: operation = new MathMultiplyOperation(); break; - case 3: /* Divide */ + case NODE_MATH_DIVIDE: operation = new MathDivideOperation(); break; - case 4: /* Sine */ + case NODE_MATH_SIN: operation = new MathSineOperation(); break; - case 5: /* Cosine */ + case NODE_MATH_COS: operation = new MathCosineOperation(); break; - case 6: /* Tangent */ + case NODE_MATH_TAN: operation = new MathTangentOperation(); break; - case 7: /* Arc-Sine */ + case NODE_MATH_ASIN: operation = new MathArcSineOperation(); break; - case 8: /* Arc-Cosine */ + case NODE_MATH_ACOS: operation = new MathArcCosineOperation(); break; - case 9: /* Arc-Tangent */ + case NODE_MATH_ATAN: operation = new MathArcTangentOperation(); break; - case 10: /* Power */ + case NODE_MATH_POW: operation = new MathPowerOperation(); break; - case 11: /* Logarithm */ + case NODE_MATH_LOG: operation = new MathLogarithmOperation(); break; - case 12: /* Minimum */ + case NODE_MATH_MIN: operation = new MathMinimumOperation(); break; - case 13: /* Maximum */ + case NODE_MATH_MAX: operation = new MathMaximumOperation(); break; - case 14: /* Round */ + case NODE_MATH_ROUND: operation = new MathRoundOperation(); break; - case 15: /* Less Than */ + case NODE_MATH_LESS: operation = new MathLessThanOperation(); break; - case 16: /* Greater Than */ + case NODE_MATH_GREATER: operation = new MathGreaterThanOperation(); break; - case 17: /* Modulo */ + case NODE_MATH_MOD: operation = new MathModuloOperation(); break; - case 18: /* Absolute Value */ + case NODE_MATH_ABS: operation = new MathAbsoluteOperation(); break; } diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp index ea1443598a9..fa9a957f83c 100644 --- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp @@ -60,7 +60,7 @@ void ConvertDepthToRadiusOperation::initExecution() this->m_inputOperation = this->getInputSocketReader(0); float focalDistance = determineFocalDistance(); - if (focalDistance == 0.0f) focalDistance = 1e10f; /* if the dof is 0.0 then set it be be far away */ + if (focalDistance == 0.0f) focalDistance = 1e10f; /* if the dof is 0.0 then set it to be far away */ this->m_inverseFocalDistance = 1.0f / focalDistance; this->m_aspect = (this->getWidth() > this->getHeight()) ? (this->getHeight() / (float)this->getWidth()) : (this->getWidth() / (float)this->getHeight()); this->m_aperture = 0.5f * (this->m_cam_lens / (this->m_aspect * cam_sensor)) / this->m_fStop; diff --git a/source/blender/compositor/operations/COM_ConvertOperation.cpp b/source/blender/compositor/operations/COM_ConvertOperation.cpp index 6b3e4067b18..1445b78552f 100644 --- a/source/blender/compositor/operations/COM_ConvertOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertOperation.cpp @@ -292,6 +292,9 @@ void ConvertHSVToRGBOperation::executePixelSampled(float output[4], float x, flo float inputColor[4]; this->m_inputOperation->readSampled(inputColor, x, y, sampler); hsv_to_rgb_v(inputColor, output); + output[0] = max_ff(output[0], 0.0f); + output[1] = max_ff(output[1], 0.0f); + output[2] = max_ff(output[2], 0.0f); output[3] = inputColor[3]; } diff --git a/source/blender/compositor/operations/COM_CropOperation.cpp b/source/blender/compositor/operations/COM_CropOperation.cpp index c514b576dcf..9bcc6fb2541 100644 --- a/source/blender/compositor/operations/COM_CropOperation.cpp +++ b/source/blender/compositor/operations/COM_CropOperation.cpp @@ -109,9 +109,9 @@ bool CropImageOperation::determineDependingAreaOfInterest(rcti *input, ReadBuffe return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } -void CropImageOperation::determineResolution(unsigned int resolution[2], unsigned int preferedResolution[2]) +void CropImageOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) { - NodeOperation::determineResolution(resolution, preferedResolution); + NodeOperation::determineResolution(resolution, preferredResolution); updateArea(); resolution[0] = this->m_xmax - this->m_xmin; resolution[1] = this->m_ymax - this->m_ymin; diff --git a/source/blender/compositor/operations/COM_CropOperation.h b/source/blender/compositor/operations/COM_CropOperation.h index 4890ede18a9..0b396ca7800 100644 --- a/source/blender/compositor/operations/COM_CropOperation.h +++ b/source/blender/compositor/operations/COM_CropOperation.h @@ -56,7 +56,7 @@ private: public: CropImageOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void determineResolution(unsigned int resolution[2], unsigned int preferedResolution[2]); + void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp index 67f52934b13..962a95ebd05 100644 --- a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp @@ -69,16 +69,16 @@ void DirectionalBlurOperation::initExecution() void DirectionalBlurOperation::executePixel(float output[4], int x, int y, void *data) { const int iterations = pow(2.0f, this->m_data->iter); - float col[4] = {0, 0, 0, 0}; - float col2[4] = {0, 0, 0, 0}; - this->m_inputProgram->readSampled(col2, x, y, COM_PS_NEAREST); + float col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + float col2[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + this->m_inputProgram->readSampled(col2, x, y, COM_PS_BILINEAR); float ltx = this->m_tx; float lty = this->m_ty; float lsc = this->m_sc; float lrot = this->m_rot; /* blur the image */ for (int i = 0; i < iterations; ++i) { - const float cs = cos(lrot), ss = sin(lrot); + const float cs = cosf(lrot), ss = sinf(lrot); const float isc = 1.0f / (1.0f + lsc); const float v = isc * (y - this->m_center_y_pix) + lty; @@ -87,7 +87,7 @@ void DirectionalBlurOperation::executePixel(float output[4], int x, int y, void this->m_inputProgram->readSampled(col, cs * u + ss * v + this->m_center_x_pix, cs * v - ss * u + this->m_center_y_pix, - COM_PS_NEAREST); + COM_PS_BILINEAR); add_v4_v4(col2, col); diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl b/source/blender/compositor/operations/COM_OpenCLKernels.cl index 1b965eb8659..cbd05cbec17 100644 --- a/source/blender/compositor/operations/COM_OpenCLKernels.cl +++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl @@ -80,10 +80,10 @@ __kernel void bokehBlurKernel(__read_only image2d_t boundingBox, __read_only ima } //KERNEL --- DEFOCUS /VARIABLESIZEBOKEHBLUR --- -__kernel void defocusKernel(__read_only image2d_t inputImage, __read_only image2d_t bokehImage, - __read_only image2d_t inputSize, - __write_only image2d_t output, int2 offsetInput, int2 offsetOutput, - int step, int maxBlurScalar, float threshold, float scalar, int2 dimension, int2 offset) +__kernel void defocusKernel(__read_only image2d_t inputImage, __read_only image2d_t bokehImage, + __read_only image2d_t inputSize, + __write_only image2d_t output, int2 offsetInput, int2 offsetOutput, + int step, int maxBlurScalar, float threshold, float scalar, int2 dimension, int2 offset) { float4 color = {1.0f, 0.0f, 0.0f, 1.0f}; int2 coords = {get_global_id(0), get_global_id(1)}; @@ -212,8 +212,8 @@ __kernel void erodeKernel(__read_only image2d_t inputImage, __write_only image2 // KERNEL --- DIRECTIONAL BLUR --- __kernel void directionalBlurKernel(__read_only image2d_t inputImage, __write_only image2d_t output, - int2 offsetOutput, int iterations, float scale, float rotation, float2 translate, - float2 center, int2 offset) + int2 offsetOutput, int iterations, float scale, float rotation, float2 translate, + float2 center, int2 offset) { int2 coords = {get_global_id(0), get_global_id(1)}; coords += offset; diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp index bcef652a8b5..12b04c386f2 100644 --- a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp +++ b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp @@ -50,34 +50,52 @@ void SunBeamsOperation::initExecution() * For a target point (x,y) the sector should be chosen such that * ``u >= v >= 0`` * This removes the need to handle all sorts of special cases. + * + * Template parameters: + * fxu : buffer increment in x for sector u+1 + * fxv : buffer increment in x for sector v+1 + * fyu : buffer increment in y for sector u+1 + * fyv : buffer increment in y for sector v+1 */ -template <int fxx, int fxy, int fyx, int fyy> +template <int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator { /* utility functions implementing the matrix transform to/from sector space */ - - static inline void buffer_to_sector(int x, int y, int &u, int &v) + + static inline void buffer_to_sector(const float source[2], int x, int y, int &u, int &v) { - u = x * fxx + y * fyx; - v = x * fxy + y * fyy; + int x0 = (int)source[0]; + int y0 = (int)source[1]; + x -= x0; + y -= y0; + u = x * fxu + y * fyu; + v = x * fxv + y * fyv; } - static inline void buffer_to_sector(float x, float y, float &u, float &v) + static inline void buffer_to_sector(const float source[2], float x, float y, float &u, float &v) { - u = x * fxx + y * fyx; - v = x * fxy + y * fyy; + int x0 = (int)source[0]; + int y0 = (int)source[1]; + x -= (float)x0; + y -= (float)y0; + u = x * fxu + y * fyu; + v = x * fxv + y * fyv; } - static inline void sector_to_buffer(int u, int v, int &x, int &y) + static inline void sector_to_buffer(const float source[2], int u, int v, int &x, int &y) { - x = u * fxx + v * fxy; - y = u * fyx + v * fyy; + int x0 = (int)source[0]; + int y0 = (int)source[1]; + x = x0 + u * fxu + v * fxv; + y = y0 + u * fyu + v * fyv; } - static inline void sector_to_buffer(float u, float v, float &x, float &y) + static inline void sector_to_buffer(const float source[2], float u, float v, float &x, float &y) { - x = u * fxx + v * fxy; - y = u * fyx + v * fyy; + int x0 = (int)source[0]; + int y0 = (int)source[1]; + x = (float)x0 + u * fxu + v * fxv; + y = (float)y0 + u * fyu + v * fyv; } /** @@ -91,12 +109,12 @@ struct BufferLineAccumulator { * \param num Total steps in the loop * \param v, dv Vertical offset in sector space, for line offset perpendicular to the loop axis */ - static float *init_buffer_iterator(MemoryBuffer *input, const float source[2], const float pt_ofs[2], + static float *init_buffer_iterator(MemoryBuffer *input, const float source[2], const float co[2], float dist_min, float dist_max, int &x, int &y, int &num, float &v, float &dv, float &falloff_factor) { float pu, pv; - buffer_to_sector(pt_ofs[0], pt_ofs[1], pu, pv); + buffer_to_sector(source, co[0], co[1], pu, pv); /* line angle */ float tan_phi = pv / pu; @@ -113,9 +131,7 @@ struct BufferLineAccumulator { int end = (int)ceilf(umin); num = end - start; - sector_to_buffer(end, (int)ceilf(v), x, y); - x += (int)source[0]; - y += (int)source[1]; + sector_to_buffer(source, end, (int)ceilf(v), x, y); falloff_factor = dist_max > dist_min ? dr / (float)(dist_max - dist_min) : 0.0f; @@ -130,7 +146,7 @@ struct BufferLineAccumulator { * The loop runs backwards(!) over the primary sector space axis u, i.e. increasing distance to pt. * After each step it decrements v by dv < 1, adding a buffer shift when necessary. */ - static void eval(MemoryBuffer *input, float output[4], const float pt_ofs[2], const float source[2], + static void eval(MemoryBuffer *input, float output[4], const float co[2], const float source[2], float dist_min, float dist_max) { rcti rect = *input->getRect(); @@ -139,14 +155,16 @@ struct BufferLineAccumulator { float v, dv; float falloff_factor; float border[4]; - - if ((int)pt_ofs[0] == 0 && (int)pt_ofs[1] == 0) { + + zero_v4(output); + + if ((int)(co[0] - source[0]) == 0 && (int)(co[1] - source[1]) == 0) { copy_v4_v4(output, input->getBuffer() + COM_NUMBER_OF_CHANNELS * ((int)source[0] + input->getWidth() * (int)source[1])); return; } /* initialise the iteration variables */ - float *buffer = init_buffer_iterator(input, source, pt_ofs, dist_min, dist_max, x, y, num, v, dv, falloff_factor); + float *buffer = init_buffer_iterator(input, source, co, dist_min, dist_max, x, y, num, v, dv, falloff_factor); zero_v3(border); border[3] = 1.0f; @@ -178,18 +196,18 @@ struct BufferLineAccumulator { */ /* decrement u */ - x -= fxx; - y -= fyx; - buffer -= (fxx + fyx * buffer_width) * COM_NUMBER_OF_CHANNELS; + x -= fxu; + y -= fyu; + buffer -= (fxu + fyu * buffer_width) * COM_NUMBER_OF_CHANNELS; /* decrement v (in steps of dv < 1) */ v_local -= dv; if (v_local < 0.0f) { v_local += 1.0f; - x -= fxy; - y -= fyy; - buffer -= (fxy + fyy * buffer_width) * COM_NUMBER_OF_CHANNELS; + x -= fxv; + y -= fyv; + buffer -= (fxv + fyv * buffer_width) * COM_NUMBER_OF_CHANNELS; } } @@ -233,21 +251,21 @@ static void accumulate_line(MemoryBuffer *input, float output[4], const float co if (pt_ofs[0] > 0.0f) { if (pt_ofs[1] > 0.0f) { /* 2 */ - BufferLineAccumulator<0, 1, 1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator<0, 1, 1, 0>::eval(input, output, co, source, dist_min, dist_max); } else { /* 7 */ - BufferLineAccumulator<0, 1, -1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator<0, 1, -1, 0>::eval(input, output, co, source, dist_min, dist_max); } } else { if (pt_ofs[1] > 0.0f) { /* 3 */ - BufferLineAccumulator<0, -1, 1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator<0, -1, 1, 0>::eval(input, output, co, source, dist_min, dist_max); } else { /* 6 */ - BufferLineAccumulator<0, -1, -1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator<0, -1, -1, 0>::eval(input, output, co, source, dist_min, dist_max); } } } @@ -255,21 +273,21 @@ static void accumulate_line(MemoryBuffer *input, float output[4], const float co if (pt_ofs[0] > 0.0f) { if (pt_ofs[1] > 0.0f) { /* 1 */ - BufferLineAccumulator< 1, 0, 0, 1>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator< 1, 0, 0, 1>::eval(input, output, co, source, dist_min, dist_max); } else { /* 8 */ - BufferLineAccumulator< 1, 0, 0, -1>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator< 1, 0, 0, -1>::eval(input, output, co, source, dist_min, dist_max); } } else { if (pt_ofs[1] > 0.0f) { /* 4 */ - BufferLineAccumulator<-1, 0, 0, 1>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator<-1, 0, 0, 1>::eval(input, output, co, source, dist_min, dist_max); } else { /* 5 */ - BufferLineAccumulator<-1, 0, 0, -1>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator<-1, 0, 0, -1>::eval(input, output, co, source, dist_min, dist_max); } } } diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 7d8e278f0cf..baab8a05030 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -120,8 +120,8 @@ static void acf_generic_root_backdrop(bAnimContext *ac, bAnimListElem *ale, floa glColor3fv(color); /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */ - uiSetRoundBox((expanded) ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT)); - uiDrawBox(GL_POLYGON, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8); + UI_draw_roundbox_corner_set((expanded) ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT)); + UI_draw_roundbox_gl_mode(GL_POLYGON, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8); } @@ -420,8 +420,8 @@ static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float ymi * - top and bottom * - special hack: make the top a bit higher, since we are first... */ - uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT); - uiDrawBox(GL_POLYGON, 0, yminc - 2, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8); + UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT); + UI_draw_roundbox_gl_mode(GL_POLYGON, 0, yminc - 2, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8); } /* name for summary entries */ @@ -800,8 +800,8 @@ static void acf_group_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc glColor3fv(color); /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */ - uiSetRoundBox(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT)); - uiDrawBox(GL_POLYGON, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8); + UI_draw_roundbox_corner_set(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT)); + UI_draw_roundbox_gl_mode(GL_POLYGON, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8); } /* name for group entries */ @@ -2365,6 +2365,83 @@ static bAnimChannelType ACF_DSSPK = acf_dsspk_setting_ptr /* pointer for setting */ }; +/* GPencil Expander ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_dsgpencil_icon(bAnimListElem *UNUSED(ale)) +{ + return ICON_GREASEPENCIL; +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_dsgpencil_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg) +{ + /* clear extra return data first */ + *neg = false; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return GP_DATA_EXPAND; + + case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ + return ADT_NLA_EVAL_OFF; + + case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ + *neg = true; + return ADT_CURVES_NOT_VISIBLE; + + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_dsgpencil_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type) +{ + bGPdata *gpd = (bGPdata *)ale->data; + + /* clear extra return data first */ + *type = 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return GET_ACF_FLAG_PTR(gpd->flag, type); + + case ACHANNEL_SETTING_SELECT: /* selected */ + case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ + case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ + if (gpd->adt) + return GET_ACF_FLAG_PTR(gpd->adt->flag, type); + return NULL; + + default: /* unsupported */ + return NULL; + } +} + +/* grease pencil expander type define */ +static bAnimChannelType ACF_DSGPENCIL = +{ + "GPencil DS Expander", /* type name */ + ACHANNEL_ROLE_EXPANDER, /* role */ + + acf_generic_dataexpand_color, /* backdrop color */ + acf_generic_dataexpand_backdrop, /* backdrop */ + acf_generic_indention_1, /* indent level */ + acf_generic_basic_offset, /* offset */ + + acf_generic_idblock_name, /* name */ + acf_generic_idblock_name_prop, /* name prop */ + acf_dsgpencil_icon, /* icon */ + + acf_generic_dataexpand_setting_valid, /* has setting */ + acf_dsgpencil_setting_flag, /* flag for setting */ + acf_dsgpencil_setting_ptr /* pointer for setting */ +}; + /* ShapeKey Entry ------------------------------------------- */ /* name for ShapeKey */ @@ -3010,12 +3087,12 @@ static void acf_nlaaction_backdrop(bAnimContext *ac, bAnimListElem *ale, float y /* only on top left corner, to show that this channel sits on top of the preceding ones * while still linking into the action line strip to the right */ - uiSetRoundBox(UI_CNR_TOP_LEFT); + UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT); /* draw slightly shifted up vertically to look like it has more separation from other channels, * but we then need to slightly shorten it so that it doesn't look like it overlaps */ - uiDrawBox(GL_POLYGON, offset, yminc + NLACHANNEL_SKIP, (float)v2d->cur.xmax, ymaxc + NLACHANNEL_SKIP - 1, 8); + UI_draw_roundbox_gl_mode(GL_POLYGON, offset, yminc + NLACHANNEL_SKIP, (float)v2d->cur.xmax, ymaxc + NLACHANNEL_SKIP - 1, 8); } /* name for nla action entries */ @@ -3162,6 +3239,7 @@ static void ANIM_init_channel_typeinfo_data(void) animchannelTypeInfo[type++] = &ACF_DSLAT; /* Lattice Channel */ animchannelTypeInfo[type++] = &ACF_DSLINESTYLE; /* LineStyle Channel */ animchannelTypeInfo[type++] = &ACF_DSSPK; /* Speaker Channel */ + animchannelTypeInfo[type++] = &ACF_DSGPENCIL; /* GreasePencil Channel */ animchannelTypeInfo[type++] = &ACF_SHAPEKEY; /* ShapeKey */ @@ -3407,6 +3485,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float /* step 4) draw special toggles ................................. * - in Graph Editor, checkboxes for visibility in curves area * - in NLA Editor, glowing dots for solo/not solo... + * - in Grease Pencil mode, color swatches for layer color */ if (ac->sl) { if ((ac->spacetype == SPACE_IPO) && acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) { @@ -3431,6 +3510,10 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float /* just skip - drawn as widget now */ offset += ICON_WIDTH; } + else if (ale->type == ANIMTYPE_GPLAYER) { + /* just skip - drawn as a widget */ + offset += ICON_WIDTH; + } } /* step 5) draw name ............................................... */ @@ -3449,7 +3532,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float acf->name(ale, name); offset += 3; - UI_DrawString(offset, ytext, name); + UI_draw_string(offset, ytext, name); /* draw red underline if channel is disabled */ if ((ale->type == ANIMTYPE_FCURVE) && (ale->flag & FCURVE_DISABLED)) { @@ -3601,18 +3684,6 @@ static void achannel_nlatrack_solo_widget_cb(bContext *C, void *adt_poin, void * WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_RENAME, NULL); } -/* callback for rename widgets - clear rename-in-progress */ -static void achannel_setting_rename_done_cb(bContext *C, void *ads_poin, void *UNUSED(arg2)) -{ - bDopeSheet *ads = (bDopeSheet *)ads_poin; - - /* reset rename index so that edit box disappears now that editing is done */ - ads->renameIndex = 0; - - /* send notifiers */ - WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_RENAME, NULL); -} - /* callback for widget sliders - insert keyframes */ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poin) { @@ -3788,9 +3859,9 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann /* type of button */ if (negflag) - butType = ICONTOGN; + butType = UI_BTYPE_ICON_TOGGLE_N; else - butType = ICONTOG; + butType = UI_BTYPE_ICON_TOGGLE; /* draw button for setting */ if (ptr && flag) { @@ -3819,18 +3890,18 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann case ACHANNEL_SETTING_PROTECT: /* General - protection flags */ case ACHANNEL_SETTING_MUTE: /* General - muting flags */ case ACHANNEL_SETTING_PINNED: /* NLA Actions - 'map/nomap' */ - uiButSetNFunc(but, achannel_setting_flush_widget_cb, MEM_dupallocN(ale), SET_INT_IN_POINTER(setting)); + UI_but_funcN_set(but, achannel_setting_flush_widget_cb, MEM_dupallocN(ale), SET_INT_IN_POINTER(setting)); break; /* settings needing special attention */ case ACHANNEL_SETTING_SOLO: /* NLA Tracks - Solo toggle */ - uiButSetFunc(but, achannel_nlatrack_solo_widget_cb, ale->adt, ale->data); + UI_but_func_set(but, achannel_nlatrack_solo_widget_cb, ale->adt, ale->data); break; /* no flushing */ case ACHANNEL_SETTING_EXPAND: /* expanding - cannot flush, otherwise all would open/close at once */ default: - uiButSetFunc(but, achannel_setting_widget_cb, NULL, NULL); + UI_but_func_set(but, achannel_setting_widget_cb, NULL, NULL); break; } } @@ -3861,7 +3932,7 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale ymid = y - 0.5f * ICON_WIDTH; /* no button backdrop behind icons */ - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); /* step 1) draw expand widget ....................................... */ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_EXPAND)) { @@ -3878,6 +3949,7 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale /* step 3) draw special toggles ................................. * - in Graph Editor, checkboxes for visibility in curves area * - in NLA Editor, glowing dots for solo/not solo... + * - in Grease Pencil mode, color swatches for layer color */ if (ac->sl) { if ((ac->spacetype == SPACE_IPO) && acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) { @@ -3890,6 +3962,23 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_SOLO); offset += ICON_WIDTH; } + else if (ale->type == ANIMTYPE_GPLAYER) { + /* color swatch for layer color */ + bGPDlayer *gpl = (bGPDlayer *)ale->data; + PointerRNA ptr; + + RNA_pointer_create(ale->id, &RNA_GPencilLayer, ale->data, &ptr); + + UI_block_emboss_set(block, UI_EMBOSS); + + uiDefButR(block, UI_BTYPE_COLOR, 1, "", offset, yminc, ICON_WIDTH, ICON_WIDTH, + &ptr, "color", -1, + 0, 0, 0, 0, gpl->info); + + UI_block_emboss_set(block, UI_EMBOSS_NONE); + + offset += ICON_WIDTH; + } } /* step 4) draw text - check if renaming widget is in use... */ @@ -3908,14 +3997,20 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale if (acf->name_prop(ale, &ptr, &prop)) { uiBut *but; - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); - but = uiDefButR(block, TEX, 1, "", offset + 3, yminc, RENAME_TEXT_WIDTH, channel_height, + but = uiDefButR(block, UI_BTYPE_TEXT, 1, "", offset + 3, yminc, RENAME_TEXT_WIDTH, channel_height, &ptr, RNA_property_identifier(prop), -1, 0, 0, -1, -1, NULL); - uiButSetFunc(but, achannel_setting_rename_done_cb, ac->ads, NULL); - uiButActiveOnly(C, ac->ar, block, but); - uiBlockSetEmboss(block, UI_EMBOSSN); + /* copy what outliner does here, see outliner_buttons */ + if (UI_but_active_only(C, ac->ar, block, but) == false) { + ac->ads->renameIndex = 0; + + /* send notifiers */ + WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_RENAME, NULL); + } + + UI_block_emboss_set(block, UI_EMBOSS_NONE); } } } @@ -3972,16 +4067,16 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale uiBut *but; PointerRNA *opptr_b; - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); offset += UI_UNIT_X; - but = uiDefIconButO(block, BUT, "NLA_OT_action_pushdown", WM_OP_INVOKE_DEFAULT, ICON_NLA_PUSHDOWN, + but = uiDefIconButO(block, UI_BTYPE_BUT, "NLA_OT_action_pushdown", WM_OP_INVOKE_DEFAULT, ICON_NLA_PUSHDOWN, (int)v2d->cur.xmax - offset, ymid, UI_UNIT_X, UI_UNIT_X, NULL); - opptr_b = uiButGetOperatorPtrRNA(but); + opptr_b = UI_but_operator_ptr_get(but); RNA_int_set(opptr_b, "channel_index", channel_index); - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); } } @@ -3999,7 +4094,7 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale offset += SLIDER_WIDTH; /* need backdrop behind sliders... */ - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); if (ale->id) { /* Slider using RNA Access -------------------- */ PointerRNA id_ptr, ptr; @@ -4037,9 +4132,9 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale /* assign keyframing function according to slider type */ if (ale->type == ANIMTYPE_SHAPEKEY) - uiButSetFunc(but, achannel_setting_slider_shapekey_cb, ale->id, ale->data); + UI_but_func_set(but, achannel_setting_slider_shapekey_cb, ale->id, ale->data); else - uiButSetFunc(but, achannel_setting_slider_cb, ale->id, ale->data); + UI_but_func_set(but, achannel_setting_slider_cb, ale->id, ale->data); } /* free the path if necessary */ diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index b6ab0407711..d8ad6506186 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -129,6 +129,7 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datat case ANIMTYPE_DSLAT: case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: + case ANIMTYPE_DSGPENCIL: { /* need to verify that this data is valid for now */ if (ale->adt) { @@ -136,6 +137,13 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datat } break; } + case ANIMTYPE_GPLAYER: + { + bGPDlayer *gpl = (bGPDlayer *)ale->data; + + ACHANNEL_SET_FLAG(gpl, ACHANNEL_SETFLAG_CLEAR, GP_LAYER_ACTIVE); + break; + } } } @@ -176,6 +184,7 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datat case ANIMTYPE_DSSPK: case ANIMTYPE_DSNTREE: case ANIMTYPE_DSTEX: + case ANIMTYPE_DSGPENCIL: { /* need to verify that this data is valid for now */ if (ale && ale->adt) { @@ -184,8 +193,14 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datat break; } - /* unhandled currently, but may be interesting */ case ANIMTYPE_GPLAYER: + { + bGPDlayer *gpl = (bGPDlayer *)channel_data; + gpl->flag |= GP_LAYER_ACTIVE; + break; + } + + /* unhandled currently, but may be interesting */ case ANIMTYPE_MASKLAYER: case ANIMTYPE_SHAPEKEY: case ANIMTYPE_NLAACTION: @@ -268,6 +283,7 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d case ANIMTYPE_DSLAT: case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: + case ANIMTYPE_DSGPENCIL: { if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED)) sel = ACHANNEL_SETFLAG_CLEAR; @@ -361,6 +377,7 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d case ANIMTYPE_DSLAT: case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: + case ANIMTYPE_DSGPENCIL: { /* need to verify that this data is valid for now */ if (ale->adt) { @@ -843,6 +860,13 @@ static void rearrange_animchannel_add_to_islands(ListBase *islands, ListBase *sr is_sel = SEL_NLT(nlt); break; } + case ANIMTYPE_GPLAYER: + { + bGPDlayer *gpl = (bGPDlayer *)channel; + + is_sel = SEL_GPL(gpl); + break; + } default: printf("rearrange_animchannel_add_to_islands(): don't know how to handle channels of type %d\n", type); return; @@ -1167,6 +1191,47 @@ static void rearrange_action_channels(bAnimContext *ac, bAction *act, eRearrange /* ------------------- */ +static void rearrange_gpencil_channels(bAnimContext *ac, eRearrangeAnimChan_Mode mode) +{ + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + + /* get rearranging function */ + AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode); + + if (rearrange_func == NULL) + return; + + /* get Grease Pencil datablocks */ + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA); + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + + for (ale = anim_data.first; ale; ale = ale->next) { + ListBase anim_data_visible = {NULL, NULL}; + bGPdata *gpd = ale->data; + + /* only consider layers if this datablock is open */ + BLI_assert(ale->type == ANIMTYPE_GPDATABLOCK); + if ((gpd->flag & GP_DATA_EXPAND) == 0) + continue; + + /* Filter visible data. */ + rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_GPLAYER); + + /* rearrange datablock's layers */ + rearrange_animchannel_islands(&gpd->layers, rearrange_func, mode, ANIMTYPE_GPLAYER, &anim_data_visible); + + /* free visible layers data */ + BLI_freelistN(&anim_data_visible); + } + + /* free GPD channel data */ + ANIM_animdata_freelist(&anim_data); +} + +/* ------------------- */ + static int animchannels_rearrange_exec(bContext *C, wmOperator *op) { bAnimContext ac; @@ -1182,7 +1247,7 @@ static int animchannels_rearrange_exec(bContext *C, wmOperator *op) /* method to move channels depends on the editor */ if (ac.datatype == ANIMCONT_GPENCIL) { /* Grease Pencil channels */ - printf("Grease Pencil not supported for moving yet\n"); + rearrange_gpencil_channels(&ac, mode); } else if (ac.datatype == ANIMCONT_MASK) { /* Grease Pencil channels */ @@ -1585,175 +1650,6 @@ static void ANIM_OT_channels_delete(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ******************** Set Channel Visibility Operator *********************** */ -/* NOTE: this operator is only valid in the Graph Editor channels region */ - -static int animchannels_visibility_set_exec(bContext *C, wmOperator *UNUSED(op)) -{ - bAnimContext ac; - ListBase anim_data = {NULL, NULL}; - ListBase all_data = {NULL, NULL}; - bAnimListElem *ale; - int filter; - - /* get editor data */ - if (ANIM_animdata_get_context(C, &ac) == 0) - return OPERATOR_CANCELLED; - - /* get list of all channels that selection may need to be flushed to - * - hierarchy mustn't affect what we have access to here... - */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS); - ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype); - - /* hide all channels not selected - * - hierarchy matters if we're doing this from the channels region - * since we only want to apply this to channels we can "see", - * and have these affect their relatives - * - but for Graph Editor, this gets used also from main region - * where hierarchy doesn't apply, as for [#21276] - */ - if ((ac.spacetype == SPACE_IPO) && (ac.regiontype != RGN_TYPE_CHANNELS)) { - /* graph editor (case 2) */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_UNSEL | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); - } - else { - /* standard case */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_UNSEL | ANIMFILTER_NODUPLIS); - } - ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); - - for (ale = anim_data.first; ale; ale = ale->next) { - /* clear setting first */ - ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_CLEAR); - - /* now also flush selection status as appropriate - * NOTE: in some cases, this may result in repeat flushing being performed - */ - ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, 0); - } - - ANIM_animdata_freelist(&anim_data); - - /* make all the selected channels visible */ - filter = (ANIMFILTER_SEL | ANIMFILTER_NODUPLIS); - ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); - - for (ale = anim_data.first; ale; ale = ale->next) { - /* hack: skip object channels for now, since flushing those will always flush everything, but they are always included */ - /* TODO: find out why this is the case, and fix that */ - if (ale->type == ANIMTYPE_OBJECT) - continue; - - /* enable the setting */ - ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD); - - /* now, also flush selection status up/down as appropriate */ - ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, 1); - } - - ANIM_animdata_freelist(&anim_data); - BLI_freelistN(&all_data); - - - /* send notifier that things have changed */ - WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); - - return OPERATOR_FINISHED; -} - -static void ANIM_OT_channels_visibility_set(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Set Visibility"; - ot->idname = "ANIM_OT_channels_visibility_set"; - ot->description = "Make only the selected animation channels visible in the Graph Editor"; - - /* api callbacks */ - ot->exec = animchannels_visibility_set_exec; - ot->poll = ED_operator_graphedit_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - - -/* ******************** Toggle Channel Visibility Operator *********************** */ -/* NOTE: this operator is only valid in the Graph Editor channels region */ - -static int animchannels_visibility_toggle_exec(bContext *C, wmOperator *UNUSED(op)) -{ - bAnimContext ac; - ListBase anim_data = {NULL, NULL}; - ListBase all_data = {NULL, NULL}; - bAnimListElem *ale; - int filter; - short vis = ACHANNEL_SETFLAG_ADD; - - /* get editor data */ - if (ANIM_animdata_get_context(C, &ac) == 0) - return OPERATOR_CANCELLED; - - /* get list of all channels that selection may need to be flushed to - * - hierarchy mustn't affect what we have access to here... - */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS); - ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype); - - /* filter data - * - restrict this to only applying on settings we can get to in the list - */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS); - ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); - - /* See if we should be making showing all selected or hiding */ - for (ale = anim_data.first; ale; ale = ale->next) { - /* set the setting in the appropriate way (if available) */ - if (ANIM_channel_setting_get(&ac, ale, ACHANNEL_SETTING_VISIBLE)) { - vis = ACHANNEL_SETFLAG_CLEAR; - break; - } - } - - /* Now set the flags */ - for (ale = anim_data.first; ale; ale = ale->next) { - /* hack: skip object channels for now, since flushing those will always flush everything, but they are always included */ - /* TODO: find out why this is the case, and fix that */ - if (ale->type == ANIMTYPE_OBJECT) - continue; - - /* change the setting */ - ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, vis); - - /* now, also flush selection status up/down as appropriate */ - ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, (vis == ACHANNEL_SETFLAG_ADD)); - } - - /* cleanup */ - ANIM_animdata_freelist(&anim_data); - BLI_freelistN(&all_data); - - /* send notifier that things have changed */ - WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); - - return OPERATOR_FINISHED; -} - -static void ANIM_OT_channels_visibility_toggle(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Toggle Visibility"; - ot->idname = "ANIM_OT_channels_visibility_toggle"; - ot->description = "Toggle visibility in Graph Editor of all selected animation channels"; - - /* api callbacks */ - ot->exec = animchannels_visibility_toggle_exec; - ot->poll = ED_operator_graphedit_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - /* ********************** Set Flags Operator *********************** */ /* defines for setting animation-channel flags */ @@ -2334,7 +2230,7 @@ static int animchannels_deselectall_exec(bContext *C, wmOperator *op) /* 'standard' behavior - check if selected, then apply relevant selection */ if (RNA_boolean_get(op->ptr, "invert")) - ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, false, ACHANNEL_SETFLAG_TOGGLE); + ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, false, ACHANNEL_SETFLAG_INVERT); else ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, true, ACHANNEL_SETFLAG_ADD); @@ -2736,6 +2632,7 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index, case ANIMTYPE_DSLAT: case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: + case ANIMTYPE_DSGPENCIL: { /* sanity checking... */ if (ale->adt) { @@ -2897,7 +2794,13 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index, gpl->flag |= GP_LAYER_SELECT; } - notifierFlags |= (ND_ANIMCHAN | NA_EDITED); + /* change active layer, if this is selected (since we must always have an active layer) */ + if (gpl->flag & GP_LAYER_SELECT) { + ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, gpl, ANIMTYPE_GPLAYER); + } + + WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); /* Grease Pencil updates */ + notifierFlags |= (ND_ANIMCHAN | NA_EDITED); /* Animation Ediotrs updates */ break; } case ANIMTYPE_MASKDATABLOCK: @@ -3042,9 +2945,6 @@ void ED_operatortypes_animchannels(void) WM_operatortype_append(ANIM_OT_channels_expand); WM_operatortype_append(ANIM_OT_channels_collapse); - WM_operatortype_append(ANIM_OT_channels_visibility_toggle); - WM_operatortype_append(ANIM_OT_channels_visibility_set); - WM_operatortype_append(ANIM_OT_channels_fcurves_enable); WM_operatortype_append(ANIM_OT_channels_clean_empty); @@ -3110,10 +3010,6 @@ void ED_keymap_animchannels(wmKeyConfig *keyconf) /* grouping */ WM_keymap_add_item(keymap, "ANIM_OT_channels_group", GKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "ANIM_OT_channels_ungroup", GKEY, KM_PRESS, KM_ALT, 0); - - /* Graph Editor only */ - WM_keymap_add_item(keymap, "ANIM_OT_channels_visibility_set", VKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "ANIM_OT_channels_visibility_toggle", VKEY, KM_PRESS, KM_SHIFT, 0); } /* ************************************************************************** */ diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c index f3b47b168e9..eb57907c9ec 100644 --- a/source/blender/editors/animation/anim_deps.c +++ b/source/blender/editors/animation/anim_deps.c @@ -92,7 +92,7 @@ void ANIM_list_elem_update(Scene *scene, bAnimListElem *ale) RNA_property_update_main(G.main, scene, &ptr, prop); } else { - /* in other case we do standard depsgaph update, ideally + /* in other case we do standard depsgraph update, ideally * we'd be calling property update functions here too ... */ DAG_id_tag_update(id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); // XXX or do we want something more restrictive? } diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index 9c3f310a417..2d7656642d3 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -41,7 +41,6 @@ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_nla.h" -#include "BKE_object.h" #include "ED_anim_api.h" #include "ED_keyframes_edit.h" @@ -62,7 +61,7 @@ static void draw_cfra_number(Scene *scene, View2D *v2d, const float cfra, const { float xscale, yscale, x, y; char numstr[32] = " t"; /* t is the character to start replacing from */ - short slen; + int slen; /* because the frame number text is subject to the same scaling as the contents of the view */ UI_view2d_scale_get(v2d, &xscale, &yscale); @@ -79,7 +78,7 @@ static void draw_cfra_number(Scene *scene, View2D *v2d, const float cfra, const else { BLI_timecode_string_from_time_simple(&numstr[4], sizeof(numstr) - 4, 1, cfra); } - slen = (short)UI_GetStringWidth(numstr) - 1; + slen = UI_fontstyle_string_width(numstr) - 1; /* get starting coordinates for drawing */ x = cfra * xscale; @@ -91,7 +90,7 @@ static void draw_cfra_number(Scene *scene, View2D *v2d, const float cfra, const /* draw current frame number - black text */ UI_ThemeColor(TH_TEXT); - UI_DrawString(x - 0.25f * U.widget_unit, y + 0.15f * U.widget_unit, numstr); + UI_draw_string(x - 0.25f * U.widget_unit, y + 0.15f * U.widget_unit, numstr); /* restore view transform */ glScalef(xscale, 1.0, 1.0); diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index dad25eb04af..d6daa64a9f2 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -216,7 +216,7 @@ static bool actedit_get_context(bAnimContext *ac, SpaceAction *saction) /* Get data being edited in Graph Editor (depending on current 'mode') */ static bool graphedit_get_context(bAnimContext *ac, SpaceIpo *sipo) { - /* init dopesheet data if non-existant (i.e. for old files) */ + /* init dopesheet data if non-existent (i.e. for old files) */ if (sipo->ads == NULL) { sipo->ads = MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet"); sipo->ads->source = (ID *)ac->scene; @@ -267,7 +267,7 @@ static bool graphedit_get_context(bAnimContext *ac, SpaceIpo *sipo) /* Get data being edited in Graph Editor (depending on current 'mode') */ static bool nlaedit_get_context(bAnimContext *ac, SpaceNla *snla) { - /* init dopesheet data if non-existant (i.e. for old files) */ + /* init dopesheet data if non-existent (i.e. for old files) */ if (snla->ads == NULL) snla->ads = MEM_callocN(sizeof(bDopeSheet), "NlaEdit DopeSheet"); ac->ads = snla->ads; @@ -771,6 +771,21 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->adt = BKE_animdata_from_id(data); break; } + case ANIMTYPE_DSGPENCIL: + { + bGPdata *gpd = (bGPdata *)data; + AnimData *adt = gpd->adt; + + /* NOTE: we just reuse the same expand filter for this case */ + ale->flag = EXPANDED_GPD(gpd); + + // XXX: currently, this is only used for access to its animation data + ale->key_data = (adt) ? adt->action : NULL; + ale->datatype = ALE_ACT; + + ale->adt = BKE_animdata_from_id(data); + break; + } case ANIMTYPE_GROUP: { bActionGroup *agrp = (bActionGroup *)data; @@ -1255,7 +1270,7 @@ static size_t animfilter_nla(bAnimContext *UNUSED(ac), ListBase *anim_data, bDop first = adt->nla_tracks.last; } else { - /* first track to include will the the first one (as per normal) */ + /* first track to include will the first one (as per normal) */ first = adt->nla_tracks.first; } @@ -1413,27 +1428,77 @@ static size_t animdata_filter_gpencil(ListBase *anim_data, void *UNUSED(data), i /* only show if gpd is used by something... */ if (ID_REAL_USERS(gpd) < 1) continue; + + /* When asked from "AnimData" blocks (i.e. the top-level containers for normal animation), + * for convenience, this will return GP Datablocks instead. This may cause issues down + * the track, but for now, this will do... + */ + if (filter_mode & ANIMFILTER_ANIMDATA) { + /* just add GPD as a channel - this will add everything needed */ + ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_GPDATABLOCK, NULL); + } + else { + /* add gpencil animation channels */ + BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_GPD(gpd)) + { + tmp_items += animdata_filter_gpencil_data(&tmp_data, gpd, filter_mode); + } + END_ANIMFILTER_SUBCHANNELS; - /* add gpencil animation channels */ - BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_GPD(gpd)) - { - tmp_items += animdata_filter_gpencil_data(&tmp_data, gpd, filter_mode); + /* did we find anything? */ + if (tmp_items) { + /* include data-expand widget first */ + if (filter_mode & ANIMFILTER_LIST_CHANNELS) { + /* add gpd as channel too (if for drawing, and it has layers) */ + ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_GPDATABLOCK, NULL); + } + + /* now add the list of collected channels */ + BLI_movelisttolist(anim_data, &tmp_data); + BLI_assert(BLI_listbase_is_empty(&tmp_data)); + items += tmp_items; + } } - END_ANIMFILTER_SUBCHANNELS; + } + + /* return the number of items added to the list */ + return items; +} + +/* Helper for Grease Pencil data integrated with main DopeSheet */ +static size_t animdata_filter_ds_gpencil(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bGPdata *gpd, int filter_mode) +{ + ListBase tmp_data = {NULL, NULL}; + size_t tmp_items = 0; + size_t items = 0; + + /* add relevant animation channels for Grease Pencil */ + BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_GPD(gpd)) + { + /* add animation channels */ + tmp_items += animfilter_block_data(ac, &tmp_data, ads, &gpd->id, filter_mode); - /* did we find anything? */ - if (tmp_items) { - /* include data-expand widget first */ - if (filter_mode & ANIMFILTER_LIST_CHANNELS) { - /* add gpd as channel too (if for drawing, and it has layers) */ - ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_GPDATABLOCK, NULL); + /* add Grease Pencil layers */ + // TODO: do these need a separate expander? + // XXX: what order should these go in? + } + END_ANIMFILTER_SUBCHANNELS; + + /* did we find anything? */ + if (tmp_items) { + /* include data-expand widget first */ + if (filter_mode & ANIMFILTER_LIST_CHANNELS) { + /* check if filtering by active status */ + // XXX: active check here needs checking + if (ANIMCHANNEL_ACTIVEOK(gpd)) { + ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_DSGPENCIL, gpd); } - - /* now add the list of collected channels */ - BLI_movelisttolist(anim_data, &tmp_data); - BLI_assert(BLI_listbase_is_empty(&tmp_data)); - items += tmp_items; } + + /* now add the list of collected channels */ + BLI_movelisttolist(anim_data, &tmp_data); + BLI_assert(BLI_listbase_is_empty(&tmp_data)); + items += tmp_items; } /* return the number of items added to the list */ @@ -1699,6 +1764,12 @@ static size_t animdata_filter_ds_textures(bAnimContext *ac, ListBase *anim_data, mtex = (MTex **)(&wo->mtex); break; } + case ID_PA: + { + ParticleSettings *part = (ParticleSettings *)owner_id; + mtex = (MTex **)(&part->mtex); + break; + } default: { /* invalid/unsupported option */ @@ -1910,8 +1981,12 @@ static size_t animdata_filter_ds_particles(bAnimContext *ac, ListBase *anim_data /* add particle-system's animation data to temp collection */ BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_PART_OBJD(psys->part)) { - /* material's animation data */ + /* particle system's animation data */ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)psys->part, filter_mode); + + /* textures */ + if (!(ads->filterflag & ADS_FILTER_NOTEX)) + tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)psys->part, filter_mode); } END_ANIMFILTER_SUBCHANNELS; @@ -2215,6 +2290,11 @@ static size_t animdata_filter_dopesheet_ob(bAnimContext *ac, ListBase *anim_data if ((ob->particlesystem.first) && !(ads->filterflag & ADS_FILTER_NOPART)) { tmp_items += animdata_filter_ds_particles(ac, &tmp_data, ads, ob, filter_mode); } + + /* grease pencil */ + if ((ob->gpd) && !(ads->filterflag & ADS_FILTER_NOGPENCIL)) { + tmp_items += animdata_filter_ds_gpencil(ac, &tmp_data, ads, ob->gpd, filter_mode); + } } END_ANIMFILTER_SUBCHANNELS; @@ -2257,7 +2337,7 @@ static size_t animdata_filter_ds_world(bAnimContext *ac, ListBase *anim_data, bD /* textures for world */ if (!(ads->filterflag & ADS_FILTER_NOTEX)) - items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)wo, filter_mode); + tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)wo, filter_mode); /* nodes */ if ((wo->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE)) @@ -2349,6 +2429,7 @@ static size_t animdata_filter_dopesheet_scene(bAnimContext *ac, ListBase *anim_d BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_SCEC(sce)) { bNodeTree *ntree = sce->nodetree; + bGPdata *gpd = sce->gpd; World *wo = sce->world; /* Action, Drivers, or NLA for Scene */ @@ -2371,6 +2452,11 @@ static size_t animdata_filter_dopesheet_scene(bAnimContext *ac, ListBase *anim_d tmp_items += animdata_filter_ds_linestyle(ac, &tmp_data, ads, sce, filter_mode); } + /* grease pencil */ + if ((gpd) && !(ads->filterflag & ADS_FILTER_NOGPENCIL)) { + tmp_items += animdata_filter_ds_gpencil(ac, &tmp_data, ads, gpd, filter_mode); + } + /* TODO: one day, when sequencer becomes its own datatype, perhaps it should be included here */ } END_ANIMFILTER_SUBCHANNELS; diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index 7cd47fab83a..b6c7a4aa5a0 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -316,19 +316,14 @@ void debug_markers_print_list(ListBase *markers) /* ************* Marker Drawing ************ */ /* function to draw markers */ -static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag) +static void draw_marker( + View2D *v2d, TimeMarker *marker, int cfra, int flag, + /* avoid re-calculating each time */ + const float ypixels, const float xscale, const float yscale) { - float xpos, ypixels, xscale, yscale; - int icon_id = 0; - - xpos = marker->frame; - - /* no time correction for framelen! space is drawn with old values */ - ypixels = BLI_rcti_size_y(&v2d->mask); - UI_view2d_scale_get(v2d, &xscale, &yscale); - - glScalef(1.0f / xscale, 1.0f, 1.0f); - + const float xpos = marker->frame * xscale; + int icon_id; + glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -347,8 +342,8 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag) glColor4ub(0, 0, 0, 96); glBegin(GL_LINES); - glVertex2f((xpos * xscale) + 0.5f, 12.0f); - glVertex2f((xpos * xscale) + 0.5f, (v2d->cur.ymax + 12.0f) * yscale); + glVertex2f(xpos + 0.5f, 12.0f); + glVertex2f(xpos + 0.5f, (v2d->cur.ymax + 12.0f) * yscale); glEnd(); setlinestyle(0); @@ -365,7 +360,7 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag) ICON_MARKER; } - UI_icon_draw(xpos * xscale - 0.45f * UI_DPI_ICON_SIZE, UI_DPI_ICON_SIZE, icon_id); + UI_icon_draw(xpos - 0.45f * UI_DPI_ICON_SIZE, UI_DPI_ICON_SIZE, icon_id); glDisable(GL_BLEND); @@ -378,19 +373,19 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag) if (marker->flag & SELECT) { UI_ThemeColor(TH_TEXT_HI); - x = xpos * xscale + 4.0f * UI_DPI_FAC; + x = xpos + 4.0f * UI_DPI_FAC; y = (ypixels <= 39.0f * UI_DPI_FAC) ? (ypixels - 10.0f * UI_DPI_FAC) : 29.0f * UI_DPI_FAC; y = max_ii(y, min_y); } else { UI_ThemeColor(TH_TEXT); if ((marker->frame <= cfra) && (marker->frame + 5 > cfra)) { - x = xpos * xscale + 8.0f * UI_DPI_FAC; + x = xpos + 8.0f * UI_DPI_FAC; y = (ypixels <= 39.0f * UI_DPI_FAC) ? (ypixels - 10.0f * UI_DPI_FAC) : 29.0f * UI_DPI_FAC; y = max_ii(y, min_y); } else { - x = xpos * xscale + 8.0f * UI_DPI_FAC; + x = xpos + 8.0f * UI_DPI_FAC; y = 17.0f * UI_DPI_FAC; } } @@ -404,39 +399,70 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag) } #endif - UI_DrawString(x, y, marker->name); + UI_draw_string(x, y, marker->name); } - - glScalef(xscale, 1.0f, 1.0f); } /* Draw Scene-Markers in time window */ -void draw_markers_time(const bContext *C, int flag) +void ED_markers_draw(const bContext *C, int flag) { ListBase *markers = ED_context_get_markers(C); View2D *v2d; TimeMarker *marker; Scene *scene; + int select_pass; + int v2d_clip_range_x[2]; + float font_width_max; - if (markers == NULL) + /* cache values */ + float ypixels, xscale, yscale; + + if (markers == NULL || BLI_listbase_is_empty(markers)) { return; + } scene = CTX_data_scene(C); v2d = UI_view2d_fromcontext(C); - /* unselected markers are drawn at the first time */ - for (marker = markers->first; marker; marker = marker->next) { - if ((marker->flag & SELECT) == 0) { - draw_marker(v2d, marker, scene->r.cfra, flag); - } + if (flag & DRAW_MARKERS_MARGIN) { + const unsigned char shade[4] = {0, 0, 0, 16}; + glColor4ubv(shade); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glRectf(v2d->cur.xmin, 0, v2d->cur.xmax, UI_MARKER_MARGIN_Y); + + glDisable(GL_BLEND); } - - /* selected markers are drawn later */ - for (marker = markers->first; marker; marker = marker->next) { - if (marker->flag & SELECT) { - draw_marker(v2d, marker, scene->r.cfra, flag); + + /* no time correction for framelen! space is drawn with old values */ + ypixels = BLI_rcti_size_y(&v2d->mask); + UI_view2d_scale_get(v2d, &xscale, &yscale); + glScalef(1.0f / xscale, 1.0f, 1.0f); + + /* x-bounds with offset for text (adjust for long string, avoid checking string width) */ + font_width_max = (10 * UI_DPI_FAC) / xscale; + v2d_clip_range_x[0] = v2d->cur.xmin - (sizeof(marker->name) * font_width_max); + v2d_clip_range_x[1] = v2d->cur.xmax + font_width_max; + + /* loop [unselected, selected] */ + for (select_pass = 0; select_pass <= SELECT; select_pass += SELECT) { + /* unselected markers are drawn at the first time */ + for (marker = markers->first; marker; marker = marker->next) { + if ((marker->flag & SELECT) == select_pass) { + /* bounds check */ + if ((marker->frame >= v2d_clip_range_x[0]) && + (marker->frame <= v2d_clip_range_x[1])) + { + draw_marker(v2d, marker, scene->r.cfra, flag, + ypixels, xscale, yscale); + } + } } } + + glScalef(xscale, 1.0f, 1.0f); } /* ************************ Marker Wrappers API ********************* */ @@ -503,8 +529,9 @@ static int ed_markers_opwrap_invoke_custom(bContext *C, wmOperator *op, const wm /* return status modifications - for now, make this spacetype dependent as above */ if (sa->spacetype != SPACE_TIME) { /* unless successful, must add "pass-through" to let normal operator's have a chance at tackling this event */ - if (retval != OPERATOR_FINISHED) + if ((retval & (OPERATOR_FINISHED | OPERATOR_INTERFACE)) == 0) { retval |= OPERATOR_PASS_THROUGH; + } } return retval; diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 0f202003dd8..8a9e02a64ea 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -41,6 +41,7 @@ #include "DNA_scene_types.h" #include "BKE_context.h" +#include "BKE_sequencer.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_sound.h" @@ -92,9 +93,15 @@ static void change_frame_apply(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - + int frame = RNA_int_get(op->ptr, "frame"); + bool do_snap = RNA_boolean_get(op->ptr, "snap"); + + if (do_snap && CTX_wm_space_seq(C)) { + frame = BKE_sequencer_find_next_prev_edit(scene, frame, SEQ_SIDE_BOTH, true, false, false); + } + /* set the new frame number */ - CFRA = RNA_int_get(op->ptr, "frame"); + CFRA = frame; FRAMENUMBER_MIN_CLAMP(CFRA); SUBFRA = 0.0f; @@ -144,7 +151,7 @@ static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event * click-dragging over a range (modal scrubbing). */ RNA_int_set(op->ptr, "frame", frame_from_event(C, event)); - + change_frame_apply(C, op); /* add temp handler */ @@ -175,6 +182,16 @@ static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event) if (event->val == KM_RELEASE) return OPERATOR_FINISHED; break; + + case LEFTCTRLKEY: + case RIGHTCTRLKEY: + if (event->val == KM_RELEASE) { + RNA_boolean_set(op->ptr, "snap", false); + } + else if (event->val == KM_PRESS) { + RNA_boolean_set(op->ptr, "snap", true); + } + break; } return OPERATOR_RUNNING_MODAL; @@ -182,6 +199,8 @@ static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event) static void ANIM_OT_change_frame(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Change Frame"; ot->idname = "ANIM_OT_change_frame"; @@ -198,6 +217,8 @@ static void ANIM_OT_change_frame(wmOperatorType *ot) /* rna */ ot->prop = RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME); + prop = RNA_def_boolean(ot->srna, "snap", false, "Snap", ""); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } /* ****************** set preview range operator ****************************/ diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index 296a52e7f20..5799101a7db 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -39,18 +39,12 @@ #include "BLI_utildefines.h" #include "DNA_anim_types.h" -#include "DNA_object_types.h" -#include "DNA_material_types.h" #include "DNA_texture_types.h" -#include "DNA_screen_types.h" -#include "DNA_space_types.h" #include "BKE_animsys.h" #include "BKE_fcurve.h" #include "BKE_context.h" #include "BKE_report.h" -#include "BKE_material.h" -#include "BKE_texture.h" #include "ED_keyframing.h" @@ -437,7 +431,7 @@ static int add_driver_button_exec(bContext *C, wmOperator *op) const bool all = RNA_boolean_get(op->ptr, "all"); /* try to create driver using property retrieved from UI */ - uiContextActiveProperty(C, &ptr, &prop, &index); + UI_context_active_but_prop_get(C, &ptr, &prop, &index); if (all) index = -1; @@ -455,7 +449,7 @@ static int add_driver_button_exec(bContext *C, wmOperator *op) if (success) { /* send updates */ - uiContextAnimUpdate(C); + UI_context_update_anim_flag(C); WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX } @@ -492,7 +486,7 @@ static int remove_driver_button_exec(bContext *C, wmOperator *op) const bool all = RNA_boolean_get(op->ptr, "all"); /* try to find driver using property retrieved from UI */ - uiContextActiveProperty(C, &ptr, &prop, &index); + UI_context_active_but_prop_get(C, &ptr, &prop, &index); if (all) index = -1; @@ -506,7 +500,7 @@ static int remove_driver_button_exec(bContext *C, wmOperator *op) if (success) { /* send updates */ - uiContextAnimUpdate(C); + UI_context_update_anim_flag(C); WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX } @@ -542,7 +536,7 @@ static int copy_driver_button_exec(bContext *C, wmOperator *op) int index; /* try to create driver using property retrieved from UI */ - uiContextActiveProperty(C, &ptr, &prop, &index); + UI_context_active_but_prop_get(C, &ptr, &prop, &index); if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) { char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL); @@ -551,7 +545,7 @@ static int copy_driver_button_exec(bContext *C, wmOperator *op) /* only copy the driver for the button that this was involved for */ success = ANIM_copy_driver(op->reports, ptr.id.data, path, index, 0); - uiContextAnimUpdate(C); + UI_context_update_anim_flag(C); MEM_freeN(path); } @@ -586,7 +580,7 @@ static int paste_driver_button_exec(bContext *C, wmOperator *op) int index; /* try to create driver using property retrieved from UI */ - uiContextActiveProperty(C, &ptr, &prop, &index); + UI_context_active_but_prop_get(C, &ptr, &prop, &index); if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) { char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL); @@ -595,7 +589,7 @@ static int paste_driver_button_exec(bContext *C, wmOperator *op) /* only copy the driver for the button that this was involved for */ success = ANIM_paste_driver(op->reports, ptr.id.data, path, index, 0); - uiContextAnimUpdate(C); + UI_context_update_anim_flag(C); MEM_freeN(path); } diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c index 7ce33e01747..8ede1a0ad76 100644 --- a/source/blender/editors/animation/fmodifier_ui.c +++ b/source/blender/editors/animation/fmodifier_ui.c @@ -119,12 +119,12 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s /* basic settings (backdrop + mode selector + some padding) */ /* col = uiLayoutColumn(layout, true); */ /* UNUSED */ block = uiLayoutGetBlock(layout); - uiBlockBeginAlign(block); - but = uiDefButR(block, MENU, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "mode", -1, 0, 0, -1, -1, NULL); - uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL); + UI_block_align_begin(block); + but = uiDefButR(block, UI_BTYPE_MENU, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "mode", -1, 0, 0, -1, -1, NULL); + UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL); - uiDefButR(block, TOG, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "use_additive", -1, 0, 0, -1, -1, NULL); - uiBlockEndAlign(block); + uiDefButR(block, UI_BTYPE_TOGGLE, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "use_additive", -1, 0, 0, -1, -1, NULL); + UI_block_align_end(block); /* now add settings for individual modes */ switch (data->mode) { @@ -138,20 +138,20 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s /* draw polynomial order selector */ row = uiLayoutRow(layout, false); block = uiLayoutGetBlock(row); - but = uiDefButI(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 0.5f * UI_UNIT_X, 0, bwidth, UI_UNIT_Y, + but = uiDefButI(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 0.5f * UI_UNIT_X, 0, bwidth, UI_UNIT_Y, &data->poly_order, 1, 100, 0, 0, TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)")); - uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL); + UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL); /* calculate maximum width of label for "x^n" labels */ if (data->arraysize > 2) { BLI_snprintf(xval, sizeof(xval), "x^%u", data->arraysize); - maxXWidth = UI_GetStringWidth(xval) + 0.5 * UI_UNIT_X; /* XXX: UI_GetStringWidth is not accurate */ + maxXWidth = UI_fontstyle_string_width(xval) + 0.5 * UI_UNIT_X; /* XXX: UI_fontstyle_string_width is not accurate */ } else { /* basic size (just "x") */ - maxXWidth = UI_GetStringWidth("x") + 0.5 * UI_UNIT_X; + maxXWidth = UI_fontstyle_string_width("x") + 0.5 * UI_UNIT_X; } /* draw controls for each coefficient and a + sign at end of row */ @@ -162,12 +162,12 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s for (i = 0; (i < data->arraysize) && (cp); i++, cp++) { /* To align with first line... */ if (i) - uiDefBut(block, LABEL, 1, " ", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 1, " ", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); else - uiDefBut(block, LABEL, 1, "y =", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 1, "y =", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); /* coefficient */ - uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, bwidth / 2, UI_UNIT_Y, cp, -UI_FLT_MAX, UI_FLT_MAX, + uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, "", 0, 0, bwidth / 2, UI_UNIT_Y, cp, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, TIP_("Coefficient for polynomial")); /* 'x' param (and '+' if necessary) */ @@ -177,10 +177,10 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s BLI_strncpy(xval, "x", sizeof(xval)); else BLI_snprintf(xval, sizeof(xval), "x^%u", i); - uiDefBut(block, LABEL, 1, xval, 0, 0, maxXWidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, TIP_("Power of x")); + uiDefBut(block, UI_BTYPE_LABEL, 1, xval, 0, 0, maxXWidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, TIP_("Power of x")); if ( (i != (data->arraysize - 1)) || ((i == 0) && data->arraysize == 2) ) { - uiDefBut(block, LABEL, 1, "+", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 1, "+", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); /* next coefficient on a new row */ row = uiLayoutRow(layout, true); @@ -188,7 +188,7 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s } else { /* For alignment in UI! */ - uiDefBut(block, LABEL, 1, " ", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 1, " ", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); } } break; @@ -202,10 +202,10 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s /* draw polynomial order selector */ row = uiLayoutRow(layout, false); block = uiLayoutGetBlock(row); - but = uiDefButI(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 0, 0, width - 1.5 * UI_UNIT_X, UI_UNIT_Y, + but = uiDefButI(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 0, 0, width - 1.5 * UI_UNIT_X, UI_UNIT_Y, &data->poly_order, 1, 100, 0, 0, TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)")); - uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL); + UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL); /* draw controls for each pair of coefficients */ @@ -216,31 +216,31 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s for (i = 0; (i < data->poly_order) && (cp); i++, cp += 2) { /* To align with first line */ if (i) - uiDefBut(block, LABEL, 1, " ", 0, 0, 2.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 1, " ", 0, 0, 2.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); else - uiDefBut(block, LABEL, 1, "y =", 0, 0, 2.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 1, "y =", 0, 0, 2.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); /* opening bracket */ - uiDefBut(block, LABEL, 1, "(", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 1, "(", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); /* coefficients */ - uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, cp, -UI_FLT_MAX, UI_FLT_MAX, + uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, "", 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, cp, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, TIP_("Coefficient of x")); - uiDefBut(block, LABEL, 1, "x +", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 1, "x +", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); - uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, cp + 1, -UI_FLT_MAX, UI_FLT_MAX, + uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, "", 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, cp + 1, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, TIP_("Second coefficient")); /* closing bracket and multiplication sign */ if ( (i != (data->poly_order - 1)) || ((i == 0) && data->poly_order == 2) ) { - uiDefBut(block, LABEL, 1, ") \xc3\x97", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 1, ") \xc3\x97", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); /* set up new row for the next pair of coefficients */ row = uiLayoutRow(layout, true); block = uiLayoutGetBlock(row); } else - uiDefBut(block, LABEL, 1, ") ", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 1, ") ", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); } break; } @@ -439,11 +439,11 @@ static void draw_modifier__envelope(uiLayout *layout, ID *id, FModifier *fcm, sh row = uiLayoutRow(layout, false); block = uiLayoutGetBlock(row); - uiDefBut(block, LABEL, 1, IFACE_("Control Points:"), 0, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 1, IFACE_("Control Points:"), 0, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); - but = uiDefBut(block, BUT, B_FMODIFIER_REDRAW, IFACE_("Add Point"), 0, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y, + but = uiDefBut(block, UI_BTYPE_BUT, B_FMODIFIER_REDRAW, IFACE_("Add Point"), 0, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Add a new control-point to the envelope on the current frame")); - uiButSetFunc(but, fmod_envelope_addpoint_cb, env, NULL); + UI_but_func_set(but, fmod_envelope_addpoint_cb, env, NULL); /* control points list */ for (i = 0, fed = env->data; i < env->totvert; i++, fed++) { @@ -451,20 +451,20 @@ static void draw_modifier__envelope(uiLayout *layout, ID *id, FModifier *fcm, sh row = uiLayoutRow(layout, true); block = uiLayoutGetBlock(row); - uiBlockBeginAlign(block); - but = uiDefButF(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Fra:"), 0, 0, 4.5 * UI_UNIT_X, UI_UNIT_Y, + UI_block_align_begin(block); + but = uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Fra:"), 0, 0, 4.5 * UI_UNIT_X, UI_UNIT_Y, &fed->time, -MAXFRAMEF, MAXFRAMEF, 10, 1, TIP_("Frame that envelope point occurs")); - uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL); + UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL); - uiDefButF(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Min:"), 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, + uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Min:"), 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, &fed->min, -UI_FLT_MAX, UI_FLT_MAX, 10, 2, TIP_("Minimum bound of envelope at this point")); - uiDefButF(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Max:"), 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, + uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Max:"), 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, &fed->max, -UI_FLT_MAX, UI_FLT_MAX, 10, 2, TIP_("Maximum bound of envelope at this point")); - but = uiDefIconBut(block, BUT, B_FMODIFIER_REDRAW, ICON_X, 0, 0, 0.9 * UI_UNIT_X, UI_UNIT_Y, + but = uiDefIconBut(block, UI_BTYPE_BUT, B_FMODIFIER_REDRAW, ICON_X, 0, 0, 0.9 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Delete envelope control point")); - uiButSetFunc(but, fmod_envelope_deletepoint_cb, env, SET_INT_IN_POINTER(i)); - uiBlockBeginAlign(block); + UI_but_func_set(but, fmod_envelope_deletepoint_cb, env, SET_INT_IN_POINTER(i)); + UI_block_align_begin(block); } } @@ -575,7 +575,7 @@ void ANIM_uiTemplate_fmodifier_draw(uiLayout *layout, ID *id, ListBase *modifier sub = uiLayoutRow(row, true); uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT); - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); /* expand */ uiItemR(sub, &ptr, "show_expanded", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); @@ -597,14 +597,14 @@ void ANIM_uiTemplate_fmodifier_draw(uiLayout *layout, ID *id, ListBase *modifier /* 'mute' button */ uiItemR(sub, &ptr, "mute", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); /* delete button */ - but = uiDefIconBut(block, BUT, B_REDR, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefIconBut(block, UI_BTYPE_BUT, B_REDR, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Delete F-Curve Modifier")); - uiButSetFunc(but, delete_fmodifier_cb, modifiers, fcm); + UI_but_func_set(but, delete_fmodifier_cb, modifiers, fcm); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); } /* when modifier is expanded, draw settings */ diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index c5e54cc1c7c..d2dbe961b42 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -39,7 +39,6 @@ #include "MEM_guardedalloc.h" -#include "BLI_blenlib.h" #include "BLI_dlrbTree.h" #include "BLI_utildefines.h" @@ -155,6 +154,7 @@ static DLRBT_Node *nalloc_ak_gpframe(void *data) /* store settings based on state of BezTriple */ ak->cfra = gpf->framenum; ak->sel = (gpf->flag & GP_FRAME_SELECT) ? SELECT : 0; + ak->key_type = gpf->key_type; /* set 'modified', since this is used to identify long keyframes */ ak->modified = 1; @@ -171,6 +171,10 @@ static void nupdate_ak_gpframe(void *node, void *data) /* set selection status and 'touched' status */ if (gpf->flag & GP_FRAME_SELECT) ak->sel = SELECT; ak->modified += 1; + + /* for keyframe type, 'proper' keyframes have priority over breakdowns (and other types for now) */ + if (gpf->key_type == BEZT_KEYTYPE_KEYFRAME) + ak->key_type = BEZT_KEYTYPE_KEYFRAME; } /* ......... */ @@ -732,6 +736,21 @@ void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos) BLI_dlrbTree_free(&blocks); } +void draw_gpencil_channel(View2D *v2d, bDopeSheet *ads, bGPdata *gpd, float ypos) +{ + DLRBT_Tree keys; + + BLI_dlrbTree_init(&keys); + + gpencil_to_keylist(ads, gpd, &keys); + + BLI_dlrbTree_linkedlist_sync(&keys); + + draw_keylist(v2d, &keys, NULL, ypos, 0); + + BLI_dlrbTree_free(&keys); +} + void draw_gpl_channel(View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos) { DLRBT_Tree keys; @@ -924,6 +943,20 @@ void action_to_keylist(AnimData *adt, bAction *act, DLRBT_Tree *keys, DLRBT_Tree } +void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, DLRBT_Tree *keys) +{ + bGPDlayer *gpl; + + if (gpd && keys) { + /* for now, just aggregate out all the frames, but only for visible layers */ + for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { + if ((gpl->flag & GP_LAYER_HIDE) == 0) { + gpl_to_keylist(ads, gpl, keys); + } + } + } +} + void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, DLRBT_Tree *keys) { bGPDframe *gpf; diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c index 7f612de14b7..439b3b94974 100644 --- a/source/blender/editors/animation/keyframes_edit.c +++ b/source/blender/editors/animation/keyframes_edit.c @@ -41,9 +41,7 @@ #include "DNA_anim_types.h" #include "DNA_object_types.h" -#include "DNA_node_types.h" #include "DNA_scene_types.h" -#include "DNA_space_types.h" #include "BKE_fcurve.h" @@ -548,6 +546,44 @@ static short ok_bezier_region_lasso(KeyframeEditData *ked, BezTriple *bezt) return 0; } +/** + * only called from #ok_bezier_region_circle + */ +static bool bezier_region_circle_test( + const struct KeyframeEdit_CircleData *data_circle, + const float xy[2]) +{ + if (BLI_rctf_isect_pt_v(data_circle->rectf_scaled, xy)) { + float xy_view[2]; + + BLI_rctf_transform_pt_v(data_circle->rectf_view, data_circle->rectf_scaled, xy_view, xy); + + xy_view[0] = xy_view[0] - data_circle->mval[0]; + xy_view[1] = xy_view[1] - data_circle->mval[1]; + return len_squared_v2(xy_view) < data_circle->radius_squared; + } + + return false; +} + + +static short ok_bezier_region_circle(KeyframeEditData *ked, BezTriple *bezt) +{ + /* rect is stored in data property (it's of type rectf, but may not be set) */ + if (ked->data) { + short ok = 0; + +#define KEY_CHECK_OK(_index) bezier_region_circle_test(ked->data, bezt->vec[_index]) + KEYFRAME_OK_CHECKS(KEY_CHECK_OK); +#undef KEY_CHECK_OK + + /* return ok flags */ + return ok; + } + else + return 0; +} + KeyframeEditFunc ANIM_editkeyframes_ok(short mode) { @@ -567,6 +603,8 @@ KeyframeEditFunc ANIM_editkeyframes_ok(short mode) return ok_bezier_region; case BEZT_OK_REGION_LASSO: /* only if the point falls within KeyframeEdit_LassoData defined data */ return ok_bezier_region_lasso; + case BEZT_OK_REGION_CIRCLE: /* only if the point falls within KeyframeEdit_LassoData defined data */ + return ok_bezier_region_circle; default: /* nothing was ok */ return NULL; } diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index 56165c36efa..d00a64abb9b 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -49,7 +49,6 @@ #include "BKE_global.h" #include "RNA_access.h" -#include "RNA_enum_types.h" #include "ED_anim_api.h" #include "ED_keyframing.h" @@ -724,7 +723,7 @@ static void paste_animedit_keys_fcurve(FCurve *fcu, tAnimCopybufItem *aci, float } } - /* just start pasting, with the the first keyframe on the current frame, and so on */ + /* just start pasting, with the first keyframe on the current frame, and so on */ for (i = 0, bezt = aci->bezt; i < aci->totvert; i++, bezt++) { /* temporarily apply offset to src beztriple while copying */ bezt->vec[0][0] += offset; diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 4c2d90179a7..7e2ce4cd3f1 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -658,7 +658,7 @@ static bool visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop) /* validate data */ if (ELEM(NULL, ptr, ptr->data, prop)) - return 0; + return false; /* get first constraint and determine type of keyframe constraints to check for * - constraints can be on either Objects or PoseChannels, so we only check if the @@ -880,7 +880,7 @@ bool insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *pr /* no F-Curve to add keyframe to? */ if (fcu == NULL) { BKE_report(reports, RPT_ERROR, "No F-Curve to add keyframes to"); - return 0; + return false; } /* F-Curve not editable? */ if (fcurve_is_keyframable(fcu) == 0) { @@ -888,13 +888,13 @@ bool insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *pr "F-Curve with path '%s[%d]' cannot be keyframed, ensure that it is not locked or sampled, " "and try removing F-Modifiers", fcu->rna_path, fcu->array_index); - return 0; + return false; } /* if no property given yet, try to validate from F-Curve info */ if ((ptr.id.data == NULL) && (ptr.data == NULL)) { BKE_report(reports, RPT_ERROR, "No RNA pointer available to retrieve values for keyframing from"); - return 0; + return false; } if (prop == NULL) { PointerRNA tmp_ptr; @@ -907,7 +907,7 @@ bool insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *pr BKE_reportf(reports, RPT_ERROR, "Could not insert keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)", idname, fcu->rna_path); - return 0; + return false; } else { /* property found, so overwrite 'ptr' to make later code easier */ @@ -956,18 +956,18 @@ bool insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *pr /* only return success if keyframe added */ if (insert_mode) - return 1; + return true; } else { /* just insert keyframe */ insert_vert_fcurve(fcu, cfra, curval, flag); /* return success */ - return 1; + return true; } /* failed */ - return 0; + return false; } /* Main Keyframing API call: @@ -1284,10 +1284,10 @@ static int modify_key_op_poll(bContext *C) /* if no area or active scene */ if (ELEM(NULL, sa, scene)) - return 0; + return false; /* should be fine */ - return 1; + return true; } /* Insert Key Operator ------------------------ */ @@ -1402,12 +1402,12 @@ static int insert_key_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UN uiLayout *layout; /* call the menu, which will call this operator again, hence the canceled */ - pup = uiPupMenuBegin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE); + layout = UI_popup_menu_layout(pup); uiItemsEnumO(layout, "ANIM_OT_keyframe_insert_menu", "type"); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } else { /* just call the exec() on the active keyingset */ @@ -1704,7 +1704,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op) flag = ANIM_get_keyframing_flags(scene, 1); /* try to insert keyframe using property retrieved from UI */ - uiContextActiveProperty(C, &ptr, &prop, &index); + UI_context_active_but_prop_get(C, &ptr, &prop, &index); if ((ptr.id.data && ptr.data && prop) && RNA_property_animateable(&ptr, prop)) { path = RNA_path_from_ID_to_property(&ptr, prop); @@ -1751,7 +1751,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op) if (success) { /* send updates */ - uiContextAnimUpdate(C); + UI_context_update_anim_flag(C); /* send notifiers that keyframes have been changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL); @@ -1792,7 +1792,7 @@ static int delete_key_button_exec(bContext *C, wmOperator *op) const bool all = RNA_boolean_get(op->ptr, "all"); /* try to insert keyframe using property retrieved from UI */ - uiContextActiveProperty(C, &ptr, &prop, &index); + UI_context_active_but_prop_get(C, &ptr, &prop, &index); if (ptr.id.data && ptr.data && prop) { path = RNA_path_from_ID_to_property(&ptr, prop); @@ -1822,7 +1822,7 @@ static int delete_key_button_exec(bContext *C, wmOperator *op) if (success) { /* send updates */ - uiContextAnimUpdate(C); + UI_context_update_anim_flag(C); /* send notifiers that keyframes have been changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL); @@ -1862,7 +1862,7 @@ static int clear_key_button_exec(bContext *C, wmOperator *op) const bool all = RNA_boolean_get(op->ptr, "all"); /* try to insert keyframe using property retrieved from UI */ - uiContextActiveProperty(C, &ptr, &prop, &index); + UI_context_active_but_prop_get(C, &ptr, &prop, &index); if (ptr.id.data && ptr.data && prop) { path = RNA_path_from_ID_to_property(&ptr, prop); @@ -1892,7 +1892,7 @@ static int clear_key_button_exec(bContext *C, wmOperator *op) if (success) { /* send updates */ - uiContextAnimUpdate(C); + UI_context_update_anim_flag(C); /* send notifiers that keyframes have been changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL); @@ -1922,17 +1922,17 @@ void ANIM_OT_keyframe_clear_button(wmOperatorType *ot) /* ******************************************* */ /* AUTO KEYFRAME */ -int autokeyframe_cfra_can_key(Scene *scene, ID *id) +bool autokeyframe_cfra_can_key(Scene *scene, ID *id) { float cfra = (float)CFRA; // XXX for now, this will do /* only filter if auto-key mode requires this */ if (IS_AUTOKEY_ON(scene) == 0) - return 0; + return false; if (IS_AUTOKEY_MODE(scene, NORMAL)) { /* can insert anytime we like... */ - return 1; + return true; } else { /* REPLACE */ /* for whole block - only key if there's a keyframe on that frame already @@ -1952,7 +1952,7 @@ bool fcurve_frame_has_keyframe(FCurve *fcu, float frame, short filter) { /* quick sanity check */ if (ELEM(NULL, fcu, fcu->bezt)) - return 0; + return false; /* we either include all regardless of muting, or only non-muted */ if ((filter & ANIMFILTER_KEYS_MUTED) || (fcu->flag & FCURVE_MUTED) == 0) { @@ -1965,11 +1965,11 @@ bool fcurve_frame_has_keyframe(FCurve *fcu, float frame, short filter) if (replace) { /* sanity check: 'i' may in rare cases exceed arraylen */ if ((i >= 0) && (i < fcu->totvert)) - return 1; + return true; } } - return 0; + return false; } /* Checks whether an Action has a keyframe for a given frame @@ -1981,11 +1981,11 @@ static bool action_frame_has_keyframe(bAction *act, float frame, short filter) /* can only find if there is data */ if (act == NULL) - return 0; + return false; /* if only check non-muted, check if muted */ if ((filter & ANIMFILTER_KEYS_MUTED) || (act->flag & ACT_MUTED)) - return 0; + return false; /* loop over F-Curves, using binary-search to try to find matches * - this assumes that keyframes are only beztriples @@ -1994,12 +1994,12 @@ static bool action_frame_has_keyframe(bAction *act, float frame, short filter) /* only check if there are keyframes (currently only of type BezTriple) */ if (fcu->bezt && fcu->totvert) { if (fcurve_frame_has_keyframe(fcu, frame, filter)) - return 1; + return true; } } /* nothing found */ - return 0; + return false; } /* Checks whether an Object has a keyframe for a given frame */ @@ -2007,12 +2007,18 @@ static bool object_frame_has_keyframe(Object *ob, float frame, short filter) { /* error checking */ if (ob == NULL) - return 0; + return false; /* check own animation data - specifically, the action it contains */ if ((ob->adt) && (ob->adt->action)) { - if (action_frame_has_keyframe(ob->adt->action, frame, filter)) - return 1; + /* T41525 - When the active action is a NLA strip being edited, + * we need to correct the frame number to "look inside" the + * remapped action + */ + float ob_frame = BKE_nla_tweakedit_remap(ob->adt, frame, NLATIME_CONVERT_UNMAP); + + if (action_frame_has_keyframe(ob->adt->action, ob_frame, filter)) + return true; } /* try shapekey keyframes (if available, and allowed by filter) */ @@ -2025,7 +2031,7 @@ static bool object_frame_has_keyframe(Object *ob, float frame, short filter) /* 1. test for relative (with keyframes) */ if (id_frame_has_keyframe((ID *)key, frame, filter)) - return 1; + return true; /* 2. test for time */ /* TODO... yet to be implemented (this feature may evolve before then anyway) */ @@ -2039,7 +2045,7 @@ static bool object_frame_has_keyframe(Object *ob, float frame, short filter) /* we only retrieve the active material... */ if (id_frame_has_keyframe((ID *)ma, frame, filter)) - return 1; + return true; } else { int a; @@ -2049,13 +2055,13 @@ static bool object_frame_has_keyframe(Object *ob, float frame, short filter) Material *ma = give_current_material(ob, a + 1); if (id_frame_has_keyframe((ID *)ma, frame, filter)) - return 1; + return true; } } } /* nothing found */ - return 0; + return false; } /* --------------- API ------------------- */ @@ -2065,7 +2071,7 @@ bool id_frame_has_keyframe(ID *id, float frame, short filter) { /* sanity checks */ if (id == NULL) - return 0; + return false; /* perform special checks for 'macro' types */ switch (GS(id->name)) { @@ -2089,7 +2095,7 @@ bool id_frame_has_keyframe(ID *id, float frame, short filter) /* no keyframe found */ - return 0; + return false; } /* ************************************************** */ diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index ad2db0d9c66..a5c0eee8d3b 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -127,7 +127,7 @@ static int add_default_keyingset_exec(bContext *C, wmOperator *UNUSED(op)) /* call the API func, and set the active keyingset index */ BKE_keyingset_add(&scene->keyingsets, NULL, NULL, flag, keyingflag); - scene->active_keyingset = BLI_countlist(&scene->keyingsets); + scene->active_keyingset = BLI_listbase_count(&scene->keyingsets); /* send notifiers */ WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL); @@ -216,7 +216,7 @@ static int add_empty_ks_path_exec(bContext *C, wmOperator *op) /* don't use the API method for this, since that checks on values... */ ksp = MEM_callocN(sizeof(KS_Path), "KeyingSetPath Empty"); BLI_addtail(&ks->paths, ksp); - ks->active_path = BLI_countlist(&ks->paths); + ks->active_path = BLI_listbase_count(&ks->paths); ksp->groupmode = KSP_GROUP_KSNAME; // XXX? ksp->idtype = ID_OB; @@ -316,7 +316,7 @@ static int add_keyingset_button_exec(bContext *C, wmOperator *op) /* call the API func, and set the active keyingset index */ ks = BKE_keyingset_add(&scene->keyingsets, "ButtonKeyingSet", "Button Keying Set", flag, keyingflag); - scene->active_keyingset = BLI_countlist(&scene->keyingsets); + scene->active_keyingset = BLI_listbase_count(&scene->keyingsets); } else if (scene->active_keyingset < 0) { BKE_report(op->reports, RPT_ERROR, "Cannot add property to built in keying set"); @@ -327,7 +327,7 @@ static int add_keyingset_button_exec(bContext *C, wmOperator *op) } /* try to add to keyingset using property retrieved from UI */ - uiContextActiveProperty(C, &ptr, &prop, &index); + UI_context_active_but_prop_get(C, &ptr, &prop, &index); /* check if property is able to be added */ if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) { @@ -347,7 +347,7 @@ static int add_keyingset_button_exec(bContext *C, wmOperator *op) /* add path to this setting */ BKE_keyingset_add_path(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME); - ks->active_path = BLI_countlist(&ks->paths); + ks->active_path = BLI_listbase_count(&ks->paths); success = 1; /* free the temp path created */ @@ -413,7 +413,7 @@ static int remove_keyingset_button_exec(bContext *C, wmOperator *op) } /* try to add to keyingset using property retrieved from UI */ - uiContextActiveProperty(C, &ptr, &prop, &index); + UI_context_active_but_prop_get(C, &ptr, &prop, &index); if (ptr.id.data && ptr.data && prop) { path = RNA_path_from_ID_to_property(&ptr, prop); @@ -472,12 +472,12 @@ static int keyingset_active_menu_invoke(bContext *C, wmOperator *op, const wmEve uiLayout *layout; /* call the menu, which will call this operator again, hence the canceled */ - pup = uiPupMenuBegin(C, op->type->name, ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE); + layout = UI_popup_menu_layout(pup); uiItemsEnumO(layout, "ANIM_OT_keying_set_active_set", "type"); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } static int keyingset_active_menu_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c index b7ab7fe064d..7f7843a6d1d 100644 --- a/source/blender/editors/armature/armature_edit.c +++ b/source/blender/editors/armature/armature_edit.c @@ -296,7 +296,9 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op) float cursor_rel[3]; sub_v3_v3v3(cursor_rel, cursor_local, ebone->head); if (axis_flip) negate_v3(cursor_rel); - ebone->roll = ED_rollBoneToVector(ebone, cursor_rel, axis_only); + if (normalize_v3(cursor_rel) != 0.0f) { + ebone->roll = ED_rollBoneToVector(ebone, cursor_rel, axis_only); + } } } } @@ -567,7 +569,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op) * 2) between the two joints (order is dependent on active-bone/hierarchy) * 3+) error (a smarter method involving finding chains needs to be worked out */ - count = BLI_countlist(&points); + count = BLI_listbase_count(&points); if (count == 0) { BKE_report(op->reports, RPT_ERROR, "No joints selected"); diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c index b7e38546ca2..574258de4f6 100644 --- a/source/blender/editors/armature/armature_ops.c +++ b/source/blender/editors/armature/armature_ops.c @@ -28,8 +28,6 @@ * \ingroup edarmature */ -#include "BLI_math.h" - #include "RNA_access.h" #include "WM_api.h" diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c index 75fa4a5433f..3e226c39c8c 100644 --- a/source/blender/editors/armature/armature_relations.c +++ b/source/blender/editors/armature/armature_relations.c @@ -673,8 +673,8 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op) static int armature_parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event)) { EditBone *actbone = CTX_data_active_bone(C); - uiPopupMenu *pup = uiPupMenuBegin(C, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Make Parent"), ICON_NONE); - uiLayout *layout = uiPupMenuLayout(pup); + uiPopupMenu *pup = UI_popup_menu_begin(C, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Make Parent"), ICON_NONE); + uiLayout *layout = UI_popup_menu_layout(pup); int allchildbones = 0; CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) @@ -691,9 +691,9 @@ static int armature_parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const if (allchildbones) uiItemEnumO(layout, "ARMATURE_OT_parent_set", NULL, 0, "type", ARM_PAR_OFFSET); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } void ARMATURE_OT_parent_set(wmOperatorType *ot) diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c index 5ff15b84284..3126cca7457 100644 --- a/source/blender/editors/armature/armature_skinning.c +++ b/source/blender/editors/armature/armature_skinning.c @@ -43,6 +43,7 @@ #include "BKE_action.h" #include "BKE_armature.h" #include "BKE_deform.h" +#include "BKE_object_deform.h" #include "BKE_report.h" #include "BKE_subsurf.h" #include "BKE_modifier.h" @@ -52,7 +53,10 @@ #include "armature_intern.h" -#include "meshlaplacian.h" + +#ifdef WITH_OPENNL +# include "meshlaplacian.h" +#endif #if 0 #include "reeb.h" @@ -117,7 +121,7 @@ static int vgroup_add_unique_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr)) */ if (!(bone->flag & BONE_NO_DEFORM)) { if (!defgroup_find_name(ob, bone->name)) { - ED_vgroup_add_name(ob, bone->name); + BKE_object_defgroup_add_name(ob, bone->name); return 1; } } @@ -164,7 +168,7 @@ static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap) if (!wpmode || ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED))) if (!(defgroup = defgroup_find_name(ob, bone->name))) - defgroup = ED_vgroup_add_name(ob, bone->name); + defgroup = BKE_object_defgroup_add_name(ob, bone->name); if (data->list != NULL) { hgroup = (bDeformGroup ***) &data->list; @@ -276,7 +280,7 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob, if (numbones == 0) return; - if (ED_vgroup_data_create(ob->data) == false) + if (BKE_object_defgroup_data_create(ob->data) == NULL) return; /* create an array of pointer to bones that are skinnable @@ -428,7 +432,7 @@ void create_vgroups_from_armature(ReportList *reports, Scene *scene, Object *ob, bArmature *arm = par->data; if (mode == ARM_GROUPS_NAME) { - const int defbase_tot = BLI_countlist(&ob->defbase); + const int defbase_tot = BLI_listbase_count(&ob->defbase); int defbase_add; /* Traverse the bone list, trying to create empty vertex * groups corresponding to the bone. diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c index 647b640ee61..aace8c5434c 100644 --- a/source/blender/editors/armature/editarmature_retarget.c +++ b/source/blender/editors/armature/editarmature_retarget.c @@ -1205,7 +1205,7 @@ static void RIG_arcFromBoneChain(RigGraph *rg, ListBase *list, EditBone *root_bo static void RIG_findHead(RigGraph *rg) { if (rg->head == NULL) { - if (BLI_countlist(&rg->arcs) == 1) { + if (BLI_listbase_is_single(&rg->arcs)) { RigArc *arc = rg->arcs.first; rg->head = (RigNode *)arc->head; @@ -1958,7 +1958,7 @@ static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc, #endif float *vec0, *vec1; int *best_positions; - int nb_edges = BLI_countlist(&iarc->edges); + int nb_edges = BLI_listbase_count(&iarc->edges); int nb_joints = nb_edges - 1; RetargetMethod method = METHOD_MEMOIZE; int i; @@ -2152,7 +2152,7 @@ void exec_retargetArctoArc(TaskPool *UNUSED(pool), void *taskdata, int UNUSED(th RigNode *inode_start = p->inode_start; ReebArc *earc = iarc->link_mesh; - if (BLI_countlist(&iarc->edges) == 1) { + if (BLI_listbase_is_single(&iarc->edges)) { RigEdge *edge = iarc->edges.first; if (testFlipArc(iarc, inode_start)) { @@ -2454,7 +2454,7 @@ const char *RIG_nameBone(RigGraph *rg, int arc_index, int bone_index) return "None"; } - if (bone_index == BLI_countlist(&arc->edges)) { + if (bone_index == BLI_listbase_count(&arc->edges)) { return "Last joint"; } @@ -2476,10 +2476,10 @@ int RIG_nbJoints(RigGraph *rg) RigArc *arc; int total = 0; - total += BLI_countlist(&rg->nodes); + total += BLI_listbase_count(&rg->nodes); for (arc = rg->arcs.first; arc; arc = arc->next) { - total += BLI_countlist(&arc->edges) - 1; /* -1 because end nodes are already counted */ + total += BLI_listbase_count(&arc->edges) - 1; /* -1 because end nodes are already counted */ } return total; diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index d75a23a6322..3dbf7b4b65a 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -31,8 +31,6 @@ #include "BLI_blenlib.h" #include "BLI_math.h" -#include "BLF_translation.h" - #include "BKE_context.h" #include "BKE_sketch.h" @@ -403,9 +401,7 @@ static void sk_retargetStroke(bContext *C, SK_Stroke *stk) RigGraph *rg; invert_m4_m4(imat, obedit->obmat); - - copy_m3_m4(tmat, obedit->obmat); - transpose_m3(tmat); + transpose_m3_m4(tmat, obedit->obmat); arc = sk_strokeToArc(stk, imat, tmat); @@ -1358,9 +1354,7 @@ static void sk_convertStroke(bContext *C, SK_Stroke *stk) head = NULL; invert_m4_m4(invmat, obedit->obmat); - - copy_m3_m4(tmat, obedit->obmat); - transpose_m3(tmat); + transpose_m3_m4(tmat, obedit->obmat); for (i = 0; i < stk->nb_points; i++) { SK_Point *pt = stk->points + i; @@ -1579,7 +1573,7 @@ static int sk_getIntersections(bContext *C, ListBase *list, SK_Sketch *sketch, S added = MAX2(s_added, added); } - BLI_sortlist(list, cmpIntersections); + BLI_listbase_sort(list, cmpIntersections); return added; } @@ -1698,7 +1692,7 @@ int sk_detectCommandGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UN if (gest->nb_segments > 2 && gest->nb_intersections == 2 && gest->nb_self_intersections == 1) { SK_Intersection *isect, *self_isect; - /* get the the last intersection of the first pair */ + /* get the last intersection of the first pair */ for (isect = gest->intersections.first; isect; isect = isect->next) { if (isect->stroke == isect->next->stroke) { isect = isect->next; diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 49650fcadbf..b7d14e089cf 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -1303,7 +1303,7 @@ static int meshdeform_inside_cage(MeshDeformBind *mdb, float *co) /* solving */ -static int meshdeform_index(MeshDeformBind *mdb, int x, int y, int z, int n) +BLI_INLINE int meshdeform_index(MeshDeformBind *mdb, int x, int y, int z, int n) { int size = mdb->size; @@ -1321,7 +1321,7 @@ static int meshdeform_index(MeshDeformBind *mdb, int x, int y, int z, int n) return x + y * size + z * size * size; } -static void meshdeform_cell_center(MeshDeformBind *mdb, int x, int y, int z, int n, float *center) +BLI_INLINE void meshdeform_cell_center(MeshDeformBind *mdb, int x, int y, int z, int n, float *center) { x += MESHDEFORM_OFFSET[n][0]; y += MESHDEFORM_OFFSET[n][1]; diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c index da68108285f..d8a32f085bc 100644 --- a/source/blender/editors/armature/pose_edit.c +++ b/source/blender/editors/armature/pose_edit.c @@ -381,14 +381,14 @@ static void pose_copy_menu(Scene *scene) * but for constraints (just add local constraints) */ if (pose_has_protected_selected(ob, 0)) { - i = BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */ + i = BLI_listbase_count(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */ if (i < 25) nr = pupmenu("Copy Pose Attributes %t|Local Location %x1|Local Rotation %x2|Local Size %x3|%l|Visual Location %x9|Visual Rotation %x10|Visual Size %x11|%l|Constraints (All) %x4|Constraints... %x5"); else nr = pupmenu("Copy Pose Attributes %t|Local Location %x1|Local Rotation %x2|Local Size %x3|%l|Visual Location %x9|Visual Rotation %x10|Visual Size %x11|%l|Constraints (All) %x4"); } else { - i = BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */ + i = BLI_listbase_count(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */ if (i < 25) nr = pupmenu("Copy Pose Attributes %t|Local Location %x1|Local Rotation %x2|Local Size %x3|%l|Visual Location %x9|Visual Rotation %x10|Visual Size %x11|%l|Constraints (All) %x4|Constraints... %x5|%l|Transform Locks %x6|IK Limits %x7|Bone Shape %x8"); else @@ -503,7 +503,7 @@ static void pose_copy_menu(Scene *scene) /* build the puplist of constraints */ for (con = pchanact->constraints.first, i = 0; con; con = con->next, i++) { const_toggle[i] = 1; -// add_numbut(i, TOG|INT, con->name, 0, 0, &(const_toggle[i]), ""); +// add_numbut(i, UI_BTYPE_TOGGLE|INT, con->name, 0, 0, &(const_toggle[i]), ""); } // if (!do_clever_numbuts("Select Constraints", i, REDRAW)) { @@ -595,7 +595,7 @@ void POSE_OT_flip_names(wmOperatorType *ot) /* identifiers */ ot->name = "Flip Names"; ot->idname = "POSE_OT_flip_names"; - ot->description = "Flips (and corrects) the axis suffixes of the the names of selected bones"; + ot->description = "Flips (and corrects) the axis suffixes of the names of selected bones"; /* api callbacks */ ot->exec = pose_flip_names_exec; diff --git a/source/blender/editors/armature/pose_group.c b/source/blender/editors/armature/pose_group.c index 50d9d300d15..9c27fe5218a 100644 --- a/source/blender/editors/armature/pose_group.c +++ b/source/blender/editors/armature/pose_group.c @@ -144,8 +144,8 @@ static int pose_groups_menu_invoke(bContext *C, wmOperator *op, const wmEvent *U /* if there's no active group (or active is invalid), create a new menu to find it */ if (pose->active_group <= 0) { /* create a new menu, and start populating it with group names */ - pup = uiPupMenuBegin(C, op->type->name, ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE); + layout = UI_popup_menu_layout(pup); /* special entry - allow to create new group, then use that * (not to be used for removing though) @@ -160,9 +160,9 @@ static int pose_groups_menu_invoke(bContext *C, wmOperator *op, const wmEvent *U uiItemIntO(layout, grp->name, ICON_NONE, op->idname, "type", i); /* finish building the menu, and process it (should result in calling self again) */ - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } else { /* just use the active group index, and call the exec callback for the calling operator */ @@ -387,7 +387,7 @@ static int group_sort_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_CANCELLED; /* create temporary array with bone groups and indices */ - agrp_count = BLI_countlist(&pose->agroups); + agrp_count = BLI_listbase_count(&pose->agroups); agrp_array = MEM_mallocN(sizeof(tSortActionGroup) * agrp_count, "sort bone groups"); for (agrp = pose->agroups.first, i = 0; agrp; agrp = agrp->next, i++) { BLI_assert(i < agrp_count); diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c index 0609fcc29e8..2e6eace88aa 100644 --- a/source/blender/editors/armature/pose_lib.c +++ b/source/blender/editors/armature/pose_lib.c @@ -404,8 +404,8 @@ static int poselib_add_menu_invoke(bContext *C, wmOperator *op, const wmEvent *U return OPERATOR_CANCELLED; /* start building */ - pup = uiPupMenuBegin(C, op->type->name, ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE); + layout = UI_popup_menu_layout(pup); uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); /* add new (adds to the first unoccupied frame) */ @@ -420,10 +420,10 @@ static int poselib_add_menu_invoke(bContext *C, wmOperator *op, const wmEvent *U uiItemMenuF(layout, IFACE_("Replace Existing..."), 0, poselib_add_menu_invoke__replacemenu, NULL); } - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); /* this operator is only for a menu, not used further */ - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } @@ -472,7 +472,7 @@ static int poselib_add_exec(bContext *C, wmOperator *op) ANIM_apply_keyingset(C, NULL, act, ks, MODIFYKEY_MODE_INSERT, (float)frame); /* store new 'active' pose number */ - act->active_marker = BLI_countlist(&act->markers); + act->active_marker = BLI_listbase_count(&act->markers); /* done */ return OPERATOR_FINISHED; @@ -916,7 +916,7 @@ static void poselib_keytag_pose(bContext *C, Scene *scene, tPoseLib_PreviewData KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_WHOLE_CHARACTER_ID); ListBase dsources = {NULL, NULL}; - short autokey = autokeyframe_cfra_can_key(scene, &pld->ob->id); + bool autokey = autokeyframe_cfra_can_key(scene, &pld->ob->id); /* start tagging/keying */ for (agrp = act->groups.first; agrp; agrp = agrp->next) { @@ -1348,7 +1348,7 @@ static int poselib_preview_handle_event(bContext *UNUSED(C), wmOperator *op, con else { /* change to last pose */ pld->marker = pld->act->markers.last; - pld->act->active_marker = BLI_countlist(&pld->act->markers); + pld->act->active_marker = BLI_listbase_count(&pld->act->markers); pld->redraw = PL_PREVIEW_REDRAWALL; } diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c index ba5ef4f3b5d..5d5a9bf363c 100644 --- a/source/blender/editors/armature/pose_select.c +++ b/source/blender/editors/armature/pose_select.c @@ -642,7 +642,7 @@ static bool pose_select_same_group(bContext *C, Object *ob, bool extend) return 0; /* count the number of groups */ - numGroups = BLI_countlist(&pose->agroups); + numGroups = BLI_listbase_count(&pose->agroups); if (numGroups == 0) return 0; diff --git a/source/blender/editors/armature/pose_utils.c b/source/blender/editors/armature/pose_utils.c index 380a3fffc6d..1297755b7d0 100644 --- a/source/blender/editors/armature/pose_utils.c +++ b/source/blender/editors/armature/pose_utils.c @@ -49,8 +49,6 @@ #include "WM_api.h" #include "WM_types.h" - - #include "ED_armature.h" #include "ED_keyframing.h" diff --git a/source/blender/editors/armature/reeb.c b/source/blender/editors/armature/reeb.c index 8cc6059e87b..f29d15ff416 100644 --- a/source/blender/editors/armature/reeb.c +++ b/source/blender/editors/armature/reeb.c @@ -107,7 +107,7 @@ static VertexData *allocVertexData(EditMesh *em) EditVert *eve; int totvert, index; - totvert = BLI_countlist(&em->verts); + totvert = BLI_listbase_count(&em->verts); data = MEM_callocN(sizeof(VertexData) * totvert, "VertexData"); @@ -1141,7 +1141,7 @@ static int compareNodesWeight(void *vnode1, void *vnode2) void sortNodes(ReebGraph *rg) { - BLI_sortlist(&rg->nodes, compareNodesWeight); + BLI_listbase_sort(&rg->nodes, compareNodesWeight); } static int compareArcsWeight(void *varc1, void *varc2) @@ -1166,7 +1166,7 @@ static int compareArcsWeight(void *varc1, void *varc2) void sortArcs(ReebGraph *rg) { - BLI_sortlist(&rg->arcs, compareArcsWeight); + BLI_listbase_sort(&rg->arcs, compareArcsWeight); } /******************************************* JOINING ***************************************************/ @@ -1512,7 +1512,7 @@ static int filterInternalExternalReebGraph(ReebGraph *rg, float threshold_intern ReebArc *arc = NULL, *nextArc = NULL; int value = 0; - BLI_sortlist(&rg->arcs, compareArcs); + BLI_listbase_sort(&rg->arcs, compareArcs); for (arc = rg->arcs.first; arc; arc = nextArc) { nextArc = arc->next; @@ -1632,7 +1632,7 @@ int filterSmartReebGraph(ReebGraph *UNUSED(rg), float UNUSED(threshold)) #if 0 //XXX ReebArc *arc = NULL, *nextArc = NULL; - BLI_sortlist(&rg->arcs, compareArcs); + BLI_listbase_sort(&rg->arcs, compareArcs); #ifdef DEBUG_REEB { @@ -1867,7 +1867,7 @@ static void spreadWeight(EditMesh *em) { EditVert **verts, *eve; float lastWeight = 0.0f; - int totvert = BLI_countlist(&em->verts); + int totvert = BLI_listbase_count(&em->verts); int i; int work_needed = 1; @@ -2399,9 +2399,9 @@ ReebGraph *generateReebGraph(EditMesh *em, int subdivisions) rg->resolution = subdivisions; - /*totvert = BLI_countlist(&em->verts);*/ /*UNUSED*/ + /*totvert = BLI_listbase_count(&em->verts);*/ /*UNUSED*/ #ifdef DEBUG_REEB - totfaces = BLI_countlist(&em->faces); + totfaces = BLI_listbase_count(&em->faces); #endif renormalizeWeight(em, 1.0f); @@ -2460,7 +2460,7 @@ void renormalizeWeight(EditMesh *em, float newmax) EditVert *eve; float minimum, maximum, range; - if (em == NULL || BLI_countlist(&em->verts) == 0) + if (em == NULL || BLI_listbase_is_empty(&em->verts)) return; /* First pass, determine maximum and minimum */ @@ -2486,7 +2486,7 @@ int weightFromLoc(EditMesh *em, int axis) { EditVert *eve; - if (em == NULL || BLI_countlist(&em->verts) == 0 || axis < 0 || axis > 2) + if (em == NULL || BLI_listbase_is_empty(&em->verts) || axis < 0 || axis > 2) return 0; /* Copy coordinate in weight */ @@ -2738,7 +2738,7 @@ static void buildIndexedEdges(EditMesh *em, EdgeIndex *indexed_edges) int tot_indexed = 0; int offset = 0; - totvert = BLI_countlist(&em->verts); + totvert = BLI_listbase_count(&em->verts); indexed_edges->offset = MEM_callocN(totvert * sizeof(int), "EdgeIndex offset"); @@ -2791,13 +2791,13 @@ int weightFromDistance(EditMesh *em, EdgeIndex *indexed_edges) int totvert = 0; int vCount = 0; - totvert = BLI_countlist(&em->verts); + totvert = BLI_listbase_count(&em->verts); if (em == NULL || totvert == 0) { return 0; } - totedge = BLI_countlist(&em->edges); + totedge = BLI_listbase_count(&em->edges); if (totedge == 0) { return 0; diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c index f1b34182439..0f42dc923a4 100644 --- a/source/blender/editors/curve/curve_ops.c +++ b/source/blender/editors/curve/curve_ops.c @@ -36,10 +36,6 @@ #include "DNA_curve_types.h" #include "DNA_scene_types.h" -#include "BLI_math.h" -#include "BLI_blenlib.h" - - #include "RNA_access.h" #include "WM_api.h" diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index a52b2a619dc..99c64be5797 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -85,6 +85,7 @@ typedef struct { GHash *undoIndex; ListBase fcurves, drivers; int actnu; + int flag; } UndoCurve; /* Definitions needed for shape keys */ @@ -766,16 +767,7 @@ static void calc_shapeKeys(Object *obedit) /* editing the base key should update others */ if (cu->key->type == KEY_RELATIVE) { - int act_is_basis = 0; - /* find if this key is a basis for any others */ - for (currkey = cu->key->block.first; currkey; currkey = currkey->next) { - if (editnurb->shapenr - 1 == currkey->relative) { - act_is_basis = 1; - break; - } - } - - if (act_is_basis) { /* active key is a base */ + if (BKE_keyblock_is_basis(cu->key, editnurb->shapenr - 1)) { /* active key is a base */ int totvec = 0; /* Calculate needed memory to store offset */ @@ -1358,7 +1350,7 @@ void make_editNurb(Object *obedit) if (actkey) { // XXX strcpy(G.editModeTitleExtra, "(Key) "); undo_editmode_clear(); - BKE_key_convert_to_curve(actkey, cu, &cu->nurb); + BKE_keyblock_convert_to_curve(actkey, cu, &cu->nurb); } if (editnurb) { @@ -4799,7 +4791,7 @@ bool ed_editnurb_spin(float viewmat[4][4], Object *obedit, const float axis[3], ok = true; for (a = 0; a < 7; a++) { - ok = ed_editnurb_extrude_flag(cu->editnurb, 1); + ok = ed_editnurb_extrude_flag(cu->editnurb, SELECT); if (ok == false) return changed; @@ -5260,7 +5252,7 @@ static int extrude_exec(bContext *C, wmOperator *UNUSED(op)) addvert_Nurb(C, 'e', NULL); } else { - if (ed_editnurb_extrude_flag(editnurb, 1)) { /* '1'= flag */ + if (ed_editnurb_extrude_flag(editnurb, SELECT)) { if (ED_curve_updateAnimPaths(obedit->data)) WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit); @@ -5382,11 +5374,11 @@ static int toggle_cyclic_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS for (nu = editnurb->first; nu; nu = nu->next) { if (nu->pntsu > 1 || nu->pntsv > 1) { if (nu->type == CU_NURBS) { - pup = uiPupMenuBegin(C, IFACE_("Direction"), ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, IFACE_("Direction"), ICON_NONE); + layout = UI_popup_menu_layout(pup); uiItemsEnumO(layout, op->type->idname, "direction"); - uiPupMenuEnd(C, pup); - return OPERATOR_CANCELLED; + UI_popup_menu_end(C, pup); + return OPERATOR_INTERFACE; } } } @@ -6889,6 +6881,7 @@ static void undoCurve_to_editCurve(void *ucu, void *UNUSED(edata), void *cu_v) cu->actvert = undoCurve->actvert; cu->actnu = undoCurve->actnu; + cu->flag = undoCurve->flag; ED_curve_updateAnimPaths(cu); } @@ -6928,6 +6921,7 @@ static void *editCurve_to_undoCurve(void *UNUSED(edata), void *cu_v) undoCurve->actvert = cu->actvert; undoCurve->actnu = cu->actnu; + undoCurve->flag = cu->flag; return undoCurve; } diff --git a/source/blender/editors/curve/editcurve_add.c b/source/blender/editors/curve/editcurve_add.c index 8a3d4f3f4f5..c9a961d1a4d 100644 --- a/source/blender/editors/curve/editcurve_add.c +++ b/source/blender/editors/curve/editcurve_add.c @@ -355,10 +355,10 @@ Nurb *add_nurbs_primitive(bContext *C, Object *obedit, float mat[4][4], int type mul_mat3_m4_v3(mat, vec); - ed_editnurb_translate_flag(editnurb, 1, vec); - ed_editnurb_extrude_flag(cu->editnurb, 1); + ed_editnurb_translate_flag(editnurb, SELECT, vec); + ed_editnurb_extrude_flag(cu->editnurb, SELECT); mul_v3_fl(vec, -2.0f); - ed_editnurb_translate_flag(editnurb, 1, vec); + ed_editnurb_translate_flag(editnurb, SELECT, vec); BLI_remlink(editnurb, nu); @@ -460,7 +460,7 @@ Nurb *add_nurbs_primitive(bContext *C, Object *obedit, float mat[4][4], int type if (nu) { /* should always be set */ nu->flag |= CU_SMOOTH; - cu->actnu = BLI_countlist(editnurb); + cu->actnu = BLI_listbase_count(editnurb); cu->actvert = CU_ACT_NONE; BKE_nurb_test2D(nu); diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index 4655deec4c4..108166109b8 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -668,7 +668,7 @@ void ED_text_to_object(bContext *C, Text *text, const bool split_lines) offset[1] = 0.0f; offset[2] = 0.0f; - txt_add_object(C, text->lines.first, BLI_countlist(&text->lines), offset); + txt_add_object(C, text->lines.first, BLI_listbase_count(&text->lines), offset); } } @@ -1744,7 +1744,7 @@ static void font_ui_template_init(bContext *C, wmOperator *op) PropertyPointerRNA *pprop; op->customdata = pprop = MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA"); - uiIDContextProperty(C, &pprop->ptr, &pprop->prop); + UI_context_active_but_prop_get_templateID(C, &pprop->ptr, &pprop->prop); } static void font_open_cancel(bContext *UNUSED(C), wmOperator *op) @@ -1848,7 +1848,7 @@ static int font_unlink_exec(bContext *C, wmOperator *op) PointerRNA idptr; PropertyPointerRNA pprop; - uiIDContextProperty(C, &pprop.ptr, &pprop.prop); + UI_context_active_but_prop_get_templateID(C, &pprop.ptr, &pprop.prop); if (pprop.prop == NULL) { BKE_report(op->reports, RPT_ERROR, "Incorrect context for running font unlink"); diff --git a/source/blender/editors/gpencil/CMakeLists.txt b/source/blender/editors/gpencil/CMakeLists.txt index 5dc9679777f..58192f59219 100644 --- a/source/blender/editors/gpencil/CMakeLists.txt +++ b/source/blender/editors/gpencil/CMakeLists.txt @@ -39,11 +39,12 @@ set(INC_SYS set(SRC drawgpencil.c editaction_gpencil.c - gpencil_buttons.c gpencil_edit.c gpencil_ops.c gpencil_paint.c + gpencil_select.c gpencil_undo.c + gpencil_utils.c gpencil_intern.h ) diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 5a838d7bc39..4af41a56e8f 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -58,6 +58,8 @@ #include "ED_gpencil.h" #include "ED_view3d.h" +#include "UI_resources.h" + #include "gpencil_intern.h" /* ************************************************** */ @@ -73,6 +75,9 @@ typedef enum eDrawStrokeFlags { GP_DRAWDATA_ONLYI2D = (1 << 3), /* only draw 'image' strokes */ GP_DRAWDATA_IEDITHACK = (1 << 4), /* special hack for drawing strokes in Image Editor (weird coordinates) */ GP_DRAWDATA_NO_XRAY = (1 << 5), /* don't draw xray in 3D view (which is default) */ + GP_DRAWDATA_NO_ONIONS = (1 << 6), /* no onionskins should be drawn (for animation playback) */ + GP_DRAWDATA_VOLUMETRIC = (1 << 7), /* draw strokes as "volumetric" circular billboards */ + GP_DRAWDATA_FILL = (1 << 8), /* fill insides/bounded-regions of strokes */ } eDrawStrokeFlags; @@ -144,6 +149,213 @@ static void gp_draw_stroke_buffer(tGPspoint *points, int totpoints, short thickn } } +/* --------- 2D Stroke Drawing Helpers --------- */ + +/* helper function to calculate x-y drawing coordinates for 2D points */ +static void gp_calc_2d_stroke_xy(bGPDspoint *pt, short sflag, int offsx, int offsy, int winx, int winy, float r_co[2]) +{ + if (sflag & GP_STROKE_2DSPACE) { + r_co[0] = pt->x; + r_co[1] = pt->y; + } + else if (sflag & GP_STROKE_2DIMAGE) { + const float x = (float)((pt->x * winx) + offsx); + const float y = (float)((pt->y * winy) + offsy); + + r_co[0] = x; + r_co[1] = y; + } + else { + const float x = (float)(pt->x / 100 * winx) + offsx; + const float y = (float)(pt->y / 100 * winy) + offsy; + + r_co[0] = x; + r_co[1] = y; + } +} + +/* ----------- Volumetric Strokes --------------- */ + +/* draw a 2D buffer stroke in "volumetric" style + * NOTE: the stroke buffer doesn't have any coordinate offsets/transforms + */ +static void gp_draw_stroke_volumetric_buffer(tGPspoint *points, int totpoints, short thickness, + short dflag, short UNUSED(sflag)) +{ + GLUquadricObj *qobj = gluNewQuadric(); + float modelview[4][4]; + + tGPspoint *pt; + int i; + + /* error checking */ + if ((points == NULL) || (totpoints <= 0)) + return; + + /* check if buffer can be drawn */ + if (dflag & (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_ONLYV2D)) + return; + + /* get basic matrix - should be camera space (i.e "identity") */ + glGetFloatv(GL_MODELVIEW_MATRIX, (float *)modelview); + + /* draw points */ + glPushMatrix(); + + for (i = 0, pt = points; i < totpoints; i++, pt++) { + /* set the transformed position */ + // TODO: scale should change based on zoom level, which requires proper translation mult too! + modelview[3][0] = pt->x; + modelview[3][1] = pt->y; + + glLoadMatrixf((float *)modelview); + + /* draw the disk using the current state... */ + gluDisk(qobj, 0.0, pt->pressure * thickness, 32, 1); + + + modelview[3][0] = modelview[3][1] = 0.0f; + } + + glPopMatrix(); + gluDeleteQuadric(qobj); +} + +/* draw a 2D strokes in "volumetric" style */ +static void gp_draw_stroke_volumetric_2d(bGPDspoint *points, int totpoints, short thickness, + short dflag, short sflag, + int offsx, int offsy, int winx, int winy) +{ + GLUquadricObj *qobj = gluNewQuadric(); + float modelview[4][4]; + float baseloc[3]; + float scalefac = 1.0f; + + bGPDspoint *pt; + int i; + + + /* HACK: We need a scale factor for the drawing in the image editor, + * which seems to use 1 unit as it's maximum size, whereas everything + * else assumes 1 unit = 1 pixel. Otherwise, we only get a massive blob. + */ + if ((dflag & GP_DRAWDATA_IEDITHACK) && (dflag & GP_DRAWDATA_ONLYV2D)) { + scalefac = 0.001f; + } + + /* get basic matrix */ + glGetFloatv(GL_MODELVIEW_MATRIX, (float *)modelview); + copy_v3_v3(baseloc, modelview[3]); + + /* draw points */ + glPushMatrix(); + + for (i = 0, pt = points; i < totpoints; i++, pt++) { + /* set the transformed position */ + float co[2]; + + gp_calc_2d_stroke_xy(pt, sflag, offsx, offsy, winx, winy, co); + translate_m4(modelview, co[0], co[1], 0.0f); + + glLoadMatrixf((float *)modelview); + + /* draw the disk using the current state... */ + gluDisk(qobj, 0.0, pt->pressure * thickness * scalefac, 32, 1); + + /* restore matrix */ + copy_v3_v3(modelview[3], baseloc); + } + + glPopMatrix(); + gluDeleteQuadric(qobj); +} + +/* draw a 3D stroke in "volumetric" style */ +static void gp_draw_stroke_volumetric_3d(bGPDspoint *points, int totpoints, short thickness, + short UNUSED(dflag), short UNUSED(sflag)) +{ + GLUquadricObj *qobj = gluNewQuadric(); + + float base_modelview[4][4], modelview[4][4]; + float base_loc[3]; + + bGPDspoint *pt; + int i; + + + /* Get the basic modelview matrix we use for performing calculations */ + glGetFloatv(GL_MODELVIEW_MATRIX, (float *)base_modelview); + copy_v3_v3(base_loc, base_modelview[3]); + + /* Create the basic view-aligned billboard matrix we're going to actually draw qobj with: + * - We need to knock out the rotation so that we are + * simply left with a camera-facing billboard + * - The scale factors here are chosen so that the thickness + * is relatively reasonable. Otherwise, it gets far too + * large! + */ + scale_m4_fl(modelview, 0.1f); + + /* draw each point as a disk... */ + glPushMatrix(); + + for (i = 0, pt = points; i < totpoints && pt; i++, pt++) { + /* apply translation to base_modelview, so that the translated point is put in the right place */ + translate_m4(base_modelview, pt->x, pt->y, pt->z); + + /* copy the translation component to the billboard matrix we're going to use, + * then reset the base matrix to the original values so that we can do the same + * for the next point without accumulation/pollution effects + */ + copy_v3_v3(modelview[3], base_modelview[3]); /* copy offset value */ + copy_v3_v3(base_modelview[3], base_loc); /* restore */ + + /* apply our billboard matrix for drawing... */ + glLoadMatrixf((float *)modelview); + + /* draw the disk using the current state... */ + gluDisk(qobj, 0.0, pt->pressure * thickness, 32, 1); + } + + glPopMatrix(); + gluDeleteQuadric(qobj); +} + + +/* --------------- Stroke Fills ----------------- */ + +/* draw fills for shapes */ +static void gp_draw_stroke_fill(bGPDspoint *points, int totpoints, short UNUSED(thickness), + short UNUSED(dflag), short sflag, + int offsx, int offsy, int winx, int winy) +{ + bGPDspoint *pt; + int i; + + BLI_assert(totpoints >= 3); + + /* As an initial implementation, we use the OpenGL filled polygon drawing + * here since it's the easiest option to implement for this case. It does + * come with limitations (notably for concave shapes), though it shouldn't + * be much of an issue in most cases. + */ + glBegin(GL_POLYGON); + + for (i = 0, pt = points; i < totpoints; i++, pt++) { + if (sflag & GP_STROKE_3DSPACE) { + glVertex3fv(&pt->x); + } + else { + float co[2]; + + gp_calc_2d_stroke_xy(pt, sflag, offsx, offsy, winx, winy, co); + glVertex2fv(co); + } + } + + glEnd(); +} + /* ----- Existing Strokes Drawing (3D and Point) ------ */ /* draw a given stroke - just a single dot (only one point) */ @@ -160,18 +372,7 @@ static void gp_draw_stroke_point(bGPDspoint *points, short thickness, short dfla float co[2]; /* get coordinates of point */ - if (sflag & GP_STROKE_2DSPACE) { - co[0] = points->x; - co[1] = points->y; - } - else if (sflag & GP_STROKE_2DIMAGE) { - co[0] = (points->x * winx) + offsx; - co[1] = (points->y * winy) + offsy; - } - else { - co[0] = (points->x / 100 * winx) + offsx; - co[1] = (points->y / 100 * winy) + offsy; - } + gp_calc_2d_stroke_xy(points, sflag, offsx, offsy, winx, winy, co); /* if thickness is less than GP_DRAWTHICKNESS_SPECIAL, simple dot looks ok * - also mandatory in if Image Editor 'image-based' dot @@ -200,7 +401,7 @@ static void gp_draw_stroke_point(bGPDspoint *points, short thickness, short dfla } /* draw a given stroke in 3d (i.e. in 3d-space), using simple ogl lines */ -static void gp_draw_stroke_3d(bGPDspoint *points, int totpoints, short thickness, short debug) +static void gp_draw_stroke_3d(bGPDspoint *points, int totpoints, short thickness, bool debug, short UNUSED(sflag)) { bGPDspoint *pt; float curpressure = points[0].pressure; @@ -233,6 +434,7 @@ static void gp_draw_stroke_3d(bGPDspoint *points, int totpoints, short thickness glEnd(); /* draw debug points of curve on top? */ + /* XXX: for now, we represent "selected" strokes in the same way as debug, which isn't used anymore */ if (debug) { glBegin(GL_POINTS); for (i = 0, pt = points; i < totpoints && pt; i++, pt++) @@ -244,46 +446,23 @@ static void gp_draw_stroke_3d(bGPDspoint *points, int totpoints, short thickness /* ----- Fancy 2D-Stroke Drawing ------ */ /* draw a given stroke in 2d */ -static void gp_draw_stroke(bGPDspoint *points, int totpoints, short thickness_s, short dflag, short sflag, - short debug, int offsx, int offsy, int winx, int winy) +static void gp_draw_stroke_2d(bGPDspoint *points, int totpoints, short thickness_s, short dflag, short sflag, + bool debug, int offsx, int offsy, int winx, int winy) { /* otherwise thickness is twice that of the 3D view */ float thickness = (float)thickness_s * 0.5f; - - /* if thickness is less than GP_DRAWTHICKNESS_SPECIAL, 'smooth' opengl lines look better - * - 'smooth' opengl lines are also required if Image Editor 'image-based' stroke - */ - if ((thickness < GP_DRAWTHICKNESS_SPECIAL) || - ((dflag & GP_DRAWDATA_IEDITHACK) && (dflag & GP_DRAWDATA_ONLYV2D))) - { - bGPDspoint *pt; - int i; - - glBegin(GL_LINE_STRIP); - for (i = 0, pt = points; i < totpoints && pt; i++, pt++) { - if (sflag & GP_STROKE_2DSPACE) { - glVertex2f(pt->x, pt->y); - } - else if (sflag & GP_STROKE_2DIMAGE) { - const float x = (pt->x * winx) + offsx; - const float y = (pt->y * winy) + offsy; - - glVertex2f(x, y); - } - else { - const float x = (pt->x / 100 * winx) + offsx; - const float y = (pt->y / 100 * winy) + offsy; - - glVertex2f(x, y); - } - } - glEnd(); + + /* strokes in Image Editor need a scale factor, since units there are not pixels! */ + float scalefac = 1.0f; + if ((dflag & GP_DRAWDATA_IEDITHACK) && (dflag & GP_DRAWDATA_ONLYV2D)) { + scalefac = 0.001f; } + /* tessellation code - draw stroke as series of connected quads with connection * edges rotated to minimize shrinking artifacts, and rounded endcaps */ - else { + { bGPDspoint *pt1, *pt2; float pm[2]; int i; @@ -299,22 +478,8 @@ static void gp_draw_stroke(bGPDspoint *points, int totpoints, short thickness_s, float pthick; /* thickness at segment point */ /* get x and y coordinates from points */ - if (sflag & GP_STROKE_2DSPACE) { - s0[0] = pt1->x; s0[1] = pt1->y; - s1[0] = pt2->x; s1[1] = pt2->y; - } - else if (sflag & GP_STROKE_2DIMAGE) { - s0[0] = (pt1->x * winx) + offsx; - s0[1] = (pt1->y * winy) + offsy; - s1[0] = (pt2->x * winx) + offsx; - s1[1] = (pt2->y * winy) + offsy; - } - else { - s0[0] = (pt1->x / 100 * winx) + offsx; - s0[1] = (pt1->y / 100 * winy) + offsy; - s1[0] = (pt2->x / 100 * winx) + offsx; - s1[1] = (pt2->y / 100 * winy) + offsy; - } + gp_calc_2d_stroke_xy(pt1, sflag, offsx, offsy, winx, winy, s0); + gp_calc_2d_stroke_xy(pt2, sflag, offsx, offsy, winx, winy, s1); /* calculate gradient and normal - 'angle'=(ny/nx) */ m1[1] = s1[1] - s0[1]; @@ -324,7 +489,7 @@ static void gp_draw_stroke(bGPDspoint *points, int totpoints, short thickness_s, m2[0] = m1[1]; /* always use pressure from first point here */ - pthick = (pt1->pressure * thickness); + pthick = (pt1->pressure * thickness * scalefac); /* if the first segment, start of segment is segment's normal */ if (i == 0) { @@ -399,7 +564,7 @@ static void gp_draw_stroke(bGPDspoint *points, int totpoints, short thickness_s, /* if last segment, also draw end of segment (defined as segment's normal) */ if (i == totpoints - 2) { /* for once, we use second point's pressure (otherwise it won't be drawn) */ - pthick = (pt2->pressure * thickness); + pthick = (pt2->pressure * thickness * scalefac); /* calculate points for end of segment */ mt[0] = m2[0] * pthick; @@ -448,52 +613,57 @@ static void gp_draw_stroke(bGPDspoint *points, int totpoints, short thickness_s, glBegin(GL_POINTS); for (i = 0, pt = points; i < totpoints && pt; i++, pt++) { - if (sflag & GP_STROKE_2DSPACE) { - glVertex2fv(&pt->x); - } - else if (sflag & GP_STROKE_2DIMAGE) { - const float x = (float)((pt->x * winx) + offsx); - const float y = (float)((pt->y * winy) + offsy); - - glVertex2f(x, y); - } - else { - const float x = (float)(pt->x / 100 * winx) + offsx; - const float y = (float)(pt->y / 100 * winy) + offsy; - - glVertex2f(x, y); - } + float co[2]; + + gp_calc_2d_stroke_xy(pt, sflag, offsx, offsy, winx, winy, co); + glVertex2fv(co); } glEnd(); } } -/* ----- General Drawing ------ */ +/* ----- Strokes Drawing ------ */ + +/* Helper for doing all the checks on whether a stroke can be drawn */ +static bool gp_can_draw_stroke(const bGPDstroke *gps, const int dflag) +{ + /* skip stroke if it isn't in the right display space for this drawing context */ + /* 1) 3D Strokes */ + if ((dflag & GP_DRAWDATA_ONLY3D) && !(gps->flag & GP_STROKE_3DSPACE)) + return false; + if (!(dflag & GP_DRAWDATA_ONLY3D) && (gps->flag & GP_STROKE_3DSPACE)) + return false; + + /* 2) Screen Space 2D Strokes */ + if ((dflag & GP_DRAWDATA_ONLYV2D) && !(gps->flag & GP_STROKE_2DSPACE)) + return false; + if (!(dflag & GP_DRAWDATA_ONLYV2D) && (gps->flag & GP_STROKE_2DSPACE)) + return false; + + /* 3) Image Space (2D) */ + if ((dflag & GP_DRAWDATA_ONLYI2D) && !(gps->flag & GP_STROKE_2DIMAGE)) + return false; + if (!(dflag & GP_DRAWDATA_ONLYI2D) && (gps->flag & GP_STROKE_2DIMAGE)) + return false; + + + /* skip stroke if it doesn't have any valid data */ + if ((gps->points == NULL) || (gps->totpoints < 1)) + return false; + + /* stroke can be drawn */ + return true; +} /* draw a set of strokes */ static void gp_draw_strokes(bGPDframe *gpf, int offsx, int offsy, int winx, int winy, int dflag, - short debug, short lthick, const float color[4]) + bool debug, short lthick, const float color[4], const float fill_color[4]) { bGPDstroke *gps; - /* set color first (may need to reset it again later too) */ - glColor4fv(color); - for (gps = gpf->strokes.first; gps; gps = gps->next) { - /* check if stroke can be drawn - checks here generally fall into pairs */ - if ((dflag & GP_DRAWDATA_ONLY3D) && !(gps->flag & GP_STROKE_3DSPACE)) - continue; - if (!(dflag & GP_DRAWDATA_ONLY3D) && (gps->flag & GP_STROKE_3DSPACE)) - continue; - if ((dflag & GP_DRAWDATA_ONLYV2D) && !(gps->flag & GP_STROKE_2DSPACE)) - continue; - if (!(dflag & GP_DRAWDATA_ONLYV2D) && (gps->flag & GP_STROKE_2DSPACE)) - continue; - if ((dflag & GP_DRAWDATA_ONLYI2D) && !(gps->flag & GP_STROKE_2DIMAGE)) - continue; - if (!(dflag & GP_DRAWDATA_ONLYI2D) && (gps->flag & GP_STROKE_2DIMAGE)) - continue; - if ((gps->points == NULL) || (gps->totpoints < 1)) + /* check if stroke can be drawn */ + if (gp_can_draw_stroke(gps, dflag) == false) continue; /* check which stroke-drawer to use */ @@ -515,11 +685,27 @@ static void gp_draw_strokes(bGPDframe *gpf, int offsx, int offsy, int winx, int #endif } - if (gps->totpoints == 1) { - gp_draw_stroke_point(gps->points, lthick, dflag, gps->flag, offsx, offsy, winx, winy); + /* 3D Fill */ + if ((dflag & GP_DRAWDATA_FILL) && (gps->totpoints >= 3)) { + glColor4fv(fill_color); + gp_draw_stroke_fill(gps->points, gps->totpoints, lthick, dflag, gps->flag, offsx, offsy, winx, winy); + } + + /* 3D Stroke */ + glColor4fv(color); + + if (dflag & GP_DRAWDATA_VOLUMETRIC) { + /* volumetric stroke drawing */ + gp_draw_stroke_volumetric_3d(gps->points, gps->totpoints, lthick, dflag, gps->flag); } else { - gp_draw_stroke_3d(gps->points, gps->totpoints, lthick, debug); + /* 3D Lines - OpenGL primitives-based */ + if (gps->totpoints == 1) { + gp_draw_stroke_point(gps->points, lthick, dflag, gps->flag, offsx, offsy, winx, winy); + } + else { + gp_draw_stroke_3d(gps->points, gps->totpoints, lthick, debug, gps->flag); + } } if (no_xray) { @@ -534,139 +720,386 @@ static void gp_draw_strokes(bGPDframe *gpf, int offsx, int offsy, int winx, int } } else { - if (gps->totpoints == 1) { - gp_draw_stroke_point(gps->points, lthick, dflag, gps->flag, offsx, offsy, winx, winy); + /* 2D - Fill */ + if ((dflag & GP_DRAWDATA_FILL) && (gps->totpoints >= 3)) { + glColor4fv(fill_color); + gp_draw_stroke_fill(gps->points, gps->totpoints, lthick, dflag, gps->flag, offsx, offsy, winx, winy); + } + + /* 2D Strokes... */ + glColor4fv(color); + + if (dflag & GP_DRAWDATA_VOLUMETRIC) { + /* blob/disk-based "volumetric" drawing */ + gp_draw_stroke_volumetric_2d(gps->points, gps->totpoints, lthick, dflag, gps->flag, offsx, offsy, winx, winy); } else { - gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, offsx, offsy, winx, winy); + /* normal 2D strokes */ + if (gps->totpoints == 1) { + gp_draw_stroke_point(gps->points, lthick, dflag, gps->flag, offsx, offsy, winx, winy); + } + else { + gp_draw_stroke_2d(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, offsx, offsy, winx, winy); + } } } } } -/* draw grease-pencil datablock */ -static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy, int cfra, int dflag) +/* Draw selected verts for strokes being edited */ +static void gp_draw_strokes_edit(bGPDframe *gpf, int offsx, int offsy, int winx, int winy, short dflag, const float tcolor[3]) { - bGPDlayer *gpl; + bGPDstroke *gps; - /* reset line drawing style (in case previous user didn't reset) */ - setlinestyle(0); + const int no_xray = (dflag & GP_DRAWDATA_NO_XRAY); + int mask_orig = 0; - /* turn on smooth lines (i.e. anti-aliasing) */ - glEnable(GL_LINE_SMOOTH); + /* set up depth masks... */ + if (dflag & GP_DRAWDATA_ONLY3D) { + if (no_xray) { + glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig); + glDepthMask(0); + glEnable(GL_DEPTH_TEST); + + /* first arg is normally rv3d->dist, but this isn't + * available here and seems to work quite well without */ + bglPolygonOffset(1.0f, 1.0f); +#if 0 + glEnable(GL_POLYGON_OFFSET_LINE); + glPolygonOffset(-1.0f, -1.0f); +#endif + } + } - /* turn on alpha-blending */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); + + /* draw stroke verts */ + for (gps = gpf->strokes.first; gps; gps = gps->next) { + bGPDspoint *pt; + float vsize, bsize; + int i; + + /* check if stroke can be drawn */ + if (gp_can_draw_stroke(gps, dflag) == false) + continue; - /* loop over layers, drawing them */ + /* Optimisation: only draw points for selected strokes + * We assume that selected points can only occur in + * strokes that are selected too. + */ + if ((gps->flag & GP_STROKE_SELECT) == 0) + continue; + + /* Get size of verts: + * - The selected state needs to be larger than the unselected state so that + * they stand out more. + * - We use the theme setting for size of the unselected verts + */ + bsize = UI_GetThemeValuef(TH_VERTEX_SIZE); + if ((int)bsize > 8) { + vsize = 10.0f; + bsize = 8.0f; + } + else { + vsize = bsize + 2; + } + + /* First Pass: Draw all the verts (i.e. these become the unselected state) */ + if (tcolor != NULL) { + /* for now, we assume that the base color of the points is not too close to the real color */ + glColor3fv(tcolor); + } + else { + /* this doesn't work well with the default theme and black strokes... */ + UI_ThemeColor(TH_VERTEX); + } + glPointSize(bsize); + + glBegin(GL_POINTS); + for (i = 0, pt = gps->points; i < gps->totpoints && pt; i++, pt++) { + if (gps->flag & GP_STROKE_3DSPACE) { + glVertex3fv(&pt->x); + } + else { + float co[2]; + + gp_calc_2d_stroke_xy(pt, gps->flag, offsx, offsy, winx, winy, co); + glVertex2fv(co); + } + } + glEnd(); + + + /* Second Pass: Draw only verts which are selected */ + UI_ThemeColor(TH_VERTEX_SELECT); + glPointSize(vsize); + + glBegin(GL_POINTS); + for (i = 0, pt = gps->points; i < gps->totpoints && pt; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) { + if (gps->flag & GP_STROKE_3DSPACE) { + glVertex3fv(&pt->x); + } + else { + float co[2]; + + gp_calc_2d_stroke_xy(pt, gps->flag, offsx, offsy, winx, winy, co); + glVertex2fv(co); + } + } + } + glEnd(); + } + + + /* clear depth mask */ + if (dflag & GP_DRAWDATA_ONLY3D) { + if (no_xray) { + glDepthMask(mask_orig); + glDisable(GL_DEPTH_TEST); + + bglPolygonOffset(0.0, 0.0); +#if 0 + glDisable(GL_POLYGON_OFFSET_LINE); + glPolygonOffset(0, 0); +#endif + } + } +} + +/* ----- General Drawing ------ */ + +/* draw onion-skinning for a layer */ +static void gp_draw_onionskins(bGPDlayer *gpl, bGPDframe *gpf, int offsx, int offsy, int winx, int winy, + int UNUSED(cfra), int dflag, short debug, short lthick) +{ + const float alpha = gpl->color[3]; + float color[4]; + + /* 1) Draw Previous Frames First */ + if (gpl->flag & GP_LAYER_GHOST_PREVCOL) { + copy_v3_v3(color, gpl->gcolor_prev); + } + else { + copy_v3_v3(color, gpl->color); + } + + if (gpl->gstep) { + bGPDframe *gf; + float fac; + + /* draw previous frames first */ + for (gf = gpf->prev; gf; gf = gf->prev) { + /* check if frame is drawable */ + if ((gpf->framenum - gf->framenum) <= gpl->gstep) { + /* alpha decreases with distance from curframe index */ + fac = 1.0f - ((float)(gpf->framenum - gf->framenum) / (float)(gpl->gstep + 1)); + color[3] = alpha * fac * 0.66f; + gp_draw_strokes(gf, offsx, offsy, winx, winy, dflag, debug, lthick, color, color); + } + else + break; + } + } + else { + /* draw the strokes for the ghost frames (at half of the alpha set by user) */ + if (gpf->prev) { + color[3] = (alpha / 7); + gp_draw_strokes(gpf->prev, offsx, offsy, winx, winy, dflag, debug, lthick, color, color); + } + } + + + /* 2) Now draw next frames */ + if (gpl->flag & GP_LAYER_GHOST_NEXTCOL) { + copy_v3_v3(color, gpl->gcolor_next); + } + else { + copy_v3_v3(color, gpl->color); + } + + if (gpl->gstep_next) { + bGPDframe *gf; + float fac; + + /* now draw next frames */ + for (gf = gpf->next; gf; gf = gf->next) { + /* check if frame is drawable */ + if ((gf->framenum - gpf->framenum) <= gpl->gstep_next) { + /* alpha decreases with distance from curframe index */ + fac = 1.0f - ((float)(gf->framenum - gpf->framenum) / (float)(gpl->gstep_next + 1)); + color[3] = alpha * fac * 0.66f; + gp_draw_strokes(gf, offsx, offsy, winx, winy, dflag, debug, lthick, color, color); + } + else + break; + } + } + else { + /* draw the strokes for the ghost frames (at half of the alpha set by user) */ + if (gpf->next) { + color[3] = (alpha / 4); + gp_draw_strokes(gpf->next, offsx, offsy, winx, winy, dflag, debug, lthick, color, color); + } + } + + /* 3) restore alpha */ + glColor4fv(gpl->color); +} + +/* loop over gpencil data layers, drawing them */ +static void gp_draw_data_layers(bGPdata *gpd, int offsx, int offsy, int winx, int winy, int cfra, int dflag) +{ + bGPDlayer *gpl; + for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { bGPDframe *gpf; - - short debug = (gpl->flag & GP_LAYER_DRAWDEBUG) ? 1 : 0; + + bool debug = (gpl->flag & GP_LAYER_DRAWDEBUG) ? true : false; short lthick = gpl->thickness; - float color[4], tcolor[4]; - + /* don't draw layer if hidden */ - if (gpl->flag & GP_LAYER_HIDE) + if (gpl->flag & GP_LAYER_HIDE) continue; - + /* get frame to draw */ gpf = gpencil_layer_getframe(gpl, cfra, 0); - if (gpf == NULL) + if (gpf == NULL) continue; - + /* set color, stroke thickness, and point size */ glLineWidth(lthick); - copy_v4_v4(color, gpl->color); // just for copying 4 array elements - copy_v4_v4(tcolor, gpl->color); // additional copy of color (for ghosting) - glColor4fv(color); glPointSize((float)(gpl->thickness + 2)); - - /* apply xray layer setting */ - if (gpl->flag & GP_LAYER_NO_XRAY) dflag |= GP_DRAWDATA_NO_XRAY; - else dflag &= ~GP_DRAWDATA_NO_XRAY; - + + /* Add layer drawing settings to the set of "draw flags" + * NOTE: If the setting doesn't apply, it *must* be cleared, + * as dflag's carry over from the previous layer + */ +#define GP_DRAWFLAG_APPLY(condition, draw_flag_value) { \ + if (condition) dflag |= (draw_flag_value); \ + else dflag &= ~(draw_flag_value); \ + } (void)0 + + /* xray... */ + GP_DRAWFLAG_APPLY((gpl->flag & GP_LAYER_NO_XRAY), GP_DRAWDATA_NO_XRAY); + + /* volumetric strokes... */ + GP_DRAWFLAG_APPLY((gpl->flag & GP_LAYER_VOLUMETRIC), GP_DRAWDATA_VOLUMETRIC); + + /* fill strokes... */ + // XXX: this is not a very good limit + GP_DRAWFLAG_APPLY((gpl->fill[3] > 0.001f), GP_DRAWDATA_FILL); +#undef GP_DRAWFLAG_APPLY + /* draw 'onionskins' (frame left + right) */ - if (gpl->flag & GP_LAYER_ONIONSKIN) { - /* drawing method - only immediately surrounding (gstep = 0), - * or within a frame range on either side (gstep > 0)*/ - if (gpl->gstep) { - bGPDframe *gf; - float fac; - - /* draw previous frames first */ - for (gf = gpf->prev; gf; gf = gf->prev) { - /* check if frame is drawable */ - if ((gpf->framenum - gf->framenum) <= gpl->gstep) { - /* alpha decreases with distance from curframe index */ - fac = 1.0f - ((float)(gpf->framenum - gf->framenum) / (float)(gpl->gstep + 1)); - tcolor[3] = color[3] * fac * 0.66f; - gp_draw_strokes(gf, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor); - } - else - break; - } - - /* now draw next frames */ - for (gf = gpf->next; gf; gf = gf->next) { - /* check if frame is drawable */ - if ((gf->framenum - gpf->framenum) <= gpl->gstep) { - /* alpha decreases with distance from curframe index */ - fac = 1.0f - ((float)(gf->framenum - gpf->framenum) / (float)(gpl->gstep + 1)); - tcolor[3] = color[3] * fac * 0.66f; - gp_draw_strokes(gf, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor); - } - else - break; - } - - /* restore alpha */ - glColor4fv(color); - } - else { - /* draw the strokes for the ghost frames (at half of the alpha set by user) */ - if (gpf->prev) { - tcolor[3] = (color[3] / 7); - gp_draw_strokes(gpf->prev, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor); - } - - if (gpf->next) { - tcolor[3] = (color[3] / 4); - gp_draw_strokes(gpf->next, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor); - } - - /* restore alpha */ - glColor4fv(color); - } + if ((gpl->flag & GP_LAYER_ONIONSKIN) && !(dflag & GP_DRAWDATA_NO_ONIONS)) { + /* Drawing method - only immediately surrounding (gstep = 0), + * or within a frame range on either side (gstep > 0) + */ + gp_draw_onionskins(gpl, gpf, offsx, offsy, winx, winy, cfra, dflag, debug, lthick); } - + /* draw the strokes already in active frame */ - tcolor[3] = color[3]; - gp_draw_strokes(gpf, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor); - + gp_draw_strokes(gpf, offsx, offsy, winx, winy, dflag, debug, lthick, gpl->color, gpl->fill); + + /* Draw verts of selected strokes + * - when doing OpenGL renders, we don't want to be showing these, as that ends up flickering + * - locked layers can't be edited, so there's no point showing these verts + * as they will have no bearings on what gets edited + * - only show when in editmode, since operators shouldn't work otherwise + * (NOTE: doing it this way means that the toggling editmode shows visible change immediately) + */ + /* XXX: perhaps we don't want to show these when users are drawing... */ + if ((G.f & G_RENDER_OGL) == 0 && + (gpl->flag & GP_LAYER_LOCKED) == 0 && + (gpd->flag & GP_DATA_STROKE_EDITMODE)) + { + gp_draw_strokes_edit(gpf, offsx, offsy, winx, winy, dflag, + (gpl->color[3] < 0.95f) ? gpl->color : NULL); + } + /* Check if may need to draw the active stroke cache, only if this layer is the active layer * that is being edited. (Stroke buffer is currently stored in gp-data) */ if (ED_gpencil_session_active() && (gpl->flag & GP_LAYER_ACTIVE) && (gpf->flag & GP_FRAME_PAINT)) { + /* Set color for drawing buffer stroke - since this may not be set yet */ + glColor4fv(gpl->color); + /* Buffer stroke needs to be drawn with a different linestyle - * to help differentiate them from normal strokes. */ - gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag); + * to help differentiate them from normal strokes. + * + * It should also be noted that sbuffer contains temporary point types + * i.e. tGPspoints NOT bGPDspoints + */ + if (gpl->flag & GP_LAYER_VOLUMETRIC) { + gp_draw_stroke_volumetric_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag); + } + else { + gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag); + } } } - +} + +/* draw grease-pencil datablock */ +static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy, int cfra, int dflag) +{ + /* reset line drawing style (in case previous user didn't reset) */ + setlinestyle(0); + + /* turn on smooth lines (i.e. anti-aliasing) */ + glEnable(GL_LINE_SMOOTH); + + glEnable(GL_POLYGON_SMOOTH); + glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); + + /* turn on alpha-blending */ + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + /* draw! */ + gp_draw_data_layers(gpd, offsx, offsy, winx, winy, cfra, dflag); + /* turn off alpha blending, then smooth lines */ glDisable(GL_BLEND); // alpha blending glDisable(GL_LINE_SMOOTH); // smooth lines - + glDisable(GL_POLYGON_SMOOTH); // smooth poly lines + /* restore initial gl conditions */ glLineWidth(1.0); glPointSize(1.0); glColor4f(0, 0, 0, 1); } +/* if we have strokes for scenes (3d view)/clips (movie clip editor) + * and objects/tracks, multiple data blocks have to be drawn */ +static void gp_draw_data_all(Scene *scene, bGPdata *gpd, int offsx, int offsy, int winx, int winy, + int cfra, int dflag, const char spacetype) +{ + bGPdata *gpd_source = NULL; + + if (scene) { + if (spacetype == SPACE_VIEW3D) { + gpd_source = (scene->gpd ? scene->gpd : NULL); + } + else if (spacetype == SPACE_CLIP && scene->clip) { + /* currently drawing only gpencil data from either clip or track, but not both - XXX fix logic behind */ + gpd_source = (scene->clip->gpd ? scene->clip->gpd : NULL); + } + + if (gpd_source) { + gp_draw_data(gpd_source, offsx, offsy, winx, winy, cfra, dflag); + } + } + + /* scene/clip data has already been drawn, only object/track data is drawn here + * if gpd_source == gpd, we don't have any object/track data and we can skip */ + if (gpd_source == NULL || (gpd_source && gpd_source != gpd)) { + gp_draw_data(gpd, offsx, offsy, winx, winy, cfra, dflag); + } +} + /* ----- Grease Pencil Sketches Drawing API ------ */ /* ............................ @@ -732,7 +1165,7 @@ void ED_gpencil_draw_2dimage(const bContext *C) /* draw it! */ - gp_draw_data(gpd, offsx, offsy, sizex, sizey, CFRA, dflag); + gp_draw_data_all(scene, gpd, offsx, offsy, sizex, sizey, CFRA, dflag, sa->spacetype); } /* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly @@ -758,7 +1191,7 @@ void ED_gpencil_draw_view2d(const bContext *C, bool onlyv2d) /* draw it! */ if (onlyv2d) dflag |= (GP_DRAWDATA_ONLYV2D | GP_DRAWDATA_NOSTATUS); - gp_draw_data(gpd, 0, 0, ar->winx, ar->winy, CFRA, dflag); + gp_draw_data_all(scene, gpd, 0, 0, ar->winx, ar->winy, CFRA, dflag, sa->spacetype); } /* draw grease-pencil sketches to specified 3d-view assuming that matrices are already set correctly @@ -796,14 +1229,14 @@ void ED_gpencil_draw_view3d(Scene *scene, View3D *v3d, ARegion *ar, bool only3d) /* draw it! */ if (only3d) dflag |= (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_NOSTATUS); - gp_draw_data(gpd, offsx, offsy, winx, winy, CFRA, dflag); + gp_draw_data_all(scene, gpd, offsx, offsy, winx, winy, CFRA, dflag, v3d->spacetype); } -void ED_gpencil_draw_ex(bGPdata *gpd, int winx, int winy, const int cfra) +void ED_gpencil_draw_ex(Scene *scene, bGPdata *gpd, int winx, int winy, const int cfra, const char spacetype) { int dflag = GP_DRAWDATA_NOSTATUS | GP_DRAWDATA_ONLYV2D; - gp_draw_data(gpd, 0, 0, winx, winy, cfra, dflag); + gp_draw_data_all(scene, gpd, 0, 0, winx, winy, cfra, dflag, spacetype); } /* ************************************************** */ diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c index dba80164e93..73b2b033e24 100644 --- a/source/blender/editors/gpencil/editaction_gpencil.c +++ b/source/blender/editors/gpencil/editaction_gpencil.c @@ -49,8 +49,6 @@ #include "ED_keyframes_edit.h" #include "ED_markers.h" -#include "gpencil_intern.h" - /* ***************************************** */ /* NOTE ABOUT THIS FILE: * This file contains code for editing Grease Pencil data in the Action Editor @@ -253,6 +251,23 @@ void ED_gplayer_frames_duplicate(bGPDlayer *gpl) } } +/* Set keyframe type for selected frames from given gp-layer + * \param type The type of keyframe (eBezTriple_KeyframeType) to set selected frames to + */ +void ED_gplayer_frames_keytype_set(bGPDlayer *gpl, short type) +{ + bGPDframe *gpf; + + if (gpl == NULL) + return; + + for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { + if (gpf->flag & GP_FRAME_SELECT) { + gpf->key_type = type; + } + } +} + #if 0 // XXX disabled until grease pencil code stabilises again /* -------------------------------------- */ /* Copy and Paste Tools */ diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c deleted file mode 100644 index 0acff8fc0a5..00000000000 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * 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) 2008, Blender Foundation, Joshua Leung - * This is a new part of Blender - * - * Contributor(s): Joshua Leung - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/gpencil/gpencil_buttons.c - * \ingroup edgpencil - */ - - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <stddef.h> - -#include "BLI_blenlib.h" - -#include "BLF_translation.h" - -#include "DNA_gpencil_types.h" -#include "DNA_screen_types.h" -#include "DNA_space_types.h" - -#include "BKE_context.h" -#include "BKE_global.h" -#include "BKE_gpencil.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "RNA_access.h" - -#include "ED_gpencil.h" - -#include "UI_interface.h" -#include "UI_resources.h" - -#include "gpencil_intern.h" - -/* ************************************************** */ -/* GREASE PENCIL PANEL-UI DRAWING */ - -/* Every space which implements Grease-Pencil functionality should have a panel - * for the settings. All of the space-dependent parts should be coded in the panel - * code for that space, but the rest is all handled by generic panel here. - */ - -/* ------- Callbacks ----------- */ -/* These are just 'dummy wrappers' around gpencil api calls */ - -/* make layer active one after being clicked on */ -static void gp_ui_activelayer_cb(bContext *C, void *gpd, void *gpl) -{ - /* make sure the layer we want to remove is the active one */ - gpencil_layer_setactive(gpd, gpl); - - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); -} - -/* delete 'active' layer */ -static void gp_ui_dellayer_cb(bContext *C, void *gpd, void *gpl) -{ - gpencil_layer_delete((bGPdata *)gpd, (bGPDlayer *)gpl); - - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); -} - -/* move layer up */ -static void gp_ui_layer_up_cb(bContext *C, void *gpd_v, void *gpl_v) -{ - bGPdata *gpd = gpd_v; - bGPDlayer *gpl = gpl_v; - - BLI_remlink(&gpd->layers, gpl); - BLI_insertlinkbefore(&gpd->layers, gpl->prev, gpl); - - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); -} - -/* move layer down */ -static void gp_ui_layer_down_cb(bContext *C, void *gpd_v, void *gpl_v) -{ - bGPdata *gpd = gpd_v; - bGPDlayer *gpl = gpl_v; - - BLI_remlink(&gpd->layers, gpl); - BLI_insertlinkafter(&gpd->layers, gpl->next, gpl); - - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); -} - -/* ------- Drawing Code ------- */ - -/* draw the controls for a given layer */ -static void gp_drawui_layer(uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl, const bool is_v3d) -{ - uiLayout *box = NULL, *split = NULL; - uiLayout *col = NULL; - uiLayout *row = NULL, *sub = NULL; - uiBlock *block; - uiBut *but; - PointerRNA ptr; - int icon; - - /* make pointer to layer data */ - RNA_pointer_create((ID *)gpd, &RNA_GPencilLayer, gpl, &ptr); - - /* unless button has own callback, it adds this callback to button */ - block = uiLayoutGetBlock(layout); - uiBlockSetFunc(block, gp_ui_activelayer_cb, gpd, gpl); - - /* draw header ---------------------------------- */ - /* get layout-row + UI-block for header */ - box = uiLayoutBox(layout); - - row = uiLayoutRow(box, false); - uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_EXPAND); - block = uiLayoutGetBlock(row); /* err... */ - - uiBlockSetEmboss(block, UI_EMBOSSN); - - /* left-align ............................... */ - sub = uiLayoutRow(row, false); - - /* active */ - block = uiLayoutGetBlock(sub); - icon = (gpl->flag & GP_LAYER_ACTIVE) ? ICON_RADIOBUT_ON : ICON_RADIOBUT_OFF; - but = uiDefIconButBitI(block, TOG, GP_LAYER_ACTIVE, 0, icon, 0, 0, UI_UNIT_X, UI_UNIT_Y, - &gpl->flag, 0.0, 0.0, 0.0, 0.0, TIP_("Set active layer")); - uiButSetFunc(but, gp_ui_activelayer_cb, gpd, gpl); - - /* locked */ - icon = (gpl->flag & GP_LAYER_LOCKED) ? ICON_LOCKED : ICON_UNLOCKED; - uiItemR(sub, &ptr, "lock", 0, "", icon); - - /* when layer is locked or hidden, only draw header */ - if (gpl->flag & (GP_LAYER_LOCKED | GP_LAYER_HIDE)) { - char name[256]; /* gpl->info is 128, but we need space for 'locked/hidden' as well */ - - /* visibility button (only if hidden but not locked!) */ - if ((gpl->flag & GP_LAYER_HIDE) && !(gpl->flag & GP_LAYER_LOCKED)) - uiItemR(sub, &ptr, "hide", 0, "", ICON_RESTRICT_VIEW_ON); - - /* name */ - if (gpl->flag & GP_LAYER_HIDE) - BLI_snprintf(name, sizeof(name), IFACE_("%s (Hidden)"), gpl->info); - else - BLI_snprintf(name, sizeof(name), IFACE_("%s (Locked)"), gpl->info); - uiItemL(sub, name, ICON_NONE); - - /* delete button (only if hidden but not locked!) */ - if ((gpl->flag & GP_LAYER_HIDE) && !(gpl->flag & GP_LAYER_LOCKED)) { - /* right-align ............................... */ - sub = uiLayoutRow(row, true); - uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_RIGHT); - block = uiLayoutGetBlock(sub); /* XXX... err... */ - - but = uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, - NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Delete layer")); - uiButSetFunc(but, gp_ui_dellayer_cb, gpd, gpl); - } - uiBlockSetEmboss(block, UI_EMBOSS); - } - else { - /* draw rest of header -------------------------------- */ - /* visibility button */ - uiItemR(sub, &ptr, "hide", 0, "", ICON_RESTRICT_VIEW_OFF); - - /* frame locking */ - /* TODO: this needs its own icons... */ - icon = (gpl->flag & GP_LAYER_FRAMELOCK) ? ICON_RENDER_STILL : ICON_RENDER_ANIMATION; - uiItemR(sub, &ptr, "lock_frame", 0, "", icon); - - uiBlockSetEmboss(block, UI_EMBOSS); - - /* name */ - uiItemR(sub, &ptr, "info", 0, "", ICON_NONE); - - /* move up/down */ - uiBlockBeginAlign(block); - - if (gpl->prev) { - but = uiDefIconBut(block, BUT, 0, ICON_TRIA_UP, 0, 0, UI_UNIT_X, UI_UNIT_Y, - NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Move layer up")); - uiButSetFunc(but, gp_ui_layer_up_cb, gpd, gpl); - } - if (gpl->next) { - but = uiDefIconBut(block, BUT, 0, ICON_TRIA_DOWN, 0, 0, UI_UNIT_X, UI_UNIT_Y, - NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Move layer down")); - uiButSetFunc(but, gp_ui_layer_down_cb, gpd, gpl); - } - - uiBlockEndAlign(block); - - /* delete 'button' */ - uiBlockSetEmboss(block, UI_EMBOSSN); - /* right-align ............................... */ - sub = uiLayoutRow(row, true); - uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_RIGHT); - block = uiLayoutGetBlock(sub); /* XXX... err... */ - - but = uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, - NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Delete layer")); - uiButSetFunc(but, gp_ui_dellayer_cb, gpd, gpl); - uiBlockSetEmboss(block, UI_EMBOSS); - - /* new backdrop ----------------------------------- */ - box = uiLayoutBox(layout); - split = uiLayoutSplit(box, 0.5f, false); - - /* draw settings ---------------------------------- */ - /* left column ..................... */ - col = uiLayoutColumn(split, false); - - /* color */ - sub = uiLayoutColumn(col, true); - uiItemR(sub, &ptr, "color", 0, "", ICON_NONE); - uiItemR(sub, &ptr, "alpha", UI_ITEM_R_SLIDER, NULL, ICON_NONE); - - /* stroke thickness */ - uiItemR(col, &ptr, "line_width", UI_ITEM_R_SLIDER, NULL, ICON_NONE); - - /* debugging options */ - if (G.debug & G_DEBUG) { - uiItemR(col, &ptr, "show_points", 0, NULL, ICON_NONE); - } - - /* right column ................... */ - col = uiLayoutColumn(split, false); - - /* onion-skinning */ - sub = uiLayoutColumn(col, true); - uiItemR(sub, &ptr, "use_onion_skinning", 0, NULL, ICON_NONE); - uiItemR(sub, &ptr, "ghost_range_max", 0, IFACE_("Frames"), ICON_NONE); - - /* 3d-view specific drawing options */ - if (is_v3d) { - uiItemR(col, &ptr, "show_x_ray", 0, NULL, ICON_NONE); - } - } -} - -/* stroke drawing options available */ -typedef enum eGP_Stroke_Ops { - STROKE_OPTS_NORMAL = 0, - STROKE_OPTS_V3D_OFF, - STROKE_OPTS_V3D_ON, -} eGP_Stroke_Ops; - -static void draw_gpencil_space_specials(const bContext *C, uiLayout *layout) -{ - uiLayout *col, *row; - SpaceClip *sc = CTX_wm_space_clip(C); - - col = uiLayoutColumn(layout, false); - - if (sc) { - bScreen *screen = CTX_wm_screen(C); - PointerRNA sc_ptr; - - RNA_pointer_create(&screen->id, &RNA_SpaceClipEditor, sc, &sc_ptr); - row = uiLayoutRow(col, true); - uiItemR(row, &sc_ptr, "grease_pencil_source", UI_ITEM_R_EXPAND, NULL, ICON_NONE); - } -} - -/* Draw the contents for a grease-pencil panel*/ -static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, PointerRNA *ctx_ptr) -{ - PointerRNA gpd_ptr; - bGPDlayer *gpl; - uiLayout *col, *row; - SpaceClip *sc = CTX_wm_space_clip(C); - short v3d_stroke_opts = STROKE_OPTS_NORMAL; - const bool is_v3d = CTX_wm_view3d(C) != NULL; - - /* make new PointerRNA for Grease Pencil block */ - RNA_id_pointer_create((ID *)gpd, &gpd_ptr); - - /* draw gpd settings first ------------------------------------- */ - col = uiLayoutColumn(layout, false); - - /* current Grease Pencil block */ - /* TODO: show some info about who owns this? */ - uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_add", NULL, "GPENCIL_OT_data_unlink"); - - /* add new layer button - can be used even when no data, since it can add a new block too */ - uiItemO(col, IFACE_("New Layer"), ICON_NONE, "GPENCIL_OT_layer_add"); - row = uiLayoutRow(col, true); - uiItemO(row, IFACE_("Delete Frame"), ICON_NONE, "GPENCIL_OT_active_frame_delete"); - uiItemO(row, IFACE_("Convert"), ICON_NONE, "GPENCIL_OT_convert"); - - /* sanity checks... */ - if (gpd == NULL) - return; - - /* draw each layer --------------------------------------------- */ - for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { - col = uiLayoutColumn(layout, true); - gp_drawui_layer(col, gpd, gpl, is_v3d); - } - - /* draw gpd drawing settings first ------------------------------------- */ - col = uiLayoutColumn(layout, true); - /* label */ - uiItemL(col, IFACE_("Drawing Settings:"), ICON_NONE); - - /* check whether advanced 3D-View drawing space options can be used */ - if (is_v3d) { - if (gpd->flag & (GP_DATA_DEPTH_STROKE | GP_DATA_DEPTH_VIEW)) - v3d_stroke_opts = STROKE_OPTS_V3D_ON; - else - v3d_stroke_opts = STROKE_OPTS_V3D_OFF; - } - - /* drawing space options */ - row = uiLayoutRow(col, true); - uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "VIEW", NULL, ICON_NONE); - uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "CURSOR", NULL, ICON_NONE); - - if (sc == NULL) { - row = uiLayoutRow(col, true); - uiLayoutSetActive(row, v3d_stroke_opts); - uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "SURFACE", NULL, ICON_NONE); - uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "STROKE", NULL, ICON_NONE); - - row = uiLayoutRow(col, false); - uiLayoutSetActive(row, v3d_stroke_opts == STROKE_OPTS_V3D_ON); - uiItemR(row, &gpd_ptr, "use_stroke_endpoints", 0, NULL, ICON_NONE); - } -} - -void ED_gpencil_panel_standard_header(const bContext *C, Panel *pa) -{ - PointerRNA ptr; - RNA_pointer_create((ID *)CTX_wm_screen(C), &RNA_Space, CTX_wm_space_data(C), &ptr); - - uiItemR(pa->layout, &ptr, "show_grease_pencil", 0, "", ICON_NONE); -} - -/* Standard panel to be included wherever Grease Pencil is used... */ -void ED_gpencil_panel_standard(const bContext *C, Panel *pa) -{ - bGPdata **gpd_ptr = NULL; - PointerRNA ptr; - - /* if (v3d->flag2 & V3D_DISPGP)... etc. */ - - draw_gpencil_space_specials(C, pa->layout); - - /* get pointer to Grease Pencil Data */ - gpd_ptr = ED_gpencil_data_get_pointers((bContext *)C, &ptr); - - if (gpd_ptr) - draw_gpencil_panel((bContext *)C, pa->layout, *gpd_ptr, &ptr); -} - -/* ************************************************** */ diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 13334448941..63f34917a4d 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -86,35 +86,44 @@ /* ************************************************ */ /* Context Wrangling... */ -/* Get pointer to active Grease Pencil datablock, and an RNA-pointer to trace back to whatever owns it */ -bGPdata **ED_gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr) +/* Get pointer to active Grease Pencil datablock, and an RNA-pointer to trace back to whatever owns it, + * when context info is not available. + */ +bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrArea *sa, Object *ob, PointerRNA *ptr) { - ID *screen_id = (ID *)CTX_wm_screen(C); - Scene *scene = CTX_data_scene(C); - ScrArea *sa = CTX_wm_area(C); - /* if there's an active area, check if the particular editor may * have defined any special Grease Pencil context for editing... */ if (sa) { + SpaceLink *sl = sa->spacedata.first; + switch (sa->spacetype) { case SPACE_VIEW3D: /* 3D-View */ + case SPACE_TIME: /* Timeline - XXX: this is a hack to get it to show GP keyframes for 3D view */ { - Object *ob = CTX_data_active_object(C); - - /* TODO: we can include other data-types such as bones later if need be... */ - - /* just in case no active/selected object */ - if (ob && (ob->flag & SELECT)) { - /* for now, as long as there's an object, default to using that in 3D-View */ - if (ptr) RNA_id_pointer_create(&ob->id, ptr); - return &ob->gpd; + BLI_assert(scene && ELEM(scene->toolsettings->gpencil_src, + GP_TOOL_SOURCE_SCENE, GP_TOOL_SOURCE_OBJECT)); + + if (scene->toolsettings->gpencil_src == GP_TOOL_SOURCE_OBJECT) { + /* legacy behaviour for usage with old addons requiring object-linked to objects */ + + /* just in case no active/selected object... */ + if (ob && (ob->flag & SELECT)) { + /* for now, as long as there's an object, default to using that in 3D-View */ + if (ptr) RNA_id_pointer_create(&ob->id, ptr); + return &ob->gpd; + } + /* else: defaults to scene... */ + } + else { + if (ptr) RNA_id_pointer_create(&scene->id, ptr); + return &scene->gpd; } break; } case SPACE_NODE: /* Nodes Editor */ { - SpaceNode *snode = (SpaceNode *)CTX_wm_space_data(C); + SpaceNode *snode = (SpaceNode *)sl; /* return the GP data for the active node block/node */ if (snode && snode->nodetree) { @@ -128,7 +137,7 @@ bGPdata **ED_gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr) } case SPACE_SEQ: /* Sequencer */ { - SpaceSeq *sseq = (SpaceSeq *)CTX_wm_space_data(C); + SpaceSeq *sseq = (SpaceSeq *)sl; /* for now, Grease Pencil data is associated with the space (actually preview region only) */ /* XXX our convention for everything else is to link to data though... */ @@ -137,7 +146,7 @@ bGPdata **ED_gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr) } case SPACE_IMAGE: /* Image/UV Editor */ { - SpaceImage *sima = (SpaceImage *)CTX_wm_space_data(C); + SpaceImage *sima = (SpaceImage *)sl; /* for now, Grease Pencil data is associated with the space... */ /* XXX our convention for everything else is to link to data though... */ @@ -146,7 +155,7 @@ bGPdata **ED_gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr) } case SPACE_CLIP: /* Nodes Editor */ { - SpaceClip *sc = (SpaceClip *)CTX_wm_space_data(C); + SpaceClip *sc = (SpaceClip *)sl; MovieClip *clip = ED_space_clip_get_clip(sc); if (clip) { @@ -180,6 +189,26 @@ bGPdata **ED_gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr) return (scene) ? &scene->gpd : NULL; } +/* Get pointer to active Grease Pencil datablock, and an RNA-pointer to trace back to whatever owns it */ +bGPdata **ED_gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr) +{ + ID *screen_id = (ID *)CTX_wm_screen(C); + Scene *scene = CTX_data_scene(C); + ScrArea *sa = CTX_wm_area(C); + Object *ob = CTX_data_active_object(C); + + return ED_gpencil_data_get_pointers_direct(screen_id, scene, sa, ob, ptr); +} + +/* -------------------------------------------------------- */ + +/* Get the active Grease Pencil datablock, when context is not available */ +bGPdata *ED_gpencil_data_get_active_direct(ID *screen_id, Scene *scene, ScrArea *sa, Object *ob) +{ + bGPdata **gpd_ptr = ED_gpencil_data_get_pointers_direct(screen_id, scene, sa, ob, NULL); + return (gpd_ptr) ? *(gpd_ptr) : NULL; +} + /* Get the active Grease Pencil datablock */ bGPdata *ED_gpencil_data_get_active(const bContext *C) { @@ -187,6 +216,8 @@ bGPdata *ED_gpencil_data_get_active(const bContext *C) return (gpd_ptr) ? *(gpd_ptr) : NULL; } +/* -------------------------------------------------------- */ + bGPdata *ED_gpencil_data_get_active_v3d(Scene *scene, View3D *v3d) { Base *base = scene->basact; @@ -211,6 +242,15 @@ static int gp_add_poll(bContext *C) return ED_gpencil_data_get_pointers(C, NULL) != NULL; } +/* poll callback for checking if there is an active layer */ +static int gp_active_layer_poll(bContext *C) +{ + bGPdata *gpd = ED_gpencil_data_get_active(C); + bGPDlayer *gpl = gpencil_layer_getactive(gpd); + + return (gpl != NULL); +} + /* ******************* Add New Data ************************ */ /* add new datablock - wrapper around API */ @@ -327,13 +367,268 @@ void GPENCIL_OT_layer_add(wmOperatorType *ot) ot->name = "Add New Layer"; ot->idname = "GPENCIL_OT_layer_add"; ot->description = "Add new Grease Pencil layer for the active Grease Pencil datablock"; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + /* callbacks */ ot->exec = gp_layer_add_exec; ot->poll = gp_add_poll; } +/* ******************* Remove Active Layer ************************* */ + +static int gp_layer_remove_exec(bContext *C, wmOperator *op) +{ + bGPdata *gpd = ED_gpencil_data_get_active(C); + bGPDlayer *gpl = gpencil_layer_getactive(gpd); + + /* sanity checks */ + if (ELEM(NULL, gpd, gpl)) + return OPERATOR_CANCELLED; + + if (gpl->flag & GP_LAYER_LOCKED) { + BKE_report(op->reports, RPT_ERROR, "Cannot delete locked layers"); + return OPERATOR_CANCELLED; + } + + /* make the layer before this the new active layer + * - use the one after if this is the first + * - if this is the only layer, this naturally becomes NULL + */ + if (gpl->prev) + gpencil_layer_setactive(gpd, gpl->prev); + else + gpencil_layer_setactive(gpd, gpl->next); + + /* delete the layer now... */ + gpencil_layer_delete(gpd, gpl); + + /* notifiers */ + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_layer_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Layer"; + ot->idname = "GPENCIL_OT_layer_remove"; + ot->description = "Remove active Grease Pencil layer"; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* callbacks */ + ot->exec = gp_layer_remove_exec; + ot->poll = gp_active_layer_poll; +} + +/* ******************* Move Layer Up/Down ************************** */ + +enum { + GP_LAYER_MOVE_UP = -1, + GP_LAYER_MOVE_DOWN = 1 +}; + +static int gp_layer_move_exec(bContext *C, wmOperator *op) +{ + bGPdata *gpd = ED_gpencil_data_get_active(C); + bGPDlayer *gpl = gpencil_layer_getactive(gpd); + + int direction = RNA_enum_get(op->ptr, "type"); + + /* sanity checks */ + if (ELEM(NULL, gpd, gpl)) + return OPERATOR_CANCELLED; + + /* up or down? */ + if (direction == GP_LAYER_MOVE_UP) { + /* up */ + BLI_remlink(&gpd->layers, gpl); + BLI_insertlinkbefore(&gpd->layers, gpl->prev, gpl); + } + else { + /* down */ + BLI_remlink(&gpd->layers, gpl); + BLI_insertlinkafter(&gpd->layers, gpl->next, gpl); + } + + /* notifiers */ + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_layer_move(wmOperatorType *ot) +{ + static EnumPropertyItem slot_move[] = { + {GP_LAYER_MOVE_UP, "UP", 0, "Up", ""}, + {GP_LAYER_MOVE_DOWN, "DOWN", 0, "Down", ""}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name = "Move Grease Pencil Layer"; + ot->idname = "GPENCIL_OT_layer_move"; + ot->description = "Move the active Grease Pencil layer up/down in the list"; + + /* api callbacks */ + ot->exec = gp_layer_move_exec; + ot->poll = gp_active_layer_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + ot->prop = RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", ""); +} + +/* ************************************************ */ +/* Stroke Editing Operators */ + +/* poll callback for all stroke editing operators */ +static int gp_stroke_edit_poll(bContext *C) +{ + /* NOTE: this is a bit slower, but is the most accurate... */ + return CTX_DATA_COUNT(C, editable_gpencil_strokes) != 0; +} + +/* ************** Duplicate Selected Strokes **************** */ + +/* Make copies of selected point segments in a selected stroke */ +static void gp_duplicate_points(const bGPDstroke *gps, ListBase *new_strokes) +{ + bGPDspoint *pt; + int i; + + int start_idx = -1; + + + /* Step through the original stroke's points: + * - We accumulate selected points (from start_idx to current index) + * and then convert that to a new stroke + */ + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + /* searching for start, are waiting for end? */ + if (start_idx == -1) { + /* is this the first selected point for a new island? */ + if (pt->flag & GP_SPOINT_SELECT) { + start_idx = i; + } + } + else { + size_t len = 0; + + /* is this the end of current island yet? + * 1) Point i-1 was the last one that was selected + * 2) Point i is the last in the array + */ + if ((pt->flag & GP_SPOINT_SELECT) == 0) { + len = i - start_idx; + } + else if (i == gps->totpoints - 1) { + len = i - start_idx + 1; + } + //printf("copying from %d to %d = %d\n", start_idx, i, len); + + /* make copies of the relevant data */ + if (len) { + bGPDstroke *gpsd; + + /* make a stupid copy first of the entire stroke (to get the flags too) */ + gpsd = MEM_dupallocN(gps); + + /* now, make a new points array, and copy of the relevant parts */ + gpsd->points = MEM_callocN(sizeof(bGPDspoint) * len, "gps stroke points copy"); + memcpy(gpsd->points, gps->points + start_idx, sizeof(bGPDspoint) * len); + gpsd->totpoints = len; + + /* add to temp buffer */ + gpsd->next = gpsd->prev = NULL; + BLI_addtail(new_strokes, gpsd); + + /* cleanup + reset for next */ + start_idx = -1; + } + } + } +} + +static int gp_duplicate_exec(bContext *C, wmOperator *op) +{ + bGPdata *gpd = ED_gpencil_data_get_active(C); + + if (gpd == NULL) { + BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data"); + return OPERATOR_CANCELLED; + } + + /* for each visible (and editable) layer's selected strokes, + * copy the strokes into a temporary buffer, then append + * once all done + */ + CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers) + { + ListBase new_strokes = {NULL, NULL}; + bGPDframe *gpf = gpl->actframe; + bGPDstroke *gps; + + if (gpf == NULL) + continue; + + /* make copies of selected strokes, and deselect these once we're done */ + for (gps = gpf->strokes.first; gps; gps = gps->next) { + if (gps->flag & GP_STROKE_SELECT) { + if (gps->totpoints == 1) { + /* Special Case: If there's just a single point in this stroke... */ + bGPDstroke *gpsd; + + /* make direct copies of the stroke and its points */ + gpsd = MEM_dupallocN(gps); + gpsd->points = MEM_dupallocN(gps->points); + + /* add to temp buffer */ + gpsd->next = gpsd->prev = NULL; + BLI_addtail(&new_strokes, gpsd); + } + else { + /* delegate to a helper, as there's too much to fit in here (for copying subsets)... */ + gp_duplicate_points(gps, &new_strokes); + } + + /* deselect original stroke, or else the originals get moved too + * (when using the copy + move macro) + */ + gps->flag &= ~GP_STROKE_SELECT; + } + } + + /* add all new strokes in temp buffer to the frame (preventing double-copies) */ + BLI_movelisttolist(&gpf->strokes, &new_strokes); + BLI_assert(new_strokes.first == NULL); + } + CTX_DATA_END; + + /* updates */ + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_duplicate(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Duplicate Strokes"; + ot->idname = "GPENCIL_OT_duplicate"; + ot->description = "Duplicate the selected Grease Pencil strokes"; + + /* callbacks */ + ot->exec = gp_duplicate_exec; + ot->poll = gp_stroke_edit_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /* ******************* Delete Active Frame ************************ */ static int gp_actframe_delete_poll(bContext *C) @@ -378,6 +673,7 @@ void GPENCIL_OT_active_frame_delete(wmOperatorType *ot) ot->name = "Delete Active Frame"; ot->idname = "GPENCIL_OT_active_frame_delete"; ot->description = "Delete the active frame for the active Grease Pencil datablock"; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* callbacks */ @@ -385,6 +681,307 @@ void GPENCIL_OT_active_frame_delete(wmOperatorType *ot) ot->poll = gp_actframe_delete_poll; } +/* ******************* Delete Operator ************************ */ + +typedef enum eGP_DeleteMode { + /* delete selected stroke points */ + GP_DELETEOP_POINTS = 0, + /* delete selected strokes */ + GP_DELETEOP_STROKES = 1, + /* delete active frame */ + GP_DELETEOP_FRAME = 2, + /* delete selected stroke points (without splitting stroke) */ + GP_DELETEOP_POINTS_DISSOLVE = 3, +} eGP_DeleteMode; + + +/* Delete selected strokes */ +static int gp_delete_selected_strokes(bContext *C) +{ + bool changed = false; + + CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers) + { + bGPDframe *gpf = gpl->actframe; + bGPDstroke *gps, *gpsn; + + if (gpf == NULL) + continue; + + /* simply delete strokes which are selected */ + for (gps = gpf->strokes.first; gps; gps = gpsn) { + gpsn = gps->next; + + if (gps->flag & GP_STROKE_SELECT) { + /* free stroke memory arrays, then stroke itself */ + if (gps->points) MEM_freeN(gps->points); + BLI_freelinkN(&gpf->strokes, gps); + + changed = true; + } + } + } + CTX_DATA_END; + + if (changed) { + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +/* Delete selected points but keep the stroke */ +static int gp_dissolve_selected_points(bContext *C) +{ + bool changed = false; + + CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers) + { + bGPDframe *gpf = gpl->actframe; + bGPDstroke *gps, *gpsn; + + if (gpf == NULL) + continue; + + /* simply delete points from selected strokes + * NOTE: we may still have to remove the stroke if it ends up having no points! + */ + for (gps = gpf->strokes.first; gps; gps = gpsn) { + gpsn = gps->next; + + if (gps->flag & GP_STROKE_SELECT) { + bGPDspoint *pt; + int i; + + int tot = gps->totpoints; /* number of points in new buffer */ + + /* First Pass: Count how many points are selected (i.e. how many to remove) */ + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) { + /* selected point - one of the points to remove */ + tot--; + } + } + + /* if no points are left, we simply delete the entire stroke */ + if (tot <= 0) { + /* remove the entire stroke */ + MEM_freeN(gps->points); + BLI_freelinkN(&gpf->strokes, gps); + } + else { + /* just copy all unselected into a smaller buffer */ + bGPDspoint *new_points = MEM_callocN(sizeof(bGPDspoint) * tot, "new gp stroke points copy"); + bGPDspoint *npt = new_points; + + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if ((pt->flag & GP_SPOINT_SELECT) == 0) { + *npt = *pt; + npt++; + } + } + + /* free the old buffer */ + MEM_freeN(gps->points); + + /* save the new buffer */ + gps->points = new_points; + gps->totpoints = tot; + + /* deselect the stroke, since none of its selected points will still be selected */ + gps->flag &= ~GP_STROKE_SELECT; + } + + changed = true; + } + } + } + CTX_DATA_END; + + if (changed) { + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +/* Split selected strokes into segments, splitting on selected points */ +static int gp_delete_selected_points(bContext *C) +{ + bool changed = false; + + CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers) + { + bGPDframe *gpf = gpl->actframe; + bGPDstroke *gps, *gpsn; + + if (gpf == NULL) + continue; + + /* simply delete strokes which are selected */ + for (gps = gpf->strokes.first; gps; gps = gpsn) { + gpsn = gps->next; + + if (gps->flag & GP_STROKE_SELECT) { + bGPDspoint *pt; + int i; + + /* The algorithm used here is as follows: + * 1) We firstly identify the number of "islands" of non-selected points + * which will all end up being in new strokes. + * - In the most extreme case (i.e. every other vert is a 1-vert island), + * we have at most n / 2 islands + * - Once we start having larger islands than that, the number required + * becomes much less + * 2) Each island gets converted to a new stroke + */ + typedef struct tGPDeleteIsland { + int start_idx; + int end_idx; + } tGPDeleteIsland; + + tGPDeleteIsland *islands = MEM_callocN(sizeof(tGPDeleteIsland) * (gps->totpoints + 1) / 2, "gp_point_islands"); + bool in_island = false; + int num_islands = 0; + + /* First Pass: Identify start/end of islands */ + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) { + /* selected - stop accumulating to island */ + in_island = false; + } + else { + /* unselected - start of a new island? */ + int idx; + + if (in_island) { + /* extend existing island */ + idx = num_islands - 1; + islands[idx].end_idx = i; + } + else { + /* start of new island */ + in_island = true; + num_islands++; + + idx = num_islands - 1; + islands[idx].start_idx = islands[idx].end_idx = i; + } + } + } + + /* Watch out for special case where No islands = All points selected = Delete Stroke only */ + if (num_islands) { + /* there are islands, so create a series of new strokes, adding them before the "next" stroke */ + int idx; + + /* deselect old stroke, since it will be used as template for the new strokes */ + gps->flag &= ~GP_STROKE_SELECT; + + /* create each new stroke... */ + for (idx = 0; idx < num_islands; idx++) { + tGPDeleteIsland *island = &islands[idx]; + bGPDstroke *new_stroke = MEM_dupallocN(gps); + + /* compute new buffer size (+ 1 needed as the endpoint index is "inclusive") */ + new_stroke->totpoints = island->end_idx - island->start_idx + 1; + new_stroke->points = MEM_callocN(sizeof(bGPDspoint) * new_stroke->totpoints, "gp delete stroke fragment"); + + /* copy over the relevant points */ + memcpy(new_stroke->points, gps->points + island->start_idx, sizeof(bGPDspoint) * new_stroke->totpoints); + + /* add new stroke to the frame */ + if (gpsn) { + BLI_insertlinkbefore(&gpf->strokes, gpsn, new_stroke); + } + else { + BLI_addtail(&gpf->strokes, new_stroke); + } + } + } + + /* free islands */ + MEM_freeN(islands); + + /* Delete the old stroke */ + MEM_freeN(gps->points); + BLI_freelinkN(&gpf->strokes, gps); + + changed = true; + } + } + } + CTX_DATA_END; + + if (changed) { + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + + +static int gp_delete_exec(bContext *C, wmOperator *op) +{ + eGP_DeleteMode mode = RNA_enum_get(op->ptr, "type"); + int result = OPERATOR_CANCELLED; + + switch (mode) { + case GP_DELETEOP_STROKES: /* selected strokes */ + result = gp_delete_selected_strokes(C); + break; + + case GP_DELETEOP_POINTS: /* selected points (breaks the stroke into segments) */ + result = gp_delete_selected_points(C); + break; + + case GP_DELETEOP_POINTS_DISSOLVE: /* selected points (without splitting the stroke) */ + result = gp_dissolve_selected_points(C); + break; + + case GP_DELETEOP_FRAME: /* active frame */ + result = gp_actframe_delete_exec(C, op); + break; + } + + return result; +} + +void GPENCIL_OT_delete(wmOperatorType *ot) +{ + static EnumPropertyItem prop_gpencil_delete_types[] = { + {GP_DELETEOP_POINTS, "POINTS", 0, "Points", "Delete selected points and split strokes into segments"}, + {GP_DELETEOP_STROKES, "STROKES", 0, "Strokes", "Delete selected strokes"}, + {GP_DELETEOP_FRAME, "FRAME", 0, "Frame", "Delete active frame"}, + {0, "", 0, NULL, NULL}, + {GP_DELETEOP_POINTS_DISSOLVE, "DISSOLVE_POINTS", 0, "Dissolve Points", + "Delete selected points without splitting strokes"}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name = "Delete..."; + ot->idname = "GPENCIL_OT_delete"; + ot->description = "Delete selected Grease Pencil strokes, vertices, or frames"; + + /* callbacks */ + ot->invoke = WM_menu_invoke; + ot->exec = gp_delete_exec; + ot->poll = gp_stroke_edit_poll; + + /* flags */ + ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER; + + /* props */ + ot->prop = RNA_def_enum(ot->srna, "type", prop_gpencil_delete_types, 0, "Type", "Method used for deleting Grease Pencil data"); +} + /* ************************************************ */ /* Grease Pencil to Data Operator */ diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index 28eb1355caf..12f231a47bf 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -31,15 +31,74 @@ #ifndef __GPENCIL_INTERN_H__ #define __GPENCIL_INTERN_H__ -/* internal exports only */ +#include "DNA_vec_types.h" -/* ***************************************************** */ -/* Operator Defines */ +/* internal exports only */ struct bGPdata; +struct bGPDstroke; +struct bGPDspoint; + +struct ARegion; +struct View2D; struct wmOperatorType; + +/* ***************************************************** */ +/* Internal API */ + +/* Stroke Coordinates API ------------------------------ */ +/* gpencil_utils.c */ + +typedef struct GP_SpaceConversion { + struct bGPdata *gpd; + struct bGPDlayer *gpl; + + struct ScrArea *sa; + struct ARegion *ar; + struct View2D *v2d; + + rctf *subrect; /* for using the camera rect within the 3d view */ + rctf subrect_data; + + float mat[4][4]; /* transform matrix on the strokes (introduced in [b770964]) */ +} GP_SpaceConversion; + + +/** + * Check whether a given stroke segment is inside a circular brush + * + * \param mval The current screen-space coordinates (midpoint) of the brush + * \param mvalo The previous screen-space coordinates (midpoint) of the brush (NOT CURRENTLY USED) + * \param rad The radius of the brush + * + * \param x0, y0 The screen-space x and y coordinates of the start of the stroke segment + * \param x1, y1 The screen-space x and y coordinates of the end of the stroke segment + */ +bool gp_stroke_inside_circle(const int mval[2], const int UNUSED(mvalo[2]), + int rad, int x0, int y0, int x1, int y1); + + +/** + * Init settings for stroke point space conversions + * + * \param[out] r_gsc The space conversion settings struct, populated with necessary params + */ +void gp_point_conversion_init(struct bContext *C, GP_SpaceConversion *r_gsc); + +/** + * Convert a Grease Pencil coordinate (i.e. can be 2D or 3D) to screenspace (2D) + * + * \param[out] r_x The screen-space x-coordinate of the point + * \param[out] r_y The screen-space y-coordinate of the point + */ +void gp_point_to_xy(GP_SpaceConversion *settings, struct bGPDstroke *gps, struct bGPDspoint *pt, + int *r_x, int *r_y); + +/* ***************************************************** */ +/* Operator Defines */ + /* drawing ---------- */ void GPENCIL_OT_draw(struct wmOperatorType *ot); @@ -52,12 +111,29 @@ typedef enum eGPencil_PaintModes { GP_PAINTMODE_DRAW_POLY } eGPencil_PaintModes; +/* stroke editing ----- */ + +void GPENCIL_OT_select(struct wmOperatorType *ot); +void GPENCIL_OT_select_all(struct wmOperatorType *ot); +void GPENCIL_OT_select_circle(struct wmOperatorType *ot); +void GPENCIL_OT_select_border(struct wmOperatorType *ot); +void GPENCIL_OT_select_lasso(struct wmOperatorType *ot); + +void GPENCIL_OT_select_linked(struct wmOperatorType *ot); +void GPENCIL_OT_select_more(struct wmOperatorType *ot); +void GPENCIL_OT_select_less(struct wmOperatorType *ot); + +void GPENCIL_OT_duplicate(struct wmOperatorType *ot); +void GPENCIL_OT_delete(struct wmOperatorType *ot); + /* buttons editing --- */ void GPENCIL_OT_data_add(struct wmOperatorType *ot); void GPENCIL_OT_data_unlink(struct wmOperatorType *ot); void GPENCIL_OT_layer_add(struct wmOperatorType *ot); +void GPENCIL_OT_layer_remove(struct wmOperatorType *ot); +void GPENCIL_OT_layer_move(struct wmOperatorType *ot); void GPENCIL_OT_active_frame_delete(struct wmOperatorType *ot); diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index 75ff0895931..072ef32a6eb 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -36,40 +36,170 @@ #include "BLI_blenlib.h" +#include "BKE_context.h" + +#include "DNA_gpencil_types.h" + #include "WM_api.h" #include "WM_types.h" #include "RNA_access.h" #include "ED_gpencil.h" +#include "ED_object.h" +#include "ED_transform.h" #include "gpencil_intern.h" /* ****************************************** */ -/* Generic Editing Keymap */ +/* Grease Pencil Keymaps */ -void ED_keymap_gpencil(wmKeyConfig *keyconf) +/* Generic Drawing Keymap */ +static void ed_keymap_gpencil_general(wmKeyConfig *keyconf) { wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil", 0, 0); wmKeyMapItem *kmi; - /* Draw */ - + /* Draw --------------------------------------- */ /* draw */ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, 0, DKEY); RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW); - + RNA_boolean_set(kmi->ptr, "wait_for_input", false); + /* draw - straight lines */ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_CTRL, DKEY); RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW_STRAIGHT); - + RNA_boolean_set(kmi->ptr, "wait_for_input", false); + /* draw - poly lines */ - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", RIGHTMOUSE, KM_PRESS, KM_CTRL, DKEY); + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_ALT, DKEY); RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW_POLY); - + RNA_boolean_set(kmi->ptr, "wait_for_input", false); + /* erase */ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", RIGHTMOUSE, KM_PRESS, 0, DKEY); RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_ERASER); + RNA_boolean_set(kmi->ptr, "wait_for_input", false); + + /* Viewport Tools ------------------------------- */ + + /* Enter EditMode */ + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, 0, DKEY); + RNA_string_set(kmi->ptr, "data_path", "gpencil_data.use_stroke_edit_mode"); + + /* Pie Menu - For standard tools */ + WM_keymap_add_menu_pie(keymap, "GPENCIL_PIE_tool_palette", QKEY, KM_PRESS, 0, DKEY); + WM_keymap_add_menu_pie(keymap, "GPENCIL_PIE_settings_palette", WKEY, KM_PRESS, 0, DKEY); +} + +/* ==================== */ + +/* Poll callback for stroke editing mode */ +static int gp_stroke_editmode_poll(bContext *C) +{ + bGPdata *gpd = CTX_data_gpencil_data(C); + return (gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)); +} + +/* Stroke Editing Keymap - Only when editmode is enabled */ +static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf) +{ + wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Edit Mode", 0, 0); + wmKeyMapItem *kmi; + + /* set poll callback - so that this keymap only gets enabled when stroke editmode is enabled */ + keymap->poll = gp_stroke_editmode_poll; + + /* ----------------------------------------------- */ + + /* Exit EditMode */ + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "gpencil_data.use_stroke_edit_mode"); + + /* Selection ------------------------------------- */ + /* select all */ + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_all", AKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); + + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + + /* circle select */ + WM_keymap_add_item(keymap, "GPENCIL_OT_select_circle", CKEY, KM_PRESS, 0, 0); + + /* border select */ + WM_keymap_add_item(keymap, "GPENCIL_OT_select_border", BKEY, KM_PRESS, 0, 0); + + /* lasso select */ + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "deselect", false); + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT | KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "deselect", true); + + /* normal select */ + WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); + + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "extend", true); + RNA_boolean_set(kmi->ptr, "toggle", true); + + /* whole stroke select */ + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "entire_strokes", true); + + /* select linked */ + WM_keymap_add_item(keymap, "GPENCIL_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0); + + /* select more/less */ + WM_keymap_add_item(keymap, "GPENCIL_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "GPENCIL_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0); + + + /* Editing ----------------------------------------- */ + + /* duplicate and move selected points */ + WM_keymap_add_item(keymap, "GPENCIL_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0); + + /* delete */ + WM_keymap_add_item(keymap, "GPENCIL_OT_delete", XKEY, KM_PRESS, 0, 0); + + + /* Transform Tools */ + kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", GKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "gpencil_strokes", true); + + kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", EVT_TWEAK_S, KM_ANY, 0, 0); + RNA_boolean_set(kmi->ptr, "gpencil_strokes", true); + + kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_rotate", RKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "gpencil_strokes", true); + + kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_resize", SKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "gpencil_strokes", true); + + kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_mirror", MKEY, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "gpencil_strokes", true); + + kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_bend", WKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "gpencil_strokes", true); + + WM_keymap_add_item(keymap, "TRANSFORM_OT_tosphere", SKEY, KM_PRESS, KM_ALT | KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "gpencil_strokes", true); + + WM_keymap_add_item(keymap, "TRANSFORM_OT_shear", SKEY, KM_PRESS, KM_ALT | KM_CTRL | KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "gpencil_strokes", true); + + /* Proportional Editing */ + ED_keymap_proportional_cycle(keyconf, keymap); + ED_keymap_proportional_editmode(keyconf, keymap, true); +} + +/* ==================== */ + +void ED_keymap_gpencil(wmKeyConfig *keyconf) +{ + ed_keymap_gpencil_general(keyconf); + ed_keymap_gpencil_editing(keyconf); } /* ****************************************** */ @@ -80,12 +210,29 @@ void ED_operatortypes_gpencil(void) WM_operatortype_append(GPENCIL_OT_draw); + /* Editing (Strokes) ------------ */ + + WM_operatortype_append(GPENCIL_OT_select); + WM_operatortype_append(GPENCIL_OT_select_all); + WM_operatortype_append(GPENCIL_OT_select_circle); + WM_operatortype_append(GPENCIL_OT_select_border); + WM_operatortype_append(GPENCIL_OT_select_lasso); + + WM_operatortype_append(GPENCIL_OT_select_linked); + WM_operatortype_append(GPENCIL_OT_select_more); + WM_operatortype_append(GPENCIL_OT_select_less); + + WM_operatortype_append(GPENCIL_OT_duplicate); + WM_operatortype_append(GPENCIL_OT_delete); + /* Editing (Buttons) ------------ */ WM_operatortype_append(GPENCIL_OT_data_add); WM_operatortype_append(GPENCIL_OT_data_unlink); WM_operatortype_append(GPENCIL_OT_layer_add); + WM_operatortype_append(GPENCIL_OT_layer_remove); + WM_operatortype_append(GPENCIL_OT_layer_move); WM_operatortype_append(GPENCIL_OT_active_frame_delete); @@ -94,4 +241,17 @@ void ED_operatortypes_gpencil(void) /* Editing (Time) --------------- */ } +void ED_operatormacros_gpencil(void) +{ + wmOperatorType *ot; + wmOperatorTypeMacro *otmacro; + + ot = WM_operatortype_append_macro("GPENCIL_OT_duplicate_move", "Duplicate Strokes", + "Make copies of the selected Grease Pencil strokes and move them", + OPTYPE_UNDO | OPTYPE_REGISTER); + WM_operatortype_macro_define(ot, "GPENCIL_OT_duplicate"); + otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); + RNA_boolean_set(otmacro->ptr, "gpencil_strokes", true); +} + /* ****************************************** */ diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index afecdd91599..692523f3ed6 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -86,6 +86,8 @@ typedef struct tGPsdata { rctf *subrect; /* for using the camera rect within the 3d view */ rctf subrect_data; + GP_SpaceConversion gsc; /* settings to pass to gp_points_to_xy() */ + PointerRNA ownerPtr; /* pointer to owner of gp-datablock */ bGPdata *gpd; /* gp-datablock layer comes from */ bGPDlayer *gpl; /* layer we're working on */ @@ -113,6 +115,7 @@ typedef struct tGPsdata { float imat[4][4]; /* inverted transformation matrix applying when converting coords from screen-space * to region space */ + float mat[4][4]; float custom_color[4]; /* custom color - hack for enforcing a particular color for track/mask editing */ @@ -874,53 +877,6 @@ static bool gp_stroke_eraser_is_occluded(tGPsdata *p, return false; } -/* eraser tool - check if part of stroke occurs within last segment drawn by eraser */ -static short gp_stroke_eraser_strokeinside(const int mval[2], const int UNUSED(mvalo[2]), - int rad, int x0, int y0, int x1, int y1) -{ - /* simple within-radius check for now */ - const float mval_fl[2] = {mval[0], mval[1]}; - const float screen_co_a[2] = {x0, y0}; - const float screen_co_b[2] = {x1, y1}; - - if (edge_inside_circle(mval_fl, rad, screen_co_a, screen_co_b)) { - return true; - } - - /* not inside */ - return false; -} - -static void gp_point_to_xy(ARegion *ar, View2D *v2d, rctf *subrect, bGPDstroke *gps, bGPDspoint *pt, - int *r_x, int *r_y) -{ - int xyval[2]; - - if (gps->flag & GP_STROKE_3DSPACE) { - if (ED_view3d_project_int_global(ar, &pt->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { - *r_x = xyval[0]; - *r_y = xyval[1]; - } - else { - *r_x = V2D_IS_CLIPPED; - *r_y = V2D_IS_CLIPPED; - } - } - else if (gps->flag & GP_STROKE_2DSPACE) { - UI_view2d_view_to_region_clip(v2d, pt->x, pt->y, r_x, r_y); - } - else { - if (subrect == NULL) { /* normal 3D view */ - *r_x = (int)(pt->x / 100 * ar->winx); - *r_y = (int)(pt->y / 100 * ar->winy); - } - else { /* camera view, use subrect */ - *r_x = (int)((pt->x / 100) * BLI_rctf_size_x(subrect)) + subrect->xmin; - *r_y = (int)((pt->y / 100) * BLI_rctf_size_y(subrect)) + subrect->ymin; - } - } -} - /* eraser tool - evaluation per stroke */ /* TODO: this could really do with some optimization (KD-Tree/BVH?) */ @@ -939,7 +895,7 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, BLI_freelinkN(&gpf->strokes, gps); } else if (gps->totpoints == 1) { - gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, gps->points, &x0, &y0); + gp_point_to_xy(&p->gsc, gps, gps->points, &x0, &y0); /* do boundbox check first */ if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) { @@ -960,8 +916,8 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, pt1 = gps->points + i; pt2 = gps->points + i + 1; - gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, pt1, &x0, &y0); - gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, pt2, &x1, &y1); + gp_point_to_xy(&p->gsc, gps, pt1, &x0, &y0); + gp_point_to_xy(&p->gsc, gps, pt2, &x1, &y1); /* check that point segment of the boundbox of the eraser stroke */ if (((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) || @@ -971,7 +927,7 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, * eraser region (either within stroke painted, or on its lines) * - this assumes that linewidth is irrelevant */ - if (gp_stroke_eraser_strokeinside(mval, mvalo, rad, x0, y0, x1, y1)) { + if (gp_stroke_inside_circle(mval, mvalo, rad, x0, y0, x1, y1)) { if ((gp_stroke_eraser_is_occluded(p, pt1, x0, y0) == false) || (gp_stroke_eraser_is_occluded(p, pt2, x1, y1) == false)) { @@ -1062,6 +1018,7 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) p->win = CTX_wm_window(C); unit_m4(p->imat); + unit_m4(p->mat); switch (curarea->spacetype) { /* supported views first */ @@ -1148,6 +1105,9 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) p->imat[3][0] -= marker->pos[0]; p->imat[3][1] -= marker->pos[1]; } + + invert_m4_m4(p->mat, p->imat); + copy_m4_m4(p->gsc.mat, p->mat); break; } /* unsupported views */ @@ -1283,7 +1243,21 @@ static void gp_paint_initstroke(tGPsdata *p, short paintmode) } } } - + + /* init stroke point space-conversion settings... */ + p->gsc.gpd = p->gpd; + p->gsc.gpl = p->gpl; + + p->gsc.sa = p->sa; + p->gsc.ar = p->ar; + p->gsc.v2d = p->v2d; + + p->gsc.subrect_data = p->subrect_data; + p->gsc.subrect = p->subrect; + + copy_m4_m4(p->gsc.mat, p->mat); + + /* check if points will need to be made in view-aligned space */ if (p->gpd->flag & GP_DATA_VIEWALIGN) { switch (p->sa->spacetype) { @@ -1765,11 +1739,8 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event else WM_cursor_modal_set(win, BC_PAINTBRUSHCURSOR); - /* special hack: if there was an initial event, then we were invoked via a hotkey, and - * painting should start immediately. Otherwise, this was called from a toolbar, in which - * case we should wait for the mouse to be clicked. - */ - if (event->val == KM_PRESS) { + /* only start drawing immediately if we're allowed to do so... */ + if (RNA_boolean_get(op->ptr, "wait_for_input") == false) { /* hotkey invoked - start drawing */ /* printf("\tGP - set first spot\n"); */ p->status = GP_STATUS_PAINTING; @@ -1861,8 +1832,11 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) /* we don't pass on key events, GP is used with key-modifiers - prevents Dkey to insert drivers */ if (ISKEYBOARD(event->type)) { - if (ELEM(event->type, LEFTARROWKEY, DOWNARROWKEY, RIGHTARROWKEY, UPARROWKEY)) { - /* allow some keys - for frame changing: [#33412] */ + if (ELEM(event->type, LEFTARROWKEY, DOWNARROWKEY, RIGHTARROWKEY, UPARROWKEY, ZKEY)) { + /* allow some keys: + * - for frame changing [#33412] + * - for undo (during sketching sessions) + */ } else { estate = OPERATOR_RUNNING_MODAL; @@ -2046,6 +2020,8 @@ void GPENCIL_OT_draw(wmOperatorType *ot) /* settings for drawing */ ot->prop = RNA_def_enum(ot->srna, "mode", prop_gpencil_drawmodes, 0, "Mode", "Way to interpret mouse movements"); - RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", ""); + + /* NOTE: wait for input is enabled by default, so that all UI code can work properly without needing users to know about this */ + RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "Wait for first click instead of painting immediately"); } diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c new file mode 100644 index 00000000000..6478af8c306 --- /dev/null +++ b/source/blender/editors/gpencil/gpencil_select.c @@ -0,0 +1,943 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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) 2014, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/gpencil/gpencil_select.c + * \ingroup edgpencil + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stddef.h> +#include <math.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_math.h" +#include "BLI_blenlib.h" +#include "BLI_lasso.h" +#include "BLI_utildefines.h" + +#include "DNA_gpencil_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_context.h" +#include "BKE_curve.h" +#include "BKE_depsgraph.h" +#include "BKE_global.h" +#include "BKE_gpencil.h" +#include "BKE_library.h" +#include "BKE_object.h" +#include "BKE_report.h" +#include "BKE_scene.h" +#include "BKE_screen.h" + +#include "UI_interface.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "UI_view2d.h" + +#include "ED_gpencil.h" +#include "ED_view3d.h" +#include "ED_keyframing.h" + +#include "gpencil_intern.h" + +/* ********************************************** */ +/* Polling callbacks */ + +static int gpencil_select_poll(bContext *C) +{ + bGPdata *gpd = ED_gpencil_data_get_active(C); + bGPDlayer *gpl = gpencil_layer_getactive(gpd); + + /* only if there's an active layer with an active frame */ + return (gpl && gpl->actframe); +} + +/* ********************************************** */ +/* Select All Operator */ + +static int gpencil_select_all_exec(bContext *C, wmOperator *op) +{ + bGPdata *gpd = ED_gpencil_data_get_active(C); + int action = RNA_enum_get(op->ptr, "action"); + + if (gpd == NULL) { + BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data"); + return OPERATOR_CANCELLED; + } + + /* for "toggle", test for existing selected strokes */ + if (action == SEL_TOGGLE) { + action = SEL_SELECT; + + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + if (gps->flag & GP_STROKE_SELECT) { + action = SEL_DESELECT; + break; // XXX: this only gets out of the inner loop... + } + } + CTX_DATA_END; + } + + /* if deselecting, we need to deselect strokes across all frames + * - Currently, an exception is only given for deselection + * Selecting and toggling should only affect what's visible, + * while deselecting helps clean up unintended/forgotten + * stuff on other frames + */ + if (action == SEL_DESELECT) { + /* deselect strokes across editable layers + * NOTE: we limit ourselves to editable layers, since once a layer is "locked/hidden + * nothing should be able to touch it + */ + CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers) + { + bGPDframe *gpf; + + /* deselect all strokes on all frames */ + for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { + bGPDstroke *gps; + + for (gps = gpf->strokes.first; gps; gps = gps->next) { + bGPDspoint *pt; + int i; + + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + pt->flag &= ~GP_SPOINT_SELECT; + } + + gps->flag &= ~GP_STROKE_SELECT; + } + } + } + CTX_DATA_END; + } + else { + /* select or deselect all strokes */ + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + bGPDspoint *pt; + int i; + bool selected = false; + + /* Change selection status of all points, then make the stroke match */ + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + switch (action) { + case SEL_SELECT: + pt->flag |= GP_SPOINT_SELECT; + break; + //case SEL_DESELECT: + // pt->flag &= ~GP_SPOINT_SELECT; + // break; + case SEL_INVERT: + pt->flag ^= GP_SPOINT_SELECT; + break; + } + + if (pt->flag & GP_SPOINT_SELECT) + selected = true; + } + + /* Change status of stroke */ + if (selected) + gps->flag |= GP_STROKE_SELECT; + else + gps->flag &= ~GP_STROKE_SELECT; + } + CTX_DATA_END; + } + + /* updates */ + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_select_all(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "(De)select All Strokes"; + ot->idname = "GPENCIL_OT_select_all"; + ot->description = "Change selection of all Grease Pencil strokes currently visible"; + + /* callbacks */ + ot->exec = gpencil_select_all_exec; + ot->poll = gpencil_select_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + WM_operator_properties_select_all(ot); +} + +/* ********************************************** */ +/* Select Linked */ + +static int gpencil_select_linked_exec(bContext *C, wmOperator *op) +{ + bGPdata *gpd = ED_gpencil_data_get_active(C); + + if (gpd == NULL) { + BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data"); + return OPERATOR_CANCELLED; + } + + /* select all points in selected strokes */ + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + if (gps->flag & GP_STROKE_SELECT) { + bGPDspoint *pt; + int i; + + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + pt->flag |= GP_SPOINT_SELECT; + } + } + } + CTX_DATA_END; + + /* updates */ + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_select_linked(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Linked"; + ot->idname = "GPENCIL_OT_select_linked"; + ot->description = "Select all points in same strokes as already selected points"; + + /* callbacks */ + ot->exec = gpencil_select_linked_exec; + ot->poll = gpencil_select_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/* ********************************************** */ +/* Select More */ + +static int gpencil_select_more_exec(bContext *C, wmOperator *UNUSED(op)) +{ + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + if (gps->flag & GP_STROKE_SELECT) { + bGPDspoint *pt; + int i; + bool prev_sel; + + /* First Pass: Go in forward order, expanding selection if previous was selected (pre changes)... + * - This pass covers the "after" edges of selection islands + */ + prev_sel = false; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) { + /* selected point - just set flag for next point */ + prev_sel = true; + } + else { + /* unselected point - expand selection if previous was selected... */ + if (prev_sel) { + pt->flag |= GP_SPOINT_SELECT; + } + prev_sel = false; + } + } + + /* Second Pass: Go in reverse order, doing the same as before (except in opposite order) + * - This pass covers the "before" edges of selection islands + */ + prev_sel = false; + for (pt -= 1; i > 0; i--, pt--) { + if (pt->flag & GP_SPOINT_SELECT) { + prev_sel = true; + } + else { + /* unselected point - expand selection if previous was selected... */ + if (prev_sel) { + pt->flag |= GP_SPOINT_SELECT; + } + prev_sel = false; + } + } + } + } + CTX_DATA_END; + + /* updates */ + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_select_more(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select More"; + ot->idname = "GPENCIL_OT_select_more"; + ot->description = "Grow sets of selected Grease Pencil points"; + + /* callbacks */ + ot->exec = gpencil_select_more_exec; + ot->poll = gpencil_select_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/* ********************************************** */ +/* Select Less */ + +static int gpencil_select_less_exec(bContext *C, wmOperator *UNUSED(op)) +{ + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + if (gps->flag & GP_STROKE_SELECT) { + bGPDspoint *pt; + int i; + bool prev_sel; + + /* First Pass: Go in forward order, shrinking selection if previous was not selected (pre changes)... + * - This pass covers the "after" edges of selection islands + */ + prev_sel = false; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) { + /* shrink if previous wasn't selected */ + if (prev_sel == false) { + pt->flag &= ~GP_SPOINT_SELECT; + } + prev_sel = true; + } + else { + /* mark previous as being unselected - and hence, is trigger for shrinking */ + prev_sel = false; + } + } + + /* Second Pass: Go in reverse order, doing the same as before (except in opposite order) + * - This pass covers the "before" edges of selection islands + */ + prev_sel = false; + for (pt -= 1; i > 0; i--, pt--) { + if (pt->flag & GP_SPOINT_SELECT) { + /* shrink if previous wasn't selected */ + if (prev_sel == false) { + pt->flag &= ~GP_SPOINT_SELECT; + } + prev_sel = true; + } + else { + /* mark previous as being unselected - and hence, is trigger for shrinking */ + prev_sel = false; + } + } + } + } + CTX_DATA_END; + + /* updates */ + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_select_less(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Less"; + ot->idname = "GPENCIL_OT_select_less"; + ot->description = "Shrink sets of selected Grease Pencil points"; + + /* callbacks */ + ot->exec = gpencil_select_less_exec; + ot->poll = gpencil_select_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/* ********************************************** */ +/* Circle Select Operator */ + +/* Helper to check if a given stroke is within the area */ +/* NOTE: Code here is adapted (i.e. copied directly) from gpencil_paint.c::gp_stroke_eraser_dostroke() + * It would be great to de-duplicate the logic here sometime, but that can wait... + */ +static bool gp_stroke_do_circle_sel(bGPDstroke *gps, GP_SpaceConversion *gsc, + const int mx, const int my, const int radius, + const bool select, rcti *rect) +{ + bGPDspoint *pt1, *pt2; + int x0 = 0, y0 = 0, x1 = 0, y1 = 0; + int i; + bool changed = false; + + if (gps->totpoints == 1) { + gp_point_to_xy(gsc, gps, gps->points, &x0, &y0); + + /* do boundbox check first */ + if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) { + /* only check if point is inside */ + if (((x0 - mx) * (x0 - mx) + (y0 - my) * (y0 - my)) <= radius * radius) { + /* change selection */ + if (select) { + gps->points->flag |= GP_SPOINT_SELECT; + gps->flag |= GP_STROKE_SELECT; + } + else { + gps->points->flag &= ~GP_SPOINT_SELECT; + gps->flag &= ~GP_STROKE_SELECT; + } + + return true; + } + } + } + else { + /* Loop over the points in the stroke, checking for intersections + * - an intersection means that we touched the stroke + */ + for (i = 0; (i + 1) < gps->totpoints; i++) { + /* get points to work with */ + pt1 = gps->points + i; + pt2 = gps->points + i + 1; + + gp_point_to_xy(gsc, gps, pt1, &x0, &y0); + gp_point_to_xy(gsc, gps, pt2, &x1, &y1); + + /* check that point segment of the boundbox of the selection stroke */ + if (((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) || + ((!ELEM(V2D_IS_CLIPPED, x1, y1)) && BLI_rcti_isect_pt(rect, x1, y1))) + { + int mval[2] = {mx, my}; + int mvalo[2] = {mx, my}; /* dummy - this isn't used... */ + + /* check if point segment of stroke had anything to do with + * eraser region (either within stroke painted, or on its lines) + * - this assumes that linewidth is irrelevant + */ + if (gp_stroke_inside_circle(mval, mvalo, radius, x0, y0, x1, y1)) { + /* change selection of stroke, and then of both points + * (as the last point otherwise wouldn't get selected + * as we only do n-1 loops through) + */ + if (select) { + pt1->flag |= GP_SPOINT_SELECT; + pt2->flag |= GP_SPOINT_SELECT; + + changed = true; + } + else { + pt1->flag &= ~GP_SPOINT_SELECT; + pt2->flag &= ~GP_SPOINT_SELECT; + + changed = true; + } + } + } + } + + /* Ensure that stroke selection is in sync with its points */ + gpencil_stroke_sync_selection(gps); + } + + return changed; +} + + +static int gpencil_circle_select_exec(bContext *C, wmOperator *op) +{ + ScrArea *sa = CTX_wm_area(C); + + const int mx = RNA_int_get(op->ptr, "x"); + const int my = RNA_int_get(op->ptr, "y"); + const int radius = RNA_int_get(op->ptr, "radius"); + + const int gesture_mode = RNA_int_get(op->ptr, "gesture_mode"); + const bool select = (gesture_mode == GESTURE_MODAL_SELECT); + + GP_SpaceConversion gsc = {NULL}; + rcti rect = {0}; /* for bounding rect around circle (for quicky intersection testing) */ + + bool changed = false; + + + /* sanity checks */ + if (sa == NULL) { + BKE_report(op->reports, RPT_ERROR, "No active area"); + return OPERATOR_CANCELLED; + } + + /* init space conversion stuff */ + gp_point_conversion_init(C, &gsc); + + + /* rect is rectangle of selection circle */ + rect.xmin = mx - radius; + rect.ymin = my - radius; + rect.xmax = mx + radius; + rect.ymax = my + radius; + + + /* find visible strokes, and select if hit */ + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + changed |= gp_stroke_do_circle_sel(gps, &gsc, mx, my, radius, select, &rect); + } + CTX_DATA_END; + + /* updates */ + if (changed) { + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); + } + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_select_circle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Circle Select"; + ot->description = "Select Grease Pencil strokes using brush selection"; + ot->idname = "GPENCIL_OT_select_circle"; + + /* callbacks */ + ot->invoke = WM_gesture_circle_invoke; + ot->modal = WM_gesture_circle_modal; + ot->exec = gpencil_circle_select_exec; + ot->poll = gpencil_select_poll; + ot->cancel = WM_gesture_circle_cancel; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "radius", 1, 1, INT_MAX, "Radius", "", 1, INT_MAX); + RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Gesture Mode", "", INT_MIN, INT_MAX); +} + +/* ********************************************** */ +/* Box Selection */ + +static int gpencil_border_select_exec(bContext *C, wmOperator *op) +{ + ScrArea *sa = CTX_wm_area(C); + + const int gesture_mode = RNA_int_get(op->ptr, "gesture_mode"); + const bool select = (gesture_mode == GESTURE_MODAL_SELECT); + const bool extend = RNA_boolean_get(op->ptr, "extend"); + + GP_SpaceConversion gsc = {NULL}; + rcti rect = {0}; + + bool changed = false; + + + /* sanity checks */ + if (sa == NULL) { + BKE_report(op->reports, RPT_ERROR, "No active area"); + return OPERATOR_CANCELLED; + } + + /* init space conversion stuff */ + gp_point_conversion_init(C, &gsc); + + + /* deselect all strokes first? */ + if (select && !extend) { + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + bGPDspoint *pt; + int i; + + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + pt->flag &= ~GP_SPOINT_SELECT; + } + + gps->flag &= ~GP_STROKE_SELECT; + } + CTX_DATA_END; + } + + /* get settings from operator */ + WM_operator_properties_border_to_rcti(op, &rect); + + /* select/deselect points */ + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + bGPDspoint *pt; + int i; + + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + int x0, y0; + + /* convert point coords to screenspace */ + gp_point_to_xy(&gsc, gps, pt, &x0, &y0); + + /* test if in selection rect */ + if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&rect, x0, y0)) { + if (select) { + pt->flag |= GP_SPOINT_SELECT; + } + else { + pt->flag &= ~GP_SPOINT_SELECT; + } + + changed = true; + } + } + + /* Ensure that stroke selection is in sync with its points */ + gpencil_stroke_sync_selection(gps); + } + CTX_DATA_END; + + /* updates */ + if (changed) { + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); + } + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_select_border(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Border Select"; + ot->description = "Select Grease Pencil strokes within a rectangular region"; + ot->idname = "GPENCIL_OT_select_border"; + + /* callbacks */ + ot->invoke = WM_border_select_invoke; + ot->exec = gpencil_border_select_exec; + ot->modal = WM_border_select_modal; + ot->cancel = WM_border_select_cancel; + + ot->poll = gpencil_select_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* rna */ + WM_operator_properties_gesture_border(ot, true); +} + +/* ********************************************** */ +/* Lasso */ + +static int gpencil_lasso_select_exec(bContext *C, wmOperator *op) +{ + GP_SpaceConversion gsc = {NULL}; + rcti rect = {0}; + + const bool extend = RNA_boolean_get(op->ptr, "extend"); + const bool select = !RNA_boolean_get(op->ptr, "deselect"); + + int mcords_tot; + const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); + + bool changed = false; + + /* sanity check */ + if (mcords == NULL) + return OPERATOR_PASS_THROUGH; + + /* compute boundbox of lasso (for faster testing later) */ + BLI_lasso_boundbox(&rect, mcords, mcords_tot); + + /* init space conversion stuff */ + gp_point_conversion_init(C, &gsc); + + /* deselect all strokes first? */ + if (select && !extend) { + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + bGPDspoint *pt; + int i; + + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + pt->flag &= ~GP_SPOINT_SELECT; + } + + gps->flag &= ~GP_STROKE_SELECT; + } + CTX_DATA_END; + } + + /* select/deselect points */ + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + bGPDspoint *pt; + int i; + + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + int x0, y0; + + /* convert point coords to screenspace */ + gp_point_to_xy(&gsc, gps, pt, &x0, &y0); + + /* test if in lasso boundbox + within the lasso noose */ + if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&rect, x0, y0) && + BLI_lasso_is_point_inside(mcords, mcords_tot, x0, y0, INT_MAX)) + { + if (select) { + pt->flag |= GP_SPOINT_SELECT; + } + else { + pt->flag &= ~GP_SPOINT_SELECT; + } + + changed = true; + } + } + + /* Ensure that stroke selection is in sync with its points */ + gpencil_stroke_sync_selection(gps); + } + CTX_DATA_END; + + /* cleanup */ + MEM_freeN((void *)mcords); + + /* updates */ + if (changed) { + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); + } + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_select_lasso(wmOperatorType *ot) +{ + ot->name = "Lasso Select Strokes"; + ot->description = "Select Grease Pencil strokes using lasso selection"; + ot->idname = "GPENCIL_OT_select_lasso"; + + ot->invoke = WM_gesture_lasso_invoke; + ot->modal = WM_gesture_lasso_modal; + ot->exec = gpencil_lasso_select_exec; + ot->poll = gpencil_select_poll; + ot->cancel = WM_gesture_lasso_cancel; + + /* flags */ + ot->flag = OPTYPE_UNDO; + + RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", ""); + RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect rather than select items"); + RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection instead of deselecting everything first"); +} + +/* ********************************************** */ +/* Mouse Click to Select */ + +static int gpencil_select_exec(bContext *C, wmOperator *op) +{ + ScrArea *sa = CTX_wm_area(C); + + /* "radius" is simply a threshold (screen space) to make it easier to test with a tolerance */ + const float radius = 0.75f * U.widget_unit; + const int radius_squared = (int)(radius * radius); + + bool extend = RNA_boolean_get(op->ptr, "extend"); + bool deselect = RNA_boolean_get(op->ptr, "deselect"); + bool toggle = RNA_boolean_get(op->ptr, "toggle"); + bool whole = RNA_boolean_get(op->ptr, "entire_strokes"); + + int location[2] = {0}; + int mx, my; + + GP_SpaceConversion gsc = {NULL}; + + bGPDstroke *hit_stroke = NULL; + bGPDspoint *hit_point = NULL; + + /* sanity checks */ + if (sa == NULL) { + BKE_report(op->reports, RPT_ERROR, "No active area"); + return OPERATOR_CANCELLED; + } + + /* init space conversion stuff */ + gp_point_conversion_init(C, &gsc); + + /* get mouse location */ + RNA_int_get_array(op->ptr, "location", location); + + mx = location[0]; + my = location[1]; + + /* First Pass: Find stroke point which gets hit */ + /* XXX: maybe we should go from the top of the stack down instead... */ + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + bGPDspoint *pt; + int i; + int hit_index = -1; + + /* firstly, check for hit-point */ + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + int x0, y0; + + gp_point_to_xy(&gsc, gps, pt, &x0, &y0); + + /* do boundbox check first */ + if (!ELEM(V2D_IS_CLIPPED, x0, x0)) { + /* only check if point is inside */ + if (((x0 - mx) * (x0 - mx) + (y0 - my) * (y0 - my)) <= radius_squared) { + hit_stroke = gps; + hit_point = pt; + break; + } + } + } + + /* skip to next stroke if nothing found */ + if (hit_index == -1) + continue; + } + CTX_DATA_END; + + /* Abort if nothing hit... */ + if (ELEM(NULL, hit_stroke, hit_point)) { + return OPERATOR_CANCELLED; + } + + /* adjust selection behaviour - for toggle option */ + if (toggle) { + deselect = (hit_point->flag & GP_SPOINT_SELECT) != 0; + } + + /* If not extending selection, deselect everything else */ + if (extend == false) { + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + /* deselect stroke and its points if selected */ + if (gps->flag & GP_STROKE_SELECT) { + bGPDspoint *pt; + int i; + + /* deselect points */ + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + pt->flag &= ~GP_SPOINT_SELECT; + } + + /* deselect stroke itself too */ + gps->flag &= ~GP_STROKE_SELECT; + } + } + CTX_DATA_END; + } + + /* Perform selection operations... */ + if (whole) { + bGPDspoint *pt; + int i; + + /* entire stroke's points */ + for (i = 0, pt = hit_stroke->points; i < hit_stroke->totpoints; i++, pt++) { + if (deselect == false) + pt->flag |= GP_SPOINT_SELECT; + else + pt->flag &= ~GP_SPOINT_SELECT; + } + + /* stroke too... */ + if (deselect == false) + hit_stroke->flag |= GP_STROKE_SELECT; + else + hit_stroke->flag &= ~GP_STROKE_SELECT; + } + else { + /* just the point (and the stroke) */ + if (deselect == false) { + /* we're adding selection, so selection must be true */ + hit_point->flag |= GP_SPOINT_SELECT; + hit_stroke->flag |= GP_STROKE_SELECT; + } + else { + /* deselect point */ + hit_point->flag &= ~GP_SPOINT_SELECT; + + /* ensure that stroke is selected correctly */ + gpencil_stroke_sync_selection(hit_stroke); + } + } + + /* updates */ + if (hit_point != NULL) { + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); + } + + return OPERATOR_FINISHED; +} + +static int gpencil_select_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + RNA_int_set_array(op->ptr, "location", event->mval); + return gpencil_select_exec(C, op); +} + +void GPENCIL_OT_select(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Select"; + ot->description = "Select Grease Pencil strokes and/or stroke points"; + ot->idname = "GPENCIL_OT_select"; + + /* callbacks */ + ot->invoke = gpencil_select_invoke; + ot->exec = gpencil_select_exec; + ot->poll = gpencil_select_poll; + + /* flag */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_mouse_select(ot); + + prop = RNA_def_boolean(ot->srna, "entire_strokes", false, "Entire Strokes", "Select entire strokes instead of just the nearest stroke vertex"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + + prop = RNA_def_int_vector(ot->srna, "location", 2, NULL, INT_MIN, INT_MAX, "Location", "Mouse location", INT_MIN, INT_MAX); + RNA_def_property_flag(prop, PROP_HIDDEN); +} + +/* ********************************************** */ diff --git a/source/blender/editors/gpencil/gpencil_undo.c b/source/blender/editors/gpencil/gpencil_undo.c index ff92d69f39d..b1bbeabbd55 100644 --- a/source/blender/editors/gpencil/gpencil_undo.c +++ b/source/blender/editors/gpencil/gpencil_undo.c @@ -133,7 +133,12 @@ void gpencil_undo_push(bGPdata *gpd) while (undo_node) { bGPundonode *next_node = undo_node->next; - + + /* HACK: animdata wasn't duplicated, so it shouldn't be freed here, + * or else the real copy will segfault when accessed + */ + undo_node->gpd->adt = NULL; + BKE_gpencil_free(undo_node->gpd); MEM_freeN(undo_node->gpd); @@ -145,7 +150,7 @@ void gpencil_undo_push(bGPdata *gpd) /* create new undo node */ undo_node = MEM_callocN(sizeof(bGPundonode), "gpencil undo node"); - undo_node->gpd = gpencil_data_duplicate(gpd); + undo_node->gpd = gpencil_data_duplicate(gpd, true); cur_node = undo_node; @@ -157,6 +162,11 @@ void gpencil_undo_finish(void) bGPundonode *undo_node = undo_nodes.first; while (undo_node) { + /* HACK: animdata wasn't duplicated, so it shouldn't be freed here, + * or else the real copy will segfault when accessed + */ + undo_node->gpd->adt = NULL; + BKE_gpencil_free(undo_node->gpd); MEM_freeN(undo_node->gpd); diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c new file mode 100644 index 00000000000..4a913c3d2e5 --- /dev/null +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -0,0 +1,166 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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) 2014, Blender Foundation + * + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/gpencil/gpencil_utils.c + * \ingroup edgpencil + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stddef.h> +#include <math.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_math.h" +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" + +#include "DNA_gpencil_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_gpencil.h" +#include "BKE_library.h" +#include "BKE_object.h" +#include "BKE_report.h" +#include "BKE_scene.h" +#include "BKE_screen.h" + +#include "UI_interface.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "UI_view2d.h" + +#include "ED_gpencil.h" +#include "ED_view3d.h" + +#include "gpencil_intern.h" + +/* ******************************************************** */ + +/* Check if part of stroke occurs within last segment drawn by eraser */ +bool gp_stroke_inside_circle(const int mval[2], const int UNUSED(mvalo[2]), + int rad, int x0, int y0, int x1, int y1) +{ + /* simple within-radius check for now */ + const float mval_fl[2] = {mval[0], mval[1]}; + const float screen_co_a[2] = {x0, y0}; + const float screen_co_b[2] = {x1, y1}; + + if (edge_inside_circle(mval_fl, rad, screen_co_a, screen_co_b)) { + return true; + } + + /* not inside */ + return false; +} + +/* ******************************************************** */ + +/* Init handling for space-conversion function (from passed-in parameters) */ +void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc) +{ + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + + /* zero out the storage (just in case) */ + memset(r_gsc, 0, sizeof(GP_SpaceConversion)); + unit_m4(r_gsc->mat); + + /* store settings */ + r_gsc->sa = sa; + r_gsc->ar = ar; + r_gsc->v2d = &ar->v2d; + + /* init region-specific stuff */ + if (sa->spacetype == SPACE_VIEW3D) { + wmWindow *win = CTX_wm_window(C); + Scene *scene = CTX_data_scene(C); + View3D *v3d = (View3D *)CTX_wm_space_data(C); + RegionView3D *rv3d = ar->regiondata; + + /* init 3d depth buffers */ + view3d_operator_needs_opengl(C); + + view3d_region_operator_needs_opengl(win, ar); + ED_view3d_autodist_init(scene, ar, v3d, 0); + + /* for camera view set the subrect */ + if (rv3d->persp == RV3D_CAMOB) { + ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &r_gsc->subrect_data, true); /* no shift */ + r_gsc->subrect = &r_gsc->subrect_data; + } + } +} + + +/* Convert Grease Pencil points to screen-space values */ +void gp_point_to_xy(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt, + int *r_x, int *r_y) +{ + ARegion *ar = gsc->ar; + View2D *v2d = gsc->v2d; + rctf *subrect = gsc->subrect; + int xyval[2]; + + if (gps->flag & GP_STROKE_3DSPACE) { + if (ED_view3d_project_int_global(ar, &pt->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { + *r_x = xyval[0]; + *r_y = xyval[1]; + } + else { + *r_x = V2D_IS_CLIPPED; + *r_y = V2D_IS_CLIPPED; + } + } + else if (gps->flag & GP_STROKE_2DSPACE) { + float vec[3] = {pt->x, pt->y, 0.0f}; + mul_m4_v3(gsc->mat, vec); + UI_view2d_view_to_region_clip(v2d, vec[0], vec[1], r_x, r_y); + } + else { + if (subrect == NULL) { /* normal 3D view */ + *r_x = (int)(pt->x / 100 * ar->winx); + *r_y = (int)(pt->y / 100 * ar->winy); + } + else { /* camera view, use subrect */ + *r_x = (int)((pt->x / 100) * BLI_rctf_size_x(subrect)) + subrect->xmin; + *r_y = (int)((pt->y / 100) * BLI_rctf_size_y(subrect)) + subrect->ymin; + } + } +} + +/* ******************************************************** */ diff --git a/source/blender/editors/include/BIF_gl.h b/source/blender/editors/include/BIF_gl.h index cd26bb22ada..2acba04368c 100644 --- a/source/blender/editors/include/BIF_gl.h +++ b/source/blender/editors/include/BIF_gl.h @@ -35,16 +35,9 @@ #include "GPU_glew.h" -#ifdef __APPLE__ - /* hacking pointsize and linewidth */ -# define glPointSize(f) glPointSize(U.pixelsize * (f)) -# define glLineWidth(f) glLineWidth(U.pixelsize * (f)) -#else - /* avoid include mismatch by referencing 'U' from both */ -# define glPointSize(f) glPointSize(((void)U.pixelsize, (f))) -# define glLineWidth(f) glLineWidth(((void)U.pixelsize, (f))) -#endif +#define glPointSize(f) glPointSize(U.pixelsize * (f)) +#define glLineWidth(f) glLineWidth(U.pixelsize * (f)) /* * these should be phased out. cpack should be replaced in diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 956ec308daa..cd0cfeb7e7f 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -159,6 +159,7 @@ typedef enum eAnim_ChannelType { ANIMTYPE_DSLAT, ANIMTYPE_DSLINESTYLE, ANIMTYPE_DSSPK, + ANIMTYPE_DSGPENCIL, ANIMTYPE_SHAPEKEY, diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index 05fb76b7aea..cad33c34fe3 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -30,6 +30,7 @@ #ifndef __ED_GPENCIL_H__ #define __ED_GPENCIL_H__ +struct ID; struct ListBase; struct bContext; struct bScreen; @@ -38,11 +39,11 @@ struct ARegion; struct View3D; struct SpaceNode; struct SpaceSeq; +struct Object; struct bGPdata; struct bGPDlayer; struct bGPDframe; struct PointerRNA; -struct Panel; struct ImBuf; struct wmKeyConfig; @@ -65,14 +66,26 @@ typedef struct tGPspoint { /* ----------- Grease Pencil Tools/Context ------------- */ +/* Context-dependent */ struct bGPdata **ED_gpencil_data_get_pointers(const struct bContext *C, struct PointerRNA *ptr); struct bGPdata *ED_gpencil_data_get_active(const struct bContext *C); + +/* Context independent (i.e. each required part is passed in instead) */ +struct bGPdata **ED_gpencil_data_get_pointers_direct(struct ID *screen_id, struct Scene *scene, + struct ScrArea *sa, struct Object *ob, + struct PointerRNA *ptr); +struct bGPdata *ED_gpencil_data_get_active_direct(struct ID *screen_id, struct Scene *scene, + struct ScrArea *sa, struct Object *ob); + +/* 3D View */ struct bGPdata *ED_gpencil_data_get_active_v3d(struct Scene *scene, struct View3D *v3d); /* ----------- Grease Pencil Operators ----------------- */ void ED_keymap_gpencil(struct wmKeyConfig *keyconf); + void ED_operatortypes_gpencil(void); +void ED_operatormacros_gpencil(void); /* ------------ Grease-Pencil Drawing API ------------------ */ /* drawgpencil.c */ @@ -80,10 +93,8 @@ void ED_operatortypes_gpencil(void); void ED_gpencil_draw_2dimage(const struct bContext *C); void ED_gpencil_draw_view2d(const struct bContext *C, bool onlyv2d); void ED_gpencil_draw_view3d(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, bool only3d); -void ED_gpencil_draw_ex(struct bGPdata *gpd, int winx, int winy, const int cfra); - -void ED_gpencil_panel_standard_header(const struct bContext *C, struct Panel *pa); -void ED_gpencil_panel_standard(const struct bContext *C, struct Panel *pa); +void ED_gpencil_draw_ex(struct Scene *scene, struct bGPdata *gpd, int winx, int winy, + const int cfra, const char spacetype); /* ----------- Grease-Pencil AnimEdit API ------------------ */ bool ED_gplayer_frames_looper(struct bGPDlayer *gpl, struct Scene *scene, @@ -99,6 +110,8 @@ void ED_gpencil_select_frame(struct bGPDlayer *gpl, int selx, short select_mode bool ED_gplayer_frames_delete(struct bGPDlayer *gpl); void ED_gplayer_frames_duplicate(struct bGPDlayer *gpl); +void ED_gplayer_frames_keytype_set(struct bGPDlayer *gpl, short type); + void ED_gplayer_snap_frames(struct bGPDlayer *gpl, struct Scene *scene, short mode); #if 0 diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h index a9995de068e..1188ecd0aa5 100644 --- a/source/blender/editors/include/ED_image.h +++ b/source/blender/editors/include/ED_image.h @@ -79,5 +79,7 @@ int ED_space_image_maskedit_mask_poll(struct bContext *C); void ED_image_draw_info(struct Scene *scene, struct ARegion *ar, bool color_manage, bool use_default_view, int channels, int x, int y, const unsigned char cp[4], const float fp[4], const float linearcol[4], int *zp, float *zpf); +bool ED_space_image_show_cache(struct SpaceImage *sima); + #endif /* __ED_IMAGE_H__ */ diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h index 58a262e150a..0359153317b 100644 --- a/source/blender/editors/include/ED_keyframes_draw.h +++ b/source/blender/editors/include/ED_keyframes_draw.h @@ -120,8 +120,9 @@ void draw_object_channel(struct View2D *v2d, struct bDopeSheet *ads, struct Obje void draw_scene_channel(struct View2D *v2d, struct bDopeSheet *ads, struct Scene *sce, float ypos); /* DopeSheet Summary */ void draw_summary_channel(struct View2D *v2d, struct bAnimContext *ac, float ypos); -/* Grease Pencil Layer */ -// XXX not restored +/* Grease Pencil datablock summary */ +void draw_gpencil_channel(struct View2D *v2d, struct bDopeSheet *ads, struct bGPdata *gpd, float ypos); +/* Grease Pencil Layer */ void draw_gpl_channel(struct View2D *v2d, struct bDopeSheet *ads, struct bGPDlayer *gpl, float ypos); /* Mask Layer */ void draw_masklay_channel(struct View2D *v2d, struct bDopeSheet *ads, struct MaskLayer *masklay, float ypos); @@ -139,11 +140,11 @@ void ob_to_keylist(struct bDopeSheet *ads, struct Object *ob, struct DLRBT_Tree void scene_to_keylist(struct bDopeSheet *ads, struct Scene *sce, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks); /* DopeSheet Summary */ void summary_to_keylist(struct bAnimContext *ac, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks); +/* Grease Pencil datablock summary */ +void gpencil_to_keylist(struct bDopeSheet *ads, struct bGPdata *gpd, struct DLRBT_Tree *keys); /* Grease Pencil Layer */ -// XXX not restored void gpl_to_keylist(struct bDopeSheet *ads, struct bGPDlayer *gpl, struct DLRBT_Tree *keys); /* Mask */ -// XXX not restored void mask_to_keylist(struct bDopeSheet *UNUSED(ads), struct MaskLayer *masklay, struct DLRBT_Tree *keys); /* ActKeyColumn API ---------------- */ diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h index c8365689803..e9b22e49ac2 100644 --- a/source/blender/editors/include/ED_keyframes_edit.h +++ b/source/blender/editors/include/ED_keyframes_edit.h @@ -58,6 +58,7 @@ typedef enum eEditKeyframes_Validate { BEZT_OK_VALUERANGE, BEZT_OK_REGION, BEZT_OK_REGION_LASSO, + BEZT_OK_REGION_CIRCLE, } eEditKeyframes_Validate; /* ------------ */ @@ -107,6 +108,14 @@ struct KeyframeEdit_LassoData { int mcords_tot; }; +/* use with BEZT_OK_REGION_CIRCLE */ +struct KeyframeEdit_CircleData { + const rctf *rectf_scaled; + const rctf *rectf_view; + float mval[2]; + float radius_squared; +}; + /* ************************************************ */ /* Non-Destuctive Editing API (keyframes_edit.c) */ @@ -233,7 +242,7 @@ short bezt_selmap_flush(KeyframeEditData *ked, struct BezTriple *bezt); /* ----------- BezTriple Callback (Assorted Utilities) ---------- */ -/* used to calculate the the average location of all relevant BezTriples by summing their locations */ +/* used to calculate the average location of all relevant BezTriples by summing their locations */ short bezt_calc_average(KeyframeEditData *ked, struct BezTriple *bezt); /* used to extract a set of cfra-elems from the keyframes */ diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h index 5c7b3c531be..e5b5e79875d 100644 --- a/source/blender/editors/include/ED_keyframing.h +++ b/source/blender/editors/include/ED_keyframing.h @@ -293,7 +293,7 @@ bool ANIM_paste_driver(struct ReportList *reports, struct ID *id, const char rna (U.autokey_flag & AUTOKEY_FLAG_##flag)) /* auto-keyframing feature - checks for whether anything should be done for the current frame */ -int autokeyframe_cfra_can_key(struct Scene *scene, struct ID *id); +bool autokeyframe_cfra_can_key(struct Scene *scene, struct ID *id); /* ************ Keyframe Checking ******************** */ diff --git a/source/blender/editors/include/ED_markers.h b/source/blender/editors/include/ED_markers.h index 76d36623b60..5eaf459a4e1 100644 --- a/source/blender/editors/include/ED_markers.h +++ b/source/blender/editors/include/ED_markers.h @@ -43,10 +43,11 @@ struct TimeMarker; /* flags for drawing markers */ enum { DRAW_MARKERS_LINES = (1 << 0), - DRAW_MARKERS_LOCAL = (1 << 1) + DRAW_MARKERS_LOCAL = (1 << 1), + DRAW_MARKERS_MARGIN = (1 << 2), }; -void draw_markers_time(const struct bContext *C, int flag); +void ED_markers_draw(const struct bContext *C, int flag); /* Backend API ----------------------------- */ diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 6a562da0a0e..8eb7fdf0c40 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -101,8 +101,8 @@ struct DerivedMesh *EDBM_mesh_deform_dm_get(struct BMEditMesh *em); * verts select/deselect edges and faces, if in edge select mode, * edges select/deselect faces and vertices, and in face select mode faces select/deselect * edges and vertices.*/ -void EDBM_select_more(struct BMEditMesh *em); -void EDBM_select_less(struct BMEditMesh *em); +void EDBM_select_more(struct BMEditMesh *em, const bool use_face_step); +void EDBM_select_less(struct BMEditMesh *em, const bool use_face_step); void EDBM_selectmode_flush_ex(struct BMEditMesh *em, const short selectmode); void EDBM_selectmode_flush(struct BMEditMesh *em); @@ -220,14 +220,8 @@ void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store); #define WEIGHT_SUBTRACT 3 bool ED_vgroup_sync_from_pose(struct Object *ob); -struct bDeformGroup *ED_vgroup_add(struct Object *ob); -struct bDeformGroup *ED_vgroup_add_name(struct Object *ob, const char *name); -void ED_vgroup_delete(struct Object *ob, struct bDeformGroup *defgroup); -void ED_vgroup_clear(struct Object *ob); void ED_vgroup_select_by_name(struct Object *ob, const char *name); -bool ED_vgroup_data_create(struct ID *id); void ED_vgroup_data_clamp_range(struct ID *id, const int total); -bool ED_vgroup_array_get(struct ID *id, struct MDeformVert **dvert_arr, int *dvert_tot); bool ED_vgroup_array_copy(struct Object *ob, struct Object *ob_from); bool ED_vgroup_parray_alloc(struct ID *id, struct MDeformVert ***dvert_arr, int *dvert_tot, const bool use_vert_sel); @@ -244,8 +238,6 @@ void ED_vgroup_mirror(struct Object *ob, const bool all_vgroups, const bool use_topology, int *r_totmirr, int *r_totfail); -bool ED_vgroup_object_is_edit_mode(struct Object *ob); - void ED_vgroup_vert_add(struct Object *ob, struct bDeformGroup *dg, int vertnum, float weight, int assignmode); void ED_vgroup_vert_remove(struct Object *ob, struct bDeformGroup *dg, int vertnum); float ED_vgroup_vert_weight(struct Object *ob, struct bDeformGroup *dg, int vertnum); @@ -267,6 +259,7 @@ void ED_mesh_vertices_remove(struct Mesh *mesh, struct ReportList *reports, int void ED_mesh_calc_tessface(struct Mesh *mesh); void ED_mesh_update(struct Mesh *mesh, struct bContext *C, int calc_edges, int calc_tessface); +void ED_mesh_uv_texture_ensure(struct Mesh *me, const char *name); int ED_mesh_uv_texture_add(struct Mesh *me, const char *name, const bool active_set); bool ED_mesh_uv_texture_remove_index(struct Mesh *me, const int n); bool ED_mesh_uv_texture_remove_active(struct Mesh *me); diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 39586039e8f..900da3ee07c 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -209,12 +209,6 @@ bool ED_object_multires_update_totlevels_cb(struct Object *ob, void *totlevel_v) /* object_select.c */ void ED_object_select_linked_by_id(struct bContext *C, struct ID *id); - -bool *ED_vgroup_subset_from_select_type(struct Object *ob, enum eVGroupSelect subset_type, - int *r_vgroup_tot, int *r_subset_count); -void ED_vgroup_subset_to_index_array(const bool *vgroup_validmap, const int vgroup_tot, - int *r_vgroup_subset_map); - struct EnumPropertyItem *ED_object_vgroup_selection_itemf_helper( const struct bContext *C, struct PointerRNA *ptr, diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h index ab1dbabe793..0227ae3e85a 100644 --- a/source/blender/editors/include/ED_render.h +++ b/source/blender/editors/include/ED_render.h @@ -40,6 +40,7 @@ struct ScrArea; struct RegionView3D; struct RenderEngine; struct View3D; +struct wmWindowManager; /* render_ops.c */ @@ -52,7 +53,7 @@ void ED_render_engine_changed(struct Main *bmain); void ED_render_engine_area_exit(struct ScrArea *sa); void ED_render_scene_update(struct Main *bmain, struct Scene *scene, int updated); -void ED_viewport_render_kill_jobs(const struct bContext *C, bool free_database); +void ED_viewport_render_kill_jobs(struct wmWindowManager *wm, struct Main *bmain, bool free_database); struct Scene *ED_render_job_get_scene(const struct bContext *C); /* Render the preview @@ -72,7 +73,7 @@ void ED_preview_free_dbase(void); void ED_preview_shader_job(const struct bContext *C, void *owner, struct ID *id, struct ID *parent, struct MTex *slot, int sizex, int sizey, int method); void ED_preview_icon_job(const struct bContext *C, void *owner, struct ID *id, unsigned int *rect, int sizex, int sizey); -void ED_preview_kill_jobs(const struct bContext *C); +void ED_preview_kill_jobs(struct wmWindowManager *wm, struct Main *bmain); void ED_preview_draw(const struct bContext *C, void *idp, void *parentp, void *slot, rcti *rect); diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index d31be3e961f..ed2465647da 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -110,7 +110,7 @@ void ED_screen_animation_timer_update(struct bScreen *screen, int redraws, in ScrArea *ED_screen_full_newspace(struct bContext *C, ScrArea *sa, int type); void ED_screen_full_prevspace(struct bContext *C, ScrArea *sa); void ED_screen_full_restore(struct bContext *C, ScrArea *sa); -struct ScrArea *ED_screen_full_toggle(struct bContext *C, struct wmWindow *win, struct ScrArea *sa); +struct ScrArea *ED_screen_state_toggle(struct bContext *C, struct wmWindow *win, struct ScrArea *sa, const short state); void ED_screens_header_tools_menu_create(struct bContext *C, struct uiLayout *layout, void *arg); /* anim */ diff --git a/source/blender/editors/include/ED_screen_types.h b/source/blender/editors/include/ED_screen_types.h index 2b02606c6d9..effecf43839 100644 --- a/source/blender/editors/include/ED_screen_types.h +++ b/source/blender/editors/include/ED_screen_types.h @@ -93,10 +93,13 @@ typedef struct AZone { short x1, y1, x2, y2; /* for clip */ rcti rect; + /* for fade in/out */ + float alpha; } AZone; /* actionzone type */ #define AZONE_AREA 1 /* corner widgets for splitting areas */ #define AZONE_REGION 2 /* when a region is collapsed, draw a handle to expose */ +#define AZONE_FULLSCREEN 3 /* when in editor fullscreen draw a corner to go to normal mode */ #endif /* __ED_SCREEN_TYPES_H__ */ diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index daa6864b5aa..cf848098188 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -99,6 +99,7 @@ enum TfmMode { #define CTX_MOVIECLIP (1 << 6) #define CTX_MASK (1 << 7) #define CTX_PAINT_CURVE (1 << 8) +#define CTX_GPENCIL_STROKES (1 << 9) /* Standalone call to get the transformation center corresponding to the current situation * returns 1 if successful, 0 otherwise (usually means there's no selection) @@ -146,6 +147,7 @@ int BIF_countTransformOrientation(const struct bContext *C); #define P_CORRECT_UV (1 << 8) #define P_NO_DEFAULTS (1 << 10) #define P_NO_TEXSPACE (1 << 11) +#define P_GPENCIL_EDIT (1 << 12) void Transform_Properties(struct wmOperatorType *ot, int flags); diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h index 4b82fa40c6a..3e8f234e979 100644 --- a/source/blender/editors/include/ED_uvedit.h +++ b/source/blender/editors/include/ED_uvedit.h @@ -31,6 +31,7 @@ #define __ED_UVEDIT_H__ struct ARegionType; +struct BMesh; struct BMEditMesh; struct BMFace; struct BMLoop; @@ -52,6 +53,7 @@ void ED_keymap_uvedit(struct wmKeyConfig *keyconf); void ED_uvedit_assign_image(struct Main *bmain, struct Scene *scene, struct Object *obedit, struct Image *ima, struct Image *previma); bool ED_uvedit_minmax(struct Scene *scene, struct Image *ima, struct Object *obedit, float min[2], float max[2]); +void ED_uvedit_select_all(struct BMesh *bm); bool ED_object_get_active_image(struct Object *ob, int mat_nr, struct Image **r_ima, struct ImageUser **r_iuser, struct bNode **r_node, struct bNodeTree **r_ntree); @@ -92,19 +94,24 @@ void uvedit_uv_select_disable(struct BMEditMesh *em, struct Scene *scene, struct bool ED_uvedit_nearest_uv(struct Scene *scene, struct Object *obedit, struct Image *ima, const float co[2], float r_uv[2]); +void ED_uvedit_get_aspect(struct Scene *scene, struct Object *ob, struct BMesh *em, float *aspx, float *aspy); + /* uvedit_unwrap_ops.c */ void ED_uvedit_live_unwrap_begin(struct Scene *scene, struct Object *obedit); void ED_uvedit_live_unwrap_re_solve(void); void ED_uvedit_live_unwrap_end(short cancel); void ED_uvedit_live_unwrap(struct Scene *scene, struct Object *obedit); +void ED_uvedit_pack_islands(struct Scene *scene, struct Object *ob, struct BMesh *bm, bool selected, bool correct_aspect, bool do_rotate); +void ED_uvedit_unwrap_cube_project(struct Object *ob, struct BMesh *bm, float cube_size, bool use_select); /* single call up unwrap using scene settings, used for edge tag unwrapping */ void ED_unwrap_lscm(struct Scene *scene, struct Object *obedit, const short sel); + /* uvedit_draw.c */ -void draw_image_cursor(struct ARegion *ar, const float cursor[2]); -void draw_uvedit_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene, struct Object *obedit, struct Object *obact); +void ED_image_draw_cursor(struct ARegion *ar, const float cursor[2]); +void ED_uvedit_draw_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene, struct Object *obedit, struct Object *obact); /* uvedit_buttons.c */ void ED_uvedit_buttons_register(struct ARegionType *art); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index bd4f37cfb1e..76ad4ba7bdb 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -309,7 +309,7 @@ void ED_view3d_draw_offscreen(struct Scene *scene, struct View3D *v3d, struct AR struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag, bool draw_background, int alpha_mode, char err_out[256]); struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(struct Scene *scene, struct Object *camera, int width, int height, unsigned int flag, int drawtype, - bool use_solid_tex, bool draw_background, int alpha_mode, char err_out[256]); + bool use_solid_tex, bool use_gpencil, bool draw_background, int alpha_mode, char err_out[256]); void ED_view3d_offscreen_sky_color_get(struct Scene *scene, float sky_color[3]); struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]); diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index 1d79cf749f9..618fa44349e 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -426,13 +426,11 @@ DEF_ICON(CURVE_PATH) DEF_ICON(COLOR_RED) DEF_ICON(COLOR_GREEN) DEF_ICON(COLOR_BLUE) -#ifndef DEF_ICON_BLANK_SKIP - DEF_ICON(BLANK652) - DEF_ICON(BLANK653) - DEF_ICON(BLANK654) - DEF_ICON(BLANK655) -#endif - +DEF_ICON(TRIA_RIGHT_BAR) +DEF_ICON(TRIA_DOWN_BAR) +DEF_ICON(TRIA_LEFT_BAR) +DEF_ICON(TRIA_UP_BAR) + /* EMPTY */ DEF_ICON(FORCE_FORCE) DEF_ICON(FORCE_WIND) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index bc794bf3350..2251f3fd0e4 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -98,20 +98,23 @@ typedef struct uiLayout uiLayout; #define UI_SCREEN_MARGIN 10 /* uiBlock->dt and uiBut->dt */ -#define UI_EMBOSS 0 /* use widget style for drawing */ -#define UI_EMBOSSN 1 /* Nothing, only icon and/or text */ -#define UI_EMBOSSP 2 /* Pulldown menu style */ -#define UI_EMBOSST 3 /* Table */ -#define UI_EMBOSSR 4 /* Pie Menu */ +enum { + UI_EMBOSS = 0, /* use widget style for drawing */ + UI_EMBOSS_NONE = 1, /* Nothing, only icon and/or text */ + UI_EMBOSS_PULLDOWN = 2, /* Pulldown menu style */ + UI_EMBOSS_RADIAL = 3, /* Pie Menu */ +}; /* uiBlock->direction */ -#define UI_DIRECTION (UI_TOP | UI_DOWN | UI_LEFT | UI_RIGHT) -#define UI_TOP (1 << 0) -#define UI_DOWN (1 << 1) -#define UI_LEFT (1 << 2) -#define UI_RIGHT (1 << 3) -#define UI_CENTER (1 << 4) -#define UI_SHIFT_FLIPPED (1 << 5) +enum { + UI_DIR_UP = (1 << 0), + UI_DIR_DOWN = (1 << 1), + UI_DIR_LEFT = (1 << 2), + UI_DIR_RIGHT = (1 << 3), + UI_DIR_CENTER_Y = (1 << 4), + + UI_DIR_ALL = (UI_DIR_UP | UI_DIR_DOWN | UI_DIR_LEFT | UI_DIR_RIGHT), +}; #if 0 /* uiBlock->autofill (not yet used) */ @@ -121,8 +124,8 @@ typedef struct uiLayout uiLayout; /* uiBlock->flag (controls) */ #define UI_BLOCK_LOOP (1 << 0) -#define UI_BLOCK_REDRAW (1 << 1) -#define UI_BLOCK_SEARCH_MENU (1 << 2) +#define UI_BLOCK_IS_FLIP (1 << 1) +#define UI_BLOCK_NO_FLIP (1 << 2) #define UI_BLOCK_NUMSELECT (1 << 3) #define UI_BLOCK_NO_WIN_CLIP (1 << 4) /* don't apply window clipping */ /* was UI_BLOCK_ENTER_OK */ #define UI_BLOCK_CLIPBOTTOM (1 << 5) @@ -131,7 +134,7 @@ typedef struct uiLayout uiLayout; #define UI_BLOCK_KEEP_OPEN (1 << 8) #define UI_BLOCK_POPUP (1 << 9) #define UI_BLOCK_OUT_1 (1 << 10) -#define UI_BLOCK_NO_FLIP (1 << 11) +#define UI_BLOCK_SEARCH_MENU (1 << 11) #define UI_BLOCK_POPUP_MEMORY (1 << 12) #define UI_BLOCK_CLIP_EVENTS (1 << 13) /* stop handling mouse events */ @@ -156,8 +159,8 @@ typedef struct uiLayout uiLayout; /* but->flag - general state flags. */ enum { /* warning, the first 6 flags are internal */ - UI_ICON_SUBMENU = (1 << 6), - UI_ICON_PREVIEW = (1 << 7), + UI_BUT_ICON_SUBMENU = (1 << 6), + UI_BUT_ICON_PREVIEW = (1 << 7), UI_BUT_NODE_LINK = (1 << 8), UI_BUT_NODE_ACTIVE = (1 << 9), @@ -234,56 +237,57 @@ typedef enum { /* assigned to but->type, OR'd with the flags above when passing args */ typedef enum { - BUT = (1 << 9), - ROW = (2 << 9), - TOG = (3 << 9), - NUM = (5 << 9), - TEX = (6 << 9), - TOGN = (9 << 9), - LABEL = (10 << 9), - MENU = (11 << 9), /* Dropdown list, actually! */ - ICONTOG = (13 << 9), - NUMSLI = (14 << 9), - COLOR = (15 << 9), - SCROLL = (18 << 9), - BLOCK = (19 << 9), - BUTM = (20 << 9), - SEPR = (21 << 9), - LINK = (22 << 9), - INLINK = (23 << 9), - KEYEVT = (24 << 9), - HSVCUBE = (26 << 9), - PULLDOWN = (27 << 9), /* Menu, actually! */ - ROUNDBOX = (28 << 9), - BUT_COLORBAND = (30 << 9), - BUT_NORMAL = (31 << 9), - BUT_CURVE = (32 << 9), - ICONTOGN = (34 << 9), - LISTBOX = (35 << 9), - LISTROW = (36 << 9), - TOGBUT = (37 << 9), - OPTION = (38 << 9), - OPTIONN = (39 << 9), - TRACKPREVIEW = (40 << 9), - /* buttons with value >= SEARCH_MENU don't get undo pushes */ - SEARCH_MENU = (41 << 9), - BUT_EXTRA = (42 << 9), - HSVCIRCLE = (43 << 9), - HOTKEYEVT = (46 << 9), - BUT_IMAGE = (47 << 9), - HISTOGRAM = (48 << 9), - WAVEFORM = (49 << 9), - VECTORSCOPE = (50 << 9), - PROGRESSBAR = (51 << 9), - SEARCH_MENU_UNLINK = (52 << 9), - NODESOCKET = (53 << 9), - SEPRLINE = (54 << 9), - GRIP = (55 << 9), + UI_BTYPE_BUT = (1 << 9), + UI_BTYPE_ROW = (2 << 9), + UI_BTYPE_TEXT = (3 << 9), + UI_BTYPE_MENU = (4 << 9), /* dropdown list */ + UI_BTYPE_BUT_MENU = (5 << 9), + UI_BTYPE_NUM = (6 << 9), /* number button */ + UI_BTYPE_NUM_SLIDER = (7 << 9), /* number slider */ + UI_BTYPE_TOGGLE = (8 << 9), + UI_BTYPE_TOGGLE_N = (9 << 9), + UI_BTYPE_ICON_TOGGLE = (10 << 9), + UI_BTYPE_ICON_TOGGLE_N = (11 << 9), + UI_BTYPE_BUT_TOGGLE = (12 << 9), /* same as regular toggle, but no on/off state displayed */ + UI_BTYPE_CHECKBOX = (13 << 9), /* similar to toggle, display a 'tick' */ + UI_BTYPE_CHECKBOX_N = (14 << 9), + UI_BTYPE_COLOR = (15 << 9), + UI_BTYPE_SCROLL = (18 << 9), + UI_BTYPE_BLOCK = (19 << 9), + UI_BTYPE_LABEL = (20 << 9), + UI_BTYPE_LINK = (22 << 9), + UI_BTYPE_INLINK = (23 << 9), + UI_BTYPE_KEY_EVENT = (24 << 9), + UI_BTYPE_HSVCUBE = (26 << 9), + UI_BTYPE_PULLDOWN = (27 << 9), /* menu (often used in headers), **_MENU /w different draw-type */ + UI_BTYPE_ROUNDBOX = (28 << 9), + UI_BTYPE_COLORBAND = (30 << 9), + UI_BTYPE_UNITVEC = (31 << 9), /* sphere widget (used to input a unit-vector, aka normal) */ + UI_BTYPE_CURVE = (32 << 9), + UI_BTYPE_LISTBOX = (36 << 9), + UI_BTYPE_LISTROW = (37 << 9), + UI_BTYPE_HSVCIRCLE = (38 << 9), + UI_BTYPE_TRACK_PREVIEW = (40 << 9), + + /* buttons with value >= UI_BTYPE_SEARCH_MENU don't get undo pushes */ + UI_BTYPE_SEARCH_MENU = (41 << 9), + UI_BTYPE_EXTRA = (42 << 9), + UI_BTYPE_HOTKEY_EVENT = (46 << 9), + UI_BTYPE_IMAGE = (47 << 9), /* non-interactive image, used for splash screen */ + UI_BTYPE_HISTOGRAM = (48 << 9), + UI_BTYPE_WAVEFORM = (49 << 9), + UI_BTYPE_VECTORSCOPE = (50 << 9), + UI_BTYPE_PROGRESS_BAR = (51 << 9), + UI_BTYPE_SEARCH_MENU_UNLINK = (52 << 9), + UI_BTYPE_NODE_SOCKET = (53 << 9), + UI_BTYPE_SEPR = (54 << 9), + UI_BTYPE_SEPR_LINE = (55 << 9), + UI_BTYPE_GRIP = (56 << 9), /* resize handle (resize uilist) */ } eButType; #define BUTTYPE (63 << 9) -/* gradient types, for color picker HSVCUBE etc */ +/* gradient types, for color picker UI_BTYPE_HSVCUBE etc */ #define UI_GRAD_SV 0 #define UI_GRAD_HV 1 #define UI_GRAD_HS 2 @@ -301,35 +305,36 @@ typedef enum { * Functions to draw various shapes, taking theme settings into account. * Used for code that draws its own UI style elements. */ -void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad); -void uiSetRoundBox(int type); -int uiGetRoundBox(void); -void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad); -void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, float maxy); -void uiDrawBox(int mode, float minx, float miny, float maxx, float maxy, float rad); -void uiDrawBoxShade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown); -void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadeLeft, float shadeRight); +void UI_draw_roundbox(float minx, float miny, float maxx, float maxy, float rad); +void UI_draw_roundbox_corner_set(int type); +int UI_draw_roundbox_corner_get(void); +void UI_draw_roundbox_unfilled(float minx, float miny, float maxx, float maxy, float rad); +void UI_draw_box_shadow(unsigned char alpha, float minx, float miny, float maxx, float maxy); +void UI_draw_roundbox_gl_mode(int mode, float minx, float miny, float maxx, float maxy, float rad); +void UI_draw_roundbox_shade_x(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown); +void UI_draw_roundbox_shade_y(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadeLeft, float shadeRight); +void UI_draw_text_underline(int pos_x, int pos_y, int len, int height); /* state for scrolldrawing */ #define UI_SCROLL_PRESSED (1 << 0) #define UI_SCROLL_ARROWS (1 << 1) #define UI_SCROLL_NO_OUTLINE (1 << 2) -void uiWidgetScrollDraw(struct uiWidgetColors *wcol, const struct rcti *rect, const struct rcti *slider, int state); +void UI_draw_widget_scroll(struct uiWidgetColors *wcol, const struct rcti *rect, const struct rcti *slider, int state); /* Callbacks * - * uiBlockSetHandleFunc/ButmFunc are for handling events through a callback. + * UI_block_func_handle_set/ButmFunc are for handling events through a callback. * HandleFunc gets the retval passed on, and ButmFunc gets a2. The latter is * mostly for compatibility with older code. * - * uiButSetCompleteFunc is for tab completion. + * UI_but_func_complete_set is for tab completion. * * uiButSearchFunc is for name buttons, showing a popup with matches * - * uiBlockSetFunc and uiButSetFunc are callbacks run when a button is used, + * UI_block_func_set and UI_but_func_set are callbacks run when a button is used, * in case events, operators or RNA are not sufficient to handle the button. * - * uiButSetNFunc will free the argument with MEM_freeN. */ + * UI_but_funcN_set will free the argument with MEM_freeN. */ typedef struct uiSearchItems uiSearchItems; @@ -348,30 +353,35 @@ typedef void (*uiMenuHandleFunc)(struct bContext *C, void *arg, int event); /* Popup Menus * * Functions used to create popup menus. For more extended menus the - * uiPupMenuBegin/End functions can be used to define own items with + * UI_popup_menu_begin/End functions can be used to define own items with * the uiItem functions in between. If it is a simple confirmation menu * or similar, popups can be created with a single function call. */ typedef struct uiPopupMenu uiPopupMenu; -struct uiPopupMenu *uiPupMenuBegin(struct bContext *C, const char *title, int icon) ATTR_NONNULL(); -void uiPupMenuEnd(struct bContext *C, struct uiPopupMenu *head); -struct uiLayout *uiPupMenuLayout(uiPopupMenu *head); +struct uiPopupMenu *UI_popup_menu_begin(struct bContext *C, const char *title, int icon) ATTR_NONNULL(); +void UI_popup_menu_end(struct bContext *C, struct uiPopupMenu *head); +struct uiLayout *UI_popup_menu_layout(uiPopupMenu *head); -void uiPupMenuReports(struct bContext *C, struct ReportList *reports) ATTR_NONNULL(); -bool uiPupMenuInvoke(struct bContext *C, const char *idname, struct ReportList *reports) ATTR_NONNULL(1, 2); +void UI_popup_menu_reports(struct bContext *C, struct ReportList *reports) ATTR_NONNULL(); +int UI_popup_menu_invoke(struct bContext *C, const char *idname, struct ReportList *reports) ATTR_NONNULL(1, 2); /* Pie menus */ typedef struct uiPieMenu uiPieMenu; -void uiPieMenuInvoke(struct bContext *C, const char *idname, const struct wmEvent *event); -void uiPieOperatorEnumInvoke(struct bContext *C, const char *title, const char *opname, - const char *propname, const struct wmEvent *event); -void uiPieEnumInvoke(struct bContext *C, const char *title, const char *path, const struct wmEvent *event); - -struct uiPieMenu *uiPieMenuBegin(struct bContext *C, const char *title, int icon, const struct wmEvent *event) ATTR_NONNULL(); -void uiPieMenuEnd(struct bContext *C, uiPieMenu *pie); -struct uiLayout *uiPieMenuLayout(struct uiPieMenu *pie); +int UI_pie_menu_invoke(struct bContext *C, const char *idname, const struct wmEvent *event); +int UI_pie_menu_invoke_from_operator_enum( + struct bContext *C, const char *title, const char *opname, + const char *propname, const struct wmEvent *event); +int UI_pie_menu_invoke_from_rna_enum( + struct bContext *C, const char *title, + const char *path, const struct wmEvent *event); + +struct uiPieMenu *UI_pie_menu_begin( + struct bContext *C, const char *title, int icon, + const struct wmEvent *event) ATTR_NONNULL(); +void UI_pie_menu_end(struct bContext *C, uiPieMenu *pie); +struct uiLayout *UI_pie_menu_layout(struct uiPieMenu *pie); /* Popup Blocks * * Functions used to create popup blocks. These are like popup menus @@ -380,12 +390,12 @@ struct uiLayout *uiPieMenuLayout(struct uiPieMenu *pie); typedef uiBlock * (*uiBlockCreateFunc)(struct bContext *C, struct ARegion *ar, void *arg1); typedef void (*uiBlockCancelFunc)(struct bContext *C, void *arg1); -void uiPupBlock(struct bContext *C, uiBlockCreateFunc func, void *arg); -void uiPupBlockO(struct bContext *C, uiBlockCreateFunc func, void *arg, const char *opname, int opcontext); -void uiPupBlockEx(struct bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func, void *arg); +void UI_popup_block_invoke(struct bContext *C, uiBlockCreateFunc func, void *arg); +void UI_popup_block_invoke_ex(struct bContext *C, uiBlockCreateFunc func, void *arg, const char *opname, int opcontext); +void UI_popup_block_ex(struct bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func, void *arg); /* void uiPupBlockOperator(struct bContext *C, uiBlockCreateFunc func, struct wmOperator *op, int opcontext); */ /* UNUSED */ -void uiPupBlockClose(struct bContext *C, uiBlock *block); +void UI_popup_block_close(struct bContext *C, uiBlock *block); /* Blocks * @@ -398,29 +408,29 @@ void uiPupBlockClose(struct bContext *C, uiBlock *block); * * */ -uiBlock *uiBeginBlock(const struct bContext *C, struct ARegion *region, const char *name, short dt); -void uiEndBlock_ex(const struct bContext *C, uiBlock *block, const int xy[2]); -void uiEndBlock(const struct bContext *C, uiBlock *block); -void uiDrawBlock(const struct bContext *C, struct uiBlock *block); -void uiBlockUpdateFromOld(const struct bContext *C, struct uiBlock *block); +uiBlock *UI_block_begin(const struct bContext *C, struct ARegion *region, const char *name, short dt); +void UI_block_end_ex(const struct bContext *C, uiBlock *block, const int xy[2]); +void UI_block_end(const struct bContext *C, uiBlock *block); +void UI_block_draw(const struct bContext *C, struct uiBlock *block); +void UI_block_update_from_old(const struct bContext *C, struct uiBlock *block); -uiBlock *uiGetBlock(const char *name, struct ARegion *ar); +uiBlock *UI_block_find_in_region(const char *name, struct ARegion *ar); -void uiBlockSetEmboss(uiBlock *block, char dt); +void UI_block_emboss_set(uiBlock *block, char dt); -void uiFreeBlock(const struct bContext *C, uiBlock *block); -void uiFreeBlocks(const struct bContext *C, struct ListBase *lb); -void uiFreeInactiveBlocks(const struct bContext *C, struct ListBase *lb); -void uiFreeActiveButtons(const struct bContext *C, struct bScreen *screen); +void UI_block_free(const struct bContext *C, uiBlock *block); +void UI_blocklist_free(const struct bContext *C, struct ListBase *lb); +void UI_blocklist_free_inactive(const struct bContext *C, struct ListBase *lb); +void UI_screen_free_active_but(const struct bContext *C, struct bScreen *screen); -void uiBlockSetRegion(uiBlock *block, struct ARegion *region); +void UI_block_region_set(uiBlock *block, struct ARegion *region); -void uiBlockSetButLock(uiBlock *block, bool val, const char *lockstr); -void uiBlockClearButLock(uiBlock *block); +void UI_block_lock_set(uiBlock *block, bool val, const char *lockstr); +void UI_block_lock_clear(uiBlock *block); /* automatic aligning, horiz or verical */ -void uiBlockBeginAlign(uiBlock *block); -void uiBlockEndAlign(uiBlock *block); +void UI_block_align_begin(uiBlock *block); +void UI_block_align_end(uiBlock *block); /* block bounds/position calculation */ typedef enum { @@ -433,44 +443,44 @@ typedef enum { UI_BLOCK_BOUNDS_PIE_CENTER, } eBlockBoundsCalc; -void uiBoundsBlock(struct uiBlock *block, int addval); -void uiTextBoundsBlock(uiBlock *block, int addval); -void uiPopupBoundsBlock(uiBlock *block, int addval, int mx, int my); -void uiMenuPopupBoundsBlock(uiBlock *block, int addvall, int mx, int my); -void uiCenteredBoundsBlock(uiBlock *block, int addval); -void uiExplicitBoundsBlock(uiBlock *block, int minx, int miny, int maxx, int maxy); +void UI_block_bounds_set_normal(struct uiBlock *block, int addval); +void UI_block_bounds_set_text(uiBlock *block, int addval); +void UI_block_bounds_set_popup(uiBlock *block, int addval, int mx, int my); +void UI_block_bounds_set_menu(uiBlock *block, int addvall, int mx, int my); +void UI_block_bounds_set_centered(uiBlock *block, int addval); +void UI_block_bounds_set_explicit(uiBlock *block, int minx, int miny, int maxx, int maxy); -int uiBlocksGetYMin(struct ListBase *lb); +int UI_blocklist_min_y_get(struct ListBase *lb); -void uiBlockSetDirection(uiBlock *block, char direction); -void uiBlockFlipOrder(uiBlock *block); -void uiBlockSetFlag(uiBlock *block, int flag); -void uiBlockClearFlag(uiBlock *block, int flag); +void UI_block_direction_set(uiBlock *block, char direction); +void UI_block_order_flip(uiBlock *block); +void UI_block_flag_enable(uiBlock *block, int flag); +void UI_block_flag_disable(uiBlock *block, int flag); -int uiButGetRetVal(uiBut *but); +int UI_but_return_value_get(uiBut *but); -void uiButSetDragID(uiBut *but, struct ID *id); -void uiButSetDragRNA(uiBut *but, struct PointerRNA *ptr); -void uiButSetDragPath(uiBut *but, const char *path); -void uiButSetDragName(uiBut *but, const char *name); -void uiButSetDragValue(uiBut *but); -void uiButSetDragImage(uiBut *but, const char *path, int icon, struct ImBuf *ima, float scale); +void UI_but_drag_set_id(uiBut *but, struct ID *id); +void UI_but_drag_set_rna(uiBut *but, struct PointerRNA *ptr); +void UI_but_drag_set_path(uiBut *but, const char *path); +void UI_but_drag_set_name(uiBut *but, const char *name); +void UI_but_drag_set_value(uiBut *but); +void UI_but_drag_set_image(uiBut *but, const char *path, int icon, struct ImBuf *ima, float scale); bool UI_but_active_drop_name(struct bContext *C); bool UI_but_active_drop_color(struct bContext *C); -void uiButSetFlag(uiBut *but, int flag); -void uiButClearFlag(uiBut *but, int flag); +void UI_but_flag_enable(uiBut *but, int flag); +void UI_but_flag_disable(uiBut *but, int flag); -void uiButSetDrawFlag(uiBut *but, int flag); -void uiButClearDrawFlag(uiBut *but, int flag); +void UI_but_drawflag_enable(uiBut *but, int flag); +void UI_but_drawflag_disable(uiBut *but, int flag); -void uiButSetMenuFromPulldown(uiBut *but); +void UI_but_type_set_menu_from_pulldown(uiBut *but); /* special button case, only draw it when used actively, for outliner etc */ -bool uiButActiveOnly(const struct bContext *C, struct ARegion *ar, uiBlock *block, uiBut *but); +bool UI_but_active_only(const struct bContext *C, struct ARegion *ar, uiBlock *block, uiBut *but); -void uiButExecute(const struct bContext *C, uiBut *but); +void UI_but_execute(const struct bContext *C, uiBut *but); /* Buttons @@ -544,10 +554,10 @@ uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcon uiBut *uiDefIconTextButO_ptr(uiBlock *block, int type, struct wmOperatorType *ot, int opcontext, int icon, const char *str, int x, int y, short width, short height, const char *tip); /* for passing inputs to ButO buttons */ -struct PointerRNA *uiButGetOperatorPtrRNA(uiBut *but); +struct PointerRNA *UI_but_operator_ptr_get(uiBut *but); -void uiButSetUnitType(uiBut *but, const int unit_type); -int uiButGetUnitType(const uiBut *but); +void UI_but_unit_type_set(uiBut *but, const int unit_type); +int UI_but_unit_type_get(const uiBut *but); enum { BUT_GET_RNAPROP_IDENTIFIER = 1, @@ -572,7 +582,7 @@ typedef struct uiStringInfo { /* Note: Expects pointers to uiStringInfo structs as parameters. * Will fill them with translated strings, when possible. * Strings in uiStringInfo must be MEM_freeN'ed by caller. */ -void uiButGetStrInfo(struct bContext *C, uiBut *but, ...) ATTR_SENTINEL(0); +void UI_but_string_info_get(struct bContext *C, uiBut *but, ...) ATTR_SENTINEL(0); /* Edit i18n stuff. */ /* Name of the main py op from i18n addon. */ @@ -602,8 +612,8 @@ void uiButGetStrInfo(struct bContext *C, uiBut *but, ...) ATTR_SENTINEL(0); #define UI_ID_PREVIEWS (1 << 11) #define UI_ID_FULL (UI_ID_RENAME | UI_ID_BROWSE | UI_ID_ADD_NEW | UI_ID_OPEN | UI_ID_ALONE | UI_ID_DELETE | UI_ID_LOCAL) -int uiIconFromID(struct ID *id); -int uiIconFromReportType(int type); +int UI_icon_from_id(struct ID *id); +int UI_icon_from_report_type(int type); uiBut *uiDefPulldownBut(uiBlock *block, uiBlockCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip); uiBut *uiDefMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip); @@ -632,41 +642,42 @@ int uiDefAutoButsRNA(uiLayout *layout, struct PointerRNA *ptr, bool (*check_prop * Game engine logic brick links. Non-functional currently in 2.5, * code to handle and draw these is disabled internally. */ -void uiSetButLink(struct uiBut *but, void **poin, void ***ppoin, short *tot, int from, int to); +void UI_but_link_set(struct uiBut *but, void **poin, void ***ppoin, short *tot, int from, int to); -void uiComposeLinks(uiBlock *block); -uiBut *uiFindInlink(uiBlock *block, void *poin); +void UI_block_links_compose(uiBlock *block); +uiBut *UI_block_links_find_inlink(uiBlock *block, void *poin); /* use inside searchfunc to add items */ -bool uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int iconid); +bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int iconid); /* bfunc gets search item *poin as arg2, or if NULL the old string */ -void uiButSetSearchFunc(uiBut *but, uiButSearchFunc sfunc, void *arg1, uiButHandleFunc bfunc, void *active); +void UI_but_func_search_set(uiBut *but, uiButSearchFunc sfunc, void *arg1, uiButHandleFunc bfunc, void *active); /* height in pixels, it's using hardcoded values still */ -int uiSearchBoxHeight(void); -int uiSearchBoxWidth(void); +int UI_searchbox_size_y(void); +int UI_searchbox_size_x(void); /* check if a string is in an existing search box */ -int uiSearchItemFindIndex(uiSearchItems *items, const char *name); +int UI_search_items_find_index(uiSearchItems *items, const char *name); -void uiBlockSetHandleFunc(uiBlock *block, uiBlockHandleFunc func, void *arg); -void uiBlockSetButmFunc(uiBlock *block, uiMenuHandleFunc func, void *arg); -void uiBlockSetFunc(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2); -void uiBlockSetNFunc(uiBlock *block, uiButHandleNFunc funcN, void *argN, void *arg2); +void UI_block_func_handle_set(uiBlock *block, uiBlockHandleFunc func, void *arg); +void UI_block_func_butmenu_set(uiBlock *block, uiMenuHandleFunc func, void *arg); +void UI_block_func_set(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2); +void UI_block_funcN_set(uiBlock *block, uiButHandleNFunc funcN, void *argN, void *arg2); -void uiButSetRenameFunc(uiBut *but, uiButHandleRenameFunc func, void *arg1); -void uiButSetFunc(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2); -void uiButSetNFunc(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2); +void UI_but_func_rename_set(uiBut *but, uiButHandleRenameFunc func, void *arg1); +void UI_but_func_set(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2); +void UI_but_funcN_set(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2); -void uiButSetCompleteFunc(uiBut *but, uiButCompleteFunc func, void *arg); +void UI_but_func_complete_set(uiBut *but, uiButCompleteFunc func, void *arg); -void uiBlockSetDrawExtraFunc(uiBlock *block, - void (*func)(const struct bContext *C, void *, void *, void *, struct rcti *rect), - void *arg1, void *arg2); +void UI_but_func_drawextra_set( + uiBlock *block, + void (*func)(const struct bContext *C, void *, void *, void *, struct rcti *rect), + void *arg1, void *arg2); bool UI_textbutton_activate_rna(const struct bContext *C, struct ARegion *ar, const void *rna_poin_data, const char *rna_prop_id); bool UI_textbutton_activate_but(const struct bContext *C, uiBut *but); -void uiButSetFocusOnEnter(struct wmWindow *win, uiBut *but); +void UI_but_focus_on_enter_event(struct wmWindow *win, uiBut *but); /* Autocomplete * @@ -680,9 +691,9 @@ typedef struct AutoComplete AutoComplete; #define AUTOCOMPLETE_FULL_MATCH 1 #define AUTOCOMPLETE_PARTIAL_MATCH 2 -AutoComplete *autocomplete_begin(const char *startname, size_t maxlen); -void autocomplete_do_name(AutoComplete *autocpl, const char *name); -int autocomplete_end(AutoComplete *autocpl, char *autoname); +AutoComplete *UI_autocomplete_begin(const char *startname, size_t maxlen); +void UI_autocomplete_update_name(AutoComplete *autocpl, const char *name); +int UI_autocomplete_end(AutoComplete *autocpl, char *autoname); /* Panels * @@ -690,15 +701,15 @@ int autocomplete_end(AutoComplete *autocpl, char *autoname); * could use a good cleanup, though how they will function in 2.5 is * not clear yet so we postpone that. */ -void uiBeginPanels(const struct bContext *C, struct ARegion *ar); -void uiEndPanels(const struct bContext *C, struct ARegion *ar, int *x, int *y); -void uiDrawPanels(const struct bContext *C, struct ARegion *ar); +void UI_panels_begin(const struct bContext *C, struct ARegion *ar); +void UI_panels_end(const struct bContext *C, struct ARegion *ar, int *x, int *y); +void UI_panels_draw(const struct bContext *C, struct ARegion *ar); -struct Panel *uiPanelFindByType(struct ARegion *ar, struct PanelType *pt); -struct Panel *uiBeginPanel(struct ScrArea *sa, struct ARegion *ar, uiBlock *block, - struct PanelType *pt, struct Panel *pa, bool *r_open); -void uiEndPanel(uiBlock *block, int width, int height); -void uiScalePanels(struct ARegion *ar, float new_width); +struct Panel *UI_panel_find_by_type(struct ARegion *ar, struct PanelType *pt); +struct Panel *UI_panel_begin(struct ScrArea *sa, struct ARegion *ar, uiBlock *block, + struct PanelType *pt, struct Panel *pa, bool *r_open); +void UI_panel_end(uiBlock *block, int width, int height); +void UI_panels_scale(struct ARegion *ar, float new_width); bool UI_panel_category_is_visible(struct ARegion *ar); void UI_panel_category_add(struct ARegion *ar, const char *name); @@ -717,10 +728,10 @@ void UI_panel_category_draw_all(struct ARegion *ar, const * handling WM events. Mostly this is done automatic by modules such * as screen/ if ED_KEYMAP_UI is set, or internally in popup functions. */ -void UI_add_region_handlers(struct ListBase *handlers); -void UI_add_popup_handlers(struct bContext *C, struct ListBase *handlers, uiPopupBlockHandle *popup, const bool accept_dbl_click); -void UI_remove_popup_handlers(struct ListBase *handlers, uiPopupBlockHandle *popup); -void UI_remove_popup_handlers_all(struct bContext *C, struct ListBase *handlers); +void UI_region_handlers_add(struct ListBase *handlers); +void UI_popup_handlers_add(struct bContext *C, struct ListBase *handlers, uiPopupBlockHandle *popup, const bool accept_dbl_click); +void UI_popup_handlers_remove(struct ListBase *handlers, uiPopupBlockHandle *popup); +void UI_popup_handlers_remove_all(struct bContext *C, struct ListBase *handlers); /* Module * @@ -797,9 +808,9 @@ enum { /* not apart of the corner flags but mixed in some functions */ #define UI_RB_ALPHA (UI_CNR_ALL + 1) -uiLayout *uiBlockLayout(uiBlock *block, int dir, int type, int x, int y, int size, int em, int padding, struct uiStyle *style); -void uiBlockSetCurLayout(uiBlock *block, uiLayout *layout); -void uiBlockLayoutResolve(uiBlock *block, int *x, int *y); +uiLayout *UI_block_layout(uiBlock *block, int dir, int type, int x, int y, int size, int em, int padding, struct uiStyle *style); +void UI_block_layout_set_current(uiBlock *block, uiLayout *layout); +void UI_block_layout_resolve(uiBlock *block, int *x, int *y); uiBlock *uiLayoutGetBlock(uiLayout *layout); @@ -810,7 +821,7 @@ const char *uiLayoutIntrospect(uiLayout *layout); // XXX - testing void uiLayoutOperatorButs(const struct bContext *C, struct uiLayout *layout, struct wmOperator *op, bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *), const char label_align, const short flag); -struct MenuType *uiButGetMenuType(uiBut *but); +struct MenuType *UI_but_menutype_get(uiBut *but); void uiLayoutSetOperatorContext(uiLayout *layout, int opcontext); void uiLayoutSetActive(uiLayout *layout, bool active); @@ -877,7 +888,7 @@ void uiTemplateImage(uiLayout *layout, struct bContext *C, struct PointerRNA *pt void uiTemplateImageSettings(uiLayout *layout, struct PointerRNA *imfptr, int color_management); void uiTemplateImageLayers(uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser); void uiTemplateRunningJobs(uiLayout *layout, struct bContext *C); -void uiOperatorSearch_But(uiBut *but); +void UI_but_func_operator_search(uiBut *but); void uiTemplateOperatorSearch(uiLayout *layout); void uiTemplateHeader3D(uiLayout *layout, struct bContext *C); void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C); @@ -935,6 +946,7 @@ void uiItemS(uiLayout *layout); /* separator */ void uiItemMenuF(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg); void uiItemMenuEnumO(uiLayout *layout, struct bContext *C, const char *opname, const char *propname, const char *name, int icon); +void uiItemMenuEnumR_prop(uiLayout *layout, struct PointerRNA *ptr, PropertyRNA *prop, const char *name, int icon); void uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *name, int icon); /* UI Operators */ @@ -943,32 +955,33 @@ typedef struct uiDragColorHandle { bool gamma_corrected; } uiDragColorHandle; -void UI_buttons_operatortypes(void); +void ED_button_operatortypes(void); void UI_drop_color_copy(struct wmDrag *drag, struct wmDropBox *drop); int UI_drop_color_poll(struct bContext *C, struct wmDrag *drag, const struct wmEvent *event); /* Helpers for Operators */ -uiBut *uiContextActiveButton(const struct bContext *C); -void uiContextActiveProperty(const struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop, int *index); -void uiContextActivePropertyHandle(struct bContext *C); -struct wmOperator *uiContextActiveOperator(const struct bContext *C); -void uiContextAnimUpdate(const struct bContext *C); -void uiFileBrowseContextProperty(const struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop); -void uiIDContextProperty(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop); +uiBut *UI_context_active_but_get(const struct bContext *C); +void UI_context_active_but_prop_get(const struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop, int *index); +void UI_context_active_but_prop_handle(struct bContext *C); +struct wmOperator *UI_context_active_operator_get(const struct bContext *C); +void UI_context_update_anim_flag(const struct bContext *C); +void UI_context_active_but_prop_get_filebrowser(const struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop); +void UI_context_active_but_prop_get_templateID(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop); /* Styled text draw */ -void uiStyleFontSet(struct uiFontStyle *fs); -void uiStyleFontDrawExt(struct uiFontStyle *fs, const struct rcti *rect, const char *str, - size_t len, float *r_xofs, float *r_yofs); -void uiStyleFontDraw(struct uiFontStyle *fs, const struct rcti *rect, const char *str); -void uiStyleFontDrawRotated(struct uiFontStyle *fs, const struct rcti *rect, const char *str); +void UI_fontstyle_set(struct uiFontStyle *fs); +void UI_fontstyle_draw_ex( + struct uiFontStyle *fs, const struct rcti *rect, const char *str, + size_t len, float *r_xofs, float *r_yofs); +void UI_fontstyle_draw(struct uiFontStyle *fs, const struct rcti *rect, const char *str); +void UI_fontstyle_draw_rotated(struct uiFontStyle *fs, const struct rcti *rect, const char *str); -int UI_GetStringWidth(const char *str); // XXX temp -void UI_DrawString(float x, float y, const char *str); // XXX temp -void UI_DrawTriIcon(float x, float y, char dir); +int UI_fontstyle_string_width(const char *str); // XXX temp +void UI_draw_string(float x, float y, const char *str); // XXX temp +void UI_draw_icon_tri(float x, float y, char dir); -uiStyle *UI_GetStyle(void); /* use for fonts etc */ -uiStyle *UI_GetStyleDraw(void); /* DPI scaled settings for drawing */ +uiStyle *UI_style_get(void); /* use for fonts etc */ +uiStyle *UI_style_get_dpi(void); /* DPI scaled settings for drawing */ /* linker workaround ack! */ void UI_template_fix_linking(void); @@ -988,12 +1001,13 @@ void UI_butstore_free(uiBlock *block, uiButStore *bs); bool UI_butstore_is_valid(uiButStore *bs); bool UI_butstore_is_registered(uiBlock *block, uiBut *but); void UI_butstore_register(uiButStore *bs_handle, uiBut **but_p); +bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *but_src); void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p); /* Float precision helpers */ #define UI_PRECISION_FLOAT_MAX 7 -int uiFloatPrecisionCalc(int prec, double value); +int UI_calc_float_precision(int prec, double value); #endif /* __UI_INTERFACE_H__ */ diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index 5b61e76f514..c3d6dd5da38 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -266,6 +266,8 @@ enum { TH_NLA_SOUND, TH_NLA_SOUND_SEL, + TH_WIDGET_EMBOSS, + TH_AXIS_X, /* X/Y/Z Axis */ TH_AXIS_Y, TH_AXIS_Z, diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h index cb7cf3ee404..4d7446a7a81 100644 --- a/source/blender/editors/include/UI_view2d.h +++ b/source/blender/editors/include/UI_view2d.h @@ -162,7 +162,7 @@ void UI_view2d_zoom_cache_reset(void); /* view matrix operations */ void UI_view2d_view_ortho(struct View2D *v2d); -void UI_view2d_view_orthoSpecial(struct ARegion *ar, struct View2D *v2d, short xaxis); +void UI_view2d_view_orthoSpecial(struct ARegion *ar, struct View2D *v2d, const bool xaxis); void UI_view2d_view_restore(const struct bContext *C); /* grid drawing */ @@ -234,5 +234,6 @@ void ED_keymap_view2d(struct wmKeyConfig *keyconf); void UI_view2d_smooth_view(struct bContext *C, struct ARegion *ar, const struct rctf *cur, const int smooth_viewtx); -#endif /* __UI_VIEW2D_H__ */ +#define UI_MARKER_MARGIN_Y (42 * UI_DPI_FAC) +#endif /* __UI_VIEW2D_H__ */ diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt index b921d17104c..972eca747b9 100644 --- a/source/blender/editors/interface/CMakeLists.txt +++ b/source/blender/editors/interface/CMakeLists.txt @@ -71,6 +71,12 @@ if(WITH_PYTHON) add_definitions(-DWITH_PYTHON) endif() +if(WIN32) + if(WITH_INPUT_IME) + add_definitions(-DWITH_INPUT_IME) + endif() +endif() + add_definitions(${GL_DEFINITIONS}) blender_add_lib(bf_editor_interface "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/editors/interface/SConscript b/source/blender/editors/interface/SConscript index 303ab7ff286..5af8bba5a9f 100644 --- a/source/blender/editors/interface/SConscript +++ b/source/blender/editors/interface/SConscript @@ -48,6 +48,10 @@ incs = [ defs = env['BF_GL_DEFINITIONS'] +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'win64-mingw'): + if env['WITH_BF_IME']: + defs.append('WITH_INPUT_IME') + if env['WITH_BF_INTERNATIONAL']: defs.append('WITH_INTERNATIONAL') diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 41bf5d5494e..38e331e6a1e 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -76,9 +76,9 @@ #include "interface_intern.h" -/* avoid unneeded calls to ui_get_but_val */ +/* avoid unneeded calls to ui_but_value_get */ #define UI_BUT_VALUE_UNSET DBL_MAX -#define UI_GET_BUT_VALUE_INIT(_but, _value) if (_value == DBL_MAX) { (_value) = ui_get_but_val(_but); } (void)0 +#define UI_GET_BUT_VALUE_INIT(_but, _value) if (_value == DBL_MAX) { (_value) = ui_but_value_get(_but); } (void)0 #define B_NOP -1 @@ -89,7 +89,7 @@ * ui_blah_blah() internal function */ -static void ui_free_but(const bContext *C, uiBut *but); +static void ui_but_free(const bContext *C, uiBut *but); bool ui_block_is_menu(const uiBlock *block) { @@ -103,17 +103,17 @@ bool ui_block_is_pie_menu(const uiBlock *block) return ((block->flag & UI_BLOCK_RADIAL) != 0); } -static bool ui_is_but_unit_radians_ex(UnitSettings *unit, const int unit_type) +static bool ui_but_is_unit_radians_ex(UnitSettings *unit, const int unit_type) { return (unit->system_rotation == USER_UNIT_ROT_RADIANS && unit_type == PROP_UNIT_ROTATION); } -static bool ui_is_but_unit_radians(const uiBut *but) +static bool ui_but_is_unit_radians(const uiBut *but) { UnitSettings *unit = but->block->unit; - const int unit_type = uiButGetUnitType(but); + const int unit_type = UI_but_unit_type_get(but); - return ui_is_but_unit_radians_ex(unit, unit_type); + return ui_but_is_unit_radians_ex(unit, unit_type); } /* ************* window matrix ************** */ @@ -209,6 +209,11 @@ void ui_window_to_region(const ARegion *ar, int *x, int *y) *y -= ar->winrct.ymin; } +void ui_region_to_window(const ARegion *ar, int *x, int *y) +{ + *x += ar->winrct.xmin; + *y += ar->winrct.ymin; +} /* ******************* block calc ************************* */ void ui_block_translate(uiBlock *block, int x, int y) @@ -222,16 +227,16 @@ void ui_block_translate(uiBlock *block, int x, int y) BLI_rctf_translate(&block->rect, x, y); } -static void ui_text_bounds_block(uiBlock *block, float offset) +static void ui_block_bounds_calc_text(uiBlock *block, float offset) { - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_style_get(); uiBut *bt, *init_col_bt, *col_bt; int i = 0, j, x1addval = offset; - uiStyleFontSet(&style->widget); + UI_fontstyle_set(&style->widget); for (init_col_bt = bt = block->buttons.first; bt; bt = bt->next) { - if (!ELEM(bt->type, SEPR, SEPRLINE)) { + if (!ELEM(bt->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) { j = BLF_width(style->widget.uifont_id, bt->drawstr, sizeof(bt->drawstr)); if (j > i) @@ -244,7 +249,7 @@ static void ui_text_bounds_block(uiBlock *block, float offset) col_bt->rect.xmin = x1addval; col_bt->rect.xmax = x1addval + i + block->bounds; - ui_check_but(col_bt); /* clips text again */ + ui_but_update(col_bt); /* clips text again */ } /* And we prepare next column. */ @@ -259,11 +264,11 @@ static void ui_text_bounds_block(uiBlock *block, float offset) col_bt->rect.xmin = x1addval; col_bt->rect.xmax = max_ff(x1addval + i + block->bounds, offset + block->minbounds); - ui_check_but(col_bt); /* clips text again */ + ui_but_update(col_bt); /* clips text again */ } } -void ui_bounds_block(uiBlock *block) +void ui_block_bounds_calc(uiBlock *block) { uiBut *bt; int xof; @@ -301,7 +306,7 @@ void ui_bounds_block(uiBlock *block) block->safety.ymax = block->rect.ymax + xof; } -static void ui_centered_bounds_block(wmWindow *window, uiBlock *block) +static void ui_block_bounds_calc_centered(wmWindow *window, uiBlock *block) { int xmax, ymax; int startx, starty; @@ -313,7 +318,7 @@ static void ui_centered_bounds_block(wmWindow *window, uiBlock *block) xmax = WM_window_pixels_x(window); ymax = WM_window_pixels_y(window); - ui_bounds_block(block); + ui_block_bounds_calc(block); width = BLI_rctf_size_x(&block->rect); height = BLI_rctf_size_y(&block->rect); @@ -324,11 +329,11 @@ static void ui_centered_bounds_block(wmWindow *window, uiBlock *block) ui_block_translate(block, startx - block->rect.xmin, starty - block->rect.ymin); /* now recompute bounds and safety */ - ui_bounds_block(block); + ui_block_bounds_calc(block); } -static void ui_centered_pie_bounds_block(uiBlock *block) +static void ui_block_bounds_calc_centered_pie(uiBlock *block) { const int xy[2] = { block->pie_data.pie_center_spawned[0], @@ -338,11 +343,12 @@ static void ui_centered_pie_bounds_block(uiBlock *block) ui_block_translate(block, xy[0], xy[1]); /* now recompute bounds and safety */ - ui_bounds_block(block); + ui_block_bounds_calc(block); } -static void ui_popup_bounds_block(wmWindow *window, uiBlock *block, - eBlockBoundsCalc bounds_calc, const int xy[2]) +static void ui_block_bounds_calc_popup( + wmWindow *window, uiBlock *block, + eBlockBoundsCalc bounds_calc, const int xy[2]) { int startx, starty, endx, endy, width, height, oldwidth, oldheight; int oldbounds, xmax, ymax; @@ -351,7 +357,7 @@ static void ui_popup_bounds_block(wmWindow *window, uiBlock *block, oldbounds = block->bounds; /* compute mouse position with user defined offset */ - ui_bounds_block(block); + ui_block_bounds_calc(block); xmax = WM_window_pixels_x(window); ymax = WM_window_pixels_y(window); @@ -363,13 +369,13 @@ static void ui_popup_bounds_block(wmWindow *window, uiBlock *block, if (bounds_calc == UI_BLOCK_BOUNDS_POPUP_MENU) { if (block->flag & UI_BLOCK_LOOP) { block->bounds = 2.5f * UI_UNIT_X; - ui_text_bounds_block(block, block->rect.xmin); + ui_block_bounds_calc_text(block, block->rect.xmin); } } /* next we recompute bounds */ block->bounds = oldbounds; - ui_bounds_block(block); + ui_block_bounds_calc(block); /* and we adjust the position to fit within window */ width = BLI_rctf_size_x(&block->rect); @@ -380,7 +386,7 @@ static void ui_popup_bounds_block(wmWindow *window, uiBlock *block, oldheight = oldheight > 0 ? oldheight : MAX2(1, height); /* offset block based on mouse position, user offset is scaled - * along in case we resized the block in ui_text_bounds_block */ + * along in case we resized the block in ui_block_bounds_calc_text */ startx = xy[0] + block->rect.xmin + (block->mx * width) / oldwidth; starty = xy[1] + block->rect.ymin + (block->my * height) / oldheight; @@ -404,11 +410,11 @@ static void ui_popup_bounds_block(wmWindow *window, uiBlock *block, ui_block_translate(block, startx - block->rect.xmin, starty - block->rect.ymin); /* now recompute bounds and safety */ - ui_bounds_block(block); + ui_block_bounds_calc(block); } /* used for various cases */ -void uiBoundsBlock(uiBlock *block, int addval) +void UI_block_bounds_set_normal(uiBlock *block, int addval) { if (block == NULL) return; @@ -418,14 +424,14 @@ void uiBoundsBlock(uiBlock *block, int addval) } /* used for pulldowns */ -void uiTextBoundsBlock(uiBlock *block, int addval) +void UI_block_bounds_set_text(uiBlock *block, int addval) { block->bounds = addval; block->bounds_type = UI_BLOCK_BOUNDS_TEXT; } /* used for block popups */ -void uiPopupBoundsBlock(uiBlock *block, int addval, int mx, int my) +void UI_block_bounds_set_popup(uiBlock *block, int addval, int mx, int my) { block->bounds = addval; block->bounds_type = UI_BLOCK_BOUNDS_POPUP_MOUSE; @@ -434,7 +440,7 @@ void uiPopupBoundsBlock(uiBlock *block, int addval, int mx, int my) } /* used for menu popups */ -void uiMenuPopupBoundsBlock(uiBlock *block, int addval, int mx, int my) +void UI_block_bounds_set_menu(uiBlock *block, int addval, int mx, int my) { block->bounds = addval; block->bounds_type = UI_BLOCK_BOUNDS_POPUP_MENU; @@ -443,13 +449,13 @@ void uiMenuPopupBoundsBlock(uiBlock *block, int addval, int mx, int my) } /* used for centered popups, i.e. splash */ -void uiCenteredBoundsBlock(uiBlock *block, int addval) +void UI_block_bounds_set_centered(uiBlock *block, int addval) { block->bounds = addval; block->bounds_type = UI_BLOCK_BOUNDS_POPUP_CENTER; } -void uiExplicitBoundsBlock(uiBlock *block, int minx, int miny, int maxx, int maxy) +void UI_block_bounds_set_explicit(uiBlock *block, int minx, int miny, int maxx, int maxy) { block->rect.xmin = minx; block->rect.ymin = miny; @@ -458,21 +464,21 @@ void uiExplicitBoundsBlock(uiBlock *block, int minx, int miny, int maxx, int max block->bounds_type = UI_BLOCK_BOUNDS_NONE; } -static int ui_but_float_precision(uiBut *but, double value) +static int ui_but_calc_float_precision(uiBut *but, double value) { int prec = (int)but->a2; /* first check for various special cases: * * If button is radians, we want additional precision (see T39861). * * If prec is not set, we fallback to a simple default */ - if (ui_is_but_unit_radians(but) && prec < 5) { + if (ui_but_is_unit_radians(but) && prec < 5) { prec = 5; } else if (prec == -1) { prec = (but->hardmax < 10.001f) ? 3 : 2; } - return uiFloatPrecisionCalc(prec, value); + return UI_calc_float_precision(prec, value); } /* ************** LINK LINE DRAWING ************* */ @@ -514,7 +520,7 @@ static void ui_draw_links(uiBlock *block) bool found_activeline = false; for (but = block->buttons.first; but; but = but->next) { - if (but->type == LINK && but->link) { + if (but->type == UI_BTYPE_LINK && but->link) { for (line = but->link->lines.first; line; line = line->next) { if (!(line->from->flag & UI_ACTIVE) && !(line->to->flag & UI_ACTIVE)) { if (line->deactive) @@ -531,7 +537,7 @@ static void ui_draw_links(uiBlock *block) /* Draw the inactive lines (lines with neither button being hovered over) */ for (but = block->buttons.first; but; but = but->next) { - if (but->type == LINK && but->link) { + if (but->type == UI_BTYPE_LINK && but->link) { for (line = but->link->lines.first; line; line = line->next) { if (!(line->from->flag & UI_ACTIVE) && !(line->to->flag & UI_ACTIVE)) { if (!line->deactive) @@ -545,7 +551,7 @@ static void ui_draw_links(uiBlock *block) * Do this last so they appear on top of inactive and grey out lines. */ if (found_activeline) { for (but = block->buttons.first; but; but = but->next) { - if (but->type == LINK && but->link) { + if (but->type == UI_BTYPE_LINK && but->link) { for (line = but->link->lines.first; line; line = line->next) { if ((line->from->flag & UI_ACTIVE) || (line->to->flag & UI_ACTIVE)) ui_draw_linkline(line, !found_selectline, false); @@ -603,8 +609,8 @@ static void ui_but_update_linklines(uiBlock *block, uiBut *oldbut, uiBut *newbut uiLinkLine *line; uiBut *but; - /* if active button is LINK */ - if (newbut->type == LINK && newbut->link) { + /* if active button is UI_BTYPE_LINK */ + if (newbut->type == UI_BTYPE_LINK && newbut->link) { SWAP(uiLink *, oldbut->link, newbut->link); @@ -618,7 +624,7 @@ static void ui_but_update_linklines(uiBlock *block, uiBut *oldbut, uiBut *newbut /* check all other button links */ for (but = block->buttons.first; but; but = but->next) { - if (but != newbut && but->type == LINK && but->link) { + if (but != newbut && but->type == UI_BTYPE_LINK && but->link) { for (line = but->link->lines.first; line; line = line->next) { if (line->to == newbut) line->to = oldbut; @@ -717,11 +723,15 @@ static bool ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBu /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position * when scrolling without moving mouse (see [#28432]) */ - if (ELEM(oldbut->type, ROW, LISTROW)) + if (ELEM(oldbut->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) oldbut->hardmax = but->hardmax; ui_but_update_linklines(block, oldbut, but); + if (!BLI_listbase_is_empty(&block->butstore)) { + UI_butstore_register_update(block, oldbut, but); + } + /* move/copy string from the new button to the old */ /* needed for alt+mouse wheel over enums */ if (but->str != but->strdata) { @@ -742,7 +752,7 @@ static bool ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBu } BLI_remlink(&block->buttons, but); - ui_free_but(C, but); + ui_but_free(C, but); /* note: if layout hasn't been applied yet, it uses old button pointers... */ } @@ -754,7 +764,7 @@ static bool ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBu /* ensures one button can get activated, and in case the buttons * draw are the same this gives O(1) lookup for each button */ BLI_remlink(&oldblock->buttons, oldbut); - ui_free_but(C, oldbut); + ui_but_free(C, oldbut); } return found_active; @@ -763,7 +773,7 @@ static bool ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBu /* needed for temporarily rename buttons, such as in outliner or file-select, * they should keep calling uiDefButs to keep them alive */ /* returns 0 when button removed */ -bool uiButActiveOnly(const bContext *C, ARegion *ar, uiBlock *block, uiBut *but) +bool UI_but_active_only(const bContext *C, ARegion *ar, uiBlock *block, uiBut *but) { uiBlock *oldblock; uiBut *oldbut; @@ -784,11 +794,11 @@ bool uiButActiveOnly(const bContext *C, ARegion *ar, uiBlock *block, uiBut *but) } } if ((activate == true) || (found == false)) { - ui_button_activate_do((bContext *)C, ar, but); + ui_but_activate_event((bContext *)C, ar, but); } else if ((found == true) && (isactive == false)) { BLI_remlink(&block->buttons, but); - ui_free_but(C, but); + ui_but_free(C, but); return false; } @@ -796,18 +806,18 @@ bool uiButActiveOnly(const bContext *C, ARegion *ar, uiBlock *block, uiBut *but) } /* simulate button click */ -void uiButExecute(const bContext *C, uiBut *but) +void UI_but_execute(const bContext *C, uiBut *but) { ARegion *ar = CTX_wm_region(C); void *active_back; - ui_button_execute_begin((bContext *)C, ar, but, &active_back); + ui_but_execute_begin((bContext *)C, ar, but, &active_back); /* Value is applied in begin. No further action required. */ - ui_button_execute_end((bContext *)C, ar, but, active_back); + ui_but_execute_end((bContext *)C, ar, but, active_back); } /* use to check if we need to disable undo, but don't make any changes * returns false if undo needs to be disabled. */ -static bool ui_is_but_rna_undo(const uiBut *but) +static bool ui_but_is_rna_undo(const uiBut *but) { if (but->rnapoin.id.data) { /* avoid undo push for buttons who's ID are screen or wm level @@ -850,7 +860,13 @@ static void ui_menu_block_set_keyaccels(uiBlock *block) * fun first pass on all buttons so first word chars always get first priority */ for (but = block->buttons.first; but; but = but->next) { - if (!ELEM(but->type, BUT, BUTM, MENU, BLOCK, PULLDOWN) || (but->flag & UI_HIDDEN)) { + if (!ELEM(but->type, + UI_BTYPE_BUT, + UI_BTYPE_BUT_MENU, + UI_BTYPE_MENU, UI_BTYPE_BLOCK, + UI_BTYPE_PULLDOWN) || + (but->flag & UI_HIDDEN)) + { /* pass */ } else if (but->menu_key == '\0') { @@ -930,7 +946,7 @@ void ui_but_add_shortcut(uiBut *but, const char *shortcut_str, const bool do_str MEM_freeN(butstr_orig); but->str = but->strdata; but->flag |= UI_BUT_HAS_SEP_CHAR; - ui_check_but(but); + ui_but_update(but); } } @@ -948,7 +964,7 @@ static bool ui_but_event_operator_string(const bContext *C, uiBut *but, char *bu found = true; } } - else if ((mt = uiButGetMenuType(but))) { + else if ((mt = UI_but_menutype_get(but))) { IDProperty *prop_menu; IDProperty *prop_menu_name; @@ -1147,7 +1163,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) } } -void uiBlockUpdateFromOld(const bContext *C, uiBlock *block) +void UI_block_update_from_old(const bContext *C, uiBlock *block) { uiBut *but_old; uiBut *but; @@ -1163,20 +1179,19 @@ void uiBlockUpdateFromOld(const bContext *C, uiBlock *block) for (but = block->buttons.first; but; but = but->next) { if (ui_but_update_from_old_block(C, block, &but, &but_old)) { - ui_check_but(but); + ui_but_update(but); } } block->auto_open = block->oldblock->auto_open; block->auto_open_last = block->oldblock->auto_open_last; block->tooltipdisabled = block->oldblock->tooltipdisabled; - copy_v3_v3(ui_block_hsv_get(block), - ui_block_hsv_get(block->oldblock)); + BLI_movelisttolist(&block->color_pickers.list, &block->oldblock->color_pickers.list); block->oldblock = NULL; } -void uiEndBlock_ex(const bContext *C, uiBlock *block, const int xy[2]) +void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2]) { wmWindow *window = CTX_wm_window(C); Scene *scene = CTX_data_scene(C); @@ -1184,7 +1199,7 @@ void uiEndBlock_ex(const bContext *C, uiBlock *block, const int xy[2]) BLI_assert(block->active); - uiBlockUpdateFromOld(C, block); + UI_block_update_from_old(C, block); /* inherit flags from 'old' buttons that was drawn here previous, based * on matching buttons, we need this to make button event handling non @@ -1214,9 +1229,9 @@ void uiEndBlock_ex(const bContext *C, uiBlock *block, const int xy[2]) /* handle pending stuff */ if (block->layouts.first) { - uiBlockLayoutResolve(block, NULL, NULL); + UI_block_layout_resolve(block, NULL, NULL); } - ui_block_do_align(block); + ui_block_align_calc(block); if ((block->flag & UI_BLOCK_LOOP) && (block->flag & UI_BLOCK_NUMSELECT)) { ui_menu_block_set_keyaccels(block); /* could use a different flag to check */ } @@ -1230,40 +1245,40 @@ void uiEndBlock_ex(const bContext *C, uiBlock *block, const int xy[2]) case UI_BLOCK_BOUNDS_NONE: break; case UI_BLOCK_BOUNDS: - ui_bounds_block(block); + ui_block_bounds_calc(block); break; case UI_BLOCK_BOUNDS_TEXT: - ui_text_bounds_block(block, 0.0f); + ui_block_bounds_calc_text(block, 0.0f); break; case UI_BLOCK_BOUNDS_POPUP_CENTER: - ui_centered_bounds_block(window, block); + ui_block_bounds_calc_centered(window, block); break; case UI_BLOCK_BOUNDS_PIE_CENTER: - ui_centered_pie_bounds_block(block); + ui_block_bounds_calc_centered_pie(block); break; /* fallback */ case UI_BLOCK_BOUNDS_POPUP_MOUSE: case UI_BLOCK_BOUNDS_POPUP_MENU: - ui_popup_bounds_block(window, block, block->bounds_type, xy); + ui_block_bounds_calc_popup(window, block, block->bounds_type, xy); break; } if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) { - uiBoundsBlock(block, 0); + UI_block_bounds_set_normal(block, 0); } if (block->flag & UI_BUT_ALIGN) { - uiBlockEndAlign(block); + UI_block_align_end(block); } block->endblock = 1; } -void uiEndBlock(const bContext *C, uiBlock *block) +void UI_block_end(const bContext *C, uiBlock *block) { wmWindow *window = CTX_wm_window(C); - uiEndBlock_ex(C, block, &window->eventstate->x); + UI_block_end_ex(C, block, &window->eventstate->x); } /* ************** BLOCK DRAWING FUNCTION ************* */ @@ -1304,9 +1319,9 @@ static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, u } /* uses local copy of style, to scale things down, and allow widgets to change stuff */ -void uiDrawBlock(const bContext *C, uiBlock *block) +void UI_block_draw(const bContext *C, uiBlock *block) { - uiStyle style = *UI_GetStyleDraw(); /* XXX pass on as arg */ + uiStyle style = *UI_style_get_dpi(); /* XXX pass on as arg */ ARegion *ar; uiBut *but; rcti rect; @@ -1318,7 +1333,7 @@ void uiDrawBlock(const bContext *C, uiBlock *block) ar = CTX_wm_region(C); if (!block->endblock) - uiEndBlock(C, block); + UI_block_end(C, block); /* disable AA, makes widgets too blurry */ multisample_enabled = glIsEnabled(GL_MULTISAMPLE_ARB); @@ -1385,12 +1400,12 @@ void uiDrawBlock(const bContext *C, uiBlock *block) * * \return (0 == UNSELECT), (1 == SELECT), (-1 == DO-NOTHING) */ -int ui_is_but_push_ex(uiBut *but, double *value) +int ui_but_is_pushed_ex(uiBut *but, double *value) { int is_push = 0; if (but->bit) { - const bool state = ELEM(but->type, TOGN, ICONTOGN, OPTIONN) ? false : true; + const bool state = ELEM(but->type, UI_BTYPE_TOGGLE_N, UI_BTYPE_ICON_TOGGLE_N, UI_BTYPE_CHECKBOX_N) ? false : true; int lvalue; UI_GET_BUT_VALUE_INIT(but, *value); lvalue = (int)*value; @@ -1403,27 +1418,27 @@ int ui_is_but_push_ex(uiBut *but, double *value) } else { switch (but->type) { - case BUT: - case HOTKEYEVT: - case KEYEVT: - case COLOR: + case UI_BTYPE_BUT: + case UI_BTYPE_HOTKEY_EVENT: + case UI_BTYPE_KEY_EVENT: + case UI_BTYPE_COLOR: is_push = -1; break; - case TOGBUT: - case TOG: - case ICONTOG: - case OPTION: + case UI_BTYPE_BUT_TOGGLE: + case UI_BTYPE_TOGGLE: + case UI_BTYPE_ICON_TOGGLE: + case UI_BTYPE_CHECKBOX: UI_GET_BUT_VALUE_INIT(but, *value); if (*value != (double)but->hardmin) is_push = true; break; - case ICONTOGN: - case TOGN: - case OPTIONN: + case UI_BTYPE_ICON_TOGGLE_N: + case UI_BTYPE_TOGGLE_N: + case UI_BTYPE_CHECKBOX_N: UI_GET_BUT_VALUE_INIT(but, *value); if (*value == 0.0) is_push = true; break; - case ROW: - case LISTROW: + case UI_BTYPE_ROW: + case UI_BTYPE_LISTROW: UI_GET_BUT_VALUE_INIT(but, *value); /* support for rna enum buts */ if (but->rnaprop && (RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG)) { @@ -1441,15 +1456,15 @@ int ui_is_but_push_ex(uiBut *but, double *value) return is_push; } -int ui_is_but_push(uiBut *but) +int ui_but_is_pushed(uiBut *but) { double value = UI_BUT_VALUE_UNSET; - return ui_is_but_push_ex(but, &value); + return ui_but_is_pushed_ex(but, &value); } -static void ui_check_but_select(uiBut *but, double *value) +static void ui_but_update_select_flag(uiBut *but, double *value) { - switch (ui_is_but_push_ex(but, value)) { + switch (ui_but_is_pushed_ex(but, value)) { case true: but->flag |= UI_SELECT; break; @@ -1459,13 +1474,13 @@ static void ui_check_but_select(uiBut *but, double *value) } } -static uiBut *ui_find_inlink(uiBlock *block, void *poin) +static uiBut *ui_linkline_find_inlink(uiBlock *block, void *poin) { uiBut *but; but = block->buttons.first; while (but) { - if (but->type == INLINK) { + if (but->type == UI_BTYPE_INLINK) { if (but->poin == poin) return but; } but = but->next; @@ -1473,7 +1488,7 @@ static uiBut *ui_find_inlink(uiBlock *block, void *poin) return NULL; } -static void ui_add_link_line(ListBase *listb, uiBut *but, uiBut *bt, short deactive) +static void ui_linkline_add(ListBase *listb, uiBut *but, uiBut *bt, short deactive) { uiLinkLine *line; @@ -1484,12 +1499,12 @@ static void ui_add_link_line(ListBase *listb, uiBut *but, uiBut *bt, short deact line->deactive = deactive; } -uiBut *uiFindInlink(uiBlock *block, void *poin) +uiBut *UI_block_links_find_inlink(uiBlock *block, void *poin) { - return ui_find_inlink(block, poin); + return ui_linkline_find_inlink(block, poin); } -void uiComposeLinks(uiBlock *block) +void UI_block_links_compose(uiBlock *block) { uiBut *but, *bt; uiLink *link; @@ -1498,7 +1513,7 @@ void uiComposeLinks(uiBlock *block) but = block->buttons.first; while (but) { - if (but->type == LINK) { + if (but->type == UI_BTYPE_LINK) { link = but->link; /* for all pointers in the array */ @@ -1506,26 +1521,26 @@ void uiComposeLinks(uiBlock *block) if (link->ppoin) { ppoin = link->ppoin; for (a = 0; a < *(link->totlink); a++) { - bt = ui_find_inlink(block, (*ppoin)[a]); + bt = ui_linkline_find_inlink(block, (*ppoin)[a]); if (bt) { if ((but->flag & UI_BUT_SCA_LINK_GREY) || (bt->flag & UI_BUT_SCA_LINK_GREY)) { - ui_add_link_line(&link->lines, but, bt, true); + ui_linkline_add(&link->lines, but, bt, true); } else { - ui_add_link_line(&link->lines, but, bt, false); + ui_linkline_add(&link->lines, but, bt, false); } } } } else if (link->poin) { - bt = ui_find_inlink(block, *link->poin); + bt = ui_linkline_find_inlink(block, *link->poin); if (bt) { if ((but->flag & UI_BUT_SCA_LINK_GREY) || (bt->flag & UI_BUT_SCA_LINK_GREY)) { - ui_add_link_line(&link->lines, but, bt, true); + ui_linkline_add(&link->lines, but, bt, true); } else { - ui_add_link_line(&link->lines, but, bt, false); + ui_linkline_add(&link->lines, but, bt, false); } } } @@ -1538,7 +1553,7 @@ void uiComposeLinks(uiBlock *block) /* ************************************************ */ -void uiBlockSetButLock(uiBlock *block, bool val, const char *lockstr) +void UI_block_lock_set(uiBlock *block, bool val, const char *lockstr) { if (val) { block->lock = val; @@ -1546,7 +1561,7 @@ void uiBlockSetButLock(uiBlock *block, bool val, const char *lockstr) } } -void uiBlockClearButLock(uiBlock *block) +void UI_block_lock_clear(uiBlock *block) { block->lock = false; block->lockstr = NULL; @@ -1554,7 +1569,7 @@ void uiBlockClearButLock(uiBlock *block) /* *************************************************************** */ -void ui_delete_linkline(uiLinkLine *line, uiBut *but) +void ui_linkline_remove(uiLinkLine *line, uiBut *but) { uiLink *link; int a, b; @@ -1595,7 +1610,7 @@ void ui_delete_linkline(uiLinkLine *line, uiBut *but) * an edit override pointer while dragging for example */ /* for buttons pointing to color for example */ -void ui_get_but_vectorf(uiBut *but, float vec[3]) +void ui_but_v3_get(uiBut *but, float vec[3]) { PropertyRNA *prop; int a; @@ -1641,13 +1656,13 @@ void ui_get_but_vectorf(uiBut *but, float vec[3]) } } - if (but->type == BUT_NORMAL) { + if (but->type == UI_BTYPE_UNITVEC) { normalize_v3(vec); } } /* for buttons pointing to color for example */ -void ui_set_but_vectorf(uiBut *but, const float vec[3]) +void ui_but_v3_set(uiBut *but, const float vec[3]) { PropertyRNA *prop; @@ -1687,7 +1702,7 @@ void ui_set_but_vectorf(uiBut *but, const float vec[3]) } } -bool ui_is_but_float(const uiBut *but) +bool ui_but_is_float(const uiBut *but) { if (but->pointype == UI_BUT_POIN_FLOAT && but->poin) return true; @@ -1698,28 +1713,31 @@ bool ui_is_but_float(const uiBut *but) return false; } -bool ui_is_but_bool(const uiBut *but) +bool ui_but_is_bool(const uiBut *but) { - if (ELEM(but->type, TOG, TOGN, ICONTOG, ICONTOGN)) + if (ELEM(but->type, UI_BTYPE_TOGGLE, UI_BTYPE_TOGGLE_N, UI_BTYPE_ICON_TOGGLE, UI_BTYPE_ICON_TOGGLE_N)) return true; if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_BOOLEAN) return true; + if ((but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) && (but->type == UI_BTYPE_ROW)) + return true; + return false; } -bool ui_is_but_unit(const uiBut *but) +bool ui_but_is_unit(const uiBut *but) { UnitSettings *unit = but->block->unit; - const int unit_type = uiButGetUnitType(but); + const int unit_type = UI_but_unit_type_get(but); if (unit_type == PROP_UNIT_NONE) return false; #if 1 /* removed so angle buttons get correct snapping */ - if (ui_is_but_unit_radians_ex(unit, unit_type)) + if (ui_but_is_unit_radians_ex(unit, unit_type)) return false; #endif @@ -1739,7 +1757,7 @@ bool ui_is_but_unit(const uiBut *but) /** * Check if this button is similar enough to be grouped with another. */ -bool ui_is_but_compatible(const uiBut *but_a, const uiBut *but_b) +bool ui_but_is_compatible(const uiBut *but_a, const uiBut *but_b) { if (but_a->type != but_b->type) return false; @@ -1747,12 +1765,10 @@ bool ui_is_but_compatible(const uiBut *but_a, const uiBut *but_b) return false; if (but_a->rnaprop) { + /* skip 'rnapoin.data', 'rnapoin.id.data' + * allow different data to have the same props edited at once */ if (but_a->rnapoin.type != but_b->rnapoin.type) return false; - if (but_a->rnapoin.data != but_b->rnapoin.data) - return false; - if (but_a->rnapoin.id.data != but_b->rnapoin.id.data) - return false; if (RNA_property_type(but_a->rnaprop) != RNA_property_type(but_b->rnaprop)) return false; if (RNA_property_subtype(but_a->rnaprop) != RNA_property_subtype(but_b->rnaprop)) @@ -1762,7 +1778,7 @@ bool ui_is_but_compatible(const uiBut *but_a, const uiBut *but_b) return true; } -bool ui_is_but_rna_valid(uiBut *but) +bool ui_but_is_rna_valid(uiBut *but) { if (but->rnaprop == NULL || RNA_struct_contains_property(&but->rnapoin, but->rnaprop)) { return true; @@ -1773,7 +1789,7 @@ bool ui_is_but_rna_valid(uiBut *but) } } -double ui_get_but_val(uiBut *but) +double ui_but_value_get(uiBut *but) { PropertyRNA *prop; double value = 0.0; @@ -1829,7 +1845,7 @@ double ui_get_but_val(uiBut *but) return value; } -void ui_set_but_val(uiBut *but, double value) +void ui_but_value_set(uiBut *but, double value) { PropertyRNA *prop; @@ -1908,18 +1924,18 @@ void ui_set_but_val(uiBut *but, double value) value = *((float *)but->poin) = (float)value; } - ui_check_but_select(but, &value); + ui_but_update_select_flag(but, &value); } -int ui_get_but_string_max_length(uiBut *but) +int ui_but_string_get_max_length(uiBut *but) { - if (ELEM(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) + if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) return but->hardmax; else return UI_MAX_DRAW_STR; } -uiBut *ui_get_but_drag_multi_edit(uiBut *but) +uiBut *ui_but_drag_multi_edit_get(uiBut *but) { uiBut *but_iter; @@ -1937,7 +1953,7 @@ uiBut *ui_get_but_drag_multi_edit(uiBut *but) static double ui_get_but_scale_unit(uiBut *but, double value) { UnitSettings *unit = but->block->unit; - int unit_type = uiButGetUnitType(but); + int unit_type = UI_but_unit_type_get(but); /* Time unit is a bit special, not handled by BKE_scene_unit_scale() for now. */ if (unit_type == PROP_UNIT_TIME) { /* WARNING - using evil_C :| */ @@ -1950,11 +1966,11 @@ static double ui_get_but_scale_unit(uiBut *but, double value) } /* str will be overwritten */ -void ui_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen) +void ui_but_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen) { - if (ui_is_but_unit(but)) { + if (ui_but_is_unit(but)) { UnitSettings *unit = but->block->unit; - int unit_type = uiButGetUnitType(but); + int unit_type = UI_but_unit_type_get(but); char *orig_str; orig_str = BLI_strdup(str); @@ -1972,7 +1988,7 @@ static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double va { UnitSettings *unit = but->block->unit; const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0; - int unit_type = uiButGetUnitType(but); + int unit_type = UI_but_unit_type_get(but); int precision; if (unit->scale_length < 0.0001f) unit->scale_length = 1.0f; // XXX do_versions @@ -1994,7 +2010,7 @@ static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double va static float ui_get_but_step_unit(uiBut *but, float step_default) { - int unit_type = RNA_SUBTYPE_UNIT_VALUE(uiButGetUnitType(but)); + int unit_type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but)); double step; step = bUnit_ClosestScalar(ui_get_but_scale_unit(but, step_default), but->block->unit->system, unit_type); @@ -2012,9 +2028,9 @@ static float ui_get_but_step_unit(uiBut *but, float step_default) /** * \param float_precision For number buttons the precision to use or -1 to fallback to the button default. */ -void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision) +void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision) { - if (but->rnaprop && ELEM(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) { + if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) { PropertyType type; const char *buf = NULL; int buf_len; @@ -2051,12 +2067,12 @@ void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int MEM_freeN((void *)buf); } } - else if (but->type == TEX) { + else if (but->type == UI_BTYPE_TEXT) { /* string */ BLI_strncpy(str, but->poin, maxlen); return; } - else if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) { + else if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) { /* string */ BLI_strncpy(str, but->poin, maxlen); return; @@ -2068,14 +2084,14 @@ void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int /* number editing */ double value; - value = ui_get_but_val(but); + value = ui_but_value_get(but); - if (ui_is_but_float(but)) { - if (ui_is_but_unit(but)) { + if (ui_but_is_float(but)) { + if (ui_but_is_unit(but)) { ui_get_but_string_unit(but, str, maxlen, value, false, float_precision); } else { - const int prec = (float_precision == -1) ? ui_but_float_precision(but, value) : float_precision; + const int prec = (float_precision == -1) ? ui_but_calc_float_precision(but, value) : float_precision; BLI_snprintf(str, maxlen, "%.*f", prec, value); } } @@ -2083,9 +2099,9 @@ void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int BLI_snprintf(str, maxlen, "%d", (int)value); } } -void ui_get_but_string(uiBut *but, char *str, const size_t maxlen) +void ui_but_string_get(uiBut *but, char *str, const size_t maxlen) { - ui_get_but_string_ex(but, str, maxlen, -1); + ui_but_string_get_ex(but, str, maxlen, -1); } #ifdef WITH_PYTHON @@ -2093,7 +2109,7 @@ void ui_get_but_string(uiBut *but, char *str, const size_t maxlen) static bool ui_set_but_string_eval_num_unit(bContext *C, uiBut *but, const char *str, double *value) { char str_unit_convert[256]; - const int unit_type = uiButGetUnitType(but); + const int unit_type = UI_but_unit_type_get(but); BLI_strncpy(str_unit_convert, str, sizeof(str_unit_convert)); @@ -2108,14 +2124,14 @@ static bool ui_set_but_string_eval_num_unit(bContext *C, uiBut *but, const char #endif /* WITH_PYTHON */ -bool ui_set_but_string_eval_num(bContext *C, uiBut *but, const char *str, double *value) +bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double *value) { bool ok = false; #ifdef WITH_PYTHON if (str[0] != '\0') { - bool is_unit_but = (ui_is_but_float(but) && ui_is_but_unit(but)); + bool is_unit_but = (ui_but_is_float(but) && ui_but_is_unit(but)); /* only enable verbose if we won't run again with units */ if (BPY_button_exec(C, str, value, is_unit_but == false) != -1) { /* if the value parsed ok without unit conversion this button may still need a unit multiplier */ @@ -2149,9 +2165,9 @@ bool ui_set_but_string_eval_num(bContext *C, uiBut *but, const char *str, double } -bool ui_set_but_string(bContext *C, uiBut *but, const char *str) +bool ui_but_string_set(bContext *C, uiBut *but, const char *str) { - if (but->rnaprop && ELEM(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) { + if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) { if (RNA_property_editable(&but->rnapoin, but->rnaprop)) { PropertyType type; @@ -2196,14 +2212,14 @@ bool ui_set_but_string(bContext *C, uiBut *but, const char *str) } } } - else if (but->type == TEX) { + else if (but->type == UI_BTYPE_TEXT) { /* string */ - if (ui_is_but_utf8(but)) BLI_strncpy_utf8(but->poin, str, but->hardmax); + if (ui_but_is_utf8(but)) BLI_strncpy_utf8(but->poin, str, but->hardmax); else BLI_strncpy(but->poin, str, but->hardmax); return true; } - else if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) { + else if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) { /* string */ BLI_strncpy(but->poin, str, but->hardmax); return true; @@ -2220,38 +2236,37 @@ bool ui_set_but_string(bContext *C, uiBut *but, const char *str) /* number editing */ double value; - if (ui_set_but_string_eval_num(C, but, str, &value) == false) { + if (ui_but_string_set_eval_num(C, but, str, &value) == false) { return false; } - if (!ui_is_but_float(but)) value = (int)floor(value + 0.5); + if (!ui_but_is_float(but)) value = (int)floor(value + 0.5); /* not that we use hard limits here */ if (value < (double)but->hardmin) value = but->hardmin; if (value > (double)but->hardmax) value = but->hardmax; - ui_set_but_val(but, value); + ui_but_value_set(but, value); return true; } return false; } -void ui_set_but_default(bContext *C, const bool all, const bool use_afterfunc) +void ui_but_default_set(bContext *C, const bool all, const bool use_afterfunc) { - const char *opstring = "UI_OT_reset_default_button"; + wmOperatorType *ot = WM_operatortype_find("UI_OT_reset_default_button", true); if (use_afterfunc) { PointerRNA *ptr; - wmOperatorType *ot = WM_operatortype_find(opstring, 0); ptr = ui_handle_afterfunc_add_operator(ot, WM_OP_EXEC_DEFAULT, true); RNA_boolean_set(ptr, "all", all); } else { PointerRNA ptr; - WM_operator_properties_create(&ptr, opstring); + WM_operator_properties_create_ptr(&ptr, ot); RNA_boolean_set(&ptr, "all", all); - WM_operator_name_call(C, opstring, WM_OP_EXEC_DEFAULT, &ptr); + WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &ptr); WM_operator_properties_free(&ptr); } } @@ -2367,7 +2382,7 @@ static void ui_set_but_soft_range(uiBut *but) but->softmax = softmax; } else if (but->poin && (but->pointype & UI_BUT_POIN_TYPES)) { - float value = ui_get_but_val(but); + float value = ui_but_value_get(but); CLAMP(value, but->hardmin, but->hardmax); but->softmin = min_ff(but->softmin, value); but->softmax = max_ff(but->softmax, value); @@ -2388,7 +2403,7 @@ static void ui_free_link(uiLink *link) } /* can be called with C==NULL */ -static void ui_free_but(const bContext *C, uiBut *but) +static void ui_but_free(const bContext *C, uiBut *but) { if (but->opptr) { WM_operator_properties_free(but->opptr); @@ -2404,7 +2419,7 @@ static void ui_free_but(const bContext *C, uiBut *but) * however they may have open tooltips or popup windows, which need to * be closed using a context pointer */ if (C) { - ui_button_active_free(C, but); + ui_but_active_free(C, but); } else { if (but->active) { @@ -2417,7 +2432,7 @@ static void ui_free_but(const bContext *C, uiBut *but) } ui_free_link(but->link); - if ((but->type == BUT_IMAGE) && but->poin) { + if ((but->type == UI_BTYPE_IMAGE) && but->poin) { IMB_freeImBuf((struct ImBuf *)but->poin); } @@ -2427,14 +2442,14 @@ static void ui_free_but(const bContext *C, uiBut *but) } /* can be called with C==NULL */ -void uiFreeBlock(const bContext *C, uiBlock *block) +void UI_block_free(const bContext *C, uiBlock *block) { uiBut *but; UI_butstore_clear(block); while ((but = BLI_pophead(&block->buttons))) { - ui_free_but(C, but); + ui_but_free(C, but); } if (block->unit) { @@ -2448,21 +2463,22 @@ void uiFreeBlock(const bContext *C, uiBlock *block) CTX_store_free_list(&block->contexts); BLI_freelistN(&block->saferct); + BLI_freelistN(&block->color_pickers.list); MEM_freeN(block); } /* can be called with C==NULL */ -void uiFreeBlocks(const bContext *C, ListBase *lb) +void UI_blocklist_free(const bContext *C, ListBase *lb) { uiBlock *block; while ((block = BLI_pophead(lb))) { - uiFreeBlock(C, block); + UI_block_free(C, block); } } -void uiFreeInactiveBlocks(const bContext *C, ListBase *lb) +void UI_blocklist_free_inactive(const bContext *C, ListBase *lb) { uiBlock *block, *nextblock; @@ -2472,7 +2488,7 @@ void uiFreeInactiveBlocks(const bContext *C, ListBase *lb) if (!block->handle) { if (!block->active) { BLI_remlink(lb, block); - uiFreeBlock(C, block); + UI_block_free(C, block); } else block->active = 0; @@ -2480,7 +2496,7 @@ void uiFreeInactiveBlocks(const bContext *C, ListBase *lb) } } -void uiBlockSetRegion(uiBlock *block, ARegion *region) +void UI_block_region_set(uiBlock *block, ARegion *region) { ListBase *lb = ®ion->uiblocks; uiBlock *oldblock = NULL; @@ -2503,7 +2519,7 @@ void uiBlockSetRegion(uiBlock *block, ARegion *region) block->oldblock = oldblock; } -uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, short dt) +uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, short dt) { uiBlock *block; wmWindow *window; @@ -2536,7 +2552,7 @@ uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, shor BLI_strncpy(block->name, name, sizeof(block->name)); if (region) - uiBlockSetRegion(block, region); + UI_block_region_set(block, region); /* window matrix and aspect */ if (region && region->swinid) { @@ -2560,23 +2576,23 @@ uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, shor return block; } -uiBlock *uiGetBlock(const char *name, ARegion *ar) +uiBlock *UI_block_find_in_region(const char *name, ARegion *ar) { return BLI_findstring(&ar->uiblocks, name, offsetof(uiBlock, name)); } -void uiBlockSetEmboss(uiBlock *block, char dt) +void UI_block_emboss_set(uiBlock *block, char dt) { block->dt = dt; } -void ui_check_but(uiBut *but) +void ui_but_update(uiBut *but) { /* if something changed in the button */ double value = UI_BUT_VALUE_UNSET; // float okwidth; // UNUSED - ui_check_but_select(but, &value); + ui_but_update_select_flag(but, &value); /* only update soft range while not editing */ if (!(but->editval || but->editstr || but->editvec)) { @@ -2589,16 +2605,16 @@ void ui_check_but(uiBut *but) /* test for min and max, icon sliders, etc */ switch (but->type) { - case NUM: - case SCROLL: - case NUMSLI: + case UI_BTYPE_NUM: + case UI_BTYPE_SCROLL: + case UI_BTYPE_NUM_SLIDER: UI_GET_BUT_VALUE_INIT(but, value); - if (value < (double)but->hardmin) ui_set_but_val(but, but->hardmin); - else if (value > (double)but->hardmax) ui_set_but_val(but, but->hardmax); + if (value < (double)but->hardmin) ui_but_value_set(but, but->hardmin); + else if (value > (double)but->hardmax) ui_but_value_set(but, but->hardmax); break; - case ICONTOG: - case ICONTOGN: + case UI_BTYPE_ICON_TOGGLE: + case UI_BTYPE_ICON_TOGGLE_N: if (!but->rnaprop || (RNA_property_flag(but->rnaprop) & PROP_ICONS_CONSECUTIVE)) { if (but->flag & UI_SELECT) but->iconadd = 1; else but->iconadd = 0; @@ -2617,7 +2633,7 @@ void ui_check_but(uiBut *but) /* name: */ switch (but->type) { - case MENU: + case UI_BTYPE_MENU: if (BLI_rctf_size_x(&but->rect) > 24.0f) { /* only needed for menus in popup blocks that don't recreate buttons on redraw */ if (but->block->flag & UI_BLOCK_LOOP) { @@ -2635,8 +2651,8 @@ void ui_check_but(uiBut *but) } break; - case NUM: - case NUMSLI: + case UI_BTYPE_NUM: + case UI_BTYPE_NUM_SLIDER: if (!but->editstr) { const char *drawstr_suffix = NULL; @@ -2646,7 +2662,7 @@ void ui_check_but(uiBut *but) slen = BLI_strncpy_rlen(but->drawstr, but->str, sizeof(but->drawstr)); - if (ui_is_but_float(but)) { + if (ui_but_is_float(but)) { if (value == (double) FLT_MAX) { slen += BLI_strncpy_rlen(but->drawstr + slen, "inf", sizeof(but->drawstr) - slen); } @@ -2654,13 +2670,13 @@ void ui_check_but(uiBut *but) slen += BLI_strncpy_rlen(but->drawstr + slen, "-inf", sizeof(but->drawstr) - slen); } /* support length type buttons */ - else if (ui_is_but_unit(but)) { + else if (ui_but_is_unit(but)) { char new_str[sizeof(but->drawstr)]; ui_get_but_string_unit(but, new_str, sizeof(new_str), value, true, -1); slen += BLI_strncpy_rlen(but->drawstr + slen, new_str, sizeof(but->drawstr) - slen); } else { - const int prec = ui_but_float_precision(but, value); + const int prec = ui_but_calc_float_precision(but, value); slen += BLI_snprintf(but->drawstr + slen, sizeof(but->drawstr) - slen, "%.*f", prec, value); } } @@ -2686,11 +2702,11 @@ void ui_check_but(uiBut *but) } break; - case LABEL: - if (ui_is_but_float(but)) { + case UI_BTYPE_LABEL: + if (ui_but_is_float(but)) { int prec; UI_GET_BUT_VALUE_INIT(but, value); - prec = ui_but_float_precision(but, value); + prec = ui_but_calc_float_precision(but, value); BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value); } else { @@ -2699,18 +2715,18 @@ void ui_check_but(uiBut *but) break; - case TEX: - case SEARCH_MENU: - case SEARCH_MENU_UNLINK: + case UI_BTYPE_TEXT: + case UI_BTYPE_SEARCH_MENU: + case UI_BTYPE_SEARCH_MENU_UNLINK: if (!but->editstr) { char str[UI_MAX_DRAW_STR]; - ui_get_but_string(but, str, UI_MAX_DRAW_STR); + ui_but_string_get(but, str, UI_MAX_DRAW_STR); BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, str); } break; - case KEYEVT: + case UI_BTYPE_KEY_EVENT: { const char *str; if (but->flag & UI_SELECT) { @@ -2723,7 +2739,7 @@ void ui_check_but(uiBut *but) BLI_snprintf(but->drawstr, UI_MAX_DRAW_STR, "%s%s", but->str, str); break; } - case HOTKEYEVT: + case UI_BTYPE_HOTKEY_EVENT: if (but->flag & UI_SELECT) { if (but->modifier_key) { @@ -2750,8 +2766,8 @@ void ui_check_but(uiBut *but) break; - case HSVCUBE: - case HSVCIRCLE: + case UI_BTYPE_HSVCUBE: + case UI_BTYPE_HSVCIRCLE: break; default: BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR); @@ -2767,10 +2783,10 @@ void ui_check_but(uiBut *but) } -void uiBlockBeginAlign(uiBlock *block) +void UI_block_align_begin(uiBlock *block) { /* if other align was active, end it */ - if (block->flag & UI_BUT_ALIGN) uiBlockEndAlign(block); + if (block->flag & UI_BUT_ALIGN) UI_block_align_end(block); block->flag |= UI_BUT_ALIGN_DOWN; block->alignnr++; @@ -2796,17 +2812,17 @@ static bool buts_are_horiz(uiBut *but1, uiBut *but2) return (dx <= dy); } -void uiBlockEndAlign(uiBlock *block) +void UI_block_align_end(uiBlock *block) { block->flag &= ~UI_BUT_ALIGN; /* all 4 flags */ } bool ui_but_can_align(uiBut *but) { - return !ELEM(but->type, LABEL, OPTION, OPTIONN, SEPR, SEPRLINE); + return !ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_CHECKBOX, UI_BTYPE_CHECKBOX_N, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE); } -static void ui_block_do_align_but(uiBut *first, short nr) +static void ui_block_align_calc_but(uiBut *first, short nr) { uiBut *prev, *but = NULL, *next; int flag = 0, cols = 0, rows = 0; @@ -2946,7 +2962,7 @@ static void ui_block_do_align_but(uiBut *first, short nr) } } -void ui_block_do_align(uiBlock *block) +void ui_block_align_calc(uiBlock *block) { uiBut *but; short nr; @@ -2955,7 +2971,7 @@ void ui_block_do_align(uiBlock *block) for (but = block->buttons.first; but; ) { if (but->alignnr) { nr = but->alignnr; - ui_block_do_align_but(but, nr); + ui_block_align_calc_but(but, nr); /* skip with same number */ for (; but && but->alignnr == nr; but = but->next) { @@ -2972,21 +2988,21 @@ void ui_block_do_align(uiBlock *block) } } -struct ColorManagedDisplay *ui_block_display_get(uiBlock *block) +struct ColorManagedDisplay *ui_block_cm_display_get(uiBlock *block) { return IMB_colormanagement_display_get_named(block->display_device); } -void ui_block_to_display_space_v3(uiBlock *block, float pixel[3]) +void ui_block_cm_to_display_space_v3(uiBlock *block, float pixel[3]) { - struct ColorManagedDisplay *display = ui_block_display_get(block); + struct ColorManagedDisplay *display = ui_block_cm_display_get(block); IMB_colormanagement_scene_linear_to_display_v3(pixel, display); } -void ui_block_to_scene_linear_v3(uiBlock *block, float pixel[3]) +void ui_block_cm_to_scene_linear_v3(uiBlock *block, float pixel[3]) { - struct ColorManagedDisplay *display = ui_block_display_get(block); + struct ColorManagedDisplay *display = ui_block_cm_display_get(block); IMB_colormanagement_display_to_scene_linear_v3(pixel, display); } @@ -3012,7 +3028,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, BLI_assert(width >= 0 && height >= 0); /* we could do some more error checks here */ - if ((type & BUTTYPE) == LABEL) { + if ((type & BUTTYPE) == UI_BTYPE_LABEL) { BLI_assert((poin != NULL || min != 0.0f || max != 0.0f || (a1 == 0.0f && a2 != 0.0f) || (a1 != 0.0f && a1 != 1.0f)) == false); } @@ -3075,7 +3091,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, but->pos = -1; /* cursor invisible */ - if (ELEM(but->type, NUM, NUMSLI)) { /* add a space to name */ + if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) { /* add a space to name */ /* slen remains unchanged from previous assignment, ensure this stays true */ if (slen > 0 && slen < UI_MAX_NAME_STR - 2) { if (but->str[slen - 1] != ' ') { @@ -3089,12 +3105,15 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT); } else if ((block->flag & UI_BLOCK_LOOP) || - ELEM(but->type, MENU, TEX, LABEL, BLOCK, BUTM, SEARCH_MENU, PROGRESSBAR, SEARCH_MENU_UNLINK)) + ELEM(but->type, + UI_BTYPE_MENU, UI_BTYPE_TEXT, UI_BTYPE_LABEL, + UI_BTYPE_BLOCK, UI_BTYPE_BUT_MENU, UI_BTYPE_SEARCH_MENU, + UI_BTYPE_PROGRESS_BAR, UI_BTYPE_SEARCH_MENU_UNLINK)) { but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT); } #ifdef USE_NUMBUTS_LR_ALIGN - else if (ELEM(but->type, NUM, NUMSLI)) { + else if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) { but->drawflag |= UI_BUT_TEXT_LEFT; } #endif @@ -3108,9 +3127,18 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, } /* keep track of UI_interface.h */ - if (ELEM(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, BUTM, SCROLL, SEPR, SEPRLINE, GRIP)) {} - else if (but->type >= SEARCH_MENU) {} - else but->flag |= UI_BUT_UNDO; + if (ELEM(but->type, + UI_BTYPE_BLOCK, UI_BTYPE_BUT, UI_BTYPE_LABEL, + UI_BTYPE_PULLDOWN, UI_BTYPE_ROUNDBOX, UI_BTYPE_LISTBOX, + UI_BTYPE_BUT_MENU, UI_BTYPE_SCROLL, UI_BTYPE_GRIP, + UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE) || + (but->type >= UI_BTYPE_SEARCH_MENU)) + { + /* pass */ + } + else { + but->flag |= UI_BUT_UNDO; + } BLI_addtail(&block->buttons, but); @@ -3151,13 +3179,13 @@ static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *bu int column_start = 0, column_end = 0; int nbr_entries_nosepr = 0; - uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT); + UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT); RNA_property_enum_items_gettexted(block->evil_C, &but->rnapoin, but->rnaprop, &item_array, NULL, &free); /* we dont want nested rows, cols in menus */ - uiBlockSetCurLayout(block, layout); + UI_block_layout_set_current(block, layout); for (item = item_array; item->identifier; item++, totitems++) { if (!item->identifier[0]) { @@ -3186,7 +3214,7 @@ static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *bu rows++; /* Title */ - uiDefBut(block, LABEL, 0, RNA_property_ui_name(but->rnaprop), + uiDefBut(block, UI_BTYPE_LABEL, 0, RNA_property_ui_name(but->rnaprop), 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); uiItemS(layout); @@ -3229,7 +3257,7 @@ static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *bu } else { /* Do not use uiItemL here, as our root layout is a menu one, it will add a fake blank icon! */ - uiDefBut(block, LABEL, 0, item->name, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 0, item->name, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); } } else { @@ -3238,21 +3266,24 @@ static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *bu } else { if (item->icon) { - uiDefIconTextButI(block, BUTM, B_NOP, item->icon, item->name, 0, 0, + uiDefIconTextButI(block, UI_BTYPE_BUT_MENU, B_NOP, item->icon, item->name, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, &handle->retvalue, item->value, 0.0, 0, -1, item->description); } else { - uiDefButI(block, BUTM, B_NOP, item->name, 0, 0, + uiDefButI(block, UI_BTYPE_BUT_MENU, B_NOP, item->name, 0, 0, UI_UNIT_X * 5, UI_UNIT_X, &handle->retvalue, item->value, 0.0, 0, -1, item->description); } } } - uiBlockSetCurLayout(block, layout); + UI_block_layout_set_current(block, layout); if (free) { MEM_freeN(item_array); } + + BLI_assert((block->flag & UI_BLOCK_IS_FLIP) == 0); + block->flag |= UI_BLOCK_IS_FLIP; } /** @@ -3273,13 +3304,13 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s int icon = 0; uiMenuCreateFunc func = NULL; - if (ELEM(type, COLOR, HSVCIRCLE, HSVCUBE)) { + if (ELEM(type, UI_BTYPE_COLOR, UI_BTYPE_HSVCIRCLE, UI_BTYPE_HSVCUBE)) { BLI_assert(index == -1); } /* use rna values if parameters are not specified */ - if ((proptype == PROP_ENUM) && ELEM(type, MENU, ROW, LISTROW)) { - /* MENU is handled a little differently here */ + if ((proptype == PROP_ENUM) && ELEM(type, UI_BTYPE_MENU, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) { + /* UI_BTYPE_MENU is handled a little differently here */ EnumPropertyItem *item; int value; bool free; @@ -3287,7 +3318,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s RNA_property_enum_items(block->evil_C, ptr, prop, &item, NULL, &free); - if (type == MENU) { + if (type == UI_BTYPE_MENU) { value = RNA_property_enum_get(ptr, prop); } else { @@ -3308,7 +3339,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s } else { if (!str) { - if (type == MENU) { + if (type == UI_BTYPE_MENU) { str = ""; } else { @@ -3317,7 +3348,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s } } - if (type == MENU) { + if (type == UI_BTYPE_MENU) { func = ui_def_but_rna__menu; } @@ -3342,7 +3373,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s RNA_property_int_range(ptr, prop, &hardmin, &hardmax); RNA_property_int_ui_range(ptr, prop, &softmin, &softmax, &step); - if (!ELEM(type, ROW, LISTROW) && min == max) { + if (!ELEM(type, UI_BTYPE_ROW, UI_BTYPE_LISTROW) && min == max) { min = hardmin; max = hardmax; } @@ -3357,7 +3388,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s RNA_property_float_range(ptr, prop, &hardmin, &hardmax); RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision); - if (!ELEM(type, ROW, LISTROW) && min == max) { + if (!ELEM(type, UI_BTYPE_ROW, UI_BTYPE_LISTROW) && min == max) { min = hardmin; max = hardmax; } @@ -3393,20 +3424,20 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s } } - if ((type == MENU) && (but->dt == UI_EMBOSSP)) { - but->flag |= UI_ICON_SUBMENU; + if ((type == UI_BTYPE_MENU) && (but->dt == UI_EMBOSS_PULLDOWN)) { + but->flag |= UI_BUT_ICON_SUBMENU; } if (!RNA_property_editable(&but->rnapoin, prop)) { ui_def_but_rna__disable(but); } - if (but->flag & UI_BUT_UNDO && (ui_is_but_rna_undo(but) == false)) { + if (but->flag & UI_BUT_UNDO && (ui_but_is_rna_undo(but) == false)) { but->flag &= ~UI_BUT_UNDO; } /* If this button uses units, calculate the step from this */ - if ((proptype == PROP_FLOAT) && ui_is_but_unit(but)) { + if ((proptype == PROP_FLOAT) && ui_but_is_unit(but)) { but->a1 = ui_get_but_step_unit(but, but->a1); } @@ -3453,7 +3484,7 @@ static uiBut *ui_def_but_operator_ptr(uiBlock *block, int type, wmOperatorType * but = ui_def_but(block, type, -1, str, x, y, width, height, NULL, 0, 0, 0, 0, tip); but->optype = ot; but->opcontext = opcontext; - but->flag &= ~UI_BUT_UNDO; /* no need for ui_is_but_rna_undo(), we never need undo here */ + but->flag &= ~UI_BUT_UNDO; /* no need for ui_but_is_rna_undo(), we never need undo here */ if (!ot) { but->flag |= UI_BUT_DISABLED; @@ -3468,7 +3499,7 @@ uiBut *uiDefBut(uiBlock *block, int type, int retval, const char *str, int x, in { uiBut *but = ui_def_but(block, type, retval, str, x, y, width, height, poin, min, max, a1, a2, tip); - ui_check_but(but); + ui_but_update(but); return but; } @@ -3508,7 +3539,7 @@ struct AutoComplete { const char *startname; }; -AutoComplete *autocomplete_begin(const char *startname, size_t maxlen) +AutoComplete *UI_autocomplete_begin(const char *startname, size_t maxlen) { AutoComplete *autocpl; @@ -3521,7 +3552,7 @@ AutoComplete *autocomplete_begin(const char *startname, size_t maxlen) return autocpl; } -void autocomplete_do_name(AutoComplete *autocpl, const char *name) +void UI_autocomplete_update_name(AutoComplete *autocpl, const char *name) { char *truncate = autocpl->truncate; const char *startname = autocpl->startname; @@ -3551,7 +3582,7 @@ void autocomplete_do_name(AutoComplete *autocpl, const char *name) } } -int autocomplete_end(AutoComplete *autocpl, char *autoname) +int UI_autocomplete_end(AutoComplete *autocpl, char *autoname) { int match = AUTOCOMPLETE_NO_MATCH; if (autocpl->truncate[0]) { @@ -3574,14 +3605,14 @@ int autocomplete_end(AutoComplete *autocpl, char *autoname) return match; } -static void ui_check_but_and_iconize(uiBut *but, int icon) +static void ui_but_update_and_icon_set(uiBut *but, int icon) { if (icon) { but->icon = (BIFIconID) icon; but->flag |= UI_HAS_ICON; } - ui_check_but(but); + ui_but_update(but); } static uiBut *uiDefButBit(uiBlock *block, int type, int bit, int retval, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) @@ -3630,14 +3661,14 @@ uiBut *uiDefButR(uiBlock *block, int type, int retval, const char *str, int x, i { uiBut *but; but = ui_def_but_rna_propname(block, type, retval, str, x, y, width, height, ptr, propname, index, min, max, a1, a2, tip); - ui_check_but(but); + ui_but_update(but); return but; } uiBut *uiDefButR_prop(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) { uiBut *but; but = ui_def_but_rna(block, type, retval, str, x, y, width, height, ptr, prop, index, min, max, a1, a2, tip); - ui_check_but(but); + ui_but_update(but); return but; } @@ -3645,7 +3676,7 @@ uiBut *uiDefButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcontext { uiBut *but; but = ui_def_but_operator_ptr(block, type, ot, opcontext, str, x, y, width, height, tip); - ui_check_but(but); + ui_but_update(but); return but; } uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x, int y, short width, short height, const char *tip) @@ -3659,7 +3690,7 @@ uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, co uiBut *uiDefIconBut(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) { uiBut *but = ui_def_but(block, type, retval, "", x, y, width, height, poin, min, max, a1, a2, tip); - ui_check_but_and_iconize(but, icon); + ui_but_update_and_icon_set(but, icon); return but; } static uiBut *uiDefIconButBit(uiBlock *block, int type, int bit, int retval, int icon, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) @@ -3709,14 +3740,14 @@ uiBut *uiDefIconButR(uiBlock *block, int type, int retval, int icon, int x, int { uiBut *but; but = ui_def_but_rna_propname(block, type, retval, "", x, y, width, height, ptr, propname, index, min, max, a1, a2, tip); - ui_check_but_and_iconize(but, icon); + ui_but_update_and_icon_set(but, icon); return but; } uiBut *uiDefIconButR_prop(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) { uiBut *but; but = ui_def_but_rna(block, type, retval, "", x, y, width, height, ptr, prop, index, min, max, a1, a2, tip); - ui_check_but_and_iconize(but, icon); + ui_but_update_and_icon_set(but, icon); return but; } @@ -3724,7 +3755,7 @@ uiBut *uiDefIconButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcon { uiBut *but; but = ui_def_but_operator_ptr(block, type, ot, opcontext, "", x, y, width, height, tip); - ui_check_but_and_iconize(but, icon); + ui_but_update_and_icon_set(but, icon); return but; } uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, int x, int y, short width, short height, const char *tip) @@ -3737,7 +3768,7 @@ uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext uiBut *uiDefIconTextBut(uiBlock *block, int type, int retval, int icon, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) { uiBut *but = ui_def_but(block, type, retval, str, x, y, width, height, poin, min, max, a1, a2, tip); - ui_check_but_and_iconize(but, icon); + ui_but_update_and_icon_set(but, icon); but->drawflag |= UI_BUT_ICON_LEFT; return but; } @@ -3788,7 +3819,7 @@ uiBut *uiDefIconTextButR(uiBlock *block, int type, int retval, int icon, const c { uiBut *but; but = ui_def_but_rna_propname(block, type, retval, str, x, y, width, height, ptr, propname, index, min, max, a1, a2, tip); - ui_check_but_and_iconize(but, icon); + ui_but_update_and_icon_set(but, icon); but->drawflag |= UI_BUT_ICON_LEFT; return but; } @@ -3796,7 +3827,7 @@ uiBut *uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, co { uiBut *but; but = ui_def_but_rna(block, type, retval, str, x, y, width, height, ptr, prop, index, min, max, a1, a2, tip); - ui_check_but_and_iconize(but, icon); + ui_but_update_and_icon_set(but, icon); but->drawflag |= UI_BUT_ICON_LEFT; return but; } @@ -3804,7 +3835,7 @@ uiBut *uiDefIconTextButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int o { uiBut *but; but = ui_def_but_operator_ptr(block, type, ot, opcontext, str, x, y, width, height, tip); - ui_check_but_and_iconize(but, icon); + ui_but_update_and_icon_set(but, icon); but->drawflag |= UI_BUT_ICON_LEFT; return but; } @@ -3816,7 +3847,7 @@ uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcon /* END Button containing both string label and icon */ -void uiSetButLink(uiBut *but, void **poin, void ***ppoin, short *tot, int from, int to) +void UI_but_link_set(uiBut *but, void **poin, void ***ppoin, short *tot, int from, int to) { uiLink *link; @@ -3831,7 +3862,7 @@ void uiSetButLink(uiBut *but, void **poin, void ***ppoin, short *tot, int from, /* cruft to make uiBlock and uiBut private */ -int uiBlocksGetYMin(ListBase *lb) +int UI_blocklist_min_y_get(ListBase *lb) { uiBlock *block; int min = 0; @@ -3843,13 +3874,13 @@ int uiBlocksGetYMin(ListBase *lb) return min; } -void uiBlockSetDirection(uiBlock *block, char direction) +void UI_block_direction_set(uiBlock *block, char direction) { block->direction = direction; } /* this call escapes if there's alignment flags */ -void uiBlockFlipOrder(uiBlock *block) +void UI_block_order_flip(uiBlock *block) { uiBut *but; float centy, miny = 10000, maxy = -10000; @@ -3871,83 +3902,85 @@ void uiBlockFlipOrder(uiBlock *block) but->rect.ymax = centy - (but->rect.ymax - centy); SWAP(float, but->rect.ymin, but->rect.ymax); } + + block->flag ^= UI_BLOCK_IS_FLIP; } -void uiBlockSetFlag(uiBlock *block, int flag) +void UI_block_flag_enable(uiBlock *block, int flag) { block->flag |= flag; } -void uiBlockClearFlag(uiBlock *block, int flag) +void UI_block_flag_disable(uiBlock *block, int flag) { block->flag &= ~flag; } -void uiButSetFlag(uiBut *but, int flag) +void UI_but_flag_enable(uiBut *but, int flag) { but->flag |= flag; } -void uiButClearFlag(uiBut *but, int flag) +void UI_but_flag_disable(uiBut *but, int flag) { but->flag &= ~flag; } -void uiButSetDrawFlag(uiBut *but, int flag) +void UI_but_drawflag_enable(uiBut *but, int flag) { but->drawflag |= flag; } -void uiButClearDrawFlag(uiBut *but, int flag) +void UI_but_drawflag_disable(uiBut *but, int flag) { but->drawflag &= ~flag; } -void uiButSetMenuFromPulldown(uiBut *but) +void UI_but_type_set_menu_from_pulldown(uiBut *but) { - BLI_assert(but->type == PULLDOWN); - but->type = MENU; - uiButClearDrawFlag(but, UI_BUT_TEXT_RIGHT); - uiButSetDrawFlag(but, UI_BUT_TEXT_LEFT); + BLI_assert(but->type == UI_BTYPE_PULLDOWN); + but->type = UI_BTYPE_MENU; + UI_but_drawflag_disable(but, UI_BUT_TEXT_RIGHT); + UI_but_drawflag_enable(but, UI_BUT_TEXT_LEFT); } -int uiButGetRetVal(uiBut *but) +int UI_but_return_value_get(uiBut *but) { return but->retval; } -void uiButSetDragID(uiBut *but, ID *id) +void UI_but_drag_set_id(uiBut *but, ID *id) { but->dragtype = WM_DRAG_ID; but->dragpoin = (void *)id; } -void uiButSetDragRNA(uiBut *but, PointerRNA *ptr) +void UI_but_drag_set_rna(uiBut *but, PointerRNA *ptr) { but->dragtype = WM_DRAG_RNA; but->dragpoin = (void *)ptr; } -void uiButSetDragPath(uiBut *but, const char *path) +void UI_but_drag_set_path(uiBut *but, const char *path) { but->dragtype = WM_DRAG_PATH; but->dragpoin = (void *)path; } -void uiButSetDragName(uiBut *but, const char *name) +void UI_but_drag_set_name(uiBut *but, const char *name) { but->dragtype = WM_DRAG_NAME; but->dragpoin = (void *)name; } /* value from button itself */ -void uiButSetDragValue(uiBut *but) +void UI_but_drag_set_value(uiBut *but) { but->dragtype = WM_DRAG_VALUE; } -void uiButSetDragImage(uiBut *but, const char *path, int icon, struct ImBuf *imb, float scale) +void UI_but_drag_set_image(uiBut *but, const char *path, int icon, struct ImBuf *imb, float scale) { but->dragtype = WM_DRAG_PATH; but->icon = icon; /* no flag UI_HAS_ICON, so icon doesnt draw in button */ @@ -3956,7 +3989,7 @@ void uiButSetDragImage(uiBut *but, const char *path, int icon, struct ImBuf *imb but->imb_scale = scale; } -PointerRNA *uiButGetOperatorPtrRNA(uiBut *but) +PointerRNA *UI_but_operator_ptr_get(uiBut *but) { if (but->optype && !but->opptr) { but->opptr = MEM_callocN(sizeof(PointerRNA), "uiButOpPtr"); @@ -3966,12 +3999,12 @@ PointerRNA *uiButGetOperatorPtrRNA(uiBut *but) return but->opptr; } -void uiButSetUnitType(uiBut *but, const int unit_type) +void UI_but_unit_type_set(uiBut *but, const int unit_type) { but->unit_type = (unsigned char)(RNA_SUBTYPE_UNIT_VALUE(unit_type)); } -int uiButGetUnitType(const uiBut *but) +int UI_but_unit_type_get(const uiBut *but) { int ownUnit = (int)but->unit_type; @@ -3987,26 +4020,26 @@ int uiButGetUnitType(const uiBut *but) } } -void uiBlockSetHandleFunc(uiBlock *block, uiBlockHandleFunc func, void *arg) +void UI_block_func_handle_set(uiBlock *block, uiBlockHandleFunc func, void *arg) { block->handle_func = func; block->handle_func_arg = arg; } -void uiBlockSetButmFunc(uiBlock *block, uiMenuHandleFunc func, void *arg) +void UI_block_func_butmenu_set(uiBlock *block, uiMenuHandleFunc func, void *arg) { block->butm_func = func; block->butm_func_arg = arg; } -void uiBlockSetFunc(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2) +void UI_block_func_set(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2) { block->func = func; block->func_arg1 = arg1; block->func_arg2 = arg2; } -void uiBlockSetNFunc(uiBlock *block, uiButHandleNFunc funcN, void *argN, void *arg2) +void UI_block_funcN_set(uiBlock *block, uiButHandleNFunc funcN, void *argN, void *arg2) { if (block->func_argN) { MEM_freeN(block->func_argN); @@ -4017,27 +4050,27 @@ void uiBlockSetNFunc(uiBlock *block, uiButHandleNFunc funcN, void *argN, void *a block->func_arg2 = arg2; } -void uiButSetRenameFunc(uiBut *but, uiButHandleRenameFunc func, void *arg1) +void UI_but_func_rename_set(uiBut *but, uiButHandleRenameFunc func, void *arg1) { but->rename_func = func; but->rename_arg1 = arg1; } -void uiBlockSetDrawExtraFunc(uiBlock *block, void (*func)(const bContext *C, void *idv, void *arg1, void *arg2, rcti *rect), void *arg1, void *arg2) +void UI_but_func_drawextra_set(uiBlock *block, void (*func)(const bContext *C, void *idv, void *arg1, void *arg2, rcti *rect), void *arg1, void *arg2) { block->drawextra = func; block->drawextra_arg1 = arg1; block->drawextra_arg2 = arg2; } -void uiButSetFunc(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2) +void UI_but_func_set(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2) { but->func = func; but->func_arg1 = arg1; but->func_arg2 = arg2; } -void uiButSetNFunc(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2) +void UI_but_funcN_set(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2) { if (but->func_argN) { MEM_freeN(but->func_argN); @@ -4048,7 +4081,7 @@ void uiButSetNFunc(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2) but->func_arg2 = arg2; } -void uiButSetCompleteFunc(uiBut *but, uiButCompleteFunc func, void *arg) +void UI_but_func_complete_set(uiBut *but, uiButCompleteFunc func, void *arg) { but->autocomplete_func = func; but->autofunc_arg = arg; @@ -4056,67 +4089,67 @@ void uiButSetCompleteFunc(uiBut *but, uiButCompleteFunc func, void *arg) uiBut *uiDefBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip) { - uiBut *but = ui_def_but(block, BLOCK, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); + uiBut *but = ui_def_but(block, UI_BTYPE_BLOCK, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); but->block_create_func = func; - ui_check_but(but); + ui_but_update(but); return but; } uiBut *uiDefBlockButN(uiBlock *block, uiBlockCreateFunc func, void *argN, const char *str, int x, int y, short width, short height, const char *tip) { - uiBut *but = ui_def_but(block, BLOCK, 0, str, x, y, width, height, NULL, 0.0, 0.0, 0.0, 0.0, tip); + uiBut *but = ui_def_but(block, UI_BTYPE_BLOCK, 0, str, x, y, width, height, NULL, 0.0, 0.0, 0.0, 0.0, tip); but->block_create_func = func; if (but->func_argN) { MEM_freeN(but->func_argN); } but->func_argN = argN; - ui_check_but(but); + ui_but_update(but); return but; } uiBut *uiDefPulldownBut(uiBlock *block, uiBlockCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip) { - uiBut *but = ui_def_but(block, PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); + uiBut *but = ui_def_but(block, UI_BTYPE_PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); but->block_create_func = func; - ui_check_but(but); + ui_but_update(but); return but; } uiBut *uiDefMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip) { - uiBut *but = ui_def_but(block, PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); + uiBut *but = ui_def_but(block, UI_BTYPE_PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); but->menu_create_func = func; - ui_check_but(but); + ui_but_update(but); return but; } uiBut *uiDefIconTextMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, const char *str, int x, int y, short width, short height, const char *tip) { - uiBut *but = ui_def_but(block, PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); + uiBut *but = ui_def_but(block, UI_BTYPE_PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); but->icon = (BIFIconID) icon; but->flag |= UI_HAS_ICON; but->drawflag |= UI_BUT_ICON_LEFT; - but->flag |= UI_ICON_SUBMENU; + but->flag |= UI_BUT_ICON_SUBMENU; but->menu_create_func = func; - ui_check_but(but); + ui_but_update(but); return but; } uiBut *uiDefIconMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, int x, int y, short width, short height, const char *tip) { - uiBut *but = ui_def_but(block, PULLDOWN, 0, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); + uiBut *but = ui_def_but(block, UI_BTYPE_PULLDOWN, 0, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); but->icon = (BIFIconID) icon; but->flag |= UI_HAS_ICON; but->drawflag &= ~UI_BUT_ICON_LEFT; but->menu_create_func = func; - ui_check_but(but); + ui_but_update(but); return but; } @@ -4124,18 +4157,18 @@ uiBut *uiDefIconMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int ic /* Block button containing both string label and icon */ uiBut *uiDefIconTextBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int icon, const char *str, int x, int y, short width, short height, const char *tip) { - uiBut *but = ui_def_but(block, BLOCK, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); + uiBut *but = ui_def_but(block, UI_BTYPE_BLOCK, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); - /* XXX temp, old menu calls pass on icon arrow, which is now UI_ICON_SUBMENU flag */ + /* XXX temp, old menu calls pass on icon arrow, which is now UI_BUT_ICON_SUBMENU flag */ if (icon != ICON_RIGHTARROW_THIN) { but->icon = (BIFIconID) icon; but->drawflag |= UI_BUT_ICON_LEFT; } but->flag |= UI_HAS_ICON; - but->flag |= UI_ICON_SUBMENU; + but->flag |= UI_BUT_ICON_SUBMENU; but->block_create_func = func; - ui_check_but(but); + ui_but_update(but); return but; } @@ -4143,7 +4176,7 @@ uiBut *uiDefIconTextBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, /* Block button containing icon */ uiBut *uiDefIconBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int retval, int icon, int x, int y, short width, short height, const char *tip) { - uiBut *but = ui_def_but(block, BLOCK, retval, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); + uiBut *but = ui_def_but(block, UI_BTYPE_BLOCK, retval, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); but->icon = (BIFIconID) icon; but->flag |= UI_HAS_ICON; @@ -4151,15 +4184,15 @@ uiBut *uiDefIconBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int but->drawflag |= UI_BUT_ICON_LEFT; but->block_create_func = func; - ui_check_but(but); + ui_but_update(but); return but; } uiBut *uiDefKeyevtButS(uiBlock *block, int retval, const char *str, int x, int y, short width, short height, short *spoin, const char *tip) { - uiBut *but = ui_def_but(block, KEYEVT | UI_BUT_POIN_SHORT, retval, str, x, y, width, height, spoin, 0.0, 0.0, 0.0, 0.0, tip); - ui_check_but(but); + uiBut *but = ui_def_but(block, UI_BTYPE_KEY_EVENT | UI_BUT_POIN_SHORT, retval, str, x, y, width, height, spoin, 0.0, 0.0, 0.0, 0.0, tip); + ui_but_update(but); return but; } @@ -4167,25 +4200,25 @@ uiBut *uiDefKeyevtButS(uiBlock *block, int retval, const char *str, int x, int y /* modkeypoin will be set to KM_SHIFT, KM_ALT, KM_CTRL, KM_OSKEY bits */ uiBut *uiDefHotKeyevtButS(uiBlock *block, int retval, const char *str, int x, int y, short width, short height, short *keypoin, short *modkeypoin, const char *tip) { - uiBut *but = ui_def_but(block, HOTKEYEVT | UI_BUT_POIN_SHORT, retval, str, x, y, width, height, keypoin, 0.0, 0.0, 0.0, 0.0, tip); + uiBut *but = ui_def_but(block, UI_BTYPE_HOTKEY_EVENT | UI_BUT_POIN_SHORT, retval, str, x, y, width, height, keypoin, 0.0, 0.0, 0.0, 0.0, tip); but->modifier_key = *modkeypoin; - ui_check_but(but); + ui_but_update(but); return but; } -/* arg is pointer to string/name, use uiButSetSearchFunc() below to make this work */ +/* arg is pointer to string/name, use UI_but_func_search_set() below to make this work */ /* here a1 and a2, if set, control thumbnail preview rows/cols */ uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, int x, int y, short width, short height, float a1, float a2, const char *tip) { - uiBut *but = ui_def_but(block, SEARCH_MENU, retval, "", x, y, width, height, arg, 0.0, maxlen, a1, a2, tip); + uiBut *but = ui_def_but(block, UI_BTYPE_SEARCH_MENU, retval, "", x, y, width, height, arg, 0.0, maxlen, a1, a2, tip); but->icon = (BIFIconID) icon; but->flag |= UI_HAS_ICON; but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT; - ui_check_but(but); + ui_but_update(but); return but; } @@ -4193,18 +4226,18 @@ uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxle /* arg is user value, searchfunc and handlefunc both get it as arg */ /* if active set, button opens with this item visible and selected */ -void uiButSetSearchFunc(uiBut *but, uiButSearchFunc sfunc, void *arg, uiButHandleFunc bfunc, void *active) +void UI_but_func_search_set(uiBut *but, uiButSearchFunc sfunc, void *arg, uiButHandleFunc bfunc, void *active) { but->search_func = sfunc; but->search_arg = arg; - uiButSetFunc(but, bfunc, arg, active); + UI_but_func_set(but, bfunc, arg, active); /* search buttons show red-alert if item doesn't exist, not for menus */ if (0 == (but->block->flag & UI_BLOCK_LOOP)) { /* skip empty buttons, not all buttons need input, we only show invalid */ if (but->drawstr[0]) - ui_but_search_test(but); + ui_but_search_refresh(but); } } @@ -4223,7 +4256,7 @@ static void operator_enum_search_cb(const struct bContext *C, void *but, const c __func__, ot->idname, RNA_property_identifier(prop)); } else { - PointerRNA *ptr = uiButGetOperatorPtrRNA(but); /* Will create it if needed! */ + PointerRNA *ptr = UI_but_operator_ptr_get(but); /* Will create it if needed! */ EnumPropertyItem *item, *item_array; bool do_free; @@ -4232,7 +4265,7 @@ static void operator_enum_search_cb(const struct bContext *C, void *but, const c for (item = item_array; item->identifier; item++) { /* note: need to give the index rather than the identifier because the enum can be freed */ if (BLI_strcasestr(item->name, str)) { - if (false == uiSearchItemAdd(items, item->name, SET_INT_IN_POINTER(item->value), 0)) + if (false == UI_search_item_add(items, item->name, SET_INT_IN_POINTER(item->value), 0)) break; } } @@ -4245,7 +4278,7 @@ static void operator_enum_search_cb(const struct bContext *C, void *but, const c static void operator_enum_call_cb(struct bContext *UNUSED(C), void *but, void *arg2) { wmOperatorType *ot = ((uiBut *)but)->optype; - PointerRNA *opptr = uiButGetOperatorPtrRNA(but); /* Will create it if needed! */ + PointerRNA *opptr = UI_but_operator_ptr_get(but); /* Will create it if needed! */ if (ot) { if (ot->prop) { @@ -4270,13 +4303,13 @@ uiBut *uiDefSearchButO_ptr(uiBlock *block, wmOperatorType *ot, IDProperty *prope uiBut *but; but = uiDefSearchBut(block, arg, retval, icon, maxlen, x, y, width, height, a1, a2, tip); - uiButSetSearchFunc(but, operator_enum_search_cb, but, operator_enum_call_cb, NULL); + UI_but_func_search_set(but, operator_enum_search_cb, but, operator_enum_call_cb, NULL); but->optype = ot; but->opcontext = WM_OP_EXEC_DEFAULT; if (properties) { - PointerRNA *ptr = uiButGetOperatorPtrRNA(but); + PointerRNA *ptr = UI_but_operator_ptr_get(but); /* Copy idproperties. */ ptr->data = IDP_CopyProperty(properties); } @@ -4287,7 +4320,7 @@ uiBut *uiDefSearchButO_ptr(uiBlock *block, wmOperatorType *ot, IDProperty *prope /* push a new event onto event queue to activate the given button * (usually a text-field) upon entering a popup */ -void uiButSetFocusOnEnter(wmWindow *win, uiBut *but) +void UI_but_focus_on_enter_event(wmWindow *win, uiBut *but) { wmEvent event; @@ -4301,7 +4334,7 @@ void uiButSetFocusOnEnter(wmWindow *win, uiBut *but) wm_event_add(win, &event); } -void uiButGetStrInfo(bContext *C, uiBut *but, ...) +void UI_but_string_info_get(bContext *C, uiBut *but, ...) { va_list args; uiStringInfo *si; @@ -4339,8 +4372,8 @@ void uiButGetStrInfo(bContext *C, uiBut *but, ...) tmp = BLI_strdup(RNA_struct_identifier(but->rnapoin.type)); else if (but->optype) tmp = BLI_strdup(but->optype->idname); - else if (ELEM(but->type, MENU, PULLDOWN)) { - MenuType *mt = uiButGetMenuType(but); + else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) { + MenuType *mt = UI_but_menutype_get(but); if (mt) tmp = BLI_strdup(mt->idname); } @@ -4364,8 +4397,8 @@ void uiButGetStrInfo(bContext *C, uiBut *but, ...) tmp = BLI_strdup(t); } } - else if (ELEM(but->type, MENU, PULLDOWN)) { - MenuType *mt = uiButGetMenuType(but); + else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) { + MenuType *mt = UI_but_menutype_get(but); if (mt) { /* not all menus are from python */ if (mt->ext.srna) { @@ -4386,8 +4419,8 @@ void uiButGetStrInfo(bContext *C, uiBut *but, ...) _tmp = RNA_property_translation_context(but->rnaprop); else if (but->optype) _tmp = RNA_struct_translation_context(but->optype->srna); - else if (ELEM(but->type, MENU, PULLDOWN)) { - MenuType *mt = uiButGetMenuType(but); + else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) { + MenuType *mt = UI_but_menutype_get(but); if (mt) _tmp = RNA_struct_translation_context(mt->ext.srna); } @@ -4406,10 +4439,10 @@ void uiButGetStrInfo(bContext *C, uiBut *but, ...) /* enum property */ ptr = &but->rnapoin; prop = but->rnaprop; - value = (but->type == ROW) ? (int)but->hardmax : (int)ui_get_but_val(but); + value = (but->type == UI_BTYPE_ROW) ? (int)but->hardmax : (int)ui_but_value_get(but); } else if (but->optype) { - PointerRNA *opptr = uiButGetOperatorPtrRNA(but); + PointerRNA *opptr = UI_but_operator_ptr_get(but); wmOperatorType *ot = but->optype; /* if the default property of the operator is enum and it is set, @@ -4494,6 +4527,6 @@ void UI_reinit_font(void) void UI_exit(void) { ui_resources_free(); - ui_button_clipboard_free(); + ui_but_clipboard_free(); } diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c index 48e54270e95..24a30ebe3d8 100644 --- a/source/blender/editors/interface/interface_anim.c +++ b/source/blender/editors/interface/interface_anim.c @@ -34,15 +34,14 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" -#include "BLI_listbase.h" #include "BLI_string.h" #include "BLI_string_utf8.h" #include "BLI_utildefines.h" #include "BKE_context.h" -#include "BKE_animsys.h" #include "BKE_fcurve.h" #include "BKE_global.h" +#include "BKE_nla.h" #include "ED_keyframing.h" @@ -55,28 +54,37 @@ #include "interface_intern.h" -static FCurve *ui_but_get_fcurve(uiBut *but, bAction **action, bool *r_driven) +static FCurve *ui_but_get_fcurve(uiBut *but, AnimData **adt, bAction **action, bool *r_driven) { /* for entire array buttons we check the first component, it's not perfect * but works well enough in typical cases */ int rnaindex = (but->rnaindex == -1) ? 0 : but->rnaindex; - return rna_get_fcurve_context_ui(but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, action, r_driven); + return rna_get_fcurve_context_ui(but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, adt, action, r_driven); } void ui_but_anim_flag(uiBut *but, float cfra) { + AnimData *adt; + bAction *act; FCurve *fcu; bool driven; but->flag &= ~(UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN); - fcu = ui_but_get_fcurve(but, NULL, &driven); + fcu = ui_but_get_fcurve(but, &adt, &act, &driven); if (fcu) { if (!driven) { but->flag |= UI_BUT_ANIMATED; + /* T41525 - When the active action is a NLA strip being edited, + * we need to correct the frame number to "look inside" the + * remapped action + */ + if (adt) + cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP); + if (fcurve_frame_has_keyframe(fcu, cfra, 0)) but->flag |= UI_BUT_ANIMATED_KEY; } @@ -92,7 +100,7 @@ bool ui_but_anim_expression_get(uiBut *but, char *str, size_t maxlen) ChannelDriver *driver; bool driven; - fcu = ui_but_get_fcurve(but, NULL, &driven); + fcu = ui_but_get_fcurve(but, NULL, NULL, &driven); if (fcu && driven) { driver = fcu->driver; @@ -112,7 +120,7 @@ bool ui_but_anim_expression_set(uiBut *but, const char *str) ChannelDriver *driver; bool driven; - fcu = ui_but_get_fcurve(but, NULL, &driven); + fcu = ui_but_get_fcurve(but, NULL, NULL, &driven); if (fcu && driven) { driver = fcu->driver; @@ -208,7 +216,7 @@ void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra) FCurve *fcu; bool driven; - fcu = ui_but_get_fcurve(but, &action, &driven); + fcu = ui_but_get_fcurve(but, NULL, &action, &driven); if (fcu && !driven) { id = but->rnapoin.id.data; @@ -219,7 +227,14 @@ void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra) short flag = ANIM_get_keyframing_flags(scene, 1); fcu->flag &= ~FCURVE_SELECTED; - insert_keyframe(reports, id, action, ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, cfra, flag); + + /* Note: We use but->rnaindex instead of fcu->array_index, + * because a button may control all items of an array at once. + * E.g., color wheels (see T42567). */ + BLI_assert((fcu->array_index == but->rnaindex) || (but->rnaindex == -1)); + insert_keyframe(reports, id, action, ((fcu->grp) ? (fcu->grp->name) : (NULL)), + fcu->rna_path, but->rnaindex, cfra, flag); + WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); } } @@ -227,54 +242,54 @@ void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra) void ui_but_anim_insert_keyframe(bContext *C) { - /* this operator calls uiContextActiveProperty */ + /* this operator calls UI_context_active_but_prop_get */ WM_operator_name_call(C, "ANIM_OT_keyframe_insert_button", WM_OP_INVOKE_DEFAULT, NULL); } void ui_but_anim_delete_keyframe(bContext *C) { - /* this operator calls uiContextActiveProperty */ + /* this operator calls UI_context_active_but_prop_get */ WM_operator_name_call(C, "ANIM_OT_keyframe_delete_button", WM_OP_INVOKE_DEFAULT, NULL); } void ui_but_anim_clear_keyframe(bContext *C) { - /* this operator calls uiContextActiveProperty */ + /* this operator calls UI_context_active_but_prop_get */ WM_operator_name_call(C, "ANIM_OT_keyframe_clear_button", WM_OP_INVOKE_DEFAULT, NULL); } void ui_but_anim_add_driver(bContext *C) { - /* this operator calls uiContextActiveProperty */ + /* this operator calls UI_context_active_but_prop_get */ WM_operator_name_call(C, "ANIM_OT_driver_button_add", WM_OP_INVOKE_DEFAULT, NULL); } void ui_but_anim_remove_driver(bContext *C) { - /* this operator calls uiContextActiveProperty */ + /* this operator calls UI_context_active_but_prop_get */ WM_operator_name_call(C, "ANIM_OT_driver_button_remove", WM_OP_INVOKE_DEFAULT, NULL); } void ui_but_anim_copy_driver(bContext *C) { - /* this operator calls uiContextActiveProperty */ + /* this operator calls UI_context_active_but_prop_get */ WM_operator_name_call(C, "ANIM_OT_copy_driver_button", WM_OP_INVOKE_DEFAULT, NULL); } void ui_but_anim_paste_driver(bContext *C) { - /* this operator calls uiContextActiveProperty */ + /* this operator calls UI_context_active_but_prop_get */ WM_operator_name_call(C, "ANIM_OT_paste_driver_button", WM_OP_INVOKE_DEFAULT, NULL); } void ui_but_anim_add_keyingset(bContext *C) { - /* this operator calls uiContextActiveProperty */ + /* this operator calls UI_context_active_but_prop_get */ WM_operator_name_call(C, "ANIM_OT_keyingset_button_add", WM_OP_INVOKE_DEFAULT, NULL); } void ui_but_anim_remove_keyingset(bContext *C) { - /* this operator calls uiContextActiveProperty */ + /* this operator calls UI_context_active_but_prop_get */ WM_operator_name_call(C, "ANIM_OT_keyingset_button_remove", WM_OP_INVOKE_DEFAULT, NULL); } diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 235d7652539..bcd9b9a5547 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -62,7 +62,7 @@ static int roundboxtype = UI_CNR_ALL; -void uiSetRoundBox(int type) +void UI_draw_roundbox_corner_set(int type) { /* Not sure the roundbox function is the best place to change this * if this is undone, its not that big a deal, only makes curves edges @@ -71,12 +71,12 @@ void uiSetRoundBox(int type) } -int uiGetRoundBox(void) +int UI_draw_roundbox_corner_get(void) { return roundboxtype; } -void uiDrawBox(int mode, float minx, float miny, float maxx, float maxy, float rad) +void UI_draw_roundbox_gl_mode(int mode, float minx, float miny, float maxx, float maxy, float rad) { float vec[7][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293}, {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}}; @@ -152,7 +152,9 @@ static void round_box_shade_col(const float col1[3], float const col2[3], const /* linear horizontal shade within button or in outline */ /* view2d scrollers use it */ -void uiDrawBoxShade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown) +void UI_draw_roundbox_shade_x( + int mode, float minx, float miny, float maxx, float maxy, + float rad, float shadetop, float shadedown) { float vec[7][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293}, {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}}; @@ -260,8 +262,9 @@ void uiDrawBoxShade(int mode, float minx, float miny, float maxx, float maxy, fl /* linear vertical shade within button or in outline */ /* view2d scrollers use it */ -void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float maxy, - float rad, float shadeLeft, float shadeRight) +void UI_draw_roundbox_shade_y( + int mode, float minx, float miny, float maxx, float maxy, + float rad, float shadeLeft, float shadeRight) { float vec[7][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293}, {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}}; @@ -365,7 +368,7 @@ void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float } /* plain antialiased unfilled rectangle */ -void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad) +void UI_draw_roundbox_unfilled(float minx, float miny, float maxx, float maxy, float rad) { float color[4]; @@ -380,18 +383,24 @@ void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad) glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); - uiDrawBox(GL_LINE_LOOP, minx, miny, maxx, maxy, rad); + UI_draw_roundbox_gl_mode(GL_LINE_LOOP, minx, miny, maxx, maxy, rad); glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); } /* (old, used in outliner) plain antialiased filled box */ -void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad) +void UI_draw_roundbox(float minx, float miny, float maxx, float maxy, float rad) { ui_draw_anti_roundbox(GL_POLYGON, minx, miny, maxx, maxy, rad, roundboxtype & UI_RB_ALPHA); } +void UI_draw_text_underline(int pos_x, int pos_y, int len, int height) +{ + int ofs_y = 4 * U.pixelsize; + glRecti(pos_x, pos_y - ofs_y, pos_x + len, pos_y - ofs_y + (height * U.pixelsize)); +} + /* ************** SPECIAL BUTTON DRAWING FUNCTIONS ************* */ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *rect) @@ -450,8 +459,8 @@ static void draw_scope_end(const rctf *rect, GLint *scissor) /* outline */ glColor4f(0.f, 0.f, 0.f, 0.5f); - uiSetRoundBox(UI_CNR_ALL); - uiDrawBox(GL_LINE_LOOP, rect->xmin - 1, rect->ymin, rect->xmax + 1, rect->ymax + 1, 3.0f); + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rect->xmin - 1, rect->ymin, rect->xmax + 1, rect->ymax + 1, 3.0f); } static void histogram_draw_one(float r, float g, float b, float alpha, @@ -535,8 +544,8 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f(0.f, 0.f, 0.f, 0.3f); - uiSetRoundBox(UI_CNR_ALL); - uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f); + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f); /* need scissor test, histogram can draw outside of boundary */ glGetIntegerv(GL_VIEWPORT, scissor); @@ -622,8 +631,8 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f(0.f, 0.f, 0.f, 0.3f); - uiSetRoundBox(UI_CNR_ALL); - uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f); + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f); /* need scissor test, waveform can draw outside of boundary */ glGetIntegerv(GL_VIEWPORT, scissor); @@ -841,8 +850,8 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wco glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f(0.f, 0.f, 0.f, 0.3f); - uiSetRoundBox(UI_CNR_ALL); - uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f); + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f); /* need scissor test, hvectorscope can draw outside of boundary */ glGetIntegerv(GL_VIEWPORT, scissor); @@ -1067,7 +1076,7 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti if (coba == NULL) return; if (but->block->color_profile) - display = ui_block_display_get(but->block); + display = ui_block_cm_display_get(but->block); x1 = rect->xmin; sizex = rect->xmax - x1; @@ -1158,7 +1167,7 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti } } -void ui_draw_but_NORMAL(uiBut *but, uiWidgetColors *wcol, const rcti *rect) +void ui_draw_but_UNITVEC(uiBut *but, uiWidgetColors *wcol, const rcti *rect) { static GLuint displist = 0; int a, old[8]; @@ -1171,8 +1180,8 @@ void ui_draw_but_NORMAL(uiBut *but, uiWidgetColors *wcol, const rcti *rect) /* backdrop */ glColor3ubv((unsigned char *)wcol->inner); - uiSetRoundBox(UI_CNR_ALL); - uiDrawBox(GL_POLYGON, rect->xmin, rect->ymin, rect->xmax, rect->ymax, 5.0f); + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox_gl_mode(GL_POLYGON, rect->xmin, rect->ymin, rect->xmax, rect->ymax, 5.0f); /* sphere color */ glMaterialfv(GL_FRONT, GL_DIFFUSE, diffn); @@ -1189,7 +1198,7 @@ void ui_draw_but_NORMAL(uiBut *but, uiWidgetColors *wcol, const rcti *rect) glEnable(GL_LIGHT7); glEnable(GL_LIGHTING); - ui_get_but_vectorf(but, dir); + ui_but_v3_get(but, dir); dir[3] = 0.0f; /* glLightfv needs 4 args, 0.0 is sun */ glLightfv(GL_LIGHT7, GL_POSITION, dir); @@ -1511,8 +1520,8 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc if (scopes->track_disabled) { glColor4f(0.7f, 0.3f, 0.3f, 0.3f); - uiSetRoundBox(UI_CNR_ALL); - uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f); + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f); ok = 1; } @@ -1559,8 +1568,8 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc if (scopes->use_track_mask) { glColor4f(0.0f, 0.0f, 0.0f, 0.3f); - uiSetRoundBox(UI_CNR_ALL); - uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f); + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f); } glaDrawPixelsSafe(rect.xmin, rect.ymin + 1, drawibuf->x, drawibuf->y, @@ -1600,8 +1609,8 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc if (!ok) { glColor4f(0.f, 0.f, 0.f, 0.3f); - uiSetRoundBox(UI_CNR_ALL); - uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f); + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f); } /* outline */ @@ -1717,7 +1726,7 @@ static void ui_shadowbox(float minx, float miny, float maxx, float maxy, float s glShadeModel(GL_FLAT); } -void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, float maxy) +void UI_draw_box_shadow(unsigned char alpha, float minx, float miny, float maxx, float maxy) { /* accumulated outline boxes to make shade not linear, is more pleasant */ ui_shadowbox(minx, miny, maxx, maxy, 11.0, (20 * alpha) >> 8); @@ -1727,7 +1736,7 @@ void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, fl } -void ui_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int UNUSED(select)) +void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int UNUSED(select)) { int i; float rad; @@ -1758,13 +1767,13 @@ void ui_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int glColor4f(0.0f, 0.0f, 0.0f, calpha); calpha += dalpha; - uiDrawBox(GL_POLYGON, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax - 10.0f + a, rad + a); + UI_draw_roundbox_gl_mode(GL_POLYGON, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax - 10.0f + a, rad + a); } /* outline emphasis */ glEnable(GL_LINE_SMOOTH); glColor4ub(0, 0, 0, 100); - uiDrawBox(GL_LINE_LOOP, rct->xmin - 0.5f, rct->ymin - 0.5f, rct->xmax + 0.5f, rct->ymax + 0.5f, radius + 0.5f); + UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin - 0.5f, rct->ymin - 0.5f, rct->xmax + 0.5f, rct->ymax + 0.5f, radius + 0.5f); glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c index 5b7915e20c5..1294da38a41 100644 --- a/source/blender/editors/interface/interface_eyedropper.c +++ b/source/blender/editors/interface/interface_eyedropper.c @@ -91,7 +91,7 @@ static bool eyedropper_init(bContext *C, wmOperator *op) op->customdata = eye = MEM_callocN(sizeof(Eyedropper), "Eyedropper"); - uiContextActiveProperty(C, &eye->ptr, &eye->prop, &eye->index); + UI_context_active_but_prop_get(C, &eye->ptr, &eye->prop, &eye->index); if ((eye->ptr.data == NULL) || (eye->prop == NULL) || @@ -328,7 +328,7 @@ void UI_OT_eyedropper_color(wmOperatorType *ot) /* identifiers */ ot->name = "Eyedropper"; ot->idname = "UI_OT_eyedropper_color"; - ot->description = "Sample a color from the Blender Window to store in a property"; + ot->description = "Sample a data-block from the 3D view"; /* api callbacks */ ot->invoke = eyedropper_invoke; @@ -381,7 +381,7 @@ static void datadropper_draw_cb(const struct bContext *C, ARegion *ar, void *arg return; } - width = UI_GetStringWidth(name); + width = UI_fontstyle_string_width(name); x = x - ar->winrct.xmin; y = y - ar->winrct.ymin; @@ -389,11 +389,11 @@ static void datadropper_draw_cb(const struct bContext *C, ARegion *ar, void *arg glColor4ub(0, 0, 0, 50); - uiSetRoundBox(UI_CNR_ALL | UI_RB_ALPHA); - uiRoundBox(x, y, x + width + 8, y + 15, 4); + UI_draw_roundbox_corner_set(UI_CNR_ALL | UI_RB_ALPHA); + UI_draw_roundbox(x, y, x + width + 8, y + 15, 4); glColor4ub(255, 255, 255, 255); - UI_DrawString(x + 4, y + 4, name); + UI_draw_string(x + 4, y + 4, name); } @@ -411,7 +411,7 @@ static int datadropper_init(bContext *C, wmOperator *op) op->customdata = ddr = MEM_callocN(sizeof(DataDropper), "DataDropper"); - uiContextActiveProperty(C, &ddr->ptr, &ddr->prop, &index_dummy); + UI_context_active_but_prop_get(C, &ddr->ptr, &ddr->prop, &index_dummy); if ((ddr->ptr.data == NULL) || (ddr->prop == NULL) || diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 1e9e42f5ca9..86414d98951 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -87,6 +87,10 @@ #include "WM_api.h" #include "WM_types.h" +#ifdef WITH_INPUT_IME +# include "wm_window.h" +#endif + /* place the mouse at the scaled down location when un-grabbing */ #define USE_CONT_MOUSE_CORRECT /* support dragging toggle buttons */ @@ -103,9 +107,12 @@ #define UI_MAX_PASSWORD_STR 128 +/* This hack is needed because we don't have a good way to re-reference keymap items once added: T42944 */ +#define USE_KEYMAP_ADD_HACK + /* proto */ -static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to); -static void ui_add_link(bContext *C, uiBut *from, uiBut *to); +static void ui_but_smart_controller_add(bContext *C, uiBut *from, uiBut *to); +static void ui_but_link_add(bContext *C, uiBut *from, uiBut *to); static int ui_do_but_EXIT(bContext *C, uiBut *but, struct uiHandleButtonData *data, const wmEvent *event); #ifdef USE_KEYNAV_LIMIT @@ -252,16 +259,16 @@ typedef struct uiHandleButtonData { CBData *dragcbd; #ifdef USE_CONT_MOUSE_CORRECT - /* when ungrabbing buttons which are #ui_is_a_warp_but(), we may want to position them + /* when ungrabbing buttons which are #ui_but_is_cursor_warp(), we may want to position them * FLT_MAX signifies do-nothing, use #ui_block_to_window_fl() to get this into a usable space */ float ungrab_mval[2]; #endif - /* menu open (watch uiFreeActiveButtons) */ + /* menu open (watch UI_screen_free_active_but) */ uiPopupBlockHandle *menu; int menuretval; - /* search box (watch uiFreeActiveButtons) */ + /* search box (watch UI_screen_free_active_but) */ ARegion *searchbox; #ifdef USE_KEYNAV_LIMIT struct uiKeyNavLock searchbox_keynav_state; @@ -313,9 +320,9 @@ typedef struct uiAfterFunc { -static bool ui_is_but_interactive(const uiBut *but, const bool labeledit); +static bool ui_but_is_interactive(const uiBut *but, const bool labeledit); static bool ui_but_contains_pt(uiBut *but, float mx, float my); -static bool ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y); +static bool ui_but_contains_point_px(ARegion *ar, uiBut *but, int x, int y); static uiBut *ui_but_find_mouse_over_ex(ARegion *ar, const int x, const int y, const bool labeledit); static uiBut *ui_but_find_mouse_over(ARegion *ar, const wmEvent *event); static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type); @@ -390,7 +397,17 @@ void ui_pan_to_scroll(const wmEvent *event, int *type, int *val) bool ui_but_is_editable(const uiBut *but) { - return !ELEM(but->type, LABEL, SEPR, SEPRLINE, ROUNDBOX, LISTBOX, PROGRESSBAR); + return !ELEM(but->type, + UI_BTYPE_LABEL, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, + UI_BTYPE_ROUNDBOX, UI_BTYPE_LISTBOX, UI_BTYPE_PROGRESS_BAR); +} + +bool ui_but_is_editable_as_text(const uiBut *but) +{ + return ELEM(but->type, + UI_BTYPE_TEXT, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER, + UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK); + } static uiBut *ui_but_prev(uiBut *but) @@ -435,10 +452,13 @@ static uiBut *ui_but_last(uiBlock *block) return NULL; } -static bool ui_is_a_warp_but(uiBut *but) +static bool ui_but_is_cursor_warp(uiBut *but) { if (U.uiflag & USER_CONTINUOUS_MOUSE) { - if (ELEM(but->type, NUM, NUMSLI, HSVCIRCLE, TRACKPREVIEW, HSVCUBE, BUT_CURVE)) { + if (ELEM(but->type, + UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER, UI_BTYPE_HSVCIRCLE, + UI_BTYPE_TRACK_PREVIEW, UI_BTYPE_HSVCUBE, UI_BTYPE_CURVE)) + { return true; } } @@ -464,7 +484,7 @@ static void ui_mouse_scale_warp(uiHandleButtonData *data, } /* file selectors are exempt from utf-8 checks */ -bool ui_is_but_utf8(const uiBut *but) +bool ui_but_is_utf8(const uiBut *but) { if (but->rnaprop) { const int subtype = RNA_property_subtype(but->rnaprop); @@ -523,7 +543,7 @@ static void ui_apply_but_func(bContext *C, uiBut *but) * with these functions removing the buttons we are working with */ if (but->func || but->funcN || block->handle_func || but->rename_func || - (but->type == BUTM && block->butm_func) || but->optype || but->rnaprop) + (but->type == UI_BTYPE_BUT_MENU && block->butm_func) || but->optype || but->rnaprop) { after = ui_afterfunc_new(); @@ -548,7 +568,7 @@ static void ui_apply_but_func(bContext *C, uiBut *but) after->handle_func_arg = block->handle_func_arg; after->retval = but->retval; - if (but->type == BUTM) { + if (but->type == UI_BTYPE_BUT_MENU) { after->butm_func = block->butm_func; after->butm_func_arg = block->butm_func_arg; after->a2 = but->a2; @@ -570,8 +590,8 @@ static void ui_apply_but_func(bContext *C, uiBut *but) } } -/* typically call ui_apply_undo(), ui_apply_autokey() */ -static void ui_apply_undo(uiBut *but) +/* typically call ui_apply_but_undo(), ui_apply_but_autokey() */ +static void ui_apply_but_undo(uiBut *but) { uiAfterFunc *after; @@ -579,8 +599,8 @@ static void ui_apply_undo(uiBut *but) const char *str = NULL; /* define which string to use for undo */ - if (ELEM(but->type, LINK, INLINK)) str = "Add button link"; - else if (but->type == MENU) str = but->drawstr; + if (ELEM(but->type, UI_BTYPE_LINK, UI_BTYPE_INLINK)) str = "Add button link"; + else if (but->type == UI_BTYPE_MENU) str = but->drawstr; else if (but->drawstr[0]) str = but->drawstr; else str = but->tip; @@ -595,7 +615,7 @@ static void ui_apply_undo(uiBut *but) } } -static void ui_apply_autokey(bContext *C, uiBut *but) +static void ui_apply_but_autokey(bContext *C, uiBut *but) { Scene *scene = CTX_data_scene(C); @@ -689,7 +709,7 @@ static void ui_apply_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data) static void ui_apply_but_BUTM(bContext *C, uiBut *but, uiHandleButtonData *data) { - ui_set_but_val(but, but->hardmin); + ui_but_value_set(but, but->hardmin); ui_apply_but_func(C, but); data->retval = but->retval; @@ -698,10 +718,10 @@ static void ui_apply_but_BUTM(bContext *C, uiBut *but, uiHandleButtonData *data) static void ui_apply_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data) { - if (but->type == MENU) - ui_set_but_val(but, data->value); + if (but->type == UI_BTYPE_MENU) + ui_but_value_set(but, data->value); - ui_check_but(but); + ui_but_update(but); ui_apply_but_func(C, but); data->retval = but->retval; data->applied = true; @@ -712,7 +732,7 @@ static void ui_apply_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data) double value; int w, lvalue, push; - value = ui_get_but_val(but); + value = ui_but_value_get(but); lvalue = (int)value; if (but->bit) { @@ -720,17 +740,17 @@ static void ui_apply_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data) if (w) lvalue = UI_BITBUT_CLR(lvalue, but->bitnr); else lvalue = UI_BITBUT_SET(lvalue, but->bitnr); - ui_set_but_val(but, (double)lvalue); - if (but->type == ICONTOG || but->type == ICONTOGN) ui_check_but(but); + ui_but_value_set(but, (double)lvalue); + if (but->type == UI_BTYPE_ICON_TOGGLE || but->type == UI_BTYPE_ICON_TOGGLE_N) ui_but_update(but); } else { if (value == 0.0) push = 1; else push = 0; - if (ELEM(but->type, TOGN, ICONTOGN, OPTIONN)) push = !push; - ui_set_but_val(but, (double)push); - if (but->type == ICONTOG || but->type == ICONTOGN) ui_check_but(but); + if (ELEM(but->type, UI_BTYPE_TOGGLE_N, UI_BTYPE_ICON_TOGGLE_N, UI_BTYPE_CHECKBOX_N)) push = !push; + ui_but_value_set(but, (double)push); + if (but->type == UI_BTYPE_ICON_TOGGLE || but->type == UI_BTYPE_ICON_TOGGLE_N) ui_but_update(but); } ui_apply_but_func(C, but); @@ -743,14 +763,14 @@ static void ui_apply_but_ROW(bContext *C, uiBlock *block, uiBut *but, uiHandleBu { uiBut *bt; - ui_set_but_val(but, but->hardmax); + ui_but_value_set(but, but->hardmax); ui_apply_but_func(C, but); /* states of other row buttons */ for (bt = block->buttons.first; bt; bt = bt->next) - if (bt != but && bt->poin == but->poin && ELEM(bt->type, ROW, LISTROW)) - ui_check_but(bt); + if (bt != but && bt->poin == but->poin && ELEM(bt->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) + ui_but_update(bt); data->retval = but->retval; data->applied = true; @@ -761,8 +781,8 @@ static void ui_apply_but_TEX(bContext *C, uiBut *but, uiHandleButtonData *data) if (!data->str) return; - ui_set_but_string(C, but, data->str); - ui_check_but(but); + ui_but_string_set(C, but, data->str); + ui_but_update(but); /* give butfunc the original text too */ /* feature used for bone renaming, channels, etc */ @@ -778,8 +798,8 @@ static void ui_apply_but_TEX(bContext *C, uiBut *but, uiHandleButtonData *data) static void ui_apply_but_NUM(bContext *C, uiBut *but, uiHandleButtonData *data) { if (data->str) { - if (ui_set_but_string(C, but, data->str)) { - data->value = ui_get_but_val(but); + if (ui_but_string_set(C, but, data->str)) { + data->value = ui_but_value_get(but); } else { data->cancel = true; @@ -787,9 +807,9 @@ static void ui_apply_but_NUM(bContext *C, uiBut *but, uiHandleButtonData *data) } } else - ui_set_but_val(but, data->value); + ui_but_value_set(but, data->value); - ui_check_but(but); + ui_but_update(but); ui_apply_but_func(C, but); data->retval = but->retval; @@ -798,8 +818,8 @@ static void ui_apply_but_NUM(bContext *C, uiBut *but, uiHandleButtonData *data) static void ui_apply_but_VEC(bContext *C, uiBut *but, uiHandleButtonData *data) { - ui_set_but_vectorf(but, data->vec); - ui_check_but(but); + ui_but_v3_set(but, data->vec); + ui_but_update(but); ui_apply_but_func(C, but); data->retval = but->retval; @@ -836,7 +856,7 @@ static void ui_multibut_add(uiHandleButtonData *data, uiBut *but) mbut_state = MEM_callocN(sizeof(*mbut_state), __func__); mbut_state->but = but; - mbut_state->origvalue = ui_get_but_val(but); + mbut_state->origvalue = ui_but_value_get(but); BLI_linklist_prepend(&data->multi_data.mbuts, mbut_state); @@ -868,7 +888,7 @@ static void ui_multibut_restore(uiHandleButtonData *data, uiBlock *block) if (but->flag & UI_BUT_DRAG_MULTI) { uiButMultiState *mbut_state = ui_multibut_lookup(data, but); if (mbut_state) { - ui_set_but_val(but, mbut_state->origvalue); + ui_but_value_set(but, mbut_state->origvalue); } } } @@ -915,11 +935,11 @@ static bool ui_multibut_states_tag(uiBut *but_active, uiHandleButtonData *data, drag_prev = true; } - if (ui_is_but_interactive(but, false)) { + if (ui_but_is_interactive(but, false)) { /* drag checks */ if (but_active != but) { - if (ui_is_but_compatible(but_active, but)) { + if (ui_but_is_compatible(but_active, but)) { BLI_assert(but->active == NULL); @@ -981,13 +1001,13 @@ static void ui_multibut_states_apply(bContext *C, uiHandleButtonData *data, uiBl if (mbut_state) { void *active_back; - ui_button_execute_begin(C, ar, but, &active_back); + ui_but_execute_begin(C, ar, but, &active_back); BLI_assert(active_back == NULL); /* no need to check 'data->state' here */ if (data->str) { /* entering text (set all) */ but->active->value = data->value; - ui_set_but_string(C, but, data->str); + ui_but_string_set(C, but, data->str); } else { /* dragging (use delta) */ @@ -1001,7 +1021,7 @@ static void ui_multibut_states_apply(bContext *C, uiHandleButtonData *data, uiBl /* clamp based on soft limits, see: T40154 */ CLAMP(but->active->value, (double)but->softmin, (double)but->softmax); } - ui_button_execute_end(C, ar, but, active_back); + ui_but_execute_end(C, ar, but, active_back); } else { /* highly unlikely */ @@ -1050,18 +1070,18 @@ static bool ui_drag_toggle_set_xy_xy(bContext *C, ARegion *ar, const bool is_set for (but = block->buttons.first; but; but = but->next) { /* Note: ctrl is always true here because (at least for now) we always want to consider text control * in this case, even when not embossed. */ - if (ui_is_but_interactive(but, true)) { + if (ui_but_is_interactive(but, true)) { if (BLI_rctf_isect_segment(&but->rect, xy_a_block, xy_b_block)) { /* execute the button */ - if (ui_is_but_bool(but) && but->type == but_type_start) { + if (ui_but_is_bool(but) && but->type == but_type_start) { /* is it pressed? */ - bool is_set_but = ui_is_but_push(but); - BLI_assert(ui_is_but_bool(but) == true); + bool is_set_but = ui_but_is_pushed(but); + BLI_assert(ui_but_is_bool(but) == true); if (is_set_but != is_set) { - uiButExecute(C, but); + UI_but_execute(C, but); if (do_check) { - ui_check_but(but); + ui_but_update(but); } changed = true; } @@ -1164,7 +1184,7 @@ static int ui_handler_region_drag_toggle(bContext *C, const wmEvent *event, void uiBut *but = ui_but_find_mouse_over_ex(ar, drag_info->xy_init[0], drag_info->xy_init[1], true); if (but) { - ui_apply_undo(but); + ui_apply_but_undo(but); } WM_event_remove_ui_handler(&win->modalhandlers, @@ -1181,9 +1201,9 @@ static int ui_handler_region_drag_toggle(bContext *C, const wmEvent *event, void } } -static bool ui_is_but_drag_toggle(const uiBut *but) +static bool ui_but_is_drag_toggle(const uiBut *but) { - return ((ui_is_but_bool(but) == true) && + return ((ui_but_is_bool(but) == true) && /* menu check is importnt so the button dragged over isn't removed instantly */ (ui_block_is_menu(but->block) == false)); } @@ -1191,7 +1211,7 @@ static bool ui_is_but_drag_toggle(const uiBut *but) #endif /* USE_DRAG_TOGGLE */ -static bool ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, const wmEvent *event) +static bool ui_but_contains_point_px_icon(uiBut *but, ARegion *ar, const wmEvent *event) { rcti rect; int x = event->x, y = event->y; @@ -1200,7 +1220,7 @@ static bool ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, const wmEvent *eve BLI_rcti_rctf_copy(&rect, &but->rect); - if (but->imb || but->type == COLOR) { + if (but->imb || but->type == UI_BTYPE_COLOR) { /* use button size itself */ } else if (but->drawflag & UI_BUT_ICON_LEFT) { @@ -1215,7 +1235,7 @@ static bool ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, const wmEvent *eve return BLI_rcti_isect_pt(&rect, x, y); } -static bool ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event) +static bool ui_but_drag_init(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { /* prevent other WM gestures to start while we try to drag */ WM_gestures_remove(C); @@ -1225,15 +1245,15 @@ static bool ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data, button_activate_state(C, but, BUTTON_STATE_EXIT); data->cancel = true; #ifdef USE_DRAG_TOGGLE - if (ui_is_but_bool(but)) { + if (ui_but_is_bool(but)) { uiDragToggleHandle *drag_info = MEM_callocN(sizeof(*drag_info), __func__); ARegion *ar_prev; /* call here because regular mouse-up event wont run, * typically 'button_activate_exit()' handles this */ - ui_apply_autokey(C, but); + ui_apply_but_autokey(C, but); - drag_info->is_set = ui_is_but_push(but); + drag_info->is_set = ui_but_is_pushed(but); drag_info->but_cent_start[0] = BLI_rctf_cent_x(&but->rect); drag_info->but_cent_start[1] = BLI_rctf_cent_y(&but->rect); drag_info->but_type_start = but->type; @@ -1253,7 +1273,7 @@ static bool ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data, } else #endif - if (but->type == COLOR) { + if (but->type == UI_BTYPE_COLOR) { bool valid = false; uiDragColorHandle *drag_info = MEM_callocN(sizeof(*drag_info), __func__); @@ -1288,7 +1308,7 @@ static bool ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data, else { wmDrag *drag; - drag = WM_event_start_drag(C, but->icon, but->dragtype, but->dragpoin, ui_get_but_val(but), WM_DRAG_NOP); + drag = WM_event_start_drag(C, but->icon, but->dragtype, but->dragpoin, ui_but_value_get(but), WM_DRAG_NOP); if (but->imb) WM_event_drag_image(drag, but->imb, but->imb_scale, BLI_rctf_size_x(&but->rect), BLI_rctf_size_y(&but->rect)); } @@ -1300,7 +1320,7 @@ static bool ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data, /* ********************** linklines *********************** */ -static void ui_delete_active_linkline(uiBlock *block) +static void ui_linkline_remove_active(uiBlock *block) { uiBut *but; uiLink *link; @@ -1308,7 +1328,7 @@ static void ui_delete_active_linkline(uiBlock *block) int a, b; for (but = block->buttons.first; but; but = but->next) { - if (but->type == LINK && but->link) { + if (but->type == UI_BTYPE_LINK && but->link) { for (line = but->link->lines.first; line; line = nline) { nline = line->next; @@ -1349,7 +1369,7 @@ static void ui_delete_active_linkline(uiBlock *block) } -static uiLinkLine *ui_is_a_link(uiBut *from, uiBut *to) +static uiLinkLine *ui_but_find_link(uiBut *from, uiBut *to) { uiLinkLine *line; uiLink *link; @@ -1367,7 +1387,7 @@ static uiLinkLine *ui_is_a_link(uiBut *from, uiBut *to) /* XXX BAD BAD HACK, fixme later **************** */ /* Try to add an AND Controller between the sensor and the actuator logic bricks and to connect them all */ -static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to) +static void ui_but_smart_controller_add(bContext *C, uiBut *from, uiBut *to) { Object *ob = NULL; bSensor *sens_iter; @@ -1422,15 +1442,15 @@ static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to) /* (4) link the sensor->controller->actuator */ tmp_but = MEM_callocN(sizeof(uiBut), "uiBut"); - uiSetButLink(tmp_but, (void **)&cont, (void ***)&(cont->links), &(cont->totlinks), from->link->tocode, (int)to->hardmin); + UI_but_link_set(tmp_but, (void **)&cont, (void ***)&(cont->links), &(cont->totlinks), from->link->tocode, (int)to->hardmin); tmp_but->hardmin = from->link->tocode; tmp_but->poin = (char *)cont; - tmp_but->type = INLINK; - ui_add_link(C, from, tmp_but); + tmp_but->type = UI_BTYPE_INLINK; + ui_but_link_add(C, from, tmp_but); - tmp_but->type = LINK; - ui_add_link(C, tmp_but, to); + tmp_but->type = UI_BTYPE_LINK; + ui_but_link_add(C, tmp_but, to); /* (5) garbage collection */ MEM_freeN(tmp_but->link); @@ -1439,7 +1459,7 @@ static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to) WM_operator_properties_free(&props_ptr); } -static void ui_add_link(bContext *C, uiBut *from, uiBut *to) +static void ui_but_link_add(bContext *C, uiBut *from, uiBut *to) { /* in 'from' we have to add a link to 'to' */ uiLink *link; @@ -1447,22 +1467,22 @@ static void ui_add_link(bContext *C, uiBut *from, uiBut *to) void **oldppoin; int a; - if ((line = ui_is_a_link(from, to))) { + if ((line = ui_but_find_link(from, to))) { line->flag |= UI_SELECT; - ui_delete_active_linkline(from->block); + ui_linkline_remove_active(from->block); return; } - if (from->type == INLINK && to->type == INLINK) { + if (from->type == UI_BTYPE_INLINK && to->type == UI_BTYPE_INLINK) { return; } - else if (from->type == LINK && to->type == INLINK) { + else if (from->type == UI_BTYPE_LINK && to->type == UI_BTYPE_INLINK) { if (from->link->tocode != (int)to->hardmin) { - ui_add_smart_controller(C, from, to); + ui_but_smart_controller_add(C, from, to); return; } } - else if (from->type == INLINK && to->type == LINK) { + else if (from->type == UI_BTYPE_INLINK && to->type == UI_BTYPE_LINK) { if (to->link->tocode == (int)from->hardmin) { return; } @@ -1497,15 +1517,15 @@ static void ui_apply_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data) uiBut *bt; for (bt = but->block->buttons.first; bt; bt = bt->next) { - if (ui_mouse_inside_button(ar, bt, but->linkto[0] + ar->winrct.xmin, but->linkto[1] + ar->winrct.ymin) ) + if (ui_but_contains_point_px(ar, bt, but->linkto[0] + ar->winrct.xmin, but->linkto[1] + ar->winrct.ymin) ) break; } if (bt && bt != but) { - if (!ELEM(bt->type, LINK, INLINK) || !ELEM(but->type, LINK, INLINK)) + if (!ELEM(bt->type, UI_BTYPE_LINK, UI_BTYPE_INLINK) || !ELEM(but->type, UI_BTYPE_LINK, UI_BTYPE_INLINK)) return; - if (but->type == LINK) ui_add_link(C, but, bt); - else ui_add_link(C, bt, but); + if (but->type == UI_BTYPE_LINK) ui_but_link_add(C, but, bt); + else ui_but_link_add(C, bt, but); ui_apply_but_func(C, but); data->retval = but->retval; @@ -1542,7 +1562,7 @@ static void ui_apply_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonDat } -static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const bool interactive) +static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const bool interactive) { char *editstr; double *editval; @@ -1591,76 +1611,76 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut /* handle different types */ switch (but->type) { - case BUT: + case UI_BTYPE_BUT: ui_apply_but_BUT(C, but, data); break; - case TEX: - case SEARCH_MENU_UNLINK: - case SEARCH_MENU: + case UI_BTYPE_TEXT: + case UI_BTYPE_SEARCH_MENU_UNLINK: + case UI_BTYPE_SEARCH_MENU: ui_apply_but_TEX(C, but, data); break; - case TOGBUT: - case TOG: - case ICONTOG: - case ICONTOGN: - case TOGN: - case OPTION: - case OPTIONN: + case UI_BTYPE_BUT_TOGGLE: + case UI_BTYPE_TOGGLE: + case UI_BTYPE_TOGGLE_N: + case UI_BTYPE_ICON_TOGGLE: + case UI_BTYPE_ICON_TOGGLE_N: + case UI_BTYPE_CHECKBOX: + case UI_BTYPE_CHECKBOX_N: ui_apply_but_TOG(C, but, data); break; - case ROW: - case LISTROW: + case UI_BTYPE_ROW: + case UI_BTYPE_LISTROW: ui_apply_but_ROW(C, block, but, data); break; - case SCROLL: - case GRIP: - case NUM: - case NUMSLI: + case UI_BTYPE_SCROLL: + case UI_BTYPE_GRIP: + case UI_BTYPE_NUM: + case UI_BTYPE_NUM_SLIDER: ui_apply_but_NUM(C, but, data); break; - case MENU: - case BLOCK: - case PULLDOWN: + case UI_BTYPE_MENU: + case UI_BTYPE_BLOCK: + case UI_BTYPE_PULLDOWN: ui_apply_but_BLOCK(C, but, data); break; - case COLOR: + case UI_BTYPE_COLOR: if (data->cancel) ui_apply_but_VEC(C, but, data); else ui_apply_but_BLOCK(C, but, data); break; - case BUTM: + case UI_BTYPE_BUT_MENU: ui_apply_but_BUTM(C, but, data); break; - case BUT_NORMAL: - case HSVCUBE: - case HSVCIRCLE: + case UI_BTYPE_UNITVEC: + case UI_BTYPE_HSVCUBE: + case UI_BTYPE_HSVCIRCLE: ui_apply_but_VEC(C, but, data); break; - case BUT_COLORBAND: + case UI_BTYPE_COLORBAND: ui_apply_but_COLORBAND(C, but, data); break; - case BUT_CURVE: + case UI_BTYPE_CURVE: ui_apply_but_CURVE(C, but, data); break; - case KEYEVT: - case HOTKEYEVT: + case UI_BTYPE_KEY_EVENT: + case UI_BTYPE_HOTKEY_EVENT: ui_apply_but_BUT(C, but, data); break; - case LINK: - case INLINK: + case UI_BTYPE_LINK: + case UI_BTYPE_INLINK: ui_apply_but_LINK(C, but, data); break; - case BUT_IMAGE: + case UI_BTYPE_IMAGE: ui_apply_but_IMAGE(C, but, data); break; - case HISTOGRAM: + case UI_BTYPE_HISTOGRAM: ui_apply_but_HISTOGRAM(C, but, data); break; - case WAVEFORM: + case UI_BTYPE_WAVEFORM: ui_apply_but_WAVEFORM(C, but, data); break; - case TRACKPREVIEW: + case UI_BTYPE_TRACK_PREVIEW: ui_apply_but_TRACKPREVIEW(C, but, data); break; default: @@ -1698,13 +1718,13 @@ static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleB for (wmd = drags->first; wmd; wmd = wmd->next) { if (wmd->type == WM_DRAG_ID) { /* align these types with UI_but_active_drop_name */ - if (ELEM(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) { + if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) { ID *id = (ID *)wmd->poin; button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); BLI_strncpy(data->str, id->name + 2, data->maxlen); - if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) { + if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) { but->changed = true; ui_searchbox_update(C, data->searchbox, but, true); } @@ -1751,7 +1771,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, /* numeric value */ - if (ELEM(but->type, NUM, NUMSLI)) { + if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) { if (but->poin == NULL && but->rnapoin.data == NULL) { /* pass */ @@ -1760,7 +1780,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, /* Get many decimal places, then strip trailing zeros. * note: too high values start to give strange results (6 or so is ok) */ char buf_copy[UI_MAX_DRAW_STR]; - ui_get_but_string_ex(but, buf_copy, sizeof(buf_copy), 6); + ui_but_string_get_ex(but, buf_copy, sizeof(buf_copy), 6); BLI_str_rstrip_float_zero(buf_copy, '\0'); WM_clipboard_text_set(buf_copy, 0); @@ -1768,17 +1788,17 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, else { double val; - if (ui_set_but_string_eval_num(C, but, buf_paste, &val)) { + if (ui_but_string_set_eval_num(C, but, buf_paste, &val)) { button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); data->value = val; - ui_set_but_string(C, but, buf_paste); + ui_but_string_set(C, but, buf_paste); button_activate_state(C, but, BUTTON_STATE_EXIT); } } } /* NORMAL button */ - else if (but->type == BUT_NORMAL) { + else if (but->type == UI_BTYPE_UNITVEC) { float xyz[3]; if (but->poin == NULL && but->rnapoin.data == NULL) { @@ -1786,7 +1806,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, } else if (mode == 'c') { char buf_copy[UI_MAX_DRAW_STR]; - ui_get_but_vectorf(but, xyz); + ui_but_v3_get(but, xyz); BLI_snprintf(buf_copy, sizeof(buf_copy), "[%f, %f, %f]", xyz[0], xyz[1], xyz[2]); WM_clipboard_text_set(buf_copy, 0); } @@ -1797,7 +1817,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, xyz[2] = 1.0; } button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); - ui_set_but_vectorf(but, xyz); + ui_but_v3_set(but, xyz); button_activate_state(C, but, BUTTON_STATE_EXIT); } } @@ -1805,7 +1825,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, /* RGB triple */ - else if (but->type == COLOR) { + else if (but->type == UI_BTYPE_COLOR) { float rgba[4]; if (but->poin == NULL && but->rnapoin.data == NULL) { @@ -1819,7 +1839,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, else rgba[3] = 1.0f; - ui_get_but_vectorf(but, rgba); + ui_but_v3_get(but, rgba); /* convert to linear color to do compatible copy between gamma and non-gamma */ if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) srgb_to_linearrgb_v3_v3(rgba, rgba); @@ -1835,7 +1855,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, linearrgb_to_srgb_v3_v3(rgba, rgba); button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); - ui_set_but_vectorf(but, rgba); + ui_but_v3_set(but, rgba); if (but->rnaprop && RNA_property_array_length(&but->rnapoin, but->rnaprop) == 4) RNA_property_float_set_index(&but->rnapoin, but->rnaprop, 3, rgba[3]); @@ -1845,7 +1865,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, } /* text/string and ID data */ - else if (ELEM(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) { + else if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) { uiHandleButtonData *active_data = but->active; if (but->poin == NULL && but->rnapoin.data == NULL) { @@ -1860,12 +1880,12 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, else { button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); - if (ui_is_but_utf8(but)) + if (ui_but_is_utf8(but)) BLI_strncpy_utf8(active_data->str, buf_paste, active_data->maxlen); else BLI_strncpy(active_data->str, buf_paste, active_data->maxlen); - if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) { + if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) { /* else uiSearchboxData.active member is not updated [#26856] */ but->changed = true; ui_searchbox_update(C, data->searchbox, but, true); @@ -1874,7 +1894,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, } } /* colorband (not supported by system clipboard) */ - else if (but->type == BUT_COLORBAND) { + else if (but->type == UI_BTYPE_COLORBAND) { if (mode == 'c') { if (but->poin != NULL) { memcpy(&but_copypaste_coba, but->poin, sizeof(ColorBand)); @@ -1891,7 +1911,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, } } } - else if (but->type == BUT_CURVE) { + else if (but->type == UI_BTYPE_CURVE) { if (mode == 'c') { if (but->poin != NULL) { but_copypaste_curve_alive = true; @@ -1916,7 +1936,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, if (mode == 'c') { PointerRNA *opptr; char *str; - opptr = uiButGetOperatorPtrRNA(but); /* allocated when needed, the button owns it */ + opptr = UI_but_operator_ptr_get(but); /* allocated when needed, the button owns it */ str = WM_operator_pystring_ex(C, NULL, false, true, but->optype, opptr); @@ -1926,8 +1946,8 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, } } /* menu (any type) */ - else if (ELEM(but->type, MENU, PULLDOWN)) { - MenuType *mt = uiButGetMenuType(but); + else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) { + MenuType *mt = UI_but_menutype_get(but); if (mt) { char str[32 + sizeof(mt->idname)]; BLI_snprintf(str, sizeof(str), "bpy.ops.wm.call_menu(name=\"%s\")", mt->idname); @@ -1971,7 +1991,7 @@ static int ui_text_position_to_hidden(uiBut *but, int pos) return BLI_strnlen_utf8(butstr, pos); } -void ui_button_text_password_hide(char password_str[UI_MAX_PASSWORD_STR], uiBut *but, const bool restore) +void ui_but_text_password_hide(char password_str[UI_MAX_PASSWORD_STR], uiBut *but, const bool restore) { char *butstr; @@ -2034,7 +2054,7 @@ static bool ui_textedit_delete_selection(uiBut *but, uiHandleButtonData *data) */ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, const float x) { - uiStyle *style = UI_GetStyle(); // XXX pass on as arg + uiStyle *style = UI_style_get(); // XXX pass on as arg uiFontStyle *fstyle = &style->widget; const float aspect = but->block->aspect; const short fstyle_points_prev = fstyle->points; @@ -2047,18 +2067,18 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con ui_fontscale(&fstyle->points, aspect); - uiStyleFontSet(fstyle); + UI_fontstyle_set(fstyle); if (fstyle->kerning == 1) /* for BLF_width */ BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT); - ui_button_text_password_hide(password_str, but, false); + ui_but_text_password_hide(password_str, but, false); origstr = MEM_mallocN(sizeof(char) * data->maxlen, "ui_textedit origstr"); BLI_strncpy(origstr, but->editstr, data->maxlen); - if (ELEM(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) { + if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) { if (but->flag & UI_HAS_ICON) { startx += UI_DPI_ICON_SIZE / aspect; } @@ -2128,7 +2148,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con if (fstyle->kerning == 1) BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT); - ui_button_text_password_hide(password_str, but, true); + ui_but_text_password_hide(password_str, but, true); MEM_freeN(origstr); @@ -2145,7 +2165,7 @@ static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data, if (data->selextend == EXTEND_RIGHT) but->selend = but->pos; else if (data->selextend == EXTEND_LEFT) but->selsta = but->pos; - ui_check_but(but); + ui_but_update(but); } /* this is used for both utf8 and ascii, its meant to be used for single keys, @@ -2185,7 +2205,7 @@ static bool ui_textedit_type_ascii(uiBut *but, uiHandleButtonData *data, char as { char buf[2] = {ascii, '\0'}; - if (ui_is_but_utf8(but) && (BLI_str_utf8_size(buf) == -1)) { + if (ui_but_is_utf8(but) && (BLI_str_utf8_size(buf) == -1)) { printf("%s: entering invalid ascii char into an ascii key (%d)\n", __func__, (int)(unsigned char)ascii); @@ -2204,7 +2224,7 @@ static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, strCursorJump const int pos_prev = but->pos; const bool has_sel = (but->selend - but->selsta) > 0; - ui_check_but(but); + ui_but_update(but); /* special case, quit selection and set cursor */ if (has_sel && !select) { @@ -2356,7 +2376,7 @@ static bool ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, const in /* paste */ if (mode == UI_TEXTEDIT_PASTE) { - /* TODO, ensure UTF8 ui_is_but_utf8() - campbell */ + /* TODO, ensure UTF8 ui_but_is_utf8() - campbell */ /* extract the first line from the clipboard */ pbuf = WM_clipboard_text_get_firstline(false, &buf_len); @@ -2412,8 +2432,52 @@ static bool ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, const in return changed; } +#ifdef WITH_INPUT_IME +/* enable ime, and set up uibut ime data */ +static void ui_textedit_ime_begin(wmWindow *win, uiBut *UNUSED(but)) +{ + /* XXX Is this really needed? */ + int x, y; + + BLI_assert(win->ime_data == NULL); + + /* enable IME and position to cursor, it's a trick */ + x = win->eventstate->x; + /* flip y and move down a bit, prevent the IME panel cover the edit button */ + y = win->eventstate->y - 12; + + wm_window_IME_begin(win, x, y, 0, 0, true); +} + +/* disable ime, and clear uibut ime data */ +static void ui_textedit_ime_end(wmWindow *win, uiBut *UNUSED(but)) +{ + wm_window_IME_end(win); +} + +void ui_but_ime_reposition(uiBut *but, int x, int y, bool complete) +{ + BLI_assert(but->active); + + ui_region_to_window(but->active->region, &x, &y); + wm_window_IME_begin(but->active->window, x, y - 4, 0, 0, complete); +} + +/* should be ui_but_ime_data_get */ +wmIMEData *ui_but_get_ime_data(uiBut *but) +{ + if (but->active && but->active->window) { + return but->active->window->ime_data; + } + else { + return NULL; + } +} +#endif /* WITH_INPUT_IME */ + static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data) { + wmWindow *win = CTX_wm_window(C); int len; if (data->str) { @@ -2426,7 +2490,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data) if (data->applied_interactive) { /* remove any small changes so canceling edit doesn't restore invalid value: T40538 */ data->cancel = true; - ui_apply_button(C, but->block, but, data, true); + ui_apply_but(C, but->block, but, data, true); data->cancel = false; data->applied_interactive = false; @@ -2434,16 +2498,16 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data) #endif /* retrieve string */ - data->maxlen = ui_get_but_string_max_length(but); + data->maxlen = ui_but_string_get_max_length(but); data->str = MEM_callocN(sizeof(char) * data->maxlen + 1, "textedit str"); - ui_get_but_string(but, data->str, data->maxlen); + ui_but_string_get(but, data->str, data->maxlen); - if (ui_is_but_float(but) && !ui_is_but_unit(but)) { + if (ui_but_is_float(but) && !ui_but_is_unit(but)) { BLI_str_rstrip_float_zero(data->str, '\0'); } - if (ELEM(but->type, NUM, NUMSLI)) { - ui_convert_to_unit_alt_name(but, data->str, data->maxlen); + if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) { + ui_but_convert_to_unit_alt_name(but, data->str, data->maxlen); } /* won't change from now on */ @@ -2460,7 +2524,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data) but->selend = len; /* optional searchbox */ - if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) { + if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) { data->searchbox = ui_searchbox_create(C, data->region, but); ui_searchbox_update(C, data->searchbox, but, true); /* true = reset */ } @@ -2468,15 +2532,21 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data) /* reset alert flag (avoid confusion, will refresh on exit) */ but->flag &= ~UI_BUT_REDALERT; - ui_check_but(but); - - WM_cursor_modal_set(CTX_wm_window(C), BC_TEXTEDITCURSOR); + ui_but_update(but); + + WM_cursor_modal_set(win, BC_TEXTEDITCURSOR); + +#ifdef WITH_INPUT_IME + ui_textedit_ime_begin(win, but); +#endif } static void ui_textedit_end(bContext *C, uiBut *but, uiHandleButtonData *data) { + wmWindow *win = CTX_wm_window(C); + if (but) { - if (ui_is_but_utf8(but)) { + if (ui_but_is_utf8(but)) { int strip = BLI_utf8_invalid_strip(but->editstr, strlen(but->editstr)); /* not a file?, strip non utf-8 chars */ if (strip) { @@ -2505,7 +2575,13 @@ static void ui_textedit_end(bContext *C, uiBut *but, uiHandleButtonData *data) but->pos = -1; } - WM_cursor_modal_restore(CTX_wm_window(C)); + WM_cursor_modal_restore(win); + +#ifdef WITH_INPUT_IME + if (win->ime_data) { + ui_textedit_ime_end(win, but); + } +#endif } static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonData *data) @@ -2513,11 +2589,11 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa uiBut *but; /* label and roundbox can overlap real buttons (backdrops...) */ - if (ELEM(actbut->type, LABEL, SEPR, SEPRLINE, ROUNDBOX, LISTBOX)) + if (ELEM(actbut->type, UI_BTYPE_LABEL, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_ROUNDBOX, UI_BTYPE_LISTBOX)) return; for (but = actbut->next; but; but = but->next) { - if (ELEM(but->type, TEX, NUM, NUMSLI, SEARCH_MENU, SEARCH_MENU_UNLINK)) { + if (ui_but_is_editable_as_text(but)) { if (!(but->flag & UI_BUT_DISABLED)) { data->postbut = but; data->posttype = BUTTON_ACTIVATE_TEXT_EDITING; @@ -2526,7 +2602,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa } } for (but = block->buttons.first; but != actbut; but = but->next) { - if (ELEM(but->type, TEX, NUM, NUMSLI, SEARCH_MENU, SEARCH_MENU_UNLINK)) { + if (ui_but_is_editable_as_text(but)) { if (!(but->flag & UI_BUT_DISABLED)) { data->postbut = but; data->posttype = BUTTON_ACTIVATE_TEXT_EDITING; @@ -2541,11 +2617,11 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa uiBut *but; /* label and roundbox can overlap real buttons (backdrops...) */ - if (ELEM(actbut->type, LABEL, SEPR, SEPRLINE, ROUNDBOX, LISTBOX)) + if (ELEM(actbut->type, UI_BTYPE_LABEL, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_ROUNDBOX, UI_BTYPE_LISTBOX)) return; for (but = actbut->prev; but; but = but->prev) { - if (ELEM(but->type, TEX, NUM, NUMSLI, SEARCH_MENU, SEARCH_MENU_UNLINK)) { + if (ui_but_is_editable_as_text(but)) { if (!(but->flag & UI_BUT_DISABLED)) { data->postbut = but; data->posttype = BUTTON_ACTIVATE_TEXT_EDITING; @@ -2554,7 +2630,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa } } for (but = block->buttons.last; but != actbut; but = but->prev) { - if (ELEM(but->type, TEX, NUM, NUMSLI, SEARCH_MENU, SEARCH_MENU_UNLINK)) { + if (ui_but_is_editable_as_text(but)) { if (!(but->flag & UI_BUT_DISABLED)) { data->postbut = but; data->posttype = BUTTON_ACTIVATE_TEXT_EDITING; @@ -2570,6 +2646,14 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle int retval = WM_UI_HANDLER_CONTINUE; bool changed = false, inbox = false, update = false; +#ifdef WITH_INPUT_IME + wmWindow *win = CTX_wm_window(C); + wmIMEData *ime_data = win->ime_data; + bool is_ime_composing = ime_data && ime_data->is_ime_composing; +#else + bool is_ime_composing = false; +#endif + switch (event->type) { case MOUSEMOVE: case MOUSEPAN: @@ -2590,6 +2674,12 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle case RIGHTMOUSE: case ESCKEY: if (event->val == KM_PRESS) { +#ifdef WITH_INPUT_IME + /* skips button handling since it is not wanted */ + if (is_ime_composing) { + break; + } +#endif data->cancel = true; data->escapecancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); @@ -2647,7 +2737,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle } } - if (event->val == KM_PRESS) { + if (event->val == KM_PRESS && !is_ime_composing) { switch (event->type) { case VKEY: case XKEY: @@ -2763,13 +2853,21 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle break; } - if ((event->ascii || event->utf8_buf[0]) && (retval == WM_UI_HANDLER_CONTINUE)) { + if ((event->ascii || event->utf8_buf[0]) && + (retval == WM_UI_HANDLER_CONTINUE) +#ifdef WITH_INPUT_IME + && + !is_ime_composing && + !WM_event_is_ime_switch(event) +#endif + ) + { char ascii = event->ascii; const char *utf8_buf = event->utf8_buf; /* exception that's useful for number buttons, some keyboard * numpads have a comma instead of a period */ - if (ELEM(but->type, NUM, NUMSLI)) { /* could use data->min*/ + if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) { /* could use data->min*/ if (event->type == PADPERIOD && ascii == ',') { ascii = '.'; utf8_buf = NULL; /* force ascii fallback */ @@ -2798,13 +2896,32 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle update = true; } +#ifdef WITH_INPUT_IME + if (event->type == WM_IME_COMPOSITE_START || event->type == WM_IME_COMPOSITE_EVENT) { + changed = true; + + if (event->type == WM_IME_COMPOSITE_START && but->selend > but->selsta) { + ui_textedit_delete_selection(but, data); + } + if (event->type == WM_IME_COMPOSITE_EVENT && ime_data->result_len) { + ui_textedit_type_buf( + but, data, + ime_data->str_result, + ime_data->result_len); + } + } + else if (event->type == WM_IME_COMPOSITE_END) { + changed = true; + } +#endif + if (changed) { /* only update when typing for TAB key */ if (update && data->interactive) { - ui_apply_button(C, block, but, data, true); + ui_apply_but(C, block, but, data, true); } else { - ui_check_but(but); + ui_but_update(but); } but->changed = true; @@ -2839,7 +2956,7 @@ static void ui_do_but_textedit_select(bContext *C, uiBlock *block, uiBut *but, u } if (retval == WM_UI_HANDLER_BREAK) { - ui_check_but(but); + ui_but_update(but); ED_region_tag_redraw(data->region); } } @@ -2848,22 +2965,22 @@ static void ui_do_but_textedit_select(bContext *C, uiBlock *block, uiBut *but, u static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data) { - if (but->type == BUT_CURVE) { + if (but->type == UI_BTYPE_CURVE) { but->editcumap = (CurveMapping *)but->poin; } - else if (but->type == BUT_COLORBAND) { + else if (but->type == UI_BTYPE_COLORBAND) { data->coba = (ColorBand *)but->poin; but->editcoba = data->coba; } - else if (ELEM(but->type, BUT_NORMAL, HSVCUBE, HSVCIRCLE, COLOR)) { - ui_get_but_vectorf(but, data->origvec); + else if (ELEM(but->type, UI_BTYPE_UNITVEC, UI_BTYPE_HSVCUBE, UI_BTYPE_HSVCIRCLE, UI_BTYPE_COLOR)) { + ui_but_v3_get(but, data->origvec); copy_v3_v3(data->vec, data->origvec); but->editvec = data->vec; } else { float softrange, softmin, softmax; - data->startvalue = ui_get_but_val(but); + data->startvalue = ui_but_value_get(but); data->origvalue = data->startvalue; data->value = data->origvalue; but->editval = &data->value; @@ -2897,10 +3014,10 @@ static void ui_numedit_end(uiBut *but, uiHandleButtonData *data) static void ui_numedit_apply(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data) { if (data->interactive) { - ui_apply_button(C, block, but, data, true); + ui_apply_but(C, block, but, data, true); } else { - ui_check_but(but); + ui_but_update(but); } ED_region_tag_redraw(data->region); @@ -2908,7 +3025,7 @@ static void ui_numedit_apply(bContext *C, uiBlock *block, uiBut *but, uiHandleBu /* ****************** menu opening for various types **************** */ -static void ui_blockopen_begin(bContext *C, uiBut *but, uiHandleButtonData *data) +static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *data) { uiBlockCreateFunc func = NULL; uiBlockHandleCreateFunc handlefunc = NULL; @@ -2916,8 +3033,8 @@ static void ui_blockopen_begin(bContext *C, uiBut *but, uiHandleButtonData *data void *arg = NULL; switch (but->type) { - case BLOCK: - case PULLDOWN: + case UI_BTYPE_BLOCK: + case UI_BTYPE_PULLDOWN: if (but->menu_create_func) { menufunc = but->menu_create_func; arg = but->poin; @@ -2927,13 +3044,13 @@ static void ui_blockopen_begin(bContext *C, uiBut *but, uiHandleButtonData *data arg = but->poin ? but->poin : but->func_argN; } break; - case MENU: + case UI_BTYPE_MENU: BLI_assert(but->menu_create_func); menufunc = but->menu_create_func; arg = but->poin; break; - case COLOR: - ui_get_but_vectorf(but, data->origvec); + case UI_BTYPE_COLOR: + ui_but_v3_get(but, data->origvec); copy_v3_v3(data->vec, data->origvec); but->editvec = data->vec; @@ -2961,7 +3078,7 @@ static void ui_blockopen_begin(bContext *C, uiBut *but, uiHandleButtonData *data //if (but->block->auto_open == 0) but->block->auto_open = 1; } -static void ui_blockopen_end(bContext *C, uiBut *but, uiHandleButtonData *data) +static void ui_block_open_end(bContext *C, uiBut *but, uiHandleButtonData *data) { if (but) { but->editval = NULL; @@ -2976,7 +3093,7 @@ static void ui_blockopen_end(bContext *C, uiBut *but, uiHandleButtonData *data) } } -int ui_button_open_menu_direction(uiBut *but) +int ui_but_menu_direction(uiBut *but) { uiHandleButtonData *data = but->active; @@ -2986,14 +3103,14 @@ int ui_button_open_menu_direction(uiBut *but) return 0; } -/* Hack for uiList LISTROW buttons to "give" events to overlaying TEX buttons (cltr-clic rename feature & co). */ +/* Hack for uiList UI_BTYPE_LISTROW buttons to "give" events to overlaying UI_BTYPE_TEXT buttons (cltr-clic rename feature & co). */ static uiBut *ui_but_list_row_text_activate(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event, uiButtonActivateType activate_type) { ARegion *ar = CTX_wm_region(C); uiBut *labelbut = ui_but_find_mouse_over_ex(ar, event->x, event->y, true); - if (labelbut && labelbut->type == TEX && !(labelbut->flag & UI_BUT_DISABLED)) { + if (labelbut && labelbut->type == UI_BTYPE_TEXT && !(labelbut->flag & UI_BUT_DISABLED)) { /* exit listrow */ data->cancel = true; button_activate_exit(C, but, data, false, false); @@ -3050,16 +3167,16 @@ static int ui_do_but_HOTKEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data } } else if (data->state == BUTTON_STATE_WAIT_KEY_EVENT) { - - if (event->type == MOUSEMOVE) + if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { return WM_UI_HANDLER_CONTINUE; - + } + if (event->type == LEFTMOUSE && event->val == KM_PRESS) { /* only cancel if click outside the button */ - if (ui_mouse_inside_button(but->active->region, but, event->x, event->y) == 0) { + if (ui_but_contains_point_px(but->active->region, but, event->x, event->y) == 0) { /* data->cancel doesnt work, this button opens immediate */ if (but->flag & UI_BUT_IMMEDIATE) - ui_set_but_val(but, 0); + ui_but_value_set(but, 0); else data->cancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); @@ -3074,14 +3191,14 @@ static int ui_do_but_HOTKEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data if (event->ctrl) but->modifier_key |= KM_CTRL; if (event->oskey) but->modifier_key |= KM_OSKEY; - ui_check_but(but); + ui_but_update(but); ED_region_tag_redraw(data->region); if (event->val == KM_PRESS) { if (ISHOTKEY(event->type)) { if (WM_key_event_string(event->type)[0]) - ui_set_but_val(but, event->type); + ui_but_value_set(but, event->type); else data->cancel = true; @@ -3117,7 +3234,7 @@ static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, c if (event->val == KM_PRESS) { if (WM_key_event_string(event->type)[0]) - ui_set_but_val(but, event->type); + ui_but_value_set(but, event->type); else data->cancel = true; @@ -3132,10 +3249,10 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton { if (data->state == BUTTON_STATE_HIGHLIGHT) { if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY) && event->val == KM_PRESS) { - if (ELEM(event->type, PADENTER, RETKEY) && (!ui_is_but_utf8(but))) { + if (ELEM(event->type, PADENTER, RETKEY) && (!ui_but_is_utf8(but))) { /* pass - allow filesel, enter to execute */ } - else if (but->dt == UI_EMBOSSN && !event->ctrl) { + else if (but->dt == UI_EMBOSS_NONE && !event->ctrl) { /* pass */ } else { @@ -3160,7 +3277,7 @@ static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHa { /* unlink icon is on right */ if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY) && event->val == KM_PRESS && - ui_is_but_search_unlink_visible(but)) + ui_but_is_search_unlink_visible(but)) { ARegion *ar = data->region; rcti rect; @@ -3190,12 +3307,12 @@ static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, cons { #ifdef USE_DRAG_TOGGLE if (data->state == BUTTON_STATE_HIGHLIGHT) { - if (event->type == LEFTMOUSE && event->val == KM_PRESS && ui_is_but_drag_toggle(but)) { + if (event->type == LEFTMOUSE && event->val == KM_PRESS && ui_but_is_drag_toggle(but)) { #if 0 /* UNUSED */ data->togdual = event->ctrl; data->togonly = !event->shift; #endif - ui_apply_button(C, but->block, but, data, true); + ui_apply_but(C, but->block, but, data, true); button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG); data->dragstartx = event->x; data->dragstarty = event->y; @@ -3228,7 +3345,7 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, con /* first handle click on icondrag type button */ if (event->type == LEFTMOUSE && but->dragpoin) { - if (ui_but_mouse_inside_icon(but, data->region, event)) { + if (ui_but_contains_point_px_icon(but, data->region, event)) { /* tell the button to wait and keep checking further events to * see if it should start dragging */ @@ -3239,7 +3356,7 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, con } } #ifdef USE_DRAG_TOGGLE - if (event->type == LEFTMOUSE && ui_is_but_drag_toggle(but)) { + if (event->type == LEFTMOUSE && ui_but_is_drag_toggle(but)) { button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG); data->dragstartx = event->x; data->dragstarty = event->y; @@ -3250,7 +3367,7 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, con if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) { int ret = WM_UI_HANDLER_BREAK; /* XXX (a bit ugly) Special case handling for filebrowser drag button */ - if (but->dragpoin && but->imb && ui_but_mouse_inside_icon(but, data->region, event)) { + if (but->dragpoin && but->imb && ui_but_contains_point_px_icon(but, data->region, event)) { ret = WM_UI_HANDLER_CONTINUE; } button_activate_state(C, but, BUTTON_STATE_EXIT); @@ -3260,7 +3377,7 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, con else if (data->state == BUTTON_STATE_WAIT_DRAG) { /* this function also ends state */ - if (ui_but_start_drag(C, but, data, event)) { + if (ui_but_drag_init(C, but, data, event)) { return WM_UI_HANDLER_BREAK; } @@ -3290,9 +3407,9 @@ static float ui_numedit_apply_snapf(uiBut *but, float tempf, float softmin, floa else { float fac = 1.0f; - if (ui_is_but_unit(but)) { + if (ui_but_is_unit(but)) { UnitSettings *unit = but->block->unit; - int unit_type = RNA_SUBTYPE_UNIT_VALUE(uiButGetUnitType(but)); + int unit_type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but)); if (bUnit_IsValid(unit->system, unit_type)) { fac = (float)bUnit_BaseScalar(unit->system, unit_type); @@ -3358,7 +3475,7 @@ static bool ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float deler, tempf, softmin, softmax, softrange; int lvalue, temp; bool changed = false; - const bool is_float = ui_is_but_float(but); + const bool is_float = ui_but_is_float(but); if (mx == data->draglastx) return changed; @@ -3382,7 +3499,7 @@ static bool ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, softmax = but->softmax; softrange = softmax - softmin; - if (ui_is_a_warp_but(but)) { + if (ui_but_is_cursor_warp(but)) { /* Mouse location isn't screen clamped to the screen so use a linear mapping * 2px == 1-int, or 1px == 1-ClickStep */ if (is_float) { @@ -3536,7 +3653,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton retval = WM_UI_HANDLER_BREAK; } else if (event->type == LEFTMOUSE) { - data->dragstartx = data->draglastx = ui_is_a_warp_but(but) ? screen_mx : mx; + data->dragstartx = data->draglastx = ui_but_is_cursor_warp(but) ? screen_mx : mx; button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); retval = WM_UI_HANDLER_BREAK; } @@ -3594,7 +3711,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton if (event->shift) fac /= 10.0f; if (event->alt) fac /= 20.0f; - if (ui_numedit_but_NUM(but, data, (ui_is_a_warp_but(but) ? screen_mx : mx), snap, fac)) + if (ui_numedit_but_NUM(but, data, (ui_but_is_cursor_warp(but) ? screen_mx : mx), snap, fac)) ui_numedit_apply(C, block, but, data); #ifdef USE_DRAG_MULTINUM else if (data->multi_data.has_mbuts) { @@ -3627,7 +3744,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton handlewidth = min_ff(BLI_rctf_size_x(&but->rect) / 3, BLI_rctf_size_y(&but->rect)); - if (!ui_is_but_float(but)) { + if (!ui_but_is_float(but)) { if (mx < (but->rect.xmin + handlewidth)) { button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); @@ -3705,11 +3822,11 @@ static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, /* yes, 'mx' as both x/y is intentional */ ui_mouse_scale_warp(data, mx, mx, &mx_fl, &my_fl, shift); - if (but->type == NUMSLI) { + if (but->type == UI_BTYPE_NUM_SLIDER) { offs = (BLI_rctf_size_y(&but->rect) / 2.0f); deler = BLI_rctf_size_x(&but->rect) - offs; } - else if (but->type == SCROLL) { + else if (but->type == UI_BTYPE_SCROLL) { const float size = (is_horizontal) ? BLI_rctf_size_x(&but->rect) : -BLI_rctf_size_y(&but->rect); deler = size * (but->softmax - but->softmin) / (but->softmax - but->softmin + but->a1); offs = 0.0; @@ -3725,7 +3842,7 @@ static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, /* deal with mouse correction */ #ifdef USE_CONT_MOUSE_CORRECT - if (ui_is_a_warp_but(but)) { + if (ui_but_is_cursor_warp(but)) { /* OK but can go outside bounds */ if (is_horizontal) { data->ungrab_mval[0] = (but->rect.xmin + offs) + (f * deler); @@ -3748,7 +3865,7 @@ static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, if (tempf == softmin || tempf == softmax) { /* pass */ } - else if (ui_is_but_float(but)) { + else if (ui_but_is_float(but)) { if (shift) { if (tempf == softmin || tempf == softmax) {} @@ -3768,7 +3885,7 @@ static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, } } - if (!ui_is_but_float(but)) { + if (!ui_but_is_float(but)) { lvalue = floor(data->value + 0.5); CLAMP(temp, softmin, softmax); @@ -3824,7 +3941,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); retval = WM_UI_HANDLER_BREAK; } - /* alt-click on sides to get "arrows" like in NUM buttons, and match wheel usage above */ + /* alt-click on sides to get "arrows" like in UI_BTYPE_NUM buttons, and match wheel usage above */ else if (event->type == LEFTMOUSE && event->alt) { int halfpos = BLI_rctf_cent_x(&but->rect); click = 2; @@ -3932,7 +4049,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton f = softmin + f * softrange; - if (!ui_is_but_float(but)) { + if (!ui_but_is_float(but)) { if (f < temp) temp--; else temp++; @@ -4098,7 +4215,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co /* first handle click on icondrag type button */ if (event->type == LEFTMOUSE && but->dragpoin && event->val == KM_PRESS) { - if (ui_but_mouse_inside_icon(but, data->region, event)) { + if (ui_but_contains_point_px_icon(but, data->region, event)) { button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG); data->dragstartx = event->x; data->dragstarty = event->y; @@ -4106,7 +4223,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co } } #ifdef USE_DRAG_TOGGLE - if (event->type == LEFTMOUSE && event->val == KM_PRESS && (ui_is_but_drag_toggle(but))) { + if (event->type == LEFTMOUSE && event->val == KM_PRESS && (ui_but_is_drag_toggle(but))) { button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG); data->dragstartx = event->x; data->dragstarty = event->y; @@ -4118,14 +4235,14 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co button_activate_state(C, but, BUTTON_STATE_MENU_OPEN); return WM_UI_HANDLER_BREAK; } - else if (but->type == MENU) { + else if (but->type == UI_BTYPE_MENU) { if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) { const int direction = (event->type == WHEELDOWNMOUSE) ? -1 : 1; - data->value = ui_step_name_menu(but, direction); + data->value = ui_but_menu_step(but, direction); button_activate_state(C, but, BUTTON_STATE_EXIT); - ui_apply_button(C, but->block, but, data, true); + ui_apply_but(C, but->block, but, data, true); /* button's state need to be changed to EXIT so moving mouse away from this mouse wouldn't lead * to cancel changes made to this button, but changing state to EXIT also makes no button active for @@ -4154,12 +4271,12 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co else if (data->state == BUTTON_STATE_WAIT_DRAG) { /* this function also ends state */ - if (ui_but_start_drag(C, but, data, event)) { + if (ui_but_drag_init(C, but, data, event)) { return WM_UI_HANDLER_BREAK; } /* outside icon quit, not needed if drag activated */ - if (0 == ui_but_mouse_inside_icon(but, data->region, event)) { + if (0 == ui_but_contains_point_px_icon(but, data->region, event)) { button_activate_state(C, but, BUTTON_STATE_EXIT); data->cancel = true; return WM_UI_HANDLER_BREAK; @@ -4175,7 +4292,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co return WM_UI_HANDLER_CONTINUE; } -static bool ui_numedit_but_NORMAL(uiBut *but, uiHandleButtonData *data, +static bool ui_numedit_but_UNITVEC(uiBut *but, uiHandleButtonData *data, int mx, int my, const enum eSnapType snap) { @@ -4271,7 +4388,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co /* first handle click on icondrag type button */ if (event->type == LEFTMOUSE && but->dragpoin && event->val == KM_PRESS) { ui_palette_set_active(but); - if (ui_but_mouse_inside_icon(but, data->region, event)) { + if (ui_but_contains_point_px_icon(but, data->region, event)) { button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG); data->dragstartx = event->x; data->dragstarty = event->y; @@ -4294,10 +4411,12 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co return WM_UI_HANDLER_BREAK; } else if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) { - float *hsv = ui_block_hsv_get(but->block); + ColorPicker *cpicker = but->custom_data; + float hsv_static[3] = {0.0f}; + float *hsv = cpicker ? cpicker->color_data : hsv_static; float col[3]; - ui_get_but_vectorf(but, col); + ui_but_v3_get(but, col); rgb_to_hsv_compat_v(col, hsv); if (event->type == WHEELDOWNMOUSE) @@ -4310,10 +4429,10 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co } hsv_to_rgb_v(hsv, data->vec); - ui_set_but_vectorf(but, data->vec); + ui_but_v3_set(but, data->vec); button_activate_state(C, but, BUTTON_STATE_EXIT); - ui_apply_button(C, but->block, but, data, true); + ui_apply_but(C, but->block, but, data, true); return WM_UI_HANDLER_BREAK; } else if ((int)(but->a1) == UI_PALETTE_COLOR && @@ -4331,12 +4450,12 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co else if (data->state == BUTTON_STATE_WAIT_DRAG) { /* this function also ends state */ - if (ui_but_start_drag(C, but, data, event)) { + if (ui_but_drag_init(C, but, data, event)) { return WM_UI_HANDLER_BREAK; } /* outside icon quit, not needed if drag activated */ - if (0 == ui_but_mouse_inside_icon(but, data->region, event)) { + if (0 == ui_but_contains_point_px_icon(but, data->region, event)) { button_activate_state(C, but, BUTTON_STATE_EXIT); data->cancel = true; return WM_UI_HANDLER_BREAK; @@ -4355,7 +4474,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) { RNA_property_float_get_array(&but->rnapoin, but->rnaprop, target); - ui_block_to_scene_linear_v3(but->block, target); + ui_block_cm_to_scene_linear_v3(but->block, target); } else if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR) { RNA_property_float_get_array(&but->rnapoin, but->rnaprop, target); @@ -4368,7 +4487,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co } else if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR) { RNA_property_float_get_array(&but->rnapoin, but->rnaprop, color); - ui_block_to_display_space_v3(but->block, color); + ui_block_cm_to_display_space_v3(but->block, color); BKE_brush_color_set(scene, brush, color); } } @@ -4390,7 +4509,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co return WM_UI_HANDLER_CONTINUE; } -static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) +static int ui_do_but_UNITVEC(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { int mx, my; @@ -4408,7 +4527,7 @@ static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); /* also do drag the first time */ - if (ui_numedit_but_NORMAL(but, data, mx, my, snap)) + if (ui_numedit_but_UNITVEC(but, data, mx, my, snap)) ui_numedit_apply(C, block, but, data); return WM_UI_HANDLER_BREAK; @@ -4418,7 +4537,7 @@ static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut if (event->type == MOUSEMOVE) { if (mx != data->draglastx || my != data->draglasty) { const enum eSnapType snap = ui_event_to_snap(event); - if (ui_numedit_but_NORMAL(but, data, mx, my, snap)) + if (ui_numedit_but_UNITVEC(but, data, mx, my, snap)) ui_numedit_apply(C, block, but, data); } } @@ -4473,17 +4592,18 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, int my, const enum eSnapType snap, const bool shift) { + ColorPicker *cpicker = but->custom_data; + float *hsv = cpicker->color_data; float rgb[3]; - float *hsv = ui_block_hsv_get(but->block); float x, y; float mx_fl, my_fl; bool changed = true; - bool use_display_colorspace = ui_color_picker_use_display_colorspace(but); + bool use_display_colorspace = ui_but_is_colorpicker_display_space(but); ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift); #ifdef USE_CONT_MOUSE_CORRECT - if (ui_is_a_warp_but(but)) { + if (ui_but_is_cursor_warp(but)) { /* OK but can go outside bounds */ data->ungrab_mval[0] = mx_fl; data->ungrab_mval[1] = my_fl; @@ -4491,10 +4611,10 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, } #endif - ui_get_but_vectorf(but, rgb); + ui_but_v3_get(but, rgb); if (use_display_colorspace) - ui_block_to_display_space_v3(but->block, rgb); + ui_block_cm_to_display_space_v3(but->block, rgb); ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsv); @@ -4508,9 +4628,9 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, /* calculate original hsv again */ copy_v3_v3(rgb, data->origvec); if (use_display_colorspace) - ui_block_to_display_space_v3(but->block, rgb); + ui_block_cm_to_display_space_v3(but->block, rgb); - copy_v3_v3(hsvo, ui_block_hsv_get(but->block)); + copy_v3_v3(hsvo, hsv); ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsvo); @@ -4572,7 +4692,7 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, ui_color_picker_to_rgb_HSVCUBE_v(but, hsv, rgb); if (use_display_colorspace) - ui_block_to_scene_linear_v3(but->block, rgb); + ui_block_cm_to_scene_linear_v3(but->block, rgb); /* clamp because with color conversion we can exceed range [#34295] */ if (but->a1 == UI_GRAD_V_ALT) { @@ -4591,16 +4711,17 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, const wmNDOFMotionData *ndof, const enum eSnapType snap, const bool shift) { - float *hsv = ui_block_hsv_get(but->block); + ColorPicker *cpicker = but->custom_data; + float *hsv = cpicker->color_data; const float hsv_v_max = max_ff(hsv[2], but->softmax); float rgb[3]; float sensitivity = (shift ? 0.15f : 0.3f) * ndof->dt; - bool use_display_colorspace = ui_color_picker_use_display_colorspace(but); + bool use_display_colorspace = ui_but_is_colorpicker_display_space(but); - ui_get_but_vectorf(but, rgb); + ui_but_v3_get(but, rgb); if (use_display_colorspace) - ui_block_to_display_space_v3(but->block, rgb); + ui_block_cm_to_display_space_v3(but->block, rgb); ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsv); @@ -4652,10 +4773,10 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, ui_color_picker_to_rgb_HSVCUBE_v(but, hsv, rgb); if (use_display_colorspace) - ui_block_to_scene_linear_v3(but->block, rgb); + ui_block_cm_to_scene_linear_v3(but->block, rgb); copy_v3_v3(data->vec, rgb); - ui_set_but_vectorf(but, data->vec); + ui_but_v3_set(but, data->vec); } static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) @@ -4689,7 +4810,7 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu ui_ndofedit_but_HSVCUBE(but, data, ndof, snap, event->shift != 0); button_activate_state(C, but, BUTTON_STATE_EXIT); - ui_apply_button(C, but->block, but, data, true); + ui_apply_but(C, but->block, but, data, true); return WM_UI_HANDLER_BREAK; } @@ -4704,19 +4825,20 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu if (ELEM(len, 3, 4)) { float rgb[3], def_hsv[3]; float def[4]; - float *hsv = ui_block_hsv_get(but->block); - + ColorPicker *cpicker = but->custom_data; + float *hsv = cpicker->color_data; + RNA_property_float_get_default_array(&but->rnapoin, but->rnaprop, def); ui_rgb_to_color_picker_HSVCUBE_v(but, def, def_hsv); - ui_get_but_vectorf(but, rgb); + ui_but_v3_get(but, rgb); ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsv); def_hsv[0] = hsv[0]; def_hsv[1] = hsv[1]; ui_color_picker_to_rgb_HSVCUBE_v(but, def_hsv, rgb); - ui_set_but_vectorf(but, rgb); + ui_but_v3_set(but, rgb); RNA_property_update(C, &but->rnapoin, but->rnaprop); return WM_UI_HANDLER_BREAK; @@ -4758,13 +4880,14 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, bool changed = true; float mx_fl, my_fl; float rgb[3]; - float *hsv = ui_block_hsv_get(but->block); - bool use_display_colorspace = ui_color_picker_use_display_colorspace(but); + ColorPicker *cpicker = but->custom_data; + float *hsv = cpicker->color_data; + bool use_display_colorspace = ui_but_is_colorpicker_display_space(but); ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift); #ifdef USE_CONT_MOUSE_CORRECT - if (ui_is_a_warp_but(but)) { + if (ui_but_is_cursor_warp(but)) { /* OK but can go outside bounds */ data->ungrab_mval[0] = mx_fl; data->ungrab_mval[1] = my_fl; @@ -4781,9 +4904,9 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, BLI_rcti_rctf_copy(&rect, &but->rect); - ui_get_but_vectorf(but, rgb); + ui_but_v3_get(but, rgb); if (use_display_colorspace) - ui_block_to_display_space_v3(but->block, rgb); + ui_block_cm_to_display_space_v3(but->block, rgb); ui_rgb_to_color_picker_compat_v(rgb, hsv); @@ -4794,8 +4917,8 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, if (hsv[2] == 0.f) hsv[2] = 0.0001f; } else { - if (hsv[2] == 0.f) hsv[2] = 0.0001f; - if (hsv[2] == 1.f) hsv[2] = 0.9999f; + if (hsv[2] == 0.0f) hsv[2] = 0.0001f; + if (hsv[2] >= 0.9999f) hsv[2] = 0.9999f; } } @@ -4804,10 +4927,10 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, float xpos, ypos, hsvo[3], rgbo[3]; /* calculate original hsv again */ - copy_v3_v3(hsvo, ui_block_hsv_get(but->block)); + copy_v3_v3(hsvo, hsv); copy_v3_v3(rgbo, data->origvec); if (use_display_colorspace) - ui_block_to_display_space_v3(but->block, rgbo); + ui_block_cm_to_display_space_v3(but->block, rgbo); ui_rgb_to_color_picker_compat_v(rgbo, hsvo); @@ -4836,9 +4959,9 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, } if (use_display_colorspace) - ui_block_to_scene_linear_v3(but->block, rgb); + ui_block_cm_to_scene_linear_v3(but->block, rgb); - ui_set_but_vectorf(but, rgb); + ui_but_v3_set(but, rgb); data->draglastx = mx; data->draglasty = my; @@ -4850,15 +4973,16 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, const wmNDOFMotionData *ndof, const enum eSnapType snap, const bool shift) { - float *hsv = ui_block_hsv_get(but->block); - bool use_display_colorspace = ui_color_picker_use_display_colorspace(but); + ColorPicker *cpicker = but->custom_data; + float *hsv = cpicker->color_data; + bool use_display_colorspace = ui_but_is_colorpicker_display_space(but); float rgb[3]; float phi, r /*, sqr */ /* UNUSED */, v[2]; float sensitivity = (shift ? 0.06f : 0.3f) * ndof->dt; - ui_get_but_vectorf(but, rgb); + ui_but_v3_get(but, rgb); if (use_display_colorspace) - ui_block_to_display_space_v3(but->block, rgb); + ui_block_cm_to_display_space_v3(but->block, rgb); ui_rgb_to_color_picker_compat_v(rgb, hsv); /* Convert current color on hue/sat disc to circular coordinates phi, r */ @@ -4911,14 +5035,16 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, } if (use_display_colorspace) - ui_block_to_scene_linear_v3(but->block, data->vec); + ui_block_cm_to_scene_linear_v3(but->block, data->vec); - ui_set_but_vectorf(but, data->vec); + ui_but_v3_set(but, data->vec); } static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { + ColorPicker *cpicker = but->custom_data; + float *hsv = cpicker->color_data; int mx, my; mx = event->x; my = event->y; @@ -4946,7 +5072,7 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle ui_ndofedit_but_HSVCIRCLE(but, data, ndof, snap, event->shift != 0); button_activate_state(C, but, BUTTON_STATE_EXIT); - ui_apply_button(C, but->block, but, data, true); + ui_apply_but(C, but->block, but, data, true); return WM_UI_HANDLER_BREAK; } @@ -4960,20 +5086,19 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle if (len >= 3) { float rgb[3], def_hsv[3]; float *def; - float *hsv = ui_block_hsv_get(but->block); def = MEM_callocN(sizeof(float) * len, "reset_defaults - float"); RNA_property_float_get_default_array(&but->rnapoin, but->rnaprop, def); ui_color_picker_to_rgb_v(def, def_hsv); - ui_get_but_vectorf(but, rgb); + ui_but_v3_get(but, rgb); ui_rgb_to_color_picker_compat_v(rgb, hsv); def_hsv[0] = hsv[0]; def_hsv[2] = hsv[2]; hsv_to_rgb_v(def_hsv, rgb); - ui_set_but_vectorf(but, rgb); + ui_but_v3_set(but, rgb); RNA_property_update(C, &but->rnapoin, but->rnaprop); @@ -4992,15 +5117,13 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle } /* XXX hardcoded keymap check.... */ else if (event->type == WHEELDOWNMOUSE) { - float *hsv = ui_block_hsv_get(but->block); hsv[2] = CLAMPIS(hsv[2] - 0.05f, 0.0f, 1.0f); - ui_set_but_hsv(but); /* converts to rgb */ + ui_but_hsv_set(but); /* converts to rgb */ ui_numedit_apply(C, block, but, data); } else if (event->type == WHEELUPMOUSE) { - float *hsv = ui_block_hsv_get(but->block); hsv[2] = CLAMPIS(hsv[2] + 0.05f, 0.0f, 1.0f); - ui_set_but_hsv(but); /* converts to rgb */ + ui_but_hsv_set(but); /* converts to rgb */ ui_numedit_apply(C, block, but, data); } else if (event->type == MOUSEMOVE) { @@ -5177,7 +5300,7 @@ static bool ui_numedit_but_CURVE(uiBlock *block, uiBut *but, uiHandleButtonData #ifdef USE_CONT_MOUSE_CORRECT /* note: using 'cmp_last' is weak since there may be multiple points selected, * but in practice this isnt really an issue */ - if (ui_is_a_warp_but(but)) { + if (ui_but_is_cursor_warp(but)) { /* OK but can go outside bounds */ data->ungrab_mval[0] = but->rect.xmin + ((cmp_last->x - cumap->curr.xmin) * zoomx); data->ungrab_mval[1] = but->rect.ymin + ((cmp_last->y - cumap->curr.ymin) * zoomy); @@ -5375,7 +5498,7 @@ static bool ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int m float dy = my - data->draglasty; /* scale histogram values (dy / 10 for better control) */ - const float yfac = min_ff(powf(hist->ymax, 2.0f), 1.0f) * 0.5f; + const float yfac = min_ff(pow2f(hist->ymax), 1.0f) * 0.5f; hist->ymax += (dy * 0.1f) * yfac; /* 0.1 allows us to see HDR colors up to 10 */ @@ -5653,7 +5776,7 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg) wmKeyMapItem *kmi; PointerRNA ptr; uiLayout *layout; - uiStyle *style = UI_GetStyleDraw(); + uiStyle *style = UI_style_get_dpi(); IDProperty *prop = (but->opptr) ? but->opptr->data : NULL; int kmi_id = WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, true, &km); @@ -5661,20 +5784,24 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg) RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr); - block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS); - uiBlockSetHandleFunc(block, but_shortcut_name_func, but); - uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT); - uiBlockSetDirection(block, UI_CENTER); + block = UI_block_begin(C, ar, "_popup", UI_EMBOSS); + UI_block_func_handle_set(block, but_shortcut_name_func, but); + UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT); + UI_block_direction_set(block, UI_DIR_CENTER_Y); - layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 200, 20, 0, style); + layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 200, 20, 0, style); uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE); - uiPopupBoundsBlock(block, 6, -50, 26); + UI_block_bounds_set_popup(block, 6, -50, 26); return block; } +#ifdef USE_KEYMAP_ADD_HACK +static int g_kmi_id_hack; +#endif + static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg) { wmWindowManager *wm = CTX_wm_manager(C); @@ -5684,7 +5811,7 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg) wmKeyMapItem *kmi; PointerRNA ptr; uiLayout *layout; - uiStyle *style = UI_GetStyleDraw(); + uiStyle *style = UI_style_get_dpi(); IDProperty *prop = (but->opptr) ? but->opptr->data : NULL; int kmi_id; @@ -5706,16 +5833,19 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg) RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr); - block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS); - uiBlockSetHandleFunc(block, but_shortcut_name_func, but); - uiBlockSetDirection(block, UI_CENTER); + block = UI_block_begin(C, ar, "_popup", UI_EMBOSS); + UI_block_func_handle_set(block, but_shortcut_name_func, but); + UI_block_direction_set(block, UI_DIR_CENTER_Y); - layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 200, 20, 0, style); + layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 200, 20, 0, style); uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE); - uiPopupBoundsBlock(block, 6, -50, 26); - + UI_block_bounds_set_popup(block, 6, -50, 26); + +#ifdef USE_KEYMAP_ADD_HACK + g_kmi_id_hack = kmi_id; +#endif return block; } @@ -5724,9 +5854,20 @@ static void menu_add_shortcut_cancel(struct bContext *C, void *arg1) uiBut *but = (uiBut *)arg1; wmKeyMap *km; wmKeyMapItem *kmi; - IDProperty *prop = (but->opptr) ? but->opptr->data : NULL; - int kmi_id = WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, true, &km); - +#ifndef USE_KEYMAP_ADD_HACK + IDProperty *prop; +#endif + int kmi_id; + +#ifdef USE_KEYMAP_ADD_HACK + km = WM_keymap_guess_opname(C, but->optype->idname); + kmi_id = g_kmi_id_hack; + UNUSED_VARS(but); +#else + prop = (but->opptr) ? but->opptr->data : NULL; + kmi_id = WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, true, &km); +#endif + kmi = WM_keymap_item_find_id(km, kmi_id); WM_keymap_remove_item(km, kmi); } @@ -5735,7 +5876,7 @@ static void popup_change_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg { uiBut *but = (uiBut *)arg1; button_timers_tooltip_remove(C, but); - uiPupBlock(C, menu_change_shortcut, but); + UI_popup_block_invoke(C, menu_change_shortcut, but); } static void remove_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2)) @@ -5756,7 +5897,7 @@ static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2)) { uiBut *but = (uiBut *)arg1; button_timers_tooltip_remove(C, but); - uiPupBlockEx(C, menu_add_shortcut, NULL, menu_add_shortcut_cancel, but); + UI_popup_block_ex(C, menu_add_shortcut, NULL, menu_add_shortcut_cancel, but); } /** @@ -5771,8 +5912,8 @@ void ui_panel_menu(bContext *C, ARegion *ar, Panel *pa) RNA_pointer_create(&sc->id, &RNA_Panel, pa, &ptr); - pup = uiPupMenuBegin(C, IFACE_("Panel"), ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, IFACE_("Panel"), ICON_NONE); + layout = UI_popup_menu_layout(pup); if (UI_panel_category_is_visible(ar)) { char tmpstr[80]; BLI_snprintf(tmpstr, sizeof(tmpstr), "%s" UI_SEP_CHAR_S "%s", IFACE_("Pin"), IFACE_("Shift+Left Mouse")); @@ -5786,7 +5927,7 @@ void ui_panel_menu(bContext *C, ARegion *ar, Panel *pa) } } - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); } static bool ui_but_menu(bContext *C, uiBut *but) @@ -5800,17 +5941,17 @@ static bool ui_but_menu(bContext *C, uiBut *but) /* return 0;*/ /* having this menu for some buttons makes no sense */ - if (but->type == BUT_IMAGE) { + if (but->type == UI_BTYPE_IMAGE) { return false; } button_timers_tooltip_remove(C, but); /* highly unlikely getting the label ever fails */ - uiButGetStrInfo(C, but, &label, NULL); + UI_but_string_info_get(C, but, &label, NULL); - pup = uiPupMenuBegin(C, label.strinfo ? label.strinfo : "", ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, label.strinfo ? label.strinfo : "", ICON_NONE); + layout = UI_popup_menu_layout(pup); if (label.strinfo) MEM_freeN(label.strinfo); @@ -6001,19 +6142,19 @@ static bool ui_but_menu(bContext *C, uiBut *but) /* would rather use a block but, but gets weirdly positioned... */ //uiDefBlockBut(block, menu_change_shortcut, but, "Change Shortcut", 0, 0, uiLayoutGetWidth(layout), UI_UNIT_Y, ""); - but2 = uiDefIconTextBut(block, BUT, 0, 0, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Change Shortcut"), + but2 = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, 0, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Change Shortcut"), 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); - uiButSetFunc(but2, popup_change_shortcut_func, but, NULL); + UI_but_func_set(but2, popup_change_shortcut_func, but, NULL); - but2 = uiDefIconTextBut(block, BUT, 0, 0, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Shortcut"), + but2 = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, 0, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Shortcut"), 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); - uiButSetFunc(but2, remove_shortcut_func, but, NULL); + UI_but_func_set(but2, remove_shortcut_func, but, NULL); } /* only show 'add' if there's a suitable key map for it to go in */ else if (WM_keymap_guess_opname(C, but->optype->idname)) { - but2 = uiDefIconTextBut(block, BUT, 0, 0, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add Shortcut"), + but2 = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, 0, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add Shortcut"), 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); - uiButSetFunc(but2, popup_add_shortcut_func, but, NULL); + UI_but_func_set(but2, popup_add_shortcut_func, but, NULL); } uiItemS(layout); @@ -6087,7 +6228,7 @@ static bool ui_but_menu(bContext *C, uiBut *but) } uiItemFullO(layout, "UI_OT_edittranslation_init", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); return true; } @@ -6107,7 +6248,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * /* handle copy-paste */ if (ELEM(event->type, CKEY, VKEY) && event->val == KM_PRESS && (event->ctrl || event->oskey)) { /* Specific handling for listrows, we try to find their overlapping tex button. */ - if (but->type == LISTROW) { + if (but->type == UI_BTYPE_LISTROW) { uiBut *labelbut = ui_but_list_row_text_activate(C, but, data, event, BUTTON_ACTIVATE_OVER); if (labelbut) { but = labelbut; @@ -6128,11 +6269,11 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * /* pass */ } else { - if (but->type == COLOR) { + if (but->type == UI_BTYPE_COLOR) { WM_operator_name_call(C, "UI_OT_eyedropper_color", WM_OP_INVOKE_DEFAULT, NULL); return WM_UI_HANDLER_BREAK; } - else if (but->type == SEARCH_MENU_UNLINK) { + else if (but->type == UI_BTYPE_SEARCH_MENU_UNLINK) { if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_POINTER) { StructRNA *type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop); const short idcode = RNA_type_to_ID_code(type); @@ -6221,107 +6362,107 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * } switch (but->type) { - case BUT: + case UI_BTYPE_BUT: retval = ui_do_but_BUT(C, but, data, event); break; - case KEYEVT: + case UI_BTYPE_KEY_EVENT: retval = ui_do_but_KEYEVT(C, but, data, event); break; - case HOTKEYEVT: + case UI_BTYPE_HOTKEY_EVENT: retval = ui_do_but_HOTKEYEVT(C, but, data, event); break; - case TOGBUT: - case TOG: - case ICONTOG: - case ICONTOGN: - case TOGN: - case OPTION: - case OPTIONN: + case UI_BTYPE_BUT_TOGGLE: + case UI_BTYPE_TOGGLE: + case UI_BTYPE_ICON_TOGGLE: + case UI_BTYPE_ICON_TOGGLE_N: + case UI_BTYPE_TOGGLE_N: + case UI_BTYPE_CHECKBOX: + case UI_BTYPE_CHECKBOX_N: + case UI_BTYPE_ROW: retval = ui_do_but_TOG(C, but, data, event); break; - case SCROLL: + case UI_BTYPE_SCROLL: retval = ui_do_but_SCROLL(C, block, but, data, event); break; - case GRIP: + case UI_BTYPE_GRIP: retval = ui_do_but_GRIP(C, block, but, data, event); break; - case NUM: + case UI_BTYPE_NUM: retval = ui_do_but_NUM(C, block, but, data, event); break; - case NUMSLI: + case UI_BTYPE_NUM_SLIDER: retval = ui_do_but_SLI(C, block, but, data, event); break; - case LISTBOX: + case UI_BTYPE_LISTBOX: /* Nothing to do! */ break; - case LISTROW: + case UI_BTYPE_LISTROW: retval = ui_do_but_LISTROW(C, but, data, event); break; - case ROUNDBOX: - case LABEL: - case ROW: - case BUT_IMAGE: - case PROGRESSBAR: - case NODESOCKET: + case UI_BTYPE_ROUNDBOX: + case UI_BTYPE_LABEL: + case UI_BTYPE_IMAGE: + case UI_BTYPE_PROGRESS_BAR: + case UI_BTYPE_NODE_SOCKET: retval = ui_do_but_EXIT(C, but, data, event); break; - case HISTOGRAM: + case UI_BTYPE_HISTOGRAM: retval = ui_do_but_HISTOGRAM(C, block, but, data, event); break; - case WAVEFORM: + case UI_BTYPE_WAVEFORM: retval = ui_do_but_WAVEFORM(C, block, but, data, event); break; - case VECTORSCOPE: + case UI_BTYPE_VECTORSCOPE: /* Nothing to do! */ break; - case TEX: - case SEARCH_MENU: + case UI_BTYPE_TEXT: + case UI_BTYPE_SEARCH_MENU: retval = ui_do_but_TEX(C, block, but, data, event); break; - case SEARCH_MENU_UNLINK: + case UI_BTYPE_SEARCH_MENU_UNLINK: retval = ui_do_but_SEARCH_UNLINK(C, block, but, data, event); break; - case MENU: - case BLOCK: - case PULLDOWN: + case UI_BTYPE_MENU: + case UI_BTYPE_BLOCK: + case UI_BTYPE_PULLDOWN: retval = ui_do_but_BLOCK(C, but, data, event); break; - case BUTM: + case UI_BTYPE_BUT_MENU: retval = ui_do_but_BUT(C, but, data, event); break; - case COLOR: + case UI_BTYPE_COLOR: if (but->a1 == -1) /* signal to prevent calling up color picker */ retval = ui_do_but_EXIT(C, but, data, event); else retval = ui_do_but_COLOR(C, but, data, event); break; - case BUT_NORMAL: - retval = ui_do_but_NORMAL(C, block, but, data, event); + case UI_BTYPE_UNITVEC: + retval = ui_do_but_UNITVEC(C, block, but, data, event); break; - case BUT_COLORBAND: + case UI_BTYPE_COLORBAND: retval = ui_do_but_COLORBAND(C, block, but, data, event); break; - case BUT_CURVE: + case UI_BTYPE_CURVE: retval = ui_do_but_CURVE(C, block, but, data, event); break; - case HSVCUBE: + case UI_BTYPE_HSVCUBE: retval = ui_do_but_HSVCUBE(C, block, but, data, event); break; - case HSVCIRCLE: + case UI_BTYPE_HSVCIRCLE: retval = ui_do_but_HSVCIRCLE(C, block, but, data, event); break; - case LINK: - case INLINK: + case UI_BTYPE_LINK: + case UI_BTYPE_INLINK: retval = ui_do_but_LINK(C, but, data, event); break; - case TRACKPREVIEW: + case UI_BTYPE_TRACK_PREVIEW: retval = ui_do_but_TRACKPREVIEW(C, block, but, data, event); break; /* quiet warnings for unhandled types */ - case SEPR: - case SEPRLINE: - case BUT_EXTRA: + case UI_BTYPE_SEPR: + case UI_BTYPE_SEPR_LINE: + case UI_BTYPE_EXTRA: break; } @@ -6334,7 +6475,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * (event->type == BACKSPACEKEY && event->val == KM_PRESS)) { /* ctrl+backspace = reset active button; backspace = reset a whole array*/ - ui_set_but_default(C, !event->ctrl, true); + ui_but_default_set(C, !event->ctrl, true); ED_region_tag_redraw(data->region); retval = WM_UI_HANDLER_BREAK; } @@ -6346,7 +6487,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * /* if we started dragging, progress on any event */ (data->multi_data.init == BUTTON_MULTI_INIT_SETUP)) { - if (ELEM(but->type, NUM, NUMSLI) && + if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER) && ELEM(data->state, BUTTON_STATE_TEXT_EDITING, BUTTON_STATE_NUM_EDITING)) { /* initialize! */ @@ -6432,7 +6573,7 @@ static bool ui_but_isect_pie_seg(uiBlock *block, uiBut *but) return false; } -uiBut *ui_but_find_activated(ARegion *ar) +uiBut *ui_but_find_active_in_region(ARegion *ar) { uiBlock *block; uiBut *but; @@ -6445,26 +6586,26 @@ uiBut *ui_but_find_activated(ARegion *ar) return NULL; } -bool ui_button_is_active(ARegion *ar) +bool ui_but_is_active(ARegion *ar) { - return (ui_but_find_activated(ar) != NULL); + return (ui_but_find_active_in_region(ar) != NULL); } /* is called by notifier */ -void uiFreeActiveButtons(const bContext *C, bScreen *screen) +void UI_screen_free_active_but(const bContext *C, bScreen *screen) { ScrArea *sa = screen->areabase.first; for (; sa; sa = sa->next) { ARegion *ar = sa->regionbase.first; for (; ar; ar = ar->next) { - uiBut *but = ui_but_find_activated(ar); + uiBut *but = ui_but_find_active_in_region(ar); if (but) { uiHandleButtonData *data = but->active; if (data->menu == NULL && data->searchbox == NULL) if (data->state == BUTTON_STATE_HIGHLIGHT) - ui_button_active_free(C, but); + ui_but_active_free(C, but); } } } @@ -6477,10 +6618,10 @@ void uiFreeActiveButtons(const bContext *C, bScreen *screen) bool UI_but_active_drop_name(bContext *C) { ARegion *ar = CTX_wm_region(C); - uiBut *but = ui_but_find_activated(ar); + uiBut *but = ui_but_find_active_in_region(ar); if (but) { - if (ELEM(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) + if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) return 1; } @@ -6492,9 +6633,9 @@ bool UI_but_active_drop_color(bContext *C) ARegion *ar = CTX_wm_region(C); if (ar) { - uiBut *but = ui_but_find_activated(ar); + uiBut *but = ui_but_find_active_in_region(ar); - if (but && but->type == COLOR) + if (but && but->type == UI_BTYPE_COLOR) return true; } @@ -6514,7 +6655,7 @@ static void ui_blocks_set_tooltips(ARegion *ar, const bool enable) block->tooltipdisabled = !enable; } -static bool ui_mouse_inside_region(ARegion *ar, int x, int y) +static bool ui_region_contains_point_px(ARegion *ar, int x, int y) { uiBlock *block; @@ -6548,11 +6689,11 @@ static bool ui_mouse_inside_region(ARegion *ar, int x, int y) return true; } -static bool ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y) +static bool ui_but_contains_point_px(ARegion *ar, uiBut *but, int x, int y) { uiBlock *block = but->block; float mx, my; - if (!ui_mouse_inside_region(ar, x, y)) + if (!ui_region_contains_point_px(ar, x, y)) return false; mx = x; @@ -6574,30 +6715,30 @@ static bool ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y) /** * Can we mouse over the button or is it hidden/disabled/layout. - * Note: ctrl is kind of a hack currently, so that non-embossed TEX button behaves as a label when ctrl is not pressed. + * Note: ctrl is kind of a hack currently, so that non-embossed UI_BTYPE_TEXT button behaves as a label when ctrl is not pressed. */ -static bool ui_is_but_interactive(const uiBut *but, const bool labeledit) +static bool ui_but_is_interactive(const uiBut *but, const bool labeledit) { - /* note, LABEL is included for highlights, this allows drags */ - if ((but->type == LABEL) && but->dragpoin == NULL) + /* note, UI_BTYPE_LABEL is included for highlights, this allows drags */ + if ((but->type == UI_BTYPE_LABEL) && but->dragpoin == NULL) return false; - if (ELEM(but->type, ROUNDBOX, SEPR, SEPRLINE, LISTBOX)) + if (ELEM(but->type, UI_BTYPE_ROUNDBOX, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_LISTBOX)) return false; if (but->flag & UI_HIDDEN) return false; if (but->flag & UI_SCROLLED) return false; - if ((but->type == TEX) && (but->dt == UI_EMBOSSN) && !labeledit) + if ((but->type == UI_BTYPE_TEXT) && (but->dt == UI_EMBOSS_NONE) && !labeledit) return false; - if ((but->type == LISTROW) && labeledit) + if ((but->type == UI_BTYPE_LISTROW) && labeledit) return false; return true; } -bool ui_is_but_search_unlink_visible(const uiBut *but) +bool ui_but_is_search_unlink_visible(const uiBut *but) { - BLI_assert(but->type == SEARCH_MENU_UNLINK); + BLI_assert(but->type == UI_BTYPE_SEARCH_MENU_UNLINK); return ((but->editstr == NULL) && (but->drawstr[0] != '\0')); } @@ -6611,7 +6752,7 @@ static uiBut *ui_but_find_mouse_over_ex(ARegion *ar, const int x, const int y, c // if (!win->active) // return NULL; - if (!ui_mouse_inside_region(ar, x, y)) + if (!ui_region_contains_point_px(ar, x, y)) return NULL; for (block = ar->uiblocks.first; block; block = block->next) { @@ -6620,7 +6761,7 @@ static uiBut *ui_but_find_mouse_over_ex(ARegion *ar, const int x, const int y, c ui_window_to_block_fl(ar, block, &mx, &my); for (but = block->buttons.last; but; but = but->prev) { - if (ui_is_but_interactive(but, labeledit)) { + if (ui_but_is_interactive(but, labeledit)) { if (but->pie_dir != UI_RADIAL_NONE) { if (ui_but_isect_pie_seg(block, but)) { butover = but; @@ -6658,7 +6799,7 @@ static uiBut *ui_list_find_mouse_over(ARegion *ar, int x, int y) uiBut *but; float mx, my; - if (!ui_mouse_inside_region(ar, x, y)) + if (!ui_region_contains_point_px(ar, x, y)) return NULL; for (block = ar->uiblocks.first; block; block = block->next) { @@ -6667,7 +6808,7 @@ static uiBut *ui_list_find_mouse_over(ARegion *ar, int x, int y) ui_window_to_block_fl(ar, block, &mx, &my); for (but = block->buttons.last; but; but = but->prev) { - if (but->type == LISTBOX && ui_but_contains_pt(but, mx, my)) { + if (but->type == UI_BTYPE_LISTBOX && ui_but_contains_pt(but, mx, my)) { return but; } } @@ -6748,14 +6889,14 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s button_tooltip_timer_reset(C, but); /* automatic open pulldown block timer */ - if (ELEM(but->type, BLOCK, PULLDOWN)) { + if (ELEM(but->type, UI_BTYPE_BLOCK, UI_BTYPE_PULLDOWN)) { if (data->used_mouse && !data->autoopentimer) { int time; if (but->block->auto_open == true) { /* test for toolbox */ time = 1; } - else if ((but->block->flag & UI_BLOCK_LOOP && but->type != BLOCK) || but->block->auto_open == true) { + else if ((but->block->flag & UI_BLOCK_LOOP && but->type != UI_BTYPE_BLOCK) || but->block->auto_open == true) { time = 5 * U.menuthreshold2; } else if (U.uiflag & USER_MENUOPENAUTO) { @@ -6786,7 +6927,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s /* number editing */ if (state == BUTTON_STATE_NUM_EDITING) { - if (ui_is_a_warp_but(but)) + if (ui_but_is_cursor_warp(but)) WM_cursor_grab_enable(CTX_wm_window(C), true, true, NULL); ui_numedit_begin(but, data); } @@ -6796,7 +6937,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s if (but->flag & UI_BUT_DRIVEN) WM_report(C, RPT_INFO, "Can't edit driven number value, see graph editor for the driver setup."); - if (ui_is_a_warp_but(but)) { + if (ui_but_is_cursor_warp(but)) { #ifdef USE_CONT_MOUSE_CORRECT if (data->ungrab_mval[0] != FLT_MAX) { @@ -6817,9 +6958,9 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s } /* menu open */ if (state == BUTTON_STATE_MENU_OPEN) - ui_blockopen_begin(C, but, data); + ui_block_open_begin(C, but, data); else if (data->state == BUTTON_STATE_MENU_OPEN) - ui_blockopen_end(C, but, data); + ui_block_open_end(C, but, data); /* add a short delay before exiting, to ensure there is some feedback */ if (state == BUTTON_STATE_WAIT_FLASH) { @@ -6853,13 +6994,13 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s data->state = state; if (state != BUTTON_STATE_EXIT) { - /* When objects for eg. are removed, running ui_check_but() can access + /* When objects for eg. are removed, running ui_but_update() can access * the removed data - so disable update on exit. Also in case of * highlight when not in a popup menu, we remove because data used in * button below popup might have been removed by action of popup. Needs * a more reliable solution... */ if (state != BUTTON_STATE_HIGHLIGHT || (but->block->flag & UI_BLOCK_LOOP)) - ui_check_but(but); + ui_but_update(but); } /* redraw */ @@ -6880,7 +7021,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA copy_v2_fl(data->ungrab_mval, FLT_MAX); #endif - if (ELEM(but->type, BUT_CURVE, SEARCH_MENU, SEARCH_MENU_UNLINK)) { + if (ELEM(but->type, UI_BTYPE_CURVE, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) { /* XXX curve is temp */ } else { @@ -6907,7 +7048,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA /* activate right away */ if (but->flag & UI_BUT_IMMEDIATE) { - if (but->type == HOTKEYEVT) + if (but->type == UI_BTYPE_HOTKEY_EVENT) button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT); /* .. more to be added here */ } @@ -6934,7 +7075,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA else if (type == BUTTON_ACTIVATE_APPLY) button_activate_state(C, but, BUTTON_STATE_WAIT_FLASH); - if (but->type == GRIP) { + if (but->type == UI_BTYPE_GRIP) { const bool horizontal = (BLI_rctf_size_x(&but->rect) < BLI_rctf_size_y(&but->rect)); WM_cursor_modal_set(data->window, horizontal ? CURSOR_X_MOVE : CURSOR_Y_MOVE); } @@ -6946,7 +7087,7 @@ static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *da uiBlock *block = but->block; uiBut *bt; - if (but->type == GRIP) { + if (but->type == UI_BTYPE_GRIP) { WM_cursor_modal_restore(data->window); } @@ -6956,7 +7097,7 @@ static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *da /* apply the button action or value */ if (!onfree) - ui_apply_button(C, block, but, data, false); + ui_apply_but(C, block, but, data, false); #ifdef USE_DRAG_MULTINUM if (data->multi_data.has_mbuts) { @@ -6965,7 +7106,7 @@ static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *da bt->flag &= ~UI_BUT_DRAG_MULTI; if (!data->cancel) { - ui_apply_autokey(C, bt); + ui_apply_but_autokey(C, bt); } } } @@ -6989,8 +7130,8 @@ static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *da if (!onfree && !data->cancel) { /* autokey & undo push */ - ui_apply_undo(but); - ui_apply_autokey(C, but); + ui_apply_but_undo(but); + ui_apply_but_autokey(C, but); /* popup menu memory */ if (block->flag & UI_BLOCK_POPUP_MEMORY) @@ -7025,7 +7166,7 @@ static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *da but->flag &= ~(UI_ACTIVE | UI_SELECT); but->flag |= UI_BUT_LAST_ACTIVE; if (!onfree) - ui_check_but(but); + ui_but_update(but); /* adds empty mousemove in queue for re-init handler, in case mouse is * still over a button. we cannot just check for this ourselfs because @@ -7034,7 +7175,7 @@ static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *da WM_event_add_mousemove(C); } -void ui_button_active_free(const bContext *C, uiBut *but) +void ui_but_active_free(const bContext *C, uiBut *but) { uiHandleButtonData *data; @@ -7100,13 +7241,13 @@ static uiBut *ui_context_rna_button_active(const bContext *C) return ui_context_button_active(C, ui_context_rna_button_active_test); } -uiBut *uiContextActiveButton(const struct bContext *C) +uiBut *UI_context_active_but_get(const struct bContext *C) { return ui_context_button_active(C, NULL); } /* helper function for insert keyframe, reset to default, etc operators */ -void uiContextActiveProperty(const bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop, int *index) +void UI_context_active_but_prop_get(const bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop, int *index) { uiBut *activebut = ui_context_rna_button_active(C); @@ -7123,7 +7264,7 @@ void uiContextActiveProperty(const bContext *C, struct PointerRNA *ptr, struct P } } -void uiContextActivePropertyHandle(bContext *C) +void UI_context_active_but_prop_handle(bContext *C) { uiBut *activebut = ui_context_rna_button_active(C); if (activebut) { @@ -7137,7 +7278,7 @@ void uiContextActivePropertyHandle(bContext *C) } } -wmOperator *uiContextActiveOperator(const struct bContext *C) +wmOperator *UI_context_active_operator_get(const struct bContext *C) { ARegion *ar_ctx = CTX_wm_region(C); uiBlock *block; @@ -7175,7 +7316,7 @@ wmOperator *uiContextActiveOperator(const struct bContext *C) } /* helper function for insert keyframe, reset to default, etc operators */ -void uiContextAnimUpdate(const bContext *C) +void UI_context_update_anim_flag(const bContext *C) { Scene *scene = CTX_data_scene(C); ARegion *ar = CTX_wm_region(C); @@ -7260,8 +7401,8 @@ static int ui_handle_button_over(bContext *C, const wmEvent *event, ARegion *ar) return WM_UI_HANDLER_CONTINUE; } -/* exported to interface.c: uiButActiveOnly() */ -void ui_button_activate_do(bContext *C, ARegion *ar, uiBut *but) +/* exported to interface.c: UI_but_active_only() */ +void ui_but_activate_event(bContext *C, ARegion *ar, uiBut *but) { wmWindow *win = CTX_wm_window(C); wmEvent event; @@ -7283,12 +7424,12 @@ void ui_button_activate_do(bContext *C, ARegion *ar, uiBut *but) * exported so menus can start with a highlighted button, * even if the mouse isnt over it */ -void ui_button_activate_over(bContext *C, ARegion *ar, uiBut *but) +void ui_but_activate_over(bContext *C, ARegion *ar, uiBut *but) { button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER); } -void ui_button_execute_begin(struct bContext *UNUSED(C), struct ARegion *ar, uiBut *but, void **active_back) +void ui_but_execute_begin(struct bContext *UNUSED(C), struct ARegion *ar, uiBut *but, void **active_back) { /* note: ideally we would not have to change 'but->active' however * some functions we call don't use data (as they should be doing) */ @@ -7299,12 +7440,12 @@ void ui_button_execute_begin(struct bContext *UNUSED(C), struct ARegion *ar, uiB data->region = ar; } -void ui_button_execute_end(struct bContext *C, struct ARegion *UNUSED(ar), uiBut *but, void *active_back) +void ui_but_execute_end(struct bContext *C, struct ARegion *UNUSED(ar), uiBut *but, void *active_back) { - ui_apply_button(C, but->block, but, but->active, true); + ui_apply_but(C, but->block, but, but->active, true); if ((but->flag & UI_BUT_DRAG_MULTI) == 0) { - ui_apply_autokey(C, but); + ui_apply_but_autokey(C, but); } /* use onfree event so undo is handled by caller and apply is already done above */ button_activate_exit((bContext *)C, but, but->active, false, true); @@ -7316,7 +7457,7 @@ static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiBu uiBut *oldbut; uiHandleButtonData *data; - oldbut = ui_but_find_activated(ar); + oldbut = ui_but_find_active_in_region(ar); if (oldbut) { data = oldbut->active; data->cancel = true; @@ -7355,7 +7496,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) bool exit = false; if ((!ui_block_is_menu(block) || ui_block_is_pie_menu(but->block)) && - !ui_mouse_inside_button(ar, but, event->x, event->y)) + !ui_but_contains_point_px(ar, but, event->x, event->y)) { exit = true; } @@ -7390,7 +7531,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) WM_event_remove_timer(data->wm, data->window, data->autoopentimer); data->autoopentimer = NULL; - if (ui_mouse_inside_button(ar, but, event->x, event->y)) + if (ui_but_contains_point_px(ar, but, event->x, event->y)) button_activate_state(C, but, BUTTON_STATE_MENU_OPEN); } @@ -7418,7 +7559,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) break; case MOUSEMOVE: - if (ELEM(but->type, LINK, INLINK)) { + if (ELEM(but->type, UI_BTYPE_LINK, UI_BTYPE_INLINK)) { ARegion *ar = data->region; but->flag |= UI_SELECT; ui_do_button(C, block, but, event); @@ -7427,7 +7568,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) else { /* deselect the button when moving the mouse away */ /* also de-activate for buttons that only show higlights */ - if (ui_mouse_inside_button(ar, but, event->x, event->y)) { + if (ui_but_contains_point_px(ar, but, event->x, event->y)) { if (!(but->flag & UI_SELECT)) { but->flag |= (UI_SELECT | UI_ACTIVE); data->cancel = false; @@ -7472,7 +7613,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) uiBut *bt; if (data->menu && data->menu->region) { - if (ui_mouse_inside_region(data->menu->region, event->x, event->y)) { + if (ui_region_contains_point_px(data->menu->region, event->x, event->y)) { break; } } @@ -7480,7 +7621,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) bt = ui_but_find_mouse_over(ar, event); if (bt && bt->active != data) { - if (but->type != COLOR) { /* exception */ + if (but->type != UI_BTYPE_COLOR) { /* exception */ data->cancel = true; } button_activate_state(C, but, BUTTON_STATE_EXIT); @@ -7625,7 +7766,7 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar) RNA_property_int_set(&but->rnapoin, but->rnaprop, value); RNA_property_update(C, &but->rnapoin, but->rnaprop); - ui_apply_undo(but); + ui_apply_but_undo(but); ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM; ED_region_tag_redraw(ar); @@ -7669,18 +7810,18 @@ static void ui_handle_button_return_submenu(bContext *C, const wmEvent *event, u /* copy over return values from the closing menu */ if ((menu->menuretval & UI_RETURN_OK) || (menu->menuretval & UI_RETURN_UPDATE)) { - if (but->type == COLOR) + if (but->type == UI_BTYPE_COLOR) copy_v3_v3(data->vec, menu->retvec); - else if (but->type == MENU) + else if (but->type == UI_BTYPE_MENU) data->value = menu->retvalue; } if (menu->menuretval & UI_RETURN_UPDATE) { if (data->interactive) { - ui_apply_button(C, but->block, but, data, true); + ui_apply_but(C, but->block, but, data, true); } else { - ui_check_but(but); + ui_but_update(but); } menu->menuretval = 0; @@ -7694,7 +7835,7 @@ static void ui_handle_button_return_submenu(bContext *C, const wmEvent *event, u button_activate_exit(C, but, data, true, false); } else if (menu->menuretval & UI_RETURN_OUT) { - if (event->type == MOUSEMOVE && ui_mouse_inside_button(data->region, but, event->x, event->y)) { + if (event->type == MOUSEMOVE && ui_but_contains_point_px(data->region, but, event->x, event->y)) { button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT); } else { @@ -7954,7 +8095,7 @@ static bool ui_menu_pass_event_to_parent_if_nonactive(uiPopupBlockHandle *menu, static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu) { ARegion *ar = menu->region; - uiBut *but = ui_but_find_activated(ar); + uiBut *but = ui_but_find_active_in_region(ar); int retval; if (but) { @@ -7966,11 +8107,11 @@ static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlock else if (!ui_block_is_menu(but->block) || ui_block_is_pie_menu(but->block)) { /* pass, skip for dialogs */ } - else if (!ui_mouse_inside_region(but->active->region, event->x, event->y)) { + else if (!ui_region_contains_point_px(but->active->region, event->x, event->y)) { /* pass, needed to click-exit outside of non-flaoting menus */ } else if ((!ELEM(event->type, MOUSEMOVE, WHEELUPMOUSE, WHEELDOWNMOUSE, MOUSEPAN)) && ISMOUSE(event->type)) { - if (!ui_mouse_inside_button(but->active->region, but, event->x, event->y)) { + if (!ui_but_contains_point_px(but->active->region, but, event->x, event->y)) { but = NULL; } } @@ -7995,7 +8136,7 @@ static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlock return retval; } -void ui_block_calculate_pie_segment(uiBlock *block, const float event_xy[2]) +float ui_block_calc_pie_segment(uiBlock *block, const float event_xy[2]) { float seg1[2]; float seg2[2]; @@ -8012,11 +8153,12 @@ void ui_block_calculate_pie_segment(uiBlock *block, const float event_xy[2]) len = normalize_v2_v2(block->pie_data.pie_dir, seg2); - /* ten pixels for now, a bit arbitrary */ if (len < U.pie_menu_threshold * U.pixelsize) block->pie_data.flags |= UI_PIE_INVALID_DIR; else block->pie_data.flags &= ~UI_PIE_INVALID_DIR; + + return len; } static int ui_handle_menu_event( @@ -8025,7 +8167,7 @@ static int ui_handle_menu_event( { ARegion *ar; uiBlock *block; - uiBut *but, *bt; + uiBut *but; int mx, my, retval; bool inside; bool inside_title; /* check for title dragging */ @@ -8044,7 +8186,7 @@ static int ui_handle_menu_event( inside_title = inside && ((my + (UI_UNIT_Y * 1.5f)) > block->rect.ymax); /* if there's an active modal button, don't check events or outside, except for search menu */ - but = ui_but_find_activated(ar); + but = ui_but_find_active_in_region(ar); #ifdef USE_DRAG_POPUP if (menu->is_grab) { @@ -8120,15 +8262,15 @@ static int ui_handle_menu_event( if (ui_menu_pass_event_to_parent_if_nonactive(menu, but, level, retval)) break; - but = ui_but_find_activated(ar); + but = ui_but_find_active_in_region(ar); if (!but) { /* no item active, we make first active */ - if (block->direction & UI_TOP) but = ui_but_last(block); + if (block->direction & UI_DIR_UP) but = ui_but_last(block); else but = ui_but_first(block); } - if (but && ELEM(but->type, BLOCK, PULLDOWN)) + if (but && ELEM(but->type, UI_BTYPE_BLOCK, UI_BTYPE_PULLDOWN)) ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_OPEN); } @@ -8153,7 +8295,9 @@ static int ui_handle_menu_event( ui_pan_to_scroll(event, &type, &val); if (val == KM_PRESS) { - const eButType type_flip = BUT | ROW; + const bool is_next = + (ELEM(type, DOWNARROWKEY, WHEELDOWNMOUSE) == + ((block->flag & UI_BLOCK_IS_FLIP) != 0)); if (ui_menu_pass_event_to_parent_if_nonactive(menu, but, level, retval)) break; @@ -8162,58 +8306,24 @@ static int ui_handle_menu_event( ui_mouse_motion_keynav_init(&menu->keynav_state, event); #endif - but = ui_but_find_activated(ar); + but = ui_but_find_active_in_region(ar); if (but) { - /* is there a situation where UI_LEFT or UI_RIGHT would also change navigation direction? */ - if (((ELEM(type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_DOWN)) || - ((ELEM(type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_RIGHT)) || - ((ELEM(type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_TOP))) - { - /* the following is just a hack - uiBut->type set to BUT and BUTM have there menus built - * opposite ways - this should be changed so that all popup-menus use the same uiBlock->direction */ - if (but->type & type_flip) - but = ui_but_next(but); - else - but = ui_but_prev(but); - } - else { - if (but->type & type_flip) - but = ui_but_prev(but); - else - but = ui_but_next(but); - } - - if (but) { - ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE); - ui_menu_scroll(ar, block, my, but); - } + /* next button */ + but = is_next ? ui_but_next(but) : ui_but_prev(but); } if (!but) { - if (((ELEM(type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_DOWN)) || - ((ELEM(type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_RIGHT)) || - ((ELEM(type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_TOP))) - { - if ((bt = ui_but_first(block)) && (bt->type & type_flip)) { - bt = ui_but_last(block); - } - else { - /* keep ui_but_first() */ - } - } - else { - if ((bt = ui_but_first(block)) && (bt->type & type_flip)) { - /* keep ui_but_first() */ - } - else { - bt = ui_but_last(block); - } + /* wrap button */ + uiBut *but_wrap; + but_wrap = is_next ? ui_but_first(block) : ui_but_last(block); + if (but_wrap) { + but = but_wrap; } + } - if (bt) { - ui_handle_button_activate(C, ar, bt, BUTTON_ACTIVATE); - ui_menu_scroll(ar, block, my, bt); - } + if (but) { + ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE); + ui_menu_scroll(ar, block, my, but); } } @@ -8255,7 +8365,7 @@ static int ui_handle_menu_event( for (but = block->buttons.first; but; but = but->next) { bool doit = false; - if (!ELEM(but->type, LABEL, SEPR, SEPRLINE)) + if (!ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) count++; /* exception for rna layer buts */ @@ -8273,7 +8383,7 @@ static int ui_handle_menu_event( if (doit) { /* activate buttons but open menu's */ uiButtonActivateType activate; - if (but->type == PULLDOWN) { + if (but->type == UI_BTYPE_PULLDOWN) { activate = BUTTON_ACTIVATE_OPEN; } else { @@ -8328,15 +8438,15 @@ static int ui_handle_menu_event( for (but = block->buttons.first; but; but = but->next) { if (but->menu_key == event->type) { - if (ELEM(but->type, BUT, BUTM)) { + if (ELEM(but->type, UI_BTYPE_BUT, UI_BTYPE_BUT_MENU)) { /* mainly for operator buttons */ ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_APPLY); } - else if (ELEM(but->type, BLOCK, PULLDOWN)) { + else if (ELEM(but->type, UI_BTYPE_BLOCK, UI_BTYPE_PULLDOWN)) { /* open submenus (like right arrow key) */ ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_OPEN); } - else if (but->type == MENU) { + else if (but->type == UI_BTYPE_MENU) { /* activate menu items */ ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE); } @@ -8401,14 +8511,14 @@ static int ui_handle_menu_event( else if (ELEM(event->type, RETKEY, PADENTER) && event->val == KM_PRESS) { /* enter will always close this block, we let the event * get handled by the button if it is activated, otherwise we cancel */ - if (!ui_but_find_activated(ar)) + if (!ui_but_find_active_in_region(ar)) menu->menuretval = UI_RETURN_CANCEL | UI_RETURN_POPUP_OK; } #ifdef USE_DRAG_POPUP else if ((event->type == LEFTMOUSE) && (event->val == KM_PRESS) && (inside && is_floating && inside_title)) { - if (!but || !ui_mouse_inside_button(ar, but, event->x, event->y)) { + if (!but || !ui_but_contains_point_px(ar, but, event->x, event->y)) { if (but) { button_timers_tooltip_remove(C, but); } @@ -8488,7 +8598,7 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPo ar = menu->region; block = ar->uiblocks.first; - but = ui_but_find_activated(ar); + but = ui_but_find_active_in_region(ar); data = but->active; submenu = data->menu; @@ -8530,7 +8640,7 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPo static bool ui_but_pie_menu_supported_apply(uiBut *but) { - return (!ELEM(but->type, NUMSLI, NUM)); + return (!ELEM(but->type, UI_BTYPE_NUM_SLIDER, UI_BTYPE_NUM)); } static int ui_but_pie_menu_apply(bContext *C, uiPopupBlockHandle *menu, uiBut *but, bool force_close) @@ -8538,10 +8648,10 @@ static int ui_but_pie_menu_apply(bContext *C, uiPopupBlockHandle *menu, uiBut *b int retval = WM_UI_HANDLER_BREAK; if (but && ui_but_pie_menu_supported_apply(but)) { - if (but->type == MENU) { + if (but->type == UI_BTYPE_MENU) { /* forcing the pie menu to close will not handle menus */ if (!force_close) { - uiBut *active_but = ui_but_find_activated(menu->region); + uiBut *active_but = ui_but_find_active_in_region(menu->region); if (active_but) { button_activate_exit(C, active_but, active_but->active, false, false); @@ -8555,7 +8665,7 @@ static int ui_but_pie_menu_apply(bContext *C, uiPopupBlockHandle *menu, uiBut *b } } else { - ui_apply_button(C, but->block, but, but->active, false); + ui_apply_but(C, but->block, but, but->active, false); button_activate_exit((bContext *)C, but, but->active, false, true); menu->menuretval = UI_RETURN_OK; @@ -8576,7 +8686,7 @@ static uiBut *ui_block_pie_dir_activate(uiBlock *block, const wmEvent *event, Ra if ((block->flag & UI_BLOCK_NUMSELECT) && event->val == KM_PRESS) { for (but = block->buttons.first; but; but = but->next) { - if (but->pie_dir == dir && !ELEM(but->type, SEPR, SEPRLINE)) { + if (but->pie_dir == dir && !ELEM(but->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) { return but; } } @@ -8592,7 +8702,7 @@ static int ui_but_pie_button_activate(bContext *C, uiBut *but, uiPopupBlockHandl if (but == NULL) return WM_UI_HANDLER_BREAK; - active_but = ui_but_find_activated(menu->region); + active_but = ui_but_find_active_in_region(menu->region); if (active_but) button_activate_exit(C, active_but, active_but->active, false, false); @@ -8601,7 +8711,7 @@ static int ui_but_pie_button_activate(bContext *C, uiBut *but, uiPopupBlockHandl return ui_but_pie_menu_apply(C, menu, but, false); } -static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu) +static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu) { ARegion *ar; uiBlock *block; @@ -8609,6 +8719,7 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle float event_xy[2]; double duration; bool is_click_style; + float dist; /* we block all events, this is modal interaction, except for drop events which is described below */ int retval = WM_UI_HANDLER_BREAK; @@ -8637,7 +8748,7 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle ui_window_to_block_fl(ar, block, &event_xy[0], &event_xy[1]); - ui_block_calculate_pie_segment(block, event_xy); + dist = ui_block_calc_pie_segment(block, event_xy); if (event->type == TIMER) { if (event->customdata == menu->scrolltimer) { @@ -8697,7 +8808,7 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle } if (len_sq < 1.0) { - uiBut *but = ui_but_find_activated(menu->region); + uiBut *but = ui_but_find_active_in_region(menu->region); if (but) { return ui_but_pie_menu_apply(C, menu, but, true); @@ -8723,11 +8834,10 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle block->pie_data.flags |= UI_PIE_CLICK_STYLE; } else { - float len_sq = len_squared_v2v2(event_xy, block->pie_data.pie_center_init); - uiBut *but = ui_but_find_activated(menu->region); + uiBut *but = ui_but_find_active_in_region(menu->region); - if (but && (U.pie_menu_confirm >= U.pie_menu_threshold) && - (sqrtf(len_sq) >= U.pie_menu_confirm)) + if (but && (U.pie_menu_confirm > 0) && + (dist >= U.pie_menu_threshold + U.pie_menu_confirm)) { if (but) return ui_but_pie_menu_apply(C, menu, but, true); @@ -8747,12 +8857,14 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle if (!is_click_style) { float len_sq = len_squared_v2v2(event_xy, block->pie_data.pie_center_init); + /* here we use the initial position explicitly */ if (len_sq > PIE_CLICK_THRESHOLD_SQ) { block->pie_data.flags |= UI_PIE_DRAG_STYLE; } - if ((U.pie_menu_confirm >= U.pie_menu_threshold) && - (len_sq >= SQUARE(U.pie_menu_confirm))) + /* here instead, we use the offset location to account for the initial direction timeout */ + if ((U.pie_menu_confirm > 0) && + (dist >= U.pie_menu_threshold + U.pie_menu_confirm)) { block->pie_data.flags |= UI_PIE_GESTURE_END_WAIT; copy_v2_v2(block->pie_data.last_pos, event_xy); @@ -8861,7 +8973,7 @@ static int ui_handle_menus_recursive( bool do_towards_reinit = false; /* check if we have a submenu, and handle events for it first */ - but = ui_but_find_activated(menu->region); + but = ui_but_find_active_in_region(menu->region); data = (but) ? but->active : NULL; submenu = (data) ? data->menu : NULL; @@ -8888,7 +9000,7 @@ static int ui_handle_menus_recursive( /* now handle events for our own menu */ if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) { - const bool do_but_search = (but && ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)); + const bool do_but_search = (but && ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)); if (submenu && submenu->menuretval) { const bool do_ret_out_parent = (submenu->menuretval & UI_RETURN_OUT_PARENT) != 0; retval = ui_handle_menu_return_submenu(C, event, menu); @@ -8910,7 +9022,7 @@ static int ui_handle_menus_recursive( if (block->flag & UI_BLOCK_MOVEMOUSE_QUIT) { /* when there is a active search button and we close it, * we need to reinit the mouse coords [#35346] */ - if (ui_but_find_activated(menu->region) != but) { + if (ui_but_find_active_in_region(menu->region) != but) { do_towards_reinit = true; } } @@ -8919,7 +9031,7 @@ static int ui_handle_menus_recursive( uiBlock *block = menu->region->uiblocks.first; if (block->flag & UI_BLOCK_RADIAL) - retval = ui_handler_pie(C, event, menu); + retval = ui_pie_handler(C, event, menu); else if (event->type == LEFTMOUSE || event->val != KM_DBL_CLICK) retval = ui_handle_menu_event(C, event, menu, level, is_parent_inside, is_parent_menu, is_floating); } @@ -8934,7 +9046,7 @@ static int ui_handle_menus_recursive( /* *************** UI event handlers **************** */ -static int ui_handler_region(bContext *C, const wmEvent *event, void *UNUSED(userdata)) +static int ui_region_handler(bContext *C, const wmEvent *event, void *UNUSED(userdata)) { ARegion *ar; uiBut *but; @@ -8949,7 +9061,7 @@ static int ui_handler_region(bContext *C, const wmEvent *event, void *UNUSED(use } /* either handle events for already activated button or try to activate */ - but = ui_but_find_activated(ar); + but = ui_but_find_active_in_region(ar); retval = ui_handler_panel_region(C, event, ar); @@ -8973,7 +9085,7 @@ static int ui_handler_region(bContext *C, const wmEvent *event, void *UNUSED(use return retval; } -static void ui_handler_remove_region(bContext *C, void *UNUSED(userdata)) +static void ui_region_handler_remove(bContext *C, void *UNUSED(userdata)) { bScreen *sc; ARegion *ar; @@ -8981,14 +9093,14 @@ static void ui_handler_remove_region(bContext *C, void *UNUSED(userdata)) ar = CTX_wm_region(C); if (ar == NULL) return; - uiFreeBlocks(C, &ar->uiblocks); + UI_blocklist_free(C, &ar->uiblocks); sc = CTX_wm_screen(C); if (sc == NULL) return; /* delayed apply callbacks, but not for screen level regions, those * we rather do at the very end after closing them all, which will - * be done in ui_handler_region/window */ + * be done in ui_region_handler/window */ if (BLI_findindex(&sc->regionbase, ar) == -1) ui_apply_but_funcs_after(C); } @@ -9004,7 +9116,7 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE if (!ar) ar = CTX_wm_region(C); - but = ui_but_find_activated(ar); + but = ui_but_find_active_in_region(ar); if (but) { uiBut *but_other; @@ -9014,7 +9126,7 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE data = but->active; if ((data->state == BUTTON_STATE_MENU_OPEN) && - (but->type == PULLDOWN) && + (but->type == UI_BTYPE_PULLDOWN) && (but_other = ui_but_find_mouse_over(ar, event)) && (but != but_other) && (but->type == but_other->type)) @@ -9060,7 +9172,7 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE } /* two types of popups, one with operator + enum, other with regular callbacks */ -static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata) +static int ui_popup_handler(bContext *C, const wmEvent *event, void *userdata) { uiPopupBlockHandle *menu = userdata; struct ARegion *menu_region; @@ -9096,7 +9208,7 @@ static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata) } ui_popup_block_free(C, menu); - UI_remove_popup_handlers(&win->modalhandlers, menu); + UI_popup_handlers_remove(&win->modalhandlers, menu); #ifdef USE_DRAG_TOGGLE { @@ -9138,7 +9250,7 @@ static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata) return retval; } -static void ui_handler_remove_popup(bContext *C, void *userdata) +static void ui_popup_handler_remove(bContext *C, void *userdata) { uiPopupBlockHandle *menu = userdata; @@ -9149,25 +9261,25 @@ static void ui_handler_remove_popup(bContext *C, void *userdata) ui_apply_but_funcs_after(C); } -void UI_add_region_handlers(ListBase *handlers) +void UI_region_handlers_add(ListBase *handlers) { - WM_event_remove_ui_handler(handlers, ui_handler_region, ui_handler_remove_region, NULL, false); - WM_event_add_ui_handler(NULL, handlers, ui_handler_region, ui_handler_remove_region, NULL, false); + WM_event_remove_ui_handler(handlers, ui_region_handler, ui_region_handler_remove, NULL, false); + WM_event_add_ui_handler(NULL, handlers, ui_region_handler, ui_region_handler_remove, NULL, false); } -void UI_add_popup_handlers(bContext *C, ListBase *handlers, uiPopupBlockHandle *popup, const bool accept_dbl_click) +void UI_popup_handlers_add(bContext *C, ListBase *handlers, uiPopupBlockHandle *popup, const bool accept_dbl_click) { - WM_event_add_ui_handler(C, handlers, ui_handler_popup, ui_handler_remove_popup, popup, accept_dbl_click); + WM_event_add_ui_handler(C, handlers, ui_popup_handler, ui_popup_handler_remove, popup, accept_dbl_click); } -void UI_remove_popup_handlers(ListBase *handlers, uiPopupBlockHandle *popup) +void UI_popup_handlers_remove(ListBase *handlers, uiPopupBlockHandle *popup) { - WM_event_remove_ui_handler(handlers, ui_handler_popup, ui_handler_remove_popup, popup, false); + WM_event_remove_ui_handler(handlers, ui_popup_handler, ui_popup_handler_remove, popup, false); } -void UI_remove_popup_handlers_all(bContext *C, ListBase *handlers) +void UI_popup_handlers_remove_all(bContext *C, ListBase *handlers) { - WM_event_free_ui_handler_all(C, handlers, ui_handler_popup, ui_handler_remove_popup); + WM_event_free_ui_handler_all(C, handlers, ui_popup_handler, ui_popup_handler_remove); } bool UI_textbutton_activate_rna(const bContext *C, ARegion *ar, @@ -9178,7 +9290,7 @@ bool UI_textbutton_activate_rna(const bContext *C, ARegion *ar, for (block = ar->uiblocks.first; block; block = block->next) { for (but = block->buttons.first; but; but = but->next) { - if (but->type == TEX) { + if (but->type == UI_BTYPE_TEXT) { if (but->rnaprop && but->rnapoin.data == rna_poin_data) { if (STREQ(RNA_property_identifier(but->rnaprop), rna_prop_id)) { break; @@ -9191,7 +9303,7 @@ bool UI_textbutton_activate_rna(const bContext *C, ARegion *ar, } if (but) { - uiButActiveOnly(C, ar, block, but); + UI_but_active_only(C, ar, block, but); return true; } else { @@ -9207,7 +9319,7 @@ bool UI_textbutton_activate_but(const bContext *C, uiBut *actbut) for (block = ar->uiblocks.first; block; block = block->next) { for (but = block->buttons.first; but; but = but->next) - if (but == actbut && but->type == TEX) + if (but == actbut && but->type == UI_BTYPE_TEXT) break; if (but) @@ -9215,7 +9327,7 @@ bool UI_textbutton_activate_but(const bContext *C, uiBut *actbut) } if (but) { - uiButActiveOnly(C, ar, block, but); + UI_but_active_only(C, ar, block, but); return true; } else { @@ -9224,7 +9336,7 @@ bool UI_textbutton_activate_but(const bContext *C, uiBut *actbut) } -void ui_button_clipboard_free(void) +void ui_but_clipboard_free(void) { curvemapping_free_data(&but_copypaste_curve); } diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 51dd9166e46..517b8b61ac1 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -51,6 +51,7 @@ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_icons.h" +#include "BKE_appdir.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -587,7 +588,7 @@ static void init_internal_icons(void) #if 0 // temp disabled if ((btheme != NULL) && btheme->tui.iconfile[0]) { - char *icondir = BLI_get_folder(BLENDER_DATAFILES, "icons"); + char *icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons"); char iconfilestr[FILE_MAX]; if (icondir) { @@ -702,7 +703,7 @@ static void init_iconfile_list(struct ListBase *list) const char *icondir; BLI_listbase_clear(list); - icondir = BLI_get_folder(BLENDER_DATAFILES, "icons"); + icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons"); if (icondir == NULL) return; diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index efd67effd73..2c3a239b2a2 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -36,6 +36,7 @@ #include "BLI_compiler_attrs.h" #include "UI_resources.h" #include "RNA_types.h" +#include "DNA_listBase.h" struct ARegion; struct bContext; @@ -67,7 +68,7 @@ typedef enum { /* standard set */ UI_WTYPE_LABEL, UI_WTYPE_TOGGLE, - UI_WTYPE_OPTION, + UI_WTYPE_CHECKBOX, UI_WTYPE_RADIO, UI_WTYPE_NUMBER, UI_WTYPE_SLIDER, @@ -95,7 +96,7 @@ typedef enum { UI_WTYPE_ICON, UI_WTYPE_SWATCH, UI_WTYPE_RGB_PICKER, - UI_WTYPE_NORMAL, + UI_WTYPE_UNITVEC, UI_WTYPE_BOX, UI_WTYPE_SCROLL, UI_WTYPE_LISTITEM, @@ -212,20 +213,20 @@ struct uiBut { /* both these values use depends on the button type * (polymorphic struct or union would be nicer for this stuff) */ - /* (type == HSVCUBE), Use UI_GRAD_* values. - * (type == NUM), Use to store RNA 'step' value, for dragging and click-step. - * (type == LABEL), Use (a1 == 1.0f) to use a2 as a blending factor (wow, this is imaginative!). - * (type == SCROLL) Use as scroll size. - * (type == SEARCH_MENU) Use as number or rows. - * (type == COLOR) Use as indication of color palette + /* (type == UI_BTYPE_HSVCUBE), Use UI_GRAD_* values. + * (type == UI_BTYPE_NUM), Use to store RNA 'step' value, for dragging and click-step. + * (type == UI_BTYPE_LABEL), Use (a1 == 1.0f) to use a2 as a blending factor (wow, this is imaginative!). + * (type == UI_BTYPE_SCROLL) Use as scroll size. + * (type == UI_BTYPE_SEARCH_MENU) Use as number or rows. + * (type == UI_BTYPE_COLOR) Use as indication of color palette */ float a1; - /* (type == HSVCIRCLE ), Use to store the luminosity. - * (type == NUM), Use to store RNA 'precision' value, for dragging and click-step. - * (type == LABEL), If (a1 == 1.0f) use a2 as a blending factor. - * (type == SEARCH_MENU) Use as number or columns. - * (type == COLOR) Use as index in palette (not so good, needs refactor) + /* (type == UI_BTYPE_HSVCIRCLE ), Use to store the luminosity. + * (type == UI_BTYPE_NUM), Use to store RNA 'precision' value, for dragging and click-step. + * (type == UI_BTYPE_LABEL), If (a1 == 1.0f) use a2 as a blending factor. + * (type == UI_BTYPE_SEARCH_MENU) Use as number or columns. + * (type == UI_BTYPE_COLOR) Use as index in palette (not so good, needs refactor) */ float a2; @@ -257,17 +258,17 @@ struct uiBut { BIFIconID icon; bool lock; - char dt; /* drawtype: UI_EMBOSS, UI_EMBOSSN ... etc, copied from the block */ + char dt; /* drawtype: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied from the block */ signed char pie_dir; /* direction in a pie menu, used for collision detection (RadialDirection) */ char changed; /* could be made into a single flag */ unsigned char unit_type; /* so buttons can support unit systems which are not RNA */ short modifier_key; short iconadd; - /* BLOCK data */ + /* UI_BTYPE_BLOCK data */ uiBlockCreateFunc block_create_func; - /* PULLDOWN/MENU data */ + /* UI_BTYPE_PULLDOWN/UI_BTYPE_MENU data */ uiMenuCreateFunc menu_create_func; /* RNA data */ @@ -306,6 +307,16 @@ struct uiBut { uiBlock *block; }; +typedef struct ColorPicker { + struct ColorPicker *next, *prev; + float color_data[3]; /* colr data may be HSV or HSL for now */ + int representation; /* store hsv/hsl value */ +} ColorPicker; + +typedef struct ColorPickerData { + ListBase list; +} ColorPickerData; + struct PieMenuData { float pie_dir[2]; float pie_center_init[2]; @@ -365,7 +376,7 @@ struct uiBlock { short alignnr; char direction; - char dt; /* drawtype: UI_EMBOSS, UI_EMBOSSN ... etc, copied to buttons */ + char dt; /* drawtype: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied to buttons */ bool auto_open; char _pad[7]; double auto_open_last; @@ -375,7 +386,7 @@ struct uiBlock { char lock; char active; /* to keep blocks while drawing and free them afterwards */ char tooltipdisabled; /* to avoid tooltip after click */ - char endblock; /* uiEndBlock done? */ + char endblock; /* UI_block_end done? */ eBlockBoundsCalc bounds_type; /* for doing delayed */ int mx, my; @@ -392,7 +403,7 @@ struct uiBlock { void *evil_C; /* XXX hack for dynamic operator enums */ struct UnitSettings *unit; /* unit system, used a lot for numeric buttons so include here rather then fetching through the scene every time. */ - float _hsv[3]; /* XXX, only access via ui_block_hsv_get() */ + ColorPickerData color_pickers; /* XXX, only accessed by color picker templates */ bool color_profile; /* color profile for correcting linear colors for display */ @@ -410,7 +421,7 @@ typedef struct uiSafetyRct { /* interface.c */ -extern void ui_delete_linkline(uiLinkLine *line, uiBut *but); +extern void ui_linkline_remove(uiLinkLine *line, uiBut *but); void ui_fontscale(short *points, float aspect); @@ -422,49 +433,50 @@ extern void ui_block_to_window_rctf(const struct ARegion *ar, uiBlock *block, rc extern void ui_window_to_block_fl(const struct ARegion *ar, uiBlock *block, float *x, float *y); extern void ui_window_to_block(const struct ARegion *ar, uiBlock *block, int *x, int *y); extern void ui_window_to_region(const ARegion *ar, int *x, int *y); +extern void ui_region_to_window(const struct ARegion *ar, int *x, int *y); -extern double ui_get_but_val(uiBut *but); -extern void ui_set_but_val(uiBut *but, double value); -extern void ui_set_but_hsv(uiBut *but); -extern void ui_get_but_vectorf(uiBut *but, float vec[3]); -extern void ui_set_but_vectorf(uiBut *but, const float vec[3]); +extern double ui_but_value_get(uiBut *but); +extern void ui_but_value_set(uiBut *but, double value); +extern void ui_but_hsv_set(uiBut *but); +extern void ui_but_v3_get(uiBut *but, float vec[3]); +extern void ui_but_v3_set(uiBut *but, const float vec[3]); extern void ui_hsvcircle_vals_from_pos(float *val_rad, float *val_dist, const rcti *rect, const float mx, const float my); extern void ui_hsvcircle_pos_from_vals(struct uiBut *but, const rcti *rect, float *hsv, float *xpos, float *ypos); extern void ui_hsvcube_pos_from_vals(struct uiBut *but, const rcti *rect, float *hsv, float *xp, float *yp); -bool ui_color_picker_use_display_colorspace(struct uiBut *but); +bool ui_but_is_colorpicker_display_space(struct uiBut *but); -extern void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision) ATTR_NONNULL(); -extern void ui_get_but_string(uiBut *but, char *str, const size_t maxlen) ATTR_NONNULL(); -extern void ui_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen) ATTR_NONNULL(); -extern bool ui_set_but_string(struct bContext *C, uiBut *but, const char *str) ATTR_NONNULL(); -extern bool ui_set_but_string_eval_num(struct bContext *C, uiBut *but, const char *str, double *value) ATTR_NONNULL(); -extern int ui_get_but_string_max_length(uiBut *but); -extern uiBut *ui_get_but_drag_multi_edit(uiBut *but); +extern void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision) ATTR_NONNULL(); +extern void ui_but_string_get(uiBut *but, char *str, const size_t maxlen) ATTR_NONNULL(); +extern void ui_but_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen) ATTR_NONNULL(); +extern bool ui_but_string_set(struct bContext *C, uiBut *but, const char *str) ATTR_NONNULL(); +extern bool ui_but_string_set_eval_num(struct bContext *C, uiBut *but, const char *str, double *value) ATTR_NONNULL(); +extern int ui_but_string_get_max_length(uiBut *but); +extern uiBut *ui_but_drag_multi_edit_get(uiBut *but); -extern void ui_set_but_default(struct bContext *C, const bool all, const bool use_afterfunc); +extern void ui_but_default_set(struct bContext *C, const bool all, const bool use_afterfunc); -extern void ui_check_but(uiBut *but); -extern bool ui_is_but_float(const uiBut *but) ATTR_WARN_UNUSED_RESULT; -extern bool ui_is_but_bool(const uiBut *but) ATTR_WARN_UNUSED_RESULT; -extern bool ui_is_but_unit(const uiBut *but) ATTR_WARN_UNUSED_RESULT; -extern bool ui_is_but_compatible(const uiBut *but_a, const uiBut *but_b) ATTR_WARN_UNUSED_RESULT; -extern bool ui_is_but_rna_valid(uiBut *but) ATTR_WARN_UNUSED_RESULT; -extern bool ui_is_but_utf8(const uiBut *but) ATTR_WARN_UNUSED_RESULT; -extern bool ui_is_but_search_unlink_visible(const uiBut *but) ATTR_WARN_UNUSED_RESULT; +extern void ui_but_update(uiBut *but); +extern bool ui_but_is_float(const uiBut *but) ATTR_WARN_UNUSED_RESULT; +extern bool ui_but_is_bool(const uiBut *but) ATTR_WARN_UNUSED_RESULT; +extern bool ui_but_is_unit(const uiBut *but) ATTR_WARN_UNUSED_RESULT; +extern bool ui_but_is_compatible(const uiBut *but_a, const uiBut *but_b) ATTR_WARN_UNUSED_RESULT; +extern bool ui_but_is_rna_valid(uiBut *but) ATTR_WARN_UNUSED_RESULT; +extern bool ui_but_is_utf8(const uiBut *but) ATTR_WARN_UNUSED_RESULT; +extern bool ui_but_is_search_unlink_visible(const uiBut *but) ATTR_WARN_UNUSED_RESULT; -extern int ui_is_but_push_ex(uiBut *but, double *value) ATTR_WARN_UNUSED_RESULT; -extern int ui_is_but_push(uiBut *but) ATTR_WARN_UNUSED_RESULT; +extern int ui_but_is_pushed_ex(uiBut *but, double *value) ATTR_WARN_UNUSED_RESULT; +extern int ui_but_is_pushed(uiBut *but) ATTR_WARN_UNUSED_RESULT; -extern void ui_bounds_block(uiBlock *block); +extern void ui_block_bounds_calc(uiBlock *block); extern void ui_block_translate(uiBlock *block, int x, int y); -extern void ui_block_do_align(uiBlock *block); +extern void ui_block_align_calc(uiBlock *block); -extern struct ColorManagedDisplay *ui_block_display_get(uiBlock *block); -void ui_block_to_display_space_v3(uiBlock *block, float pixel[3]); -void ui_block_to_scene_linear_v3(uiBlock *block, float pixel[3]); +extern struct ColorManagedDisplay *ui_block_cm_display_get(uiBlock *block); +void ui_block_cm_to_display_space_v3(uiBlock *block, float pixel[3]); +void ui_block_cm_to_scene_linear_v3(uiBlock *block, float pixel[3]); /* interface_regions.c */ @@ -540,7 +552,7 @@ void ui_popup_menu_memory_set(uiBlock *block, struct uiBut *but); void ui_popup_translate(struct bContext *C, struct ARegion *ar, const int mdiff[2]); -float *ui_block_hsv_get(struct uiBlock *block); +ColorPicker *ui_block_colorpicker_create(struct uiBlock *block); void ui_popup_block_scrolltest(struct uiBlock *block); void ui_rgb_to_color_picker_compat_v(const float rgb[3], float r_cp[3]); @@ -557,7 +569,7 @@ int ui_searchbox_autocomplete(struct bContext *C, struct ARegion *ar, uiBut *but void ui_searchbox_event(struct bContext *C, struct ARegion *ar, uiBut *but, const struct wmEvent *event); bool ui_searchbox_apply(uiBut *but, struct ARegion *ar); void ui_searchbox_free(struct bContext *C, struct ARegion *ar); -void ui_but_search_test(uiBut *but); +void ui_but_search_refresh(uiBut *but); uiBlock *ui_popup_block_refresh(struct bContext *C, uiPopupBlockHandle *handle, ARegion *butregion, uiBut *but); @@ -570,7 +582,7 @@ uiPopupBlockHandle *ui_popup_menu_create(struct bContext *C, struct ARegion *but void ui_popup_block_free(struct bContext *C, uiPopupBlockHandle *handle); -int ui_step_name_menu(uiBut *but, int step); +int ui_but_menu_step(uiBut *but, int step); struct AutoComplete; @@ -579,7 +591,7 @@ extern int ui_handler_panel_region(struct bContext *C, const struct wmEvent *eve extern void ui_draw_aligned_panel(struct uiStyle *style, uiBlock *block, const rcti *rect, const bool show_pin); /* interface_draw.c */ -extern void ui_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int select); +extern void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int select); void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, const float alpha); @@ -587,7 +599,7 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect); void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect); void ui_draw_but_COLORBAND(uiBut *but, struct uiWidgetColors *wcol, const rcti *rect); -void ui_draw_but_NORMAL(uiBut *but, struct uiWidgetColors *wcol, const rcti *rect); +void ui_draw_but_UNITVEC(uiBut *but, struct uiWidgetColors *wcol, const rcti *rect); void ui_draw_but_CURVE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect); void ui_draw_but_IMAGE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect); void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect); @@ -596,25 +608,31 @@ void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol /* interface_handlers.c */ PointerRNA *ui_handle_afterfunc_add_operator(struct wmOperatorType *ot, int opcontext, bool create_props); extern void ui_pan_to_scroll(const struct wmEvent *event, int *type, int *val); -extern void ui_button_activate_do(struct bContext *C, struct ARegion *ar, uiBut *but); -extern void ui_button_activate_over(struct bContext *C, struct ARegion *ar, uiBut *but); -extern void ui_button_execute_begin(struct bContext *C, struct ARegion *ar, uiBut *but, void **active_back); -extern void ui_button_execute_end(struct bContext *C, struct ARegion *ar, uiBut *but, void *active_back); -extern void ui_button_active_free(const struct bContext *C, uiBut *but); -extern bool ui_button_is_active(struct ARegion *ar) ATTR_WARN_UNUSED_RESULT; -extern int ui_button_open_menu_direction(uiBut *but); -extern void ui_button_text_password_hide(char password_str[UI_MAX_DRAW_STR], uiBut *but, const bool restore); -extern uiBut *ui_but_find_activated(struct ARegion *ar); +extern void ui_but_activate_event(struct bContext *C, struct ARegion *ar, uiBut *but); +extern void ui_but_activate_over(struct bContext *C, struct ARegion *ar, uiBut *but); +extern void ui_but_execute_begin(struct bContext *C, struct ARegion *ar, uiBut *but, void **active_back); +extern void ui_but_execute_end(struct bContext *C, struct ARegion *ar, uiBut *but, void *active_back); +extern void ui_but_active_free(const struct bContext *C, uiBut *but); +extern bool ui_but_is_active(struct ARegion *ar) ATTR_WARN_UNUSED_RESULT; +extern int ui_but_menu_direction(uiBut *but); +extern void ui_but_text_password_hide(char password_str[UI_MAX_DRAW_STR], uiBut *but, const bool restore); +extern uiBut *ui_but_find_active_in_region(struct ARegion *ar); bool ui_but_is_editable(const uiBut *but); +bool ui_but_is_editable_as_text(const uiBut *but); void ui_but_pie_dir_visual(RadialDirection dir, float vec[2]); void ui_but_pie_dir(RadialDirection dir, float vec[2]); -void ui_block_calculate_pie_segment(struct uiBlock *block, const float event_xy[2]); +float ui_block_calc_pie_segment(struct uiBlock *block, const float event_xy[2]); -void ui_button_clipboard_free(void); +void ui_but_clipboard_free(void); void ui_panel_menu(struct bContext *C, ARegion *ar, Panel *pa); uiBut *ui_but_find_old(uiBlock *block_old, const uiBut *but_new); uiBut *ui_but_find_new(uiBlock *block_old, const uiBut *but_new); +#ifdef WITH_INPUT_IME +void ui_but_ime_reposition(uiBut *but, int x, int y, bool complete); +struct wmIMEData *ui_but_get_ime_data(uiBut *but); +#endif + /* interface_widgets.c */ void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3); void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float maxy, float rad, bool use_alpha); @@ -635,6 +653,7 @@ void ui_draw_menu_item(struct uiFontStyle *fstyle, rcti *rect, const char *name, void ui_draw_preview_item(struct uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state); #define UI_TEXT_MARGIN_X 0.4f +#define UI_POPUP_MARGIN (UI_DPI_FAC * 12) /* interface_style.c */ void uiStyleInit(void); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index c2bd6d307d1..7a8d2afb68e 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -237,7 +237,7 @@ static int ui_text_icon_width(uiLayout *layout, const char *name, int icon, bool if (variable) { /* it may seem odd that the icon only adds (UI_UNIT_X / 4) * but taking margins into account its fine */ - return (UI_GetStringWidth(name) + + return (UI_fontstyle_string_width(name) + (UI_UNIT_X * ((compact ? 1.25f : 1.50f) + (icon ? 0.25f : 0.0f)))); } @@ -286,7 +286,7 @@ static void ui_item_position(uiItem *item, int x, int y, int w, int h) bitem->but->rect.xmax = x + w; bitem->but->rect.ymax = y + h; - ui_check_but(bitem->but); /* for strlen */ + ui_but_update(bitem->but); /* for strlen */ } else { uiLayout *litem = (uiLayout *)item; @@ -350,7 +350,7 @@ static void ui_layer_but_cb(bContext *C, void *arg_but, void *arg_index) RNA_property_update(C, ptr, prop); for (cbut = but->block->buttons.first; cbut; cbut = cbut->next) - ui_check_but(cbut); + ui_but_update(cbut); } } @@ -371,11 +371,11 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in subtype = RNA_property_subtype(prop); sub = ui_item_local_sublayout(layout, layout, 1); - uiBlockSetCurLayout(block, sub); + UI_block_layout_set_current(block, sub); /* create label */ if (name[0]) - uiDefBut(block, LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); /* create buttons */ if (type == PROP_BOOLEAN && ELEM(subtype, PROP_LAYER, PROP_LAYER_MEMBER)) { @@ -386,7 +386,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in unsigned int layer_used = 0; unsigned int layer_active = 0; - uiBlockSetCurLayout(block, uiLayoutAbsolute(layout, false)); + UI_block_layout_set_current(block, uiLayoutAbsolute(layout, false)); unit = UI_UNIT_X * 0.75; butw = unit; @@ -410,7 +410,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in } for (b = 0; b < cols; b++) { - uiBlockBeginAlign(block); + UI_block_align_begin(block); for (a = 0; a < colbuts; a++) { const int layer_num = a + b * colbuts; @@ -428,7 +428,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in but = uiDefAutoButR(block, ptr, prop, layer_num, "", icon, x + butw * a, y + buth, butw, buth); if (subtype == PROP_LAYER_MEMBER) - uiButSetFunc(but, ui_layer_but_cb, but, SET_INT_IN_POINTER(layer_num)); + UI_but_func_set(but, ui_layer_but_cb, but, SET_INT_IN_POINTER(layer_num)); } for (a = 0; a < colbuts; a++) { const int layer_num = a + len / 2 + b * colbuts; @@ -446,9 +446,9 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in but = uiDefAutoButR(block, ptr, prop, layer_num, "", icon, x + butw * a, y, butw, buth); if (subtype == PROP_LAYER_MEMBER) - uiButSetFunc(but, ui_layer_but_cb, but, SET_INT_IN_POINTER(layer_num)); + UI_but_func_set(but, ui_layer_but_cb, but, SET_INT_IN_POINTER(layer_num)); } - uiBlockEndAlign(block); + UI_block_align_end(block); x += colbuts * butw + style->buttonspacex; } @@ -457,7 +457,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in int totdim, dim_size[3]; /* 3 == RNA_MAX_ARRAY_DIMENSION */ int row, col; - uiBlockSetCurLayout(block, uiLayoutAbsolute(layout, true)); + UI_block_layout_set_current(block, uiLayoutAbsolute(layout, true)); totdim = RNA_property_array_dimension(ptr, prop, dim_size); if (totdim != 2) return; /* only 2D matrices supported in UI so far */ @@ -470,12 +470,12 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in row = a / dim_size[0]; but = uiDefAutoButR(block, ptr, prop, a, "", ICON_NONE, x + w * col, y + (dim_size[1] * UI_UNIT_Y) - (row * UI_UNIT_Y), w, UI_UNIT_Y); - if (slider && but->type == NUM) - but->type = NUMSLI; + if (slider && but->type == UI_BTYPE_NUM) + but->type = UI_BTYPE_NUM_SLIDER; } } else if (subtype == PROP_DIRECTION && !expand) { - uiDefButR_prop(block, BUT_NORMAL, 0, name, x, y, UI_UNIT_X * 3, UI_UNIT_Y * 3, ptr, prop, 0, 0, 0, -1, -1, NULL); + uiDefButR_prop(block, UI_BTYPE_UNITVEC, 0, name, x, y, UI_UNIT_X * 3, UI_UNIT_Y * 3, ptr, prop, -1, 0, 0, -1, -1, NULL); } else { /* note, this block of code is a bit arbitrary and has just been made @@ -500,7 +500,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in } /* show checkboxes for rna on a non-emboss block (menu for eg) */ - if (type == PROP_BOOLEAN && ELEM(layout->root->block->dt, UI_EMBOSSN, UI_EMBOSSP)) { + if (type == PROP_BOOLEAN && ELEM(layout->root->block->dt, UI_EMBOSS_NONE, UI_EMBOSS_PULLDOWN)) { boolarr = MEM_callocN(sizeof(int) * len, "ui_item_array"); RNA_property_boolean_get_array(ptr, prop, boolarr); } @@ -509,12 +509,12 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in if (!icon_only) str[0] = RNA_property_array_item_char(prop, a); if (boolarr) icon = boolarr[a] ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT; but = uiDefAutoButR(block, ptr, prop, a, str, icon, 0, 0, w, UI_UNIT_Y); - if (slider && but->type == NUM) - but->type = NUMSLI; - if (toggle && but->type == OPTION) - but->type = TOG; + if (slider && but->type == UI_BTYPE_NUM) + but->type = UI_BTYPE_NUM_SLIDER; + if (toggle && but->type == UI_BTYPE_CHECKBOX) + but->type = UI_BTYPE_TOGGLE; if ((a == 0) && (subtype == PROP_AXISANGLE)) - uiButSetUnitType(but, PROP_UNIT_ROTATION); + UI_but_unit_type_set(but, PROP_UNIT_ROTATION); } if (boolarr) { @@ -523,7 +523,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in } } - uiBlockSetCurLayout(block, layout); + UI_block_layout_set_current(block, layout); } static void ui_item_enum_expand_handle(bContext *C, void *arg1, void *arg2) @@ -571,13 +571,13 @@ static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *pt /* we dont want nested rows, cols in menus */ if (radial) { layout_radial = uiLayoutRadial(layout); - uiBlockSetCurLayout(block, layout_radial); + UI_block_layout_set_current(block, layout_radial); } else if (layout->root->type != UI_LAYOUT_MENU) { - uiBlockSetCurLayout(block, ui_item_local_sublayout(layout, layout, 1)); + UI_block_layout_set_current(block, ui_item_local_sublayout(layout, layout, 1)); } else { - uiBlockSetCurLayout(block, layout); + UI_block_layout_set_current(block, layout); } for (item = item_array; item->identifier; item++) { @@ -593,20 +593,20 @@ static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *pt itemw = ui_text_icon_width(block->curlayout, icon_only ? "" : name, icon, 0); if (icon && name[0] && !icon_only) - but = uiDefIconTextButR_prop(block, ROW, 0, icon, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL); + but = uiDefIconTextButR_prop(block, UI_BTYPE_ROW, 0, icon, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL); else if (icon) - but = uiDefIconButR_prop(block, ROW, 0, icon, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL); + but = uiDefIconButR_prop(block, UI_BTYPE_ROW, 0, icon, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL); else - but = uiDefButR_prop(block, ROW, 0, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL); + but = uiDefButR_prop(block, UI_BTYPE_ROW, 0, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL); if (RNA_property_flag(prop) & PROP_ENUM_FLAG) { - uiButSetFunc(but, ui_item_enum_expand_handle, but, SET_INT_IN_POINTER(value)); + UI_but_func_set(but, ui_item_enum_expand_handle, but, SET_INT_IN_POINTER(value)); } if (ui_layout_local_dir(layout) != UI_LAYOUT_HORIZONTAL) but->drawflag |= UI_BUT_TEXT_LEFT; } - uiBlockSetCurLayout(block, layout); + UI_block_layout_set_current(block, layout); if (free) { MEM_freeN(item_array); @@ -634,16 +634,16 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, const char *n int labelw; sub = uiLayoutRow(layout, layout->align); - uiBlockSetCurLayout(block, sub); + UI_block_layout_set_current(block, sub); if (name[0]) { - /* XXX UI_GetStringWidth is not accurate */ + /* XXX UI_fontstyle_string_width is not accurate */ #if 0 - labelw = UI_GetStringWidth(name); + labelw = UI_fontstyle_string_width(name); CLAMP(labelw, w / 4, 3 * w / 4); #endif labelw = w / 3; - uiDefBut(block, LABEL, 0, name, x, y, labelw, h, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 0, name, x, y, labelw, h, NULL, 0.0, 0.0, 0, 0, ""); w = w - labelw; } @@ -651,15 +651,15 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, const char *n subtype = RNA_property_subtype(prop); if (subtype == PROP_FILEPATH || subtype == PROP_DIRPATH) { - uiBlockSetCurLayout(block, uiLayoutRow(sub, true)); + UI_block_layout_set_current(block, uiLayoutRow(sub, true)); but = uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w - UI_UNIT_X, h); - /* BUTTONS_OT_file_browse calls uiFileBrowseContextProperty */ - uiDefIconButO(block, BUT, subtype == PROP_DIRPATH ? "BUTTONS_OT_directory_browse" : "BUTTONS_OT_file_browse", + /* BUTTONS_OT_file_browse calls UI_context_active_but_prop_get_filebrowser */ + uiDefIconButO(block, UI_BTYPE_BUT, subtype == PROP_DIRPATH ? "BUTTONS_OT_directory_browse" : "BUTTONS_OT_file_browse", WM_OP_INVOKE_DEFAULT, ICON_FILESEL, x, y, UI_UNIT_X, h, NULL); } else if (flag & UI_ITEM_R_EVENT) { - uiDefButR_prop(block, KEYEVT, 0, name, x, y, w, h, ptr, prop, index, 0, 0, -1, -1, NULL); + uiDefButR_prop(block, UI_BTYPE_KEY_EVENT, 0, name, x, y, w, h, ptr, prop, index, 0, 0, -1, -1, NULL); } else if (flag & UI_ITEM_R_FULL_EVENT) { if (RNA_struct_is_a(ptr->type, &RNA_KeyMapItem)) { @@ -667,20 +667,20 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, const char *n WM_keymap_item_to_string(ptr->data, buf, sizeof(buf)); - but = uiDefButR_prop(block, HOTKEYEVT, 0, buf, x, y, w, h, ptr, prop, 0, 0, 0, -1, -1, NULL); - uiButSetFunc(but, ui_keymap_but_cb, but, NULL); + but = uiDefButR_prop(block, UI_BTYPE_HOTKEY_EVENT, 0, buf, x, y, w, h, ptr, prop, 0, 0, 0, -1, -1, NULL); + UI_but_func_set(but, ui_keymap_but_cb, but, NULL); if (flag & UI_ITEM_R_IMMEDIATE) - uiButSetFlag(but, UI_BUT_IMMEDIATE); + UI_but_flag_enable(but, UI_BUT_IMMEDIATE); } } else but = uiDefAutoButR(block, ptr, prop, index, (type == PROP_ENUM && !(flag & UI_ITEM_R_ICON_ONLY)) ? NULL : "", icon, x, y, w, h); - uiBlockSetCurLayout(block, layout); + UI_block_layout_set_current(block, layout); return but; } -void uiFileBrowseContextProperty(const bContext *C, PointerRNA *ptr, PropertyRNA **prop) +void UI_context_active_but_prop_get_filebrowser(const bContext *C, PointerRNA *ptr, PropertyRNA **prop) { ARegion *ar = CTX_wm_region(C); uiBlock *block; @@ -729,14 +729,14 @@ static void ui_item_disabled(uiLayout *layout, const char *name) uiBut *but; int w; - uiBlockSetCurLayout(block, layout); + UI_block_layout_set_current(block, layout); if (!name) name = ""; w = ui_text_icon_width(layout, name, 0, 0); - but = uiDefBut(block, LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + but = uiDefBut(block, UI_BTYPE_LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); but->flag |= UI_BUT_DISABLED; but->lock = true; but->lockstr = ""; @@ -760,24 +760,24 @@ PointerRNA uiItemFullO_ptr(uiLayout *layout, wmOperatorType *ot, const char *nam icon = ICON_BLANK1; /* create button */ - uiBlockSetCurLayout(block, layout); + UI_block_layout_set_current(block, layout); w = ui_text_icon_width(layout, name, icon, 0); if (flag & UI_ITEM_R_NO_BG) - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); /* create the button */ if (icon) { if (name[0]) { - but = uiDefIconTextButO_ptr(block, BUT, ot, context, icon, name, 0, 0, w, UI_UNIT_Y, NULL); + but = uiDefIconTextButO_ptr(block, UI_BTYPE_BUT, ot, context, icon, name, 0, 0, w, UI_UNIT_Y, NULL); } else { - but = uiDefIconButO_ptr(block, BUT, ot, context, icon, 0, 0, w, UI_UNIT_Y, NULL); + but = uiDefIconButO_ptr(block, UI_BTYPE_BUT, ot, context, icon, 0, 0, w, UI_UNIT_Y, NULL); } } else { - but = uiDefButO_ptr(block, BUT, ot, context, name, 0, 0, w, UI_UNIT_Y, NULL); + but = uiDefButO_ptr(block, UI_BTYPE_BUT, ot, context, name, 0, 0, w, UI_UNIT_Y, NULL); } assert(but->optype != NULL); @@ -787,14 +787,14 @@ PointerRNA uiItemFullO_ptr(uiLayout *layout, wmOperatorType *ot, const char *nam but->drawflag |= UI_BUT_TEXT_LEFT; if (flag & UI_ITEM_R_NO_BG) - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); if (layout->redalert) - uiButSetFlag(but, UI_BUT_REDALERT); + UI_but_flag_enable(but, UI_BUT_REDALERT); /* assign properties */ if (properties || (flag & UI_ITEM_O_RETURN_PROPS)) { - PointerRNA *opptr = uiButGetOperatorPtrRNA(but); + PointerRNA *opptr = UI_but_operator_ptr_get(but); if (properties) { opptr->data = properties; @@ -958,7 +958,7 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname } else { /* Do not use uiItemL here, as our root layout is a menu one, it will add a fake blank icon! */ - but = uiDefBut(block, LABEL, 0, item->name, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, + but = uiDefBut(block, UI_BTYPE_LABEL, 0, item->name, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); } ui_but_tip_from_enum_item(but, item); @@ -977,6 +977,9 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname if (free) { MEM_freeN(item_array); } + + /* intentionally don't touch UI_BLOCK_IS_FLIP here, + * we don't know the context this is called in */ } else if (prop && RNA_property_type(prop) != PROP_ENUM) { RNA_warning("%s.%s, not an enum type", RNA_struct_identifier(ptr.type), propname); @@ -1199,7 +1202,7 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index int len, w, h, slider, toggle, expand, icon_only, no_bg; bool is_array; - uiBlockSetCurLayout(block, layout); + UI_block_layout_set_current(block, layout); /* retrieve info */ type = RNA_property_type(prop); @@ -1258,7 +1261,7 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index ui_item_rna_size(layout, name, icon, ptr, prop, index, icon_only, &w, &h); if (no_bg) - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); /* array property */ if (index == RNA_NO_INDEX && is_array) @@ -1266,11 +1269,11 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index /* enum item */ else if (type == PROP_ENUM && index == RNA_ENUM_VALUE) { if (icon && name[0] && !icon_only) - uiDefIconTextButR_prop(block, ROW, 0, icon, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL); + uiDefIconTextButR_prop(block, UI_BTYPE_ROW, 0, icon, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL); else if (icon) - uiDefIconButR_prop(block, ROW, 0, icon, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL); + uiDefIconButR_prop(block, UI_BTYPE_ROW, 0, icon, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL); else - uiDefButR_prop(block, ROW, 0, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL); + uiDefButR_prop(block, UI_BTYPE_ROW, 0, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL); } /* expanded enum */ else if (type == PROP_ENUM && (expand || RNA_property_flag(prop) & PROP_ENUM_FLAG)) @@ -1281,29 +1284,29 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index ui_but_add_search(but, ptr, prop, NULL, NULL); if (layout->redalert) - uiButSetFlag(but, UI_BUT_REDALERT); + UI_but_flag_enable(but, UI_BUT_REDALERT); } /* single button */ else { but = uiDefAutoButR(block, ptr, prop, index, name, icon, 0, 0, w, h); - if (slider && but->type == NUM) - but->type = NUMSLI; + if (slider && but->type == UI_BTYPE_NUM) + but->type = UI_BTYPE_NUM_SLIDER; - if (toggle && but->type == OPTION) - but->type = TOG; + if (toggle && but->type == UI_BTYPE_CHECKBOX) + but->type = UI_BTYPE_TOGGLE; if (layout->redalert) - uiButSetFlag(but, UI_BUT_REDALERT); + UI_but_flag_enable(but, UI_BUT_REDALERT); } /* Mark non-embossed textfields inside a listbox. */ - if (but && (block->flag & UI_BLOCK_LIST_ITEM) && (but->type == TEX) && (but->dt & UI_EMBOSSN)) { - uiButSetFlag(but, UI_BUT_LIST_ITEM); + if (but && (block->flag & UI_BLOCK_LIST_ITEM) && (but->type == UI_BTYPE_TEXT) && (but->dt & UI_EMBOSS_NONE)) { + UI_but_flag_enable(but, UI_BUT_LIST_ITEM); } if (no_bg) - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); /* ensure text isn't added to icon_only buttons */ if (but && icon_only) { @@ -1431,6 +1434,9 @@ void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname MEM_freeN(item); } } + + /* intentionally don't touch UI_BLOCK_IS_FLIP here, + * we don't know the context this is called in */ } /* Pointer RNA button with search */ @@ -1508,11 +1514,11 @@ static void rna_search_cb(const struct bContext *C, void *arg_but, const char *s } RNA_PROP_END; - BLI_sortlist(items_list, sort_search_items_list); + BLI_listbase_sort(items_list, sort_search_items_list); /* add search items from temporary list */ for (cis = items_list->first; cis; cis = cis->next) { - if (false == uiSearchItemAdd(items, cis->name, SET_INT_IN_POINTER(cis->index), cis->iconid)) { + if (false == UI_search_item_add(items, cis->name, SET_INT_IN_POINTER(cis->index), cis->iconid)) { break; } } @@ -1564,7 +1570,7 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN /* turn button into search button */ if (searchprop) { - but->type = RNA_property_is_unlink(prop) ? SEARCH_MENU_UNLINK : SEARCH_MENU; + but->type = RNA_property_is_unlink(prop) ? UI_BTYPE_SEARCH_MENU_UNLINK : UI_BTYPE_SEARCH_MENU; but->hardmax = MAX2(but->hardmax, 256.0f); but->rnasearchpoin = *searchptr; but->rnasearchprop = searchprop; @@ -1576,7 +1582,7 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN but->str[0] = 0; } - uiButSetSearchFunc(but, rna_search_cb, but, NULL, NULL); + UI_but_func_search_set(but, rna_search_cb, but, NULL, NULL); } } @@ -1663,6 +1669,9 @@ static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt) if (layout->context) CTX_store_set(C, NULL); + + /* menus are created flipped (from event handling pov) */ + layout->root->block->flag ^= UI_BLOCK_IS_FLIP; } static uiBut *ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg, void *argN, @@ -1672,10 +1681,10 @@ static uiBut *ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuC uiBut *but; int w, h; - uiBlockSetCurLayout(block, layout); + UI_block_layout_set_current(block, layout); if (layout->root->type == UI_LAYOUT_HEADER) - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); if (!name) name = ""; @@ -1709,12 +1718,12 @@ static uiBut *ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuC } if (layout->root->type == UI_LAYOUT_HEADER) { - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); } if (ELEM(layout->root->type, UI_LAYOUT_PANEL, UI_LAYOUT_TOOLBAR) || (force_menu && layout->root->type != UI_LAYOUT_MENU)) /* We never want a dropdown in menu! */ { - uiButSetMenuFromPulldown(but); + UI_but_type_set_menu_from_pulldown(but); } return but; @@ -1748,7 +1757,7 @@ static uiBut *uiItemL_(uiLayout *layout, const char *name, int icon) uiBut *but; int w; - uiBlockSetCurLayout(block, layout); + UI_block_layout_set_current(block, layout); if (!name) name = ""; @@ -1758,11 +1767,11 @@ static uiBut *uiItemL_(uiLayout *layout, const char *name, int icon) w = ui_text_icon_width(layout, name, icon, 0); if (icon && name[0]) - but = uiDefIconTextBut(block, LABEL, 0, icon, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + but = uiDefIconTextBut(block, UI_BTYPE_LABEL, 0, icon, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); else if (icon) - but = uiDefIconBut(block, LABEL, 0, icon, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + but = uiDefIconBut(block, UI_BTYPE_LABEL, 0, icon, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); else - but = uiDefBut(block, LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + but = uiDefBut(block, UI_BTYPE_LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); /* to compensate for string size padding in ui_text_icon_width, * make text aligned right if the layout is aligned right. @@ -1791,7 +1800,7 @@ void uiItemLDrag(uiLayout *layout, PointerRNA *ptr, const char *name, int icon) if (ptr && ptr->type) if (RNA_struct_is_ID(ptr->type)) - uiButSetDragID(but, ptr->id.data); + UI_but_drag_set_id(but, ptr->id.data); } @@ -1803,7 +1812,7 @@ void uiItemV(uiLayout *layout, const char *name, int icon, int argval) int *retvalue = (block->handle) ? &block->handle->retvalue : NULL; int w; - uiBlockSetCurLayout(block, layout); + UI_block_layout_set_current(block, layout); if (!name) name = ""; @@ -1813,11 +1822,11 @@ void uiItemV(uiLayout *layout, const char *name, int icon, int argval) w = ui_text_icon_width(layout, name, icon, 0); if (icon && name[0]) - uiDefIconTextButI(block, BUT, argval, icon, name, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, -1, ""); + uiDefIconTextButI(block, UI_BTYPE_BUT, argval, icon, name, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, -1, ""); else if (icon) - uiDefIconButI(block, BUT, argval, icon, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, -1, ""); + uiDefIconButI(block, UI_BTYPE_BUT, argval, icon, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, -1, ""); else - uiDefButI(block, BUT, argval, name, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, -1, ""); + uiDefButI(block, UI_BTYPE_BUT, argval, name, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, -1, ""); } /* separator item */ @@ -1827,8 +1836,8 @@ void uiItemS(uiLayout *layout) bool is_menu = ui_block_is_menu(block); int space = (is_menu) ? 0.45f * UI_UNIT_X : 0.3f * UI_UNIT_X; - uiBlockSetCurLayout(block, layout); - uiDefBut(block, (is_menu) ? SEPRLINE : SEPR, 0, "", 0, 0, space, space, NULL, 0.0, 0.0, 0, 0, ""); + UI_block_layout_set_current(block, layout); + uiDefBut(block, (is_menu) ? UI_BTYPE_SEPR_LINE : UI_BTYPE_SEPR, 0, "", 0, 0, space, space, NULL, 0.0, 0.0, 0, 0, ""); } /* level items */ @@ -1856,8 +1865,10 @@ static void menu_item_enum_opname_menu(bContext *UNUSED(C), uiLayout *layout, vo uiLayoutSetOperatorContext(layout, lvl->opcontext); uiItemsEnumO(layout, lvl->opname, lvl->propname); + layout->root->block->flag |= UI_BLOCK_IS_FLIP; + /* override default, needed since this was assumed pre 2.70 */ - uiBlockSetDirection(layout->root->block, UI_DOWN); + UI_block_direction_set(layout->root->block, UI_DIR_DOWN); } void uiItemMenuEnumO(uiLayout *layout, bContext *C, const char *opname, const char *propname, const char *name, int icon) @@ -1908,19 +1919,12 @@ static void menu_item_enum_rna_menu(bContext *UNUSED(C), uiLayout *layout, void uiLayoutSetOperatorContext(layout, lvl->opcontext); uiItemsEnumR(layout, &lvl->rnapoin, lvl->propname); + layout->root->block->flag |= UI_BLOCK_IS_FLIP; } -void uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *name, int icon) +void uiItemMenuEnumR_prop(uiLayout *layout, struct PointerRNA *ptr, PropertyRNA *prop, const char *name, int icon) { MenuItemLevel *lvl; - PropertyRNA *prop; - - prop = RNA_struct_find_property(ptr, propname); - if (!prop) { - ui_item_disabled(layout, propname); - RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); - return; - } if (!name) name = RNA_property_ui_name(prop); @@ -1929,12 +1933,26 @@ void uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propn lvl = MEM_callocN(sizeof(MenuItemLevel), "MenuItemLevel"); lvl->rnapoin = *ptr; - BLI_strncpy(lvl->propname, propname, sizeof(lvl->propname)); + BLI_strncpy(lvl->propname, RNA_property_identifier(prop), sizeof(lvl->propname)); lvl->opcontext = layout->root->opcontext; ui_item_menu(layout, name, icon, menu_item_enum_rna_menu, NULL, lvl, RNA_property_description(prop), false); } +void uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *name, int icon) +{ + PropertyRNA *prop; + + prop = RNA_struct_find_property(ptr, propname); + if (!prop) { + ui_item_disabled(layout, propname); + RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); + return; + } + + uiItemMenuEnumR_prop(layout, ptr, prop, name, icon); +} + /**************************** Layout Items ***************************/ /* single-row layout */ @@ -2129,7 +2147,7 @@ static RadialDirection ui_get_radialbut_vec(float vec[2], short itemnum) static bool ui_item_is_radial_displayable(uiItem *item) { - if ((item->type == ITEM_BUTTON) && (((uiButtonItem *)item)->but->type == LABEL)) + if ((item->type == ITEM_BUTTON) && (((uiButtonItem *)item)->but->type == UI_BTYPE_LABEL)) return false; return true; @@ -2138,7 +2156,7 @@ static bool ui_item_is_radial_displayable(uiItem *item) static bool ui_item_is_radial_drawable(uiButtonItem *bitem) { - if (ELEM(bitem->but->type, SEPR, SEPRLINE)) + if (ELEM(bitem->but->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) return false; return true; @@ -2194,7 +2212,7 @@ static void ui_litem_layout_radial(uiLayout *litem) bitem->but->rect.xmax += 1.5f * UI_UNIT_X; /* enable drawing as pie item if supported by widget */ if (ui_item_is_radial_drawable(bitem)) - bitem->but->dt = UI_EMBOSSR; + bitem->but->dt = UI_EMBOSS_RADIAL; } ui_item_size(item, &itemw, &itemh); @@ -2499,7 +2517,7 @@ static void ui_litem_layout_split(uiLayout *litem) uiLayoutItemSplit *split = (uiLayoutItemSplit *)litem; uiItem *item; float percentage; - const int tot = BLI_countlist(&litem->items); + const int tot = BLI_listbase_count(&litem->items); int itemh, x, y, w, colw = 0; if (tot == 0) @@ -2587,7 +2605,7 @@ uiLayout *uiLayoutRow(uiLayout *layout, int align) litem->w = layout->w; BLI_addtail(&layout->items, litem); - uiBlockSetCurLayout(layout->root->block, litem); + UI_block_layout_set_current(layout->root->block, litem); return litem; } @@ -2608,7 +2626,7 @@ uiLayout *uiLayoutColumn(uiLayout *layout, int align) litem->w = layout->w; BLI_addtail(&layout->items, litem); - uiBlockSetCurLayout(layout->root->block, litem); + UI_block_layout_set_current(layout->root->block, litem); return litem; } @@ -2630,7 +2648,7 @@ uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align) flow->number = number; BLI_addtail(&layout->items, flow); - uiBlockSetCurLayout(layout->root->block, &flow->litem); + UI_block_layout_set_current(layout->root->block, &flow->litem); return &flow->litem; } @@ -2650,7 +2668,7 @@ static uiLayoutItemBx *ui_layout_box(uiLayout *layout, int type) box->litem.w = layout->w; BLI_addtail(&layout->items, box); - uiBlockSetCurLayout(layout->root->block, &box->litem); + UI_block_layout_set_current(layout->root->block, &box->litem); box->roundbox = uiDefBut(layout->root->block, type, 0, "", 0, 0, 0, 0, NULL, 0.0, 0.0, 0, 0, ""); @@ -2670,7 +2688,7 @@ uiLayout *uiLayoutRadial(uiLayout *layout) for (item = layout->root->layout->items.first; item; item = item->next) { litem = (uiLayout *)item; if (litem->item.type == ITEM_LAYOUT_RADIAL) { - uiBlockSetCurLayout(layout->root->block, litem); + UI_block_layout_set_current(layout->root->block, litem); return litem; } } @@ -2685,7 +2703,7 @@ uiLayout *uiLayoutRadial(uiLayout *layout) litem->w = layout->w; BLI_addtail(&layout->root->layout->items, litem); - uiBlockSetCurLayout(layout->root->block, litem); + UI_block_layout_set_current(layout->root->block, litem); return litem; } @@ -2693,7 +2711,7 @@ uiLayout *uiLayoutRadial(uiLayout *layout) uiLayout *uiLayoutBox(uiLayout *layout) { - return (uiLayout *)ui_layout_box(layout, ROUNDBOX); + return (uiLayout *)ui_layout_box(layout, UI_BTYPE_ROUNDBOX); } /* Check all buttons defined in this layout, and set any button flagged as UI_BUT_LIST_ITEM as active/selected. @@ -2707,7 +2725,7 @@ void ui_layout_list_set_labels_active(uiLayout *layout) ui_layout_list_set_labels_active((uiLayout *)(&bitem->item)); } else if (bitem->but->flag & UI_BUT_LIST_ITEM) { - uiButSetFlag(bitem->but, UI_SELECT); + UI_but_flag_enable(bitem->but, UI_SELECT); } } } @@ -2715,7 +2733,7 @@ void ui_layout_list_set_labels_active(uiLayout *layout) uiLayout *uiLayoutListBox(uiLayout *layout, uiList *ui_list, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *actptr, PropertyRNA *actprop) { - uiLayoutItemBx *box = ui_layout_box(layout, LISTBOX); + uiLayoutItemBx *box = ui_layout_box(layout, UI_BTYPE_LISTBOX); uiBut *but = box->roundbox; but->custom_data = ui_list; @@ -2747,7 +2765,7 @@ uiLayout *uiLayoutAbsolute(uiLayout *layout, int align) litem->redalert = layout->redalert; BLI_addtail(&layout->items, litem); - uiBlockSetCurLayout(layout->root->block, litem); + UI_block_layout_set_current(layout->root->block, litem); return litem; } @@ -2775,7 +2793,7 @@ uiLayout *uiLayoutOverlap(uiLayout *layout) litem->redalert = layout->redalert; BLI_addtail(&layout->items, litem); - uiBlockSetCurLayout(layout->root->block, litem); + UI_block_layout_set_current(layout->root->block, litem); return litem; } @@ -2797,7 +2815,7 @@ uiLayout *uiLayoutSplit(uiLayout *layout, float percentage, int align) split->percentage = percentage; BLI_addtail(&layout->items, split); - uiBlockSetCurLayout(layout->root->block, &split->litem); + UI_block_layout_set_current(layout->root->block, &split->litem); return &split->litem; } @@ -3052,7 +3070,7 @@ static void ui_item_layout(uiItem *item) static void ui_layout_end(uiBlock *block, uiLayout *layout, int *x, int *y) { if (layout->root->handlefunc) - uiBlockSetHandleFunc(block, layout->root->handlefunc, layout->root->argv); + UI_block_func_handle_set(block, layout->root->handlefunc, layout->root->argv); ui_item_estimate(&layout->item); ui_item_layout(&layout->item); @@ -3085,12 +3103,12 @@ static void ui_layout_add_padding_button(uiLayoutRoot *root) uiLayout *prev_layout = block->curlayout; block->curlayout = root->layout; - uiDefBut(block, SEPR, 0, "", 0, 0, root->padding, root->padding, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_SEPR, 0, "", 0, 0, root->padding, root->padding, NULL, 0.0, 0.0, 0, 0, ""); block->curlayout = prev_layout; } } -uiLayout *uiBlockLayout(uiBlock *block, int dir, int type, int x, int y, int size, int em, int padding, uiStyle *style) +uiLayout *UI_block_layout(uiBlock *block, int dir, int type, int x, int y, int size, int em, int padding, uiStyle *style) { uiLayout *layout; uiLayoutRoot *root; @@ -3145,7 +3163,7 @@ int uiLayoutGetOperatorContext(uiLayout *layout) } -void uiBlockSetCurLayout(uiBlock *block, uiLayout *layout) +void UI_block_layout_set_current(uiBlock *block, uiLayout *layout) { block->curlayout = layout; } @@ -3176,7 +3194,7 @@ void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv) layout->root->argv = argv; } -void uiBlockLayoutResolve(uiBlock *block, int *x, int *y) +void UI_block_layout_resolve(uiBlock *block, int *x, int *y) { uiLayoutRoot *root; @@ -3252,7 +3270,7 @@ static void ui_intro_items(DynStr *ds, ListBase *lb) /* could also use the INT but this is nicer*/ switch (item->type) { case ITEM_BUTTON: BLI_dynstr_append(ds, "'type':'BUTTON', "); break; - case ITEM_LAYOUT_ROW: BLI_dynstr_append(ds, "'type':'ROW', "); break; + case ITEM_LAYOUT_ROW: BLI_dynstr_append(ds, "'type':'UI_BTYPE_ROW', "); break; case ITEM_LAYOUT_COLUMN: BLI_dynstr_append(ds, "'type':'COLUMN', "); break; case ITEM_LAYOUT_COLUMN_FLOW: BLI_dynstr_append(ds, "'type':'COLUMN_FLOW', "); break; case ITEM_LAYOUT_ROW_FLOW: BLI_dynstr_append(ds, "'type':'ROW_FLOW', "); break; @@ -3328,7 +3346,7 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op, /* poll() on this operator may still fail, at the moment there is no nice feedback when this happens * just fails silently */ if (!WM_operator_repeat_check(C, op)) { - uiBlockSetButLock(uiLayoutGetBlock(layout), true, "Operator can't' redo"); + UI_block_lock_set(uiLayoutGetBlock(layout), true, "Operator can't' redo"); /* XXX, could give some nicer feedback or not show redo panel at all? */ uiItemL(layout, IFACE_("* Redo Unsupported *"), ICON_NONE); @@ -3388,9 +3406,9 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op, col = uiLayoutColumn(layout, false); block = uiLayoutGetBlock(col); - but = uiDefIconTextBut(block, BUT, 0, ICON_FILE_REFRESH, IFACE_("Reset"), 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_FILE_REFRESH, IFACE_("Reset"), 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Reset operator defaults")); - uiButSetFunc(but, ui_layout_operator_buts__reset_cb, op, NULL); + UI_but_func_set(but, ui_layout_operator_buts__reset_cb, op, NULL); } #endif @@ -3403,7 +3421,7 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op, for (but = block->buttons.first; but; but = but->next) { /* no undo for buttons for operator redo panels */ - uiButClearFlag(but, UI_BUT_UNDO); + UI_but_flag_disable(but, UI_BUT_UNDO); /* only for popups, see [#36109] */ @@ -3411,8 +3429,8 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op, * - this is used for allowing operators with popups to rename stuff with fewer clicks */ if (is_popup) { - if ((but->rnaprop == op->type->prop) && (but->type == TEX)) { - uiButSetFocusOnEnter(CTX_wm_window(C), but); + if ((but->rnaprop == op->type->prop) && (but->type == UI_BTYPE_TEXT)) { + UI_but_focus_on_enter_event(CTX_wm_window(C), but); } } } @@ -3420,7 +3438,7 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op, } /* this is a bit of a hack but best keep it in one place at least */ -MenuType *uiButGetMenuType(uiBut *but) +MenuType *UI_but_menutype_get(uiBut *but) { if (but->menu_create_func == ui_item_menutype_func) { return (MenuType *)but->poin; diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 817445cc14e..0f430c4f254 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -45,7 +45,6 @@ #include "BKE_global.h" #include "BKE_text.h" /* for UI_OT_reports_to_text */ #include "BKE_report.h" -#include "BKE_paint.h" #include "RNA_access.h" #include "RNA_define.h" @@ -98,7 +97,7 @@ static int copy_data_path_button_poll(bContext *C) char *path; int index; - uiContextActiveProperty(C, &ptr, &prop, &index); + UI_context_active_but_prop_get(C, &ptr, &prop, &index); if (ptr.id.data && ptr.data && prop) { path = RNA_path_from_ID_to_property(&ptr, prop); @@ -120,7 +119,7 @@ static int copy_data_path_button_exec(bContext *C, wmOperator *UNUSED(op)) int index; /* try to create driver using property retrieved from UI */ - uiContextActiveProperty(C, &ptr, &prop, &index); + UI_context_active_but_prop_get(C, &ptr, &prop, &index); if (ptr.id.data && ptr.data && prop) { path = RNA_path_from_ID_to_property(&ptr, prop); @@ -160,7 +159,7 @@ static int operator_button_property_finish(bContext *C, PointerRNA *ptr, Propert RNA_property_update(C, ptr, prop); /* as if we pressed the button */ - uiContextActivePropertyHandle(C); + UI_context_active_but_prop_handle(C); /* Since we don't want to undo _all_ edits to settings, eg window * edits on the screen or on operator settings. @@ -180,7 +179,7 @@ static int reset_default_button_poll(bContext *C) PropertyRNA *prop; int index; - uiContextActiveProperty(C, &ptr, &prop, &index); + UI_context_active_but_prop_get(C, &ptr, &prop, &index); return (ptr.data && prop && RNA_property_editable(&ptr, prop)); } @@ -193,7 +192,7 @@ static int reset_default_button_exec(bContext *C, wmOperator *op) const bool all = RNA_boolean_get(op->ptr, "all"); /* try to reset the nominated setting to its default value */ - uiContextActiveProperty(C, &ptr, &prop, &index); + UI_context_active_but_prop_get(C, &ptr, &prop, &index); /* if there is a valid property that is editable... */ if (ptr.data && prop && RNA_property_editable(&ptr, prop)) { @@ -231,7 +230,7 @@ static int unset_property_button_exec(bContext *C, wmOperator *UNUSED(op)) int index; /* try to unset the nominated property */ - uiContextActiveProperty(C, &ptr, &prop, &index); + UI_context_active_but_prop_get(C, &ptr, &prop, &index); /* if there is a valid property that is editable... */ if (ptr.data && prop && RNA_property_editable(&ptr, prop) && @@ -317,7 +316,7 @@ static bool copy_to_selected_button(bContext *C, bool all, bool poll) int index; /* try to reset the nominated setting to its default value */ - uiContextActiveProperty(C, &ptr, &prop, &index); + UI_context_active_but_prop_get(C, &ptr, &prop, &index); /* if there is a valid property that is editable... */ if (ptr.data && prop) { @@ -595,7 +594,7 @@ static int editsource_text_edit(bContext *C, wmOperator *op, static int editsource_exec(bContext *C, wmOperator *op) { - uiBut *but = uiContextActiveButton(C); + uiBut *but = UI_context_active_but_get(C); if (but) { GHashIterator ghi; @@ -605,7 +604,7 @@ static int editsource_exec(bContext *C, wmOperator *op) int ret; /* needed else the active button does not get tested */ - uiFreeActiveButtons(C, CTX_wm_screen(C)); + UI_screen_free_active_but(C, CTX_wm_screen(C)); // printf("%s: begin\n", __func__); @@ -715,7 +714,7 @@ static void edittranslation_find_po_file(const char *root, const char *uilng, ch static int edittranslation_exec(bContext *C, wmOperator *op) { - uiBut *but = uiContextActiveButton(C); + uiBut *but = UI_context_active_but_get(C); int ret = OPERATOR_CANCELLED; if (but) { @@ -755,7 +754,7 @@ static int edittranslation_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - uiButGetStrInfo(C, but, &but_label, &rna_label, &enum_label, &but_tip, &rna_tip, &enum_tip, + UI_but_string_info_get(C, but, &but_label, &rna_label, &enum_label, &but_tip, &rna_tip, &enum_tip, &rna_struct, &rna_prop, &rna_enum, &rna_ctxt, NULL); WM_operator_properties_create_ptr(&ptr, ot); @@ -877,9 +876,9 @@ static int drop_color_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED( /* find button under mouse, check if it has RNA color property and * if it does copy the data */ - but = ui_but_find_activated(ar); + but = ui_but_find_active_in_region(ar); - if (but && but->type == COLOR && but->rnaprop) { + if (but && but->type == UI_BTYPE_COLOR && but->rnaprop) { const int color_len = RNA_property_array_length(&but->rnapoin, but->rnaprop); BLI_assert(color_len <= 4); @@ -890,13 +889,13 @@ static int drop_color_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED( if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) { if (!gamma) - ui_block_to_display_space_v3(but->block, color); + ui_block_cm_to_display_space_v3(but->block, color); RNA_property_float_set_array(&but->rnapoin, but->rnaprop, color); RNA_property_update(C, &but->rnapoin, but->rnaprop); } else if (RNA_property_subtype(but->rnaprop) == PROP_COLOR) { if (gamma) - ui_block_to_scene_linear_v3(but->block, color); + ui_block_cm_to_scene_linear_v3(but->block, color); RNA_property_float_set_array(&but->rnapoin, but->rnaprop, color); RNA_property_update(C, &but->rnapoin, but->rnaprop); } @@ -932,7 +931,7 @@ static void UI_OT_drop_color(wmOperatorType *ot) /* ********************************************************* */ /* Registration */ -void UI_buttons_operatortypes(void) +void ED_button_operatortypes(void) { WM_operatortype_append(UI_OT_reset_default_theme); WM_operatortype_append(UI_OT_copy_data_path_button); diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 9265ca0d4b9..5ccfa4193e9 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -207,7 +207,7 @@ static void ui_panel_copy_offset(Panel *pa, Panel *papar) */ /* #define UI_USE_PANELTAB */ -Panel *uiPanelFindByType(ARegion *ar, PanelType *pt) +Panel *UI_panel_find_by_type(ARegion *ar, PanelType *pt) { Panel *pa; const char *idname = pt->idname; @@ -233,9 +233,9 @@ Panel *uiPanelFindByType(ARegion *ar, PanelType *pt) } /** - * \note \a pa should be return value from #uiPanelFindByType and can be NULL. + * \note \a pa should be return value from #UI_panel_find_by_type and can be NULL. */ -Panel *uiBeginPanel(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, Panel *pa, bool *r_open) +Panel *UI_panel_begin(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, Panel *pa, bool *r_open) { Panel *palast, *panext; const char *drawname = CTX_IFACE_(pt->translation_context, pt->label); @@ -336,7 +336,7 @@ Panel *uiBeginPanel(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, Pan return pa; } -void uiEndPanel(uiBlock *block, int width, int height) +void UI_panel_end(uiBlock *block, int width, int height) { Panel *pa = block->panel; @@ -363,12 +363,12 @@ void uiEndPanel(uiBlock *block, int width, int height) static void ui_offset_panel_block(uiBlock *block) { - uiStyle *style = UI_GetStyleDraw(); + uiStyle *style = UI_style_get_dpi(); uiBut *but; int ofsy; /* compute bounds and offset */ - ui_bounds_block(block); + ui_block_bounds_calc(block); ofsy = block->panel->sizey - style->panelspace; @@ -401,7 +401,7 @@ static void uiPanelPop(uiBlock *UNUSED(block)) #endif /* triangle 'icon' for panel header */ -void UI_DrawTriIcon(float x, float y, char dir) +void UI_draw_icon_tri(float x, float y, char dir) { float f3 = 0.15 * U.widget_unit; float f5 = 0.25 * U.widget_unit; @@ -542,14 +542,14 @@ static void ui_draw_aligned_panel_header(uiStyle *style, uiBlock *block, const r if (dir == 'h') { hrect.xmin = rect->xmin + pnl_icons; hrect.ymin += 2.0f / block->aspect; - uiStyleFontDraw(&style->paneltitle, &hrect, activename); + UI_fontstyle_draw(&style->paneltitle, &hrect, activename); } else { /* ignore 'pnl_icons', otherwise the text gets offset horizontally * + 0.001f to avoid flirting with float inaccuracy */ hrect.xmin = rect->xmin + (PNL_ICON + 5) / block->aspect + 0.001f; - uiStyleFontDrawRotated(&style->paneltitle, &hrect, activename); + UI_fontstyle_draw_rotated(&style->paneltitle, &hrect, activename); } } @@ -641,11 +641,11 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con else { /* in some occasions, draw a border */ if (panel->flag & PNL_SELECT) { - if (panel->control & UI_PNL_SOLID) uiSetRoundBox(UI_CNR_ALL); - else uiSetRoundBox(UI_CNR_NONE); + if (panel->control & UI_PNL_SOLID) UI_draw_roundbox_corner_set(UI_CNR_ALL); + else UI_draw_roundbox_corner_set(UI_CNR_NONE); UI_ThemeColorShade(TH_BACK, -120); - uiRoundRect(0.5f + rect->xmin, 0.5f + rect->ymin, 0.5f + rect->xmax, 0.5f + headrect.ymax + 1, 8); + UI_draw_roundbox_unfilled(0.5f + rect->xmin, 0.5f + rect->ymin, 0.5f + rect->xmax, 0.5f + headrect.ymax + 1, 8); } /* panel backdrop */ @@ -938,7 +938,7 @@ static void ui_do_animate(const bContext *C, Panel *panel) } } -void uiBeginPanels(const bContext *UNUSED(C), ARegion *ar) +void UI_panels_begin(const bContext *UNUSED(C), ARegion *ar) { Panel *pa; @@ -953,7 +953,7 @@ void uiBeginPanels(const bContext *UNUSED(C), ARegion *ar) } /* only draws blocks with panels */ -void uiEndPanels(const bContext *C, ARegion *ar, int *x, int *y) +void UI_panels_end(const bContext *C, ARegion *ar, int *x, int *y) { ScrArea *sa = CTX_wm_area(C); uiBlock *block; @@ -1012,7 +1012,7 @@ void uiEndPanels(const bContext *C, ARegion *ar, int *x, int *y) ui_panels_size(sa, ar, x, y); } -void uiDrawPanels(const bContext *C, ARegion *ar) +void UI_panels_draw(const bContext *C, ARegion *ar) { uiBlock *block; @@ -1021,18 +1021,18 @@ void uiDrawPanels(const bContext *C, ARegion *ar) /* draw panels, selected on top */ for (block = ar->uiblocks.first; block; block = block->next) { if (block->active && block->panel && !(block->panel->flag & PNL_SELECT)) { - uiDrawBlock(C, block); + UI_block_draw(C, block); } } for (block = ar->uiblocks.first; block; block = block->next) { if (block->active && block->panel && (block->panel->flag & PNL_SELECT)) { - uiDrawBlock(C, block); + UI_block_draw(C, block); } } } -void uiScalePanels(ARegion *ar, float new_width) +void UI_panels_scale(ARegion *ar, float new_width) { uiBlock *block; uiBut *but; @@ -1226,7 +1226,7 @@ static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, in bool UI_panel_category_is_visible(ARegion *ar) { - /* more then one */ + /* more than one */ return ar->panels_category.first && ar->panels_category.first != ar->panels_category.last; } @@ -1327,7 +1327,7 @@ void UI_panel_category_clear_all(ARegion *ar) BLI_freelistN(&ar->panels_category); } -/* based on uiDrawBox, check on making a version which allows us to skip some sides */ +/* based on UI_draw_roundbox_gl_mode, check on making a version which allows us to skip some sides */ static void ui_panel_category_draw_tab(int mode, float minx, float miny, float maxx, float maxy, float rad, int roundboxtype, const bool use_highlight, const bool use_shadow, @@ -1420,7 +1420,7 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active) /* no tab outlines for */ // #define USE_FLAT_INACTIVE View2D *v2d = &ar->v2d; - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_style_get(); const uiFontStyle *fstyle = &style->widget; const int fontid = fstyle->uifont_id; short fstyle_points = fstyle->points; @@ -1487,7 +1487,7 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active) BLF_enable(fontid, BLF_ROTATION); BLF_rotation(fontid, M_PI / 2); - //uiStyleFontSet(&style->widget); + //UI_fontstyle_set(&style->widget); ui_fontscale(&fstyle_points, aspect / (U.pixelsize * 1.1f)); BLF_size(fontid, fstyle_points, U.dpi); @@ -1768,7 +1768,7 @@ int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar) } /* on active button, do not handle panels */ - if (ui_button_is_active(ar)) + if (ui_but_is_active(ar)) continue; if (inside || inside_header) { diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 353106db8df..0ec59e4e4cd 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -27,8 +27,6 @@ * \ingroup edinterface */ - - #include <stdarg.h> #include <stdlib.h> #include <string.h> @@ -54,7 +52,6 @@ #include "WM_types.h" #include "wm_draw.h" #include "wm_subwindow.h" -#include "wm_window.h" #include "RNA_access.h" @@ -109,7 +106,7 @@ static int rna_property_enum_step(const bContext *C, PointerRNA *ptr, PropertyRN return value; } -int ui_step_name_menu(uiBut *but, int direction) +int ui_but_menu_step(uiBut *but, int direction) { /* currenly only RNA buttons */ if ((but->rnaprop == NULL) || (RNA_property_type(but->rnaprop) != PROP_ENUM)) { @@ -122,7 +119,7 @@ int ui_step_name_menu(uiBut *but, int direction) /******************** Creating Temporary regions ******************/ -static ARegion *ui_add_temporary_region(bScreen *sc) +static ARegion *ui_region_temp_add(bScreen *sc) { ARegion *ar; @@ -135,7 +132,7 @@ static ARegion *ui_add_temporary_region(bScreen *sc) return ar; } -static void ui_remove_temporary_region(bContext *C, bScreen *sc, ARegion *ar) +static void ui_region_temp_remove(bContext *C, bScreen *sc, ARegion *ar) { wmWindow *win = CTX_wm_window(C); if (win) @@ -225,7 +222,7 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar) wmOrtho2_region_ui(ar); /* draw background */ - ui_draw_tooltip_background(UI_GetStyle(), NULL, &bbox); + ui_draw_tooltip_background(UI_style_get(), NULL, &bbox); /* set background_color */ rgb_uchar_to_float(background_color, (const unsigned char *)theme->inner); @@ -268,15 +265,15 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar) fstyle_header.shadx = fstyle_header.shady = 0; fstyle_header.shadowalpha = 1.0f; - uiStyleFontSet(&fstyle_header); + UI_fontstyle_set(&fstyle_header); glColor3fv(tip_colors[UI_TIP_LC_MAIN]); - uiStyleFontDraw(&fstyle_header, &bbox, data->header); + UI_fontstyle_draw(&fstyle_header, &bbox, data->header); xofs = BLF_width(fstyle_header.uifont_id, data->header, sizeof(data->header)); bbox.xmin += xofs; glColor3fv(tip_colors[UI_TIP_LC_ACTIVE]); - uiStyleFontDraw(&data->fstyle, &bbox, data->active_info); + UI_fontstyle_draw(&data->fstyle, &bbox, data->active_info); bbox.xmin -= xofs; } @@ -284,18 +281,18 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar) uiFontStyle fstyle_mono = data->fstyle; fstyle_mono.uifont_id = blf_mono_font; - uiStyleFontSet(&fstyle_mono); + UI_fontstyle_set(&fstyle_mono); /* XXX, needed because we dont have mono in 'U.uifonts' */ BLF_size(fstyle_mono.uifont_id, fstyle_mono.points * U.pixelsize, U.dpi); glColor3fv(tip_colors[data->format[i].color_id]); - uiStyleFontDraw(&fstyle_mono, &bbox, data->lines[i]); + UI_fontstyle_draw(&fstyle_mono, &bbox, data->lines[i]); } else { BLI_assert(data->format[i].style == UI_TIP_STYLE_NORMAL); /* draw remaining data */ - uiStyleFontSet(&data->fstyle); + UI_fontstyle_set(&data->fstyle); glColor3fv(tip_colors[data->format[i].color_id]); - uiStyleFontDraw(&data->fstyle, &bbox, data->lines[i]); + UI_fontstyle_draw(&data->fstyle, &bbox, data->lines[i]); } if ((i + 1 != data->totline) && data->format[i + 1].is_pad) { bbox.ymax -= data->lineh * UI_TIP_PAD_FAC; @@ -324,7 +321,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) { const float pad_px = UI_TIP_PADDING; wmWindow *win = CTX_wm_window(C); - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_style_get(); static ARegionType type; ARegion *ar; uiTooltipData *data; @@ -351,7 +348,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) /* create tooltip data */ data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData"); - uiButGetStrInfo(C, but, &but_tip, &enum_label, &enum_tip, &op_keymap, &prop_keymap, &rna_struct, &rna_prop, NULL); + UI_but_string_info_get(C, but, &but_tip, &enum_label, &enum_tip, &op_keymap, &prop_keymap, &rna_struct, &rna_prop, NULL); /* Tip */ if (but_tip.strinfo) { @@ -364,8 +361,9 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) data->totline++; /* special case enum rna buttons */ - if ((but->type & ROW) && but->rnaprop && RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG) { - BLI_strncpy(data->lines[data->totline], IFACE_("(Shift-click to select multiple)"), sizeof(data->lines[0])); + if ((but->type & UI_BTYPE_ROW) && but->rnaprop && RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG) { + BLI_strncpy(data->lines[data->totline], IFACE_("(Shift-Click/Drag to select multiple)"), + sizeof(data->lines[0])); data->format[data->totline].color_id = UI_TIP_LC_NORMAL; data->totline++; @@ -396,11 +394,11 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) data->totline++; } - if (ELEM(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) { + if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) { /* better not show the value of a password */ if ((but->rnaprop && (RNA_property_subtype(but->rnaprop) == PROP_PASSWORD)) == 0) { /* full string */ - ui_get_but_string(but, buf, sizeof(buf)); + ui_but_string_get(but, buf, sizeof(buf)); if (buf[0]) { BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Value: %s"), buf); data->format[data->totline].is_pad = true; @@ -411,7 +409,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) } if (but->rnaprop) { - int unit_type = uiButGetUnitType(but); + int unit_type = UI_but_unit_type_get(but); if (unit_type == PROP_UNIT_ROTATION) { if (RNA_property_type(but->rnaprop) == PROP_FLOAT) { @@ -445,7 +443,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) else if (but->optype) { PointerRNA *opptr; char *str; - opptr = uiButGetOperatorPtrRNA(but); /* allocated when needed, the button owns it */ + opptr = UI_but_operator_ptr_get(but); /* allocated when needed, the button owns it */ /* so the context is passed to itemf functions (some py itemf functions use it) */ WM_operator_properties_sanitize(opptr, false); @@ -556,7 +554,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) } /* create area region */ - ar = ui_add_temporary_region(CTX_wm_screen(C)); + ar = ui_region_temp_add(CTX_wm_screen(C)); memset(&type, 0, sizeof(ARegionType)); type.draw = ui_tooltip_region_draw_cb; @@ -568,7 +566,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) data->fstyle = style->widget; /* copy struct */ ui_fontscale(&data->fstyle.points, aspect); - uiStyleFontSet(&data->fstyle); + UI_fontstyle_set(&data->fstyle); /* these defines tweaked depending on font */ #define TIP_BORDER_X (16.0f / aspect) @@ -668,18 +666,18 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) /* widget rect, in region coords */ { - int width = UI_ThemeMenuShadowWidth(); + const int margin = UI_POPUP_MARGIN; - data->bbox.xmin = width; - data->bbox.xmax = BLI_rcti_size_x(&rect_i) - width; - data->bbox.ymin = width; + data->bbox.xmin = margin; + data->bbox.xmax = BLI_rcti_size_x(&rect_i) - margin; + data->bbox.ymin = margin; data->bbox.ymax = BLI_rcti_size_y(&rect_i); /* region bigger for shadow */ - ar->winrct.xmin = rect_i.xmin - width; - ar->winrct.xmax = rect_i.xmax + width; - ar->winrct.ymin = rect_i.ymin - width; - ar->winrct.ymax = rect_i.ymax + width; + ar->winrct.xmin = rect_i.xmin - margin; + ar->winrct.xmax = rect_i.xmax + margin; + ar->winrct.ymin = rect_i.ymin - margin; + ar->winrct.ymax = rect_i.ymax + margin; } /* adds subwindow */ @@ -693,7 +691,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) void ui_tooltip_free(bContext *C, ARegion *ar) { - ui_remove_temporary_region(C, CTX_wm_screen(C), ar); + ui_region_temp_remove(C, CTX_wm_screen(C), ar); } @@ -728,11 +726,11 @@ typedef struct uiSearchboxData { /* exported for use by search callbacks */ /* returns zero if nothing to add */ -bool uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int iconid) +bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int iconid) { /* hijack for autocomplete */ if (items->autocpl) { - autocomplete_do_name(items->autocpl, name); + UI_autocomplete_update_name(items->autocpl, name); return true; } @@ -767,17 +765,17 @@ bool uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int ico return true; } -int uiSearchBoxHeight(void) +int UI_searchbox_size_y(void) { return SEARCH_ITEMS * UI_UNIT_Y + 2 * MENU_TOP; } -int uiSearchBoxWidth(void) +int UI_searchbox_size_x(void) { return 12 * UI_UNIT_X; } -int uiSearchItemFindIndex(uiSearchItems *items, const char *name) +int UI_search_items_find_index(uiSearchItems *items, const char *name) { int i; for (i = 0; i < items->totitem; i++) { @@ -817,7 +815,7 @@ static void ui_searchbox_select(bContext *C, ARegion *ar, uiBut *but, int step) } else { /* only let users step into an 'unset' state for unlink buttons */ - data->active = (but->type == SEARCH_MENU_UNLINK) ? -1 : 0; + data->active = (but->type == UI_BTYPE_SEARCH_MENU_UNLINK) ? -1 : 0; } } @@ -860,7 +858,7 @@ static void ui_searchbox_butrect(rcti *r_rect, uiSearchboxData *data, int itemnr int ui_searchbox_find_index(ARegion *ar, const char *name) { uiSearchboxData *data = ar->regiondata; - return uiSearchItemFindIndex(&data->items, name); + return UI_search_items_find_index(&data->items, name); } /* x and y in screencoords */ @@ -888,7 +886,7 @@ bool ui_searchbox_apply(uiBut *but, ARegion *ar) return true; } - else if (but->type == SEARCH_MENU_UNLINK) { + else if (but->type == UI_BTYPE_SEARCH_MENU_UNLINK) { /* It is valid for _UNLINK flavor to have no active element (it's a valid way to unlink). */ but->editstr[0] = '\0'; @@ -1014,11 +1012,11 @@ int ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str) int match = AUTOCOMPLETE_NO_MATCH; if (str[0]) { - data->items.autocpl = autocomplete_begin(str, ui_get_but_string_max_length(but)); + data->items.autocpl = UI_autocomplete_begin(str, ui_but_string_get_max_length(but)); but->search_func(C, but->search_arg, but->editstr, &data->items); - match = autocomplete_end(data->items.autocpl, str); + match = UI_autocomplete_end(data->items.autocpl, str); data->items.autocpl = NULL; } @@ -1118,7 +1116,7 @@ static void ui_searchbox_region_free_cb(ARegion *ar) ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) { wmWindow *win = CTX_wm_window(C); - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_style_get(); static ARegionType type; ARegion *ar; uiSearchboxData *data; @@ -1129,7 +1127,7 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) int i; /* create area region */ - ar = ui_add_temporary_region(CTX_wm_screen(C)); + ar = ui_region_temp_add(CTX_wm_screen(C)); memset(&type, 0, sizeof(ARegionType)); type.draw = ui_searchbox_region_draw_cb; @@ -1144,7 +1142,7 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) data->fstyle = style->widget; /* copy struct */ data->fstyle.align = UI_STYLE_TEXT_CENTER; ui_fontscale(&data->fstyle.points, aspect); - uiStyleFontSet(&data->fstyle); + UI_fontstyle_set(&data->fstyle); ar->regiondata = data; @@ -1166,15 +1164,15 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) /* compute position */ if (but->block->flag & UI_BLOCK_SEARCH_MENU) { - int width = UI_ThemeMenuShadowWidth(); + const int margin = UI_POPUP_MARGIN; /* this case is search menu inside other menu */ /* we copy region size */ ar->winrct = butregion->winrct; /* widget rect, in region coords */ - data->bbox.xmin = width; - data->bbox.xmax = BLI_rcti_size_x(&ar->winrct) - width; + data->bbox.xmin = margin; + data->bbox.xmax = BLI_rcti_size_x(&ar->winrct) - margin; /* Do not use shadow width for height, gives insane margin with big shadows, and issue T41548 with small ones */ data->bbox.ymin = 8 * UI_DPI_FAC; data->bbox.ymax = BLI_rcti_size_y(&ar->winrct) - 8 * UI_DPI_FAC; @@ -1188,13 +1186,13 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) } } else { - const int searchbox_width = uiSearchBoxWidth(); - const int shadow_width = UI_ThemeMenuShadowWidth(); + const int searchbox_width = UI_searchbox_size_x(); + const int margin = UI_POPUP_MARGIN; rect_fl.xmin = but->rect.xmin - 5; /* align text with button */ rect_fl.xmax = but->rect.xmax + 5; /* symmetrical */ rect_fl.ymax = but->rect.ymin; - rect_fl.ymin = rect_fl.ymax - uiSearchBoxHeight(); + rect_fl.ymin = rect_fl.ymax - UI_searchbox_size_y(); ofsx = (but->block->panel) ? but->block->panel->ofsx : 0; ofsy = (but->block->panel) ? but->block->panel->ofsy : 0; @@ -1244,15 +1242,15 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) } /* widget rect, in region coords */ - data->bbox.xmin = shadow_width; - data->bbox.xmax = BLI_rcti_size_x(&rect_i) + shadow_width; - data->bbox.ymin = shadow_width; - data->bbox.ymax = BLI_rcti_size_y(&rect_i) + shadow_width; + data->bbox.xmin = margin; + data->bbox.xmax = BLI_rcti_size_x(&rect_i) + margin; + data->bbox.ymin = margin; + data->bbox.ymax = BLI_rcti_size_y(&rect_i) + margin; /* region bigger for shadow */ - ar->winrct.xmin = rect_i.xmin - shadow_width; - ar->winrct.xmax = rect_i.xmax + shadow_width; - ar->winrct.ymin = rect_i.ymin - shadow_width; + ar->winrct.xmin = rect_i.xmin - margin; + ar->winrct.xmax = rect_i.xmax + margin; + ar->winrct.ymin = rect_i.ymin - margin; ar->winrct.ymax = rect_i.ymax; } @@ -1282,12 +1280,12 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) void ui_searchbox_free(bContext *C, ARegion *ar) { - ui_remove_temporary_region(C, CTX_wm_screen(C), ar); + ui_region_temp_remove(C, CTX_wm_screen(C), ar); } /* sets red alert if button holds a string it can't find */ /* XXX weak: search_func adds all partial matches... */ -void ui_but_search_test(uiBut *but) +void ui_but_search_refresh(uiBut *but) { uiSearchItems *items; int x1; @@ -1311,11 +1309,11 @@ void ui_but_search_test(uiBut *but) /* only redalert when we are sure of it, this can miss cases when >10 matches */ if (items->totitem == 0) { - uiButSetFlag(but, UI_BUT_REDALERT); + UI_but_flag_enable(but, UI_BUT_REDALERT); } else if (items->more == 0) { - if (uiSearchItemFindIndex(items, but->drawstr) == -1) { - uiButSetFlag(but, UI_BUT_REDALERT); + if (UI_search_items_find_index(items, but->drawstr) == -1) { + UI_but_flag_enable(but, UI_BUT_REDALERT); } } @@ -1343,7 +1341,7 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, ui_block_to_window_rctf(butregion, but->block, &butrct, &but->rect); /* widget_roundbox_set has this correction too, keep in sync */ - if (but->type != PULLDOWN) { + if (but->type != UI_BTYPE_PULLDOWN) { if (but->drawflag & UI_BUT_ALIGN_TOP) butrct.ymax += U.pixelsize; if (but->drawflag & UI_BUT_ALIGN_LEFT) @@ -1377,7 +1375,7 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, /* aspect /= (float)xsize;*/ /*UNUSED*/ { - int left = 0, right = 0, top = 0, down = 0; + bool left = 0, right = 0, top = 0, down = 0; int winx, winy; // int offscreen; @@ -1385,8 +1383,12 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, winy = WM_window_pixels_y(window); // wm_window_get_size(window, &winx, &winy); - if (block->direction & UI_CENTER) center = ysize / 2; - else center = 0; + if (block->direction & UI_DIR_CENTER_Y) { + center = ysize / 2; + } + else { + center = 0; + } /* check if there's space at all */ if (butrct.xmin - xsize > 0.0f) left = 1; @@ -1401,69 +1403,65 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, down = 1; } - dir1 = block->direction & UI_DIRECTION; + dir1 = (block->direction & UI_DIR_ALL); /* secundary directions */ - if (dir1 & (UI_TOP | UI_DOWN)) { - if (dir1 & UI_LEFT) dir2 = UI_LEFT; - else if (dir1 & UI_RIGHT) dir2 = UI_RIGHT; - dir1 &= (UI_TOP | UI_DOWN); + if (dir1 & (UI_DIR_UP | UI_DIR_DOWN)) { + if (dir1 & UI_DIR_LEFT) dir2 = UI_DIR_LEFT; + else if (dir1 & UI_DIR_RIGHT) dir2 = UI_DIR_RIGHT; + dir1 &= (UI_DIR_UP | UI_DIR_DOWN); } - if ((dir2 == 0) && (dir1 == UI_LEFT || dir1 == UI_RIGHT)) dir2 = UI_DOWN; - if ((dir2 == 0) && (dir1 == UI_TOP || dir1 == UI_DOWN)) dir2 = UI_LEFT; + if ((dir2 == 0) && (dir1 == UI_DIR_LEFT || dir1 == UI_DIR_RIGHT)) dir2 = UI_DIR_DOWN; + if ((dir2 == 0) && (dir1 == UI_DIR_UP || dir1 == UI_DIR_DOWN)) dir2 = UI_DIR_LEFT; /* no space at all? don't change */ if (left || right) { - if (dir1 == UI_LEFT && left == 0) dir1 = UI_RIGHT; - if (dir1 == UI_RIGHT && right == 0) dir1 = UI_LEFT; + if (dir1 == UI_DIR_LEFT && left == 0) dir1 = UI_DIR_RIGHT; + if (dir1 == UI_DIR_RIGHT && right == 0) dir1 = UI_DIR_LEFT; /* this is aligning, not append! */ - if (dir2 == UI_LEFT && right == 0) dir2 = UI_RIGHT; - if (dir2 == UI_RIGHT && left == 0) dir2 = UI_LEFT; + if (dir2 == UI_DIR_LEFT && right == 0) dir2 = UI_DIR_RIGHT; + if (dir2 == UI_DIR_RIGHT && left == 0) dir2 = UI_DIR_LEFT; } if (down || top) { - if (dir1 == UI_TOP && top == 0) dir1 = UI_DOWN; - if (dir1 == UI_DOWN && down == 0) dir1 = UI_TOP; - if (dir2 == UI_TOP && top == 0) dir2 = UI_DOWN; - if (dir2 == UI_DOWN && down == 0) dir2 = UI_TOP; + if (dir1 == UI_DIR_UP && top == 0) dir1 = UI_DIR_DOWN; + if (dir1 == UI_DIR_DOWN && down == 0) dir1 = UI_DIR_UP; + if (dir2 == UI_DIR_UP && top == 0) dir2 = UI_DIR_DOWN; + if (dir2 == UI_DIR_DOWN && down == 0) dir2 = UI_DIR_UP; } - if (dir1 == UI_LEFT) { + if (dir1 == UI_DIR_LEFT) { xof = butrct.xmin - block->rect.xmax; - if (dir2 == UI_TOP) yof = butrct.ymin - block->rect.ymin - center - MENU_PADDING; - else yof = butrct.ymax - block->rect.ymax + center + MENU_PADDING; + if (dir2 == UI_DIR_UP) yof = butrct.ymin - block->rect.ymin - center - MENU_PADDING; + else yof = butrct.ymax - block->rect.ymax + center + MENU_PADDING; } - else if (dir1 == UI_RIGHT) { + else if (dir1 == UI_DIR_RIGHT) { xof = butrct.xmax - block->rect.xmin; - if (dir2 == UI_TOP) yof = butrct.ymin - block->rect.ymin - center - MENU_PADDING; - else yof = butrct.ymax - block->rect.ymax + center + MENU_PADDING; + if (dir2 == UI_DIR_UP) yof = butrct.ymin - block->rect.ymin - center - MENU_PADDING; + else yof = butrct.ymax - block->rect.ymax + center + MENU_PADDING; } - else if (dir1 == UI_TOP) { + else if (dir1 == UI_DIR_UP) { yof = butrct.ymax - block->rect.ymin; - if (dir2 == UI_RIGHT) xof = butrct.xmax - block->rect.xmax; - else xof = butrct.xmin - block->rect.xmin; + if (dir2 == UI_DIR_RIGHT) xof = butrct.xmax - block->rect.xmax; + else xof = butrct.xmin - block->rect.xmin; /* changed direction? */ if ((dir1 & block->direction) == 0) { - if (block->direction & UI_SHIFT_FLIPPED) - xof += dir2 == UI_LEFT ? 25 : -25; - uiBlockFlipOrder(block); + UI_block_order_flip(block); } } - else if (dir1 == UI_DOWN) { + else if (dir1 == UI_DIR_DOWN) { yof = butrct.ymin - block->rect.ymax; - if (dir2 == UI_RIGHT) xof = butrct.xmax - block->rect.xmax; - else xof = butrct.xmin - block->rect.xmin; + if (dir2 == UI_DIR_RIGHT) xof = butrct.xmax - block->rect.xmax; + else xof = butrct.xmin - block->rect.xmin; /* changed direction? */ if ((dir1 & block->direction) == 0) { - if (block->direction & UI_SHIFT_FLIPPED) - xof += dir2 == UI_LEFT ? 25 : -25; - uiBlockFlipOrder(block); + UI_block_order_flip(block); } } /* and now we handle the exception; no space below or to top */ if (top == 0 && down == 0) { - if (dir1 == UI_LEFT || dir1 == UI_RIGHT) { + if (dir1 == UI_DIR_LEFT || dir1 == UI_DIR_RIGHT) { /* align with bottom of screen */ // yof = ysize; (not with menu scrolls) } @@ -1471,7 +1469,7 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, /* or no space left or right */ if (left == 0 && right == 0) { - if (dir1 == UI_TOP || dir1 == UI_DOWN) { + if (dir1 == UI_DIR_UP || dir1 == UI_DIR_DOWN) { /* align with left size of screen */ xof = -block->rect.xmin + 5; } @@ -1493,8 +1491,8 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, BLI_rctf_translate(&bt->rect, xof, yof); - /* ui_check_but recalculates drawstring size in pixels */ - ui_check_but(bt); + /* ui_but_update recalculates drawstring size in pixels */ + ui_but_update(bt); } BLI_rctf_translate(&block->rect, xof, yof); @@ -1522,8 +1520,8 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, /* exception for switched pulldowns... */ if (dir1 && (dir1 & block->direction) == 0) { - if (dir2 == UI_RIGHT) block->safety.xmax = block->rect.xmax + 3; - if (dir2 == UI_LEFT) block->safety.xmin = block->rect.xmin - 3; + if (dir2 == UI_DIR_RIGHT) block->safety.xmax = block->rect.xmax + 3; + if (dir2 == UI_DIR_LEFT) block->safety.xmin = block->rect.xmin - 3; } block->direction = dir1; } @@ -1551,7 +1549,7 @@ static void ui_block_region_draw(const bContext *C, ARegion *ar) } for (block = ar->uiblocks.first; block; block = block->next) - uiDrawBlock(C, block); + UI_block_draw(C, block); } static void ui_popup_block_clip(wmWindow *window, uiBlock *block) @@ -1633,7 +1631,7 @@ void ui_popup_block_scrolltest(uiBlock *block) static void ui_popup_block_remove(bContext *C, uiPopupBlockHandle *handle) { - ui_remove_temporary_region(C, CTX_wm_screen(C), handle->region); + ui_region_temp_remove(C, CTX_wm_screen(C), handle->region); if (handle->scrolltimer) WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), handle->scrolltimer); @@ -1646,7 +1644,7 @@ uiBlock *ui_popup_block_refresh( bContext *C, uiPopupBlockHandle *handle, ARegion *butregion, uiBut *but) { - const int width = UI_ThemeMenuShadowWidth(); + const int margin = UI_POPUP_MARGIN; wmWindow *window = CTX_wm_window(C); ARegion *ar = handle->region; @@ -1667,7 +1665,7 @@ uiBlock *ui_popup_block_refresh( else block = handle_create_func(C, handle, arg); - /* callbacks _must_ leave this for us, otherwise we can't call uiBlockUpdateFromOld */ + /* callbacks _must_ leave this for us, otherwise we can't call UI_block_update_from_old */ BLI_assert(!block->endblock); /* ensure we don't use mouse coords here! */ @@ -1685,9 +1683,9 @@ uiBlock *ui_popup_block_refresh( ar->regiondata = handle; - /* set UI_BLOCK_NUMSELECT before uiEndBlock() so we get alphanumeric keys assigned */ + /* set UI_BLOCK_NUMSELECT before UI_block_end() so we get alphanumeric keys assigned */ if (but) { - if (but->type == PULLDOWN) { + if (but->type == UI_BTYPE_PULLDOWN) { block->flag |= UI_BLOCK_NUMSELECT; } } @@ -1701,7 +1699,7 @@ uiBlock *ui_popup_block_refresh( block->oldblock = NULL; if (!block->endblock) - uiEndBlock_ex(C, block, handle->popup_create_vars.event_xy); + UI_block_end_ex(C, block, handle->popup_create_vars.event_xy); /* if this is being created from a button */ if (but) { @@ -1756,7 +1754,7 @@ uiBlock *ui_popup_block_refresh( ar->winrct.ymin = 0; ar->winrct.ymax = winy; - ui_block_calculate_pie_segment(block, block->pie_data.pie_center_init); + ui_block_calc_pie_segment(block, block->pie_data.pie_center_init); /* lastly set the buttons at the center of the pie menu, ready for animation */ if (U.pie_animation_timeout > 0) { @@ -1773,9 +1771,9 @@ uiBlock *ui_popup_block_refresh( /* the block and buttons were positioned in window space as in 2.4x, now * these menu blocks are regions so we bring it back to region space. * additionally we add some padding for the menu shadow or rounded menus */ - ar->winrct.xmin = block->rect.xmin - width; - ar->winrct.xmax = block->rect.xmax + width; - ar->winrct.ymin = block->rect.ymin - width; + ar->winrct.xmin = block->rect.xmin - margin; + ar->winrct.xmax = block->rect.xmax + margin; + ar->winrct.ymin = block->rect.ymin - margin; ar->winrct.ymax = block->rect.ymax + MENU_TOP; ui_block_translate(block, -ar->winrct.xmin, -ar->winrct.ymin); @@ -1783,8 +1781,8 @@ uiBlock *ui_popup_block_refresh( if (block_old) { block->oldblock = block_old; - uiBlockUpdateFromOld(C, block); - uiFreeInactiveBlocks(C, &ar->uiblocks); + UI_block_update_from_old(C, block); + UI_blocklist_free_inactive(C, &ar->uiblocks); } /* checks which buttons are visible, sets flags to prevent draw (do after region init) */ @@ -1835,7 +1833,7 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut copy_v2_v2_int(handle->popup_create_vars.event_xy, &window->eventstate->x); /* create area region */ - ar = ui_add_temporary_region(CTX_wm_screen(C)); + ar = ui_region_temp_add(CTX_wm_screen(C)); handle->region = ar; memset(&type, 0, sizeof(ARegionType)); @@ -1843,7 +1841,7 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut type.regionid = RGN_TYPE_TEMPORARY; ar->type = &type; - UI_add_region_handlers(&ar->handlers); + UI_region_handlers_add(&ar->handlers); block = ui_popup_block_refresh(C, handle, butregion, but); handle = block->handle; @@ -1875,21 +1873,23 @@ static void ui_warp_pointer(int x, int y) /********************* Color Button ****************/ /* for picker, while editing hsv */ -void ui_set_but_hsv(uiBut *but) +void ui_but_hsv_set(uiBut *but) { float col[3]; - const float *hsv = ui_block_hsv_get(but->block); - + ColorPicker *cpicker = but->custom_data; + float *hsv = cpicker->color_data; + ui_color_picker_to_rgb_v(hsv, col); - ui_set_but_vectorf(but, col); + ui_but_v3_set(but, col); } -/* also used by small picker, be careful with name checks below... */ -static void ui_update_block_buts_rgb(uiBlock *block, const float rgb[3], bool is_display_space) +/* Updates all buttons who share the same color picker as the one passed + * also used by small picker, be careful with name checks below... */ +static void ui_update_color_picker_buts_rgb(uiBlock *block, ColorPicker *cpicker, const float rgb[3], bool is_display_space) { uiBut *bt; - float *hsv = ui_block_hsv_get(block); + float *hsv = cpicker->color_data; struct ColorManagedDisplay *display = NULL; /* this is to keep the H and S value when V is equal to zero * and we are working in HSV mode, of course! @@ -1902,18 +1902,21 @@ static void ui_update_block_buts_rgb(uiBlock *block, const float rgb[3], bool is float rgb_display[3]; copy_v3_v3(rgb_display, rgb); - ui_block_to_display_space_v3(block, rgb_display); + ui_block_cm_to_display_space_v3(block, rgb_display); ui_rgb_to_color_picker_compat_v(rgb_display, hsv); } if (block->color_profile) - display = ui_block_display_get(block); + display = ui_block_cm_display_get(block); /* this updates button strings, is hackish... but button pointers are on stack of caller function */ for (bt = block->buttons.first; bt; bt = bt->next) { + if (bt->custom_data != cpicker) + continue; + if (bt->rnaprop) { - ui_set_but_vectorf(bt, rgb); + ui_but_v3_set(bt, rgb); } else if (strcmp(bt->str, "Hex: ") == 0) { @@ -1942,33 +1945,33 @@ static void ui_update_block_buts_rgb(uiBlock *block, const float rgb[3], bool is } else if (bt->str[1] == ' ') { if (bt->str[0] == 'R') { - ui_set_but_val(bt, rgb[0]); + ui_but_value_set(bt, rgb[0]); } else if (bt->str[0] == 'G') { - ui_set_but_val(bt, rgb[1]); + ui_but_value_set(bt, rgb[1]); } else if (bt->str[0] == 'B') { - ui_set_but_val(bt, rgb[2]); + ui_but_value_set(bt, rgb[2]); } else if (bt->str[0] == 'H') { - ui_set_but_val(bt, hsv[0]); + ui_but_value_set(bt, hsv[0]); } else if (bt->str[0] == 'S') { - ui_set_but_val(bt, hsv[1]); + ui_but_value_set(bt, hsv[1]); } else if (bt->str[0] == 'V') { - ui_set_but_val(bt, hsv[2]); + ui_but_value_set(bt, hsv[2]); } else if (bt->str[0] == 'L') { - ui_set_but_val(bt, hsv[2]); + ui_but_value_set(bt, hsv[2]); } } - ui_check_but(bt); + ui_but_update(bt); } } -static void do_picker_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) +static void ui_colorpicker_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) { uiBut *but = (uiBut *)bt1; uiPopupBlockHandle *popup = but->block->handle; @@ -1978,38 +1981,40 @@ static void do_picker_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) if (prop) { RNA_property_float_get_array(&ptr, prop, rgb); - ui_update_block_buts_rgb(but->block, rgb, (RNA_property_subtype(prop) == PROP_COLOR_GAMMA)); + ui_update_color_picker_buts_rgb(but->block, but->custom_data, rgb, (RNA_property_subtype(prop) == PROP_COLOR_GAMMA)); } if (popup) popup->menuretval = UI_RETURN_UPDATE; } -static void do_color_wheel_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) +static void ui_color_wheel_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) { uiBut *but = (uiBut *)bt1; uiPopupBlockHandle *popup = but->block->handle; float rgb[3]; - const float *hsv = ui_block_hsv_get(but->block); - bool use_display_colorspace = ui_color_picker_use_display_colorspace(but); + ColorPicker *cpicker = but->custom_data; + float *hsv = cpicker->color_data; + bool use_display_colorspace = ui_but_is_colorpicker_display_space(but); ui_color_picker_to_rgb_v(hsv, rgb); /* hsv is saved in display space so convert back */ if (use_display_colorspace) { - ui_block_to_scene_linear_v3(but->block, rgb); + ui_block_cm_to_scene_linear_v3(but->block, rgb); } - ui_update_block_buts_rgb(but->block, rgb, !use_display_colorspace); + ui_update_color_picker_buts_rgb(but->block, cpicker, rgb, !use_display_colorspace); if (popup) popup->menuretval = UI_RETURN_UPDATE; } -static void do_hex_rna_cb(bContext *UNUSED(C), void *bt1, void *hexcl) +static void ui_colorpicker_hex_rna_cb(bContext *UNUSED(C), void *bt1, void *hexcl) { uiBut *but = (uiBut *)bt1; uiPopupBlockHandle *popup = but->block->handle; + ColorPicker *cpicker = but->custom_data; char *hexcol = (char *)hexcl; float rgb[3]; @@ -2018,16 +2023,16 @@ static void do_hex_rna_cb(bContext *UNUSED(C), void *bt1, void *hexcl) /* Hex code is assumed to be in sRGB space (coming from other applications, web, etc) */ if (but->block->color_profile) { /* so we need to linearise it for Blender */ - ui_block_to_scene_linear_v3(but->block, rgb); + ui_block_cm_to_scene_linear_v3(but->block, rgb); } - ui_update_block_buts_rgb(but->block, rgb, false); + ui_update_color_picker_buts_rgb(but->block, cpicker, rgb, false); if (popup) popup->menuretval = UI_RETURN_UPDATE; } -static void close_popup_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) +static void ui_popup_close_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) { uiBut *but = (uiBut *)bt1; uiPopupBlockHandle *popup = but->block->handle; @@ -2036,23 +2041,23 @@ static void close_popup_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) popup->menuretval = UI_RETURN_OK; } -static void picker_new_hide_reveal(uiBlock *block, short colormode) +static void ui_colorpicker_hide_reveal(uiBlock *block, short colormode) { uiBut *bt; /* tag buttons */ for (bt = block->buttons.first; bt; bt = bt->next) { - if ((bt->func == do_picker_rna_cb) && bt->type == NUMSLI && bt->rnaindex != 3) { + if ((bt->func == ui_colorpicker_rna_cb) && bt->type == UI_BTYPE_NUM_SLIDER && bt->rnaindex != 3) { /* RGB sliders (color circle and alpha are always shown) */ if (colormode == 0) bt->flag &= ~UI_HIDDEN; else bt->flag |= UI_HIDDEN; } - else if (bt->func == do_color_wheel_rna_cb) { + else if (bt->func == ui_color_wheel_rna_cb) { /* HSV sliders */ if (colormode == 1) bt->flag &= ~UI_HIDDEN; else bt->flag |= UI_HIDDEN; } - else if (bt->func == do_hex_rna_cb || bt->type == LABEL) { + else if (bt->func == ui_colorpicker_hex_rna_cb || bt->type == UI_BTYPE_LABEL) { /* hex input or gamma correction status label */ if (colormode == 2) bt->flag &= ~UI_HIDDEN; else bt->flag |= UI_HIDDEN; @@ -2060,11 +2065,11 @@ static void picker_new_hide_reveal(uiBlock *block, short colormode) } } -static void do_picker_new_mode_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) +static void ui_colorpicker_create_mode_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) { uiBut *bt = bt1; - short colormode = ui_get_but_val(bt); - picker_new_hide_reveal(bt->block, colormode); + short colormode = ui_but_value_get(bt); + ui_colorpicker_hide_reveal(bt->block, colormode); } #define PICKER_H (7.5f * U.widget_unit) @@ -2074,43 +2079,47 @@ static void do_picker_new_mode_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(a #define PICKER_TOTAL_W (PICKER_W + PICKER_SPACE + PICKER_BAR) -static void circle_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop) +static void ui_colorpicker_circle(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, ColorPicker *cpicker) { uiBut *bt; /* HS circle */ - bt = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, prop, -1, 0.0, 0.0, 0.0, 0, TIP_("Color")); - uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); + bt = uiDefButR_prop(block, UI_BTYPE_HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, prop, -1, 0.0, 0.0, 0.0, 0, TIP_("Color")); + UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + bt->custom_data = cpicker; /* value */ if (U.color_picker_type == USER_CP_CIRCLE_HSL) { - bt = uiDefButR_prop(block, HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, -1, 0.0, 0.0, UI_GRAD_L_ALT, 0, "Lightness"); - uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); + bt = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, -1, 0.0, 0.0, UI_GRAD_L_ALT, 0, "Lightness"); + UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); } else { - bt = uiDefButR_prop(block, HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, -1, 0.0, 0.0, UI_GRAD_V_ALT, 0, TIP_("Value")); - uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); + bt = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, -1, 0.0, 0.0, UI_GRAD_V_ALT, 0, TIP_("Value")); + UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); } + bt->custom_data = cpicker; } -static void square_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int type) +static void ui_colorpicker_square(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int type, ColorPicker *cpicker) { uiBut *bt; int bartype = type + 3; /* HS square */ - bt = uiDefButR_prop(block, HSVCUBE, 0, "", 0, PICKER_BAR + PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, prop, -1, 0.0, 0.0, type, 0, TIP_("Color")); - uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); + bt = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", 0, PICKER_BAR + PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, prop, -1, 0.0, 0.0, type, 0, TIP_("Color")); + UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + bt->custom_data = cpicker; /* value */ - bt = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, prop, -1, 0.0, 0.0, bartype, 0, TIP_("Value")); - uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); + bt = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, prop, -1, 0.0, 0.0, bartype, 0, TIP_("Value")); + UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + bt->custom_data = cpicker; } /* a HS circle, V slider, rgb/hsv/hex sliders */ -static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, PropertyRNA *prop, bool show_picker) +static void ui_block_colorpicker(uiBlock *block, float rgba[4], PointerRNA *ptr, PropertyRNA *prop, bool show_picker) { static short colormode = 0; /* temp? 0=rgb, 1=hsv, 2=hex */ uiBut *bt; @@ -2120,8 +2129,9 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper float rgb_gamma[3]; unsigned char rgb_gamma_uchar[3]; float softmin, softmax, hardmin, hardmax, step, precision; - float *hsv = ui_block_hsv_get(block); int yco; + ColorPicker *cpicker = ui_block_colorpicker_create(block); + float *hsv = cpicker->color_data; width = PICKER_TOTAL_W; butwidth = width - 1.5f * UI_UNIT_X; @@ -2137,7 +2147,7 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper /* make a display version, for Hex code */ copy_v3_v3(rgb_gamma, rgba); - ui_block_to_display_space_v3(block, rgb_gamma); + ui_block_cm_to_display_space_v3(block, rgb_gamma); } /* sneaky way to check for alpha */ @@ -2149,75 +2159,86 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper switch (U.color_picker_type) { case USER_CP_SQUARE_SV: - square_picker(block, ptr, prop, UI_GRAD_SV); + ui_colorpicker_square(block, ptr, prop, UI_GRAD_SV, cpicker); break; case USER_CP_SQUARE_HS: - square_picker(block, ptr, prop, UI_GRAD_HS); + ui_colorpicker_square(block, ptr, prop, UI_GRAD_HS, cpicker); break; case USER_CP_SQUARE_HV: - square_picker(block, ptr, prop, UI_GRAD_HV); + ui_colorpicker_square(block, ptr, prop, UI_GRAD_HV, cpicker); break; /* user default */ case USER_CP_CIRCLE_HSV: case USER_CP_CIRCLE_HSL: default: - circle_picker(block, ptr, prop); + ui_colorpicker_circle(block, ptr, prop, cpicker); break; } /* mode */ yco = -1.5f * UI_UNIT_Y; - uiBlockBeginAlign(block); - bt = uiDefButS(block, ROW, 0, IFACE_("RGB"), 0, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 0.0, 0, 0, ""); - uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL); + UI_block_align_begin(block); + bt = uiDefButS(block, UI_BTYPE_ROW, 0, IFACE_("RGB"), 0, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 0.0, 0, 0, ""); + UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, NULL); + bt->custom_data = cpicker; if (U.color_picker_type == USER_CP_CIRCLE_HSL) - bt = uiDefButS(block, ROW, 0, IFACE_("HSL"), width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, ""); + bt = uiDefButS(block, UI_BTYPE_ROW, 0, IFACE_("HSL"), width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, ""); else - bt = uiDefButS(block, ROW, 0, IFACE_("HSV"), width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, ""); - uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL); - bt = uiDefButS(block, ROW, 0, IFACE_("Hex"), 2 * width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 2.0, 0, 0, ""); - uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL); - uiBlockEndAlign(block); + bt = uiDefButS(block, UI_BTYPE_ROW, 0, IFACE_("HSV"), width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, ""); + UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, NULL); + bt->custom_data = cpicker; + bt = uiDefButS(block, UI_BTYPE_ROW, 0, IFACE_("Hex"), 2 * width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 2.0, 0, 0, ""); + UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, NULL); + bt->custom_data = cpicker; + UI_block_align_end(block); yco = -3.0f * UI_UNIT_Y; if (show_picker) { - bt = uiDefIconButO(block, BUT, "UI_OT_eyedropper_color", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth + 10, yco, UI_UNIT_X, UI_UNIT_Y, NULL); - uiButSetFunc(bt, close_popup_cb, bt, NULL); + bt = uiDefIconButO(block, UI_BTYPE_BUT, "UI_OT_eyedropper_color", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth + 10, yco, UI_UNIT_X, UI_UNIT_Y, NULL); + UI_but_func_set(bt, ui_popup_close_cb, bt, NULL); + bt->custom_data = cpicker; } /* RGB values */ - uiBlockBeginAlign(block); - bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("R:"), 0, yco, butwidth, UI_UNIT_Y, ptr, prop, 0, 0.0, 0.0, 0, 3, TIP_("Red")); - uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); - bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("G:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 1, 0.0, 0.0, 0, 3, TIP_("Green")); - uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); - bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("B:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 2, 0.0, 0.0, 0, 3, TIP_("Blue")); - uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); + UI_block_align_begin(block); + bt = uiDefButR_prop(block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("R:"), 0, yco, butwidth, UI_UNIT_Y, ptr, prop, 0, 0.0, 0.0, 0, 3, TIP_("Red")); + UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + bt->custom_data = cpicker; + bt = uiDefButR_prop(block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("G:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 1, 0.0, 0.0, 0, 3, TIP_("Green")); + UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + bt->custom_data = cpicker; + bt = uiDefButR_prop(block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("B:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 2, 0.0, 0.0, 0, 3, TIP_("Blue")); + UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + bt->custom_data = cpicker; /* could use uiItemFullR(col, ptr, prop, -1, 0, UI_ITEM_R_EXPAND|UI_ITEM_R_SLIDER, "", ICON_NONE); - * but need to use uiButSetFunc for updating other fake buttons */ + * but need to use UI_but_func_set for updating other fake buttons */ /* HSV values */ yco = -3.0f * UI_UNIT_Y; - uiBlockBeginAlign(block); - bt = uiDefButF(block, NUMSLI, 0, IFACE_("H:"), 0, yco, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, TIP_("Hue")); - uiButSetFunc(bt, do_color_wheel_rna_cb, bt, hsv); - bt = uiDefButF(block, NUMSLI, 0, IFACE_("S:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation")); - uiButSetFunc(bt, do_color_wheel_rna_cb, bt, hsv); + UI_block_align_begin(block); + bt = uiDefButF(block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("H:"), 0, yco, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, TIP_("Hue")); + UI_but_func_set(bt, ui_color_wheel_rna_cb, bt, hsv); + bt->custom_data = cpicker; + bt = uiDefButF(block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("S:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation")); + UI_but_func_set(bt, ui_color_wheel_rna_cb, bt, hsv); + bt->custom_data = cpicker; if (U.color_picker_type == USER_CP_CIRCLE_HSL) - bt = uiDefButF(block, NUMSLI, 0, IFACE_("L:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, 1.0, 10, 3, TIP_("Lightness")); + bt = uiDefButF(block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("L:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, 1.0, 10, 3, TIP_("Lightness")); else - bt = uiDefButF(block, NUMSLI, 0, IFACE_("V:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, softmax, 10, 3, TIP_("Value")); + bt = uiDefButF(block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("V:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, softmax, 10, 3, TIP_("Value")); bt->hardmax = hardmax; /* not common but rgb may be over 1.0 */ - uiButSetFunc(bt, do_color_wheel_rna_cb, bt, hsv); + UI_but_func_set(bt, ui_color_wheel_rna_cb, bt, hsv); + bt->custom_data = cpicker; - uiBlockEndAlign(block); + UI_block_align_end(block); if (rgba[3] != FLT_MAX) { - bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("A: "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 3, 0.0, 0.0, 0, 3, TIP_("Alpha")); - uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); + bt = uiDefButR_prop(block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("A: "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 3, 0.0, 0.0, 0, 3, TIP_("Alpha")); + UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + bt->custom_data = cpicker; } else { rgba[3] = 1.0f; @@ -2227,17 +2248,18 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper BLI_snprintf(hexcol, sizeof(hexcol), "%02X%02X%02X", UNPACK3_EX((unsigned int), rgb_gamma_uchar, )); yco = -3.0f * UI_UNIT_Y; - bt = uiDefBut(block, TEX, 0, IFACE_("Hex: "), 0, yco, butwidth, UI_UNIT_Y, hexcol, 0, 8, 0, 0, TIP_("Hex triplet for color (#RRGGBB)")); - uiButSetFunc(bt, do_hex_rna_cb, bt, hexcol); - uiDefBut(block, LABEL, 0, IFACE_("(Gamma Corrected)"), 0, yco - UI_UNIT_Y, butwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + bt = uiDefBut(block, UI_BTYPE_TEXT, 0, IFACE_("Hex: "), 0, yco, butwidth, UI_UNIT_Y, hexcol, 0, 8, 0, 0, TIP_("Hex triplet for color (#RRGGBB)")); + UI_but_func_set(bt, ui_colorpicker_hex_rna_cb, bt, hexcol); + bt->custom_data = cpicker; + uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("(Gamma Corrected)"), 0, yco - UI_UNIT_Y, butwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); ui_rgb_to_color_picker_v(rgb_gamma, hsv); - picker_new_hide_reveal(block, colormode); + ui_colorpicker_hide_reveal(block, colormode); } -static int ui_picker_small_wheel_cb(const bContext *UNUSED(C), uiBlock *block, const wmEvent *event) +static int ui_colorpicker_small_wheel_cb(const bContext *UNUSED(C), uiBlock *block, const wmEvent *event) { float add = 0.0f; @@ -2250,16 +2272,17 @@ static int ui_picker_small_wheel_cb(const bContext *UNUSED(C), uiBlock *block, c uiBut *but; for (but = block->buttons.first; but; but = but->next) { - if (but->type == HSVCUBE && but->active == NULL) { + if (but->type == UI_BTYPE_HSVCUBE && but->active == NULL) { uiPopupBlockHandle *popup = block->handle; float rgb[3]; - float *hsv = ui_block_hsv_get(block); - bool use_display_colorspace = ui_color_picker_use_display_colorspace(but); + ColorPicker *cpicker = but->custom_data; + float *hsv = cpicker->color_data; + bool use_display_colorspace = ui_but_is_colorpicker_display_space(but); - ui_get_but_vectorf(but, rgb); + ui_but_v3_get(but, rgb); if (use_display_colorspace) - ui_block_to_display_space_v3(block, rgb); + ui_block_cm_to_display_space_v3(block, rgb); ui_rgb_to_color_picker_compat_v(rgb, hsv); @@ -2267,11 +2290,11 @@ static int ui_picker_small_wheel_cb(const bContext *UNUSED(C), uiBlock *block, c ui_color_picker_to_rgb_v(hsv, rgb); if (use_display_colorspace) - ui_block_to_scene_linear_v3(block, rgb); + ui_block_cm_to_scene_linear_v3(block, rgb); - ui_set_but_vectorf(but, rgb); + ui_but_v3_set(but, rgb); - ui_update_block_buts_rgb(block, rgb, !use_display_colorspace); + ui_update_color_picker_buts_rgb(block, cpicker, rgb, !use_display_colorspace); if (popup) popup->menuretval = UI_RETURN_UPDATE; @@ -2288,7 +2311,7 @@ uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_ uiBlock *block; bool show_picker = true; - block = uiBeginBlock(C, handle->region, __func__, UI_EMBOSS); + block = UI_block_begin(C, handle->region, __func__, UI_EMBOSS); if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) { block->color_profile = false; @@ -2304,15 +2327,15 @@ uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_ copy_v3_v3(handle->retvec, but->editvec); - uiBlockPicker(block, handle->retvec, &but->rnapoin, but->rnaprop, show_picker); + ui_block_colorpicker(block, handle->retvec, &but->rnapoin, but->rnaprop, show_picker); - block->flag = UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_KEEP_OPEN | UI_BLOCK_OUT_1 | UI_BLOCK_MOVEMOUSE_QUIT; - uiBoundsBlock(block, 0.5 * UI_UNIT_X); + block->flag = UI_BLOCK_LOOP | UI_BLOCK_KEEP_OPEN | UI_BLOCK_OUT_1 | UI_BLOCK_MOVEMOUSE_QUIT; + UI_block_bounds_set_normal(block, 0.5 * UI_UNIT_X); - block->block_event_func = ui_picker_small_wheel_cb; + block->block_event_func = ui_colorpicker_small_wheel_cb; /* and lets go */ - block->direction = UI_TOP; + block->direction = UI_DIR_UP; return block; } @@ -2448,39 +2471,39 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi /* allow overriding the direction from menu_func */ direction = pup->block->direction; } - else if ((pup->but->type == PULLDOWN) || - (uiButGetMenuType(pup->but) != NULL)) + else if ((pup->but->type == UI_BTYPE_PULLDOWN) || + (UI_but_menutype_get(pup->but) != NULL)) { - direction = UI_DOWN; + direction = UI_DIR_DOWN; } else { - direction = UI_TOP; + direction = UI_DIR_UP; } } else { minwidth = 50; - direction = UI_DOWN; + direction = UI_DIR_DOWN; } - flip = (direction == UI_DOWN); + flip = (direction == UI_DIR_DOWN); block = pup->block; /* in some cases we create the block before the region, * so we set it delayed here if necessary */ if (BLI_findindex(&handle->region->uiblocks, block) == -1) - uiBlockSetRegion(block, handle->region); + UI_block_region_set(block, handle->region); block->direction = direction; - uiBlockLayoutResolve(block, &width, &height); + UI_block_layout_resolve(block, &width, &height); - uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT); + UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT); if (pup->popup) { uiBut *but_activate = NULL; - uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_NUMSELECT); - uiBlockSetDirection(block, direction); + UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_NUMSELECT); + UI_block_direction_set(block, direction); /* offset the mouse position, possibly based on earlier selection */ if ((block->flag & UI_BLOCK_POPUP_MEMORY) && @@ -2518,11 +2541,11 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi * to be within the window bounds may move it away from the mouse, * This ensures we set an item to be active. */ if (but_activate) { - ui_button_activate_over(C, handle->region, but_activate); + ui_but_activate_over(C, handle->region, but_activate); } block->minbounds = minwidth; - uiMenuPopupBoundsBlock(block, 1, offset[0], offset[1]); + UI_block_bounds_set_menu(block, 1, offset[0], offset[1]); } else { /* for a header menu we set the direction automatic */ @@ -2531,19 +2554,19 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi if (sa && sa->headertype == HEADERDOWN) { ARegion *ar = CTX_wm_region(C); if (ar && ar->regiontype == RGN_TYPE_HEADER) { - uiBlockSetDirection(block, UI_TOP); - uiBlockFlipOrder(block); + UI_block_direction_set(block, UI_DIR_UP); + UI_block_order_flip(block); } } } block->minbounds = minwidth; - uiTextBoundsBlock(block, 3.0f * UI_UNIT_X); + UI_block_bounds_set_text(block, 3.0f * UI_UNIT_X); } /* if menu slides out of other menu, override direction */ if (pup->slideout) - uiBlockSetDirection(block, UI_RIGHT); + UI_block_direction_set(block, UI_DIR_RIGHT); return pup->block; } @@ -2552,14 +2575,14 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut uiMenuCreateFunc menu_func, void *arg) { wmWindow *window = CTX_wm_window(C); - uiStyle *style = UI_GetStyleDraw(); + uiStyle *style = UI_style_get_dpi(); uiPopupBlockHandle *handle; uiPopupMenu *pup; pup = MEM_callocN(sizeof(uiPopupMenu), __func__); - pup->block = uiBeginBlock(C, NULL, __func__, UI_EMBOSSP); + pup->block = UI_block_begin(C, NULL, __func__, UI_EMBOSS_PULLDOWN); pup->block->flag |= UI_BLOCK_NUMSELECT; /* default menus to numselect */ - pup->layout = uiBlockLayout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, MENU_PADDING, style); + pup->layout = UI_block_layout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, MENU_PADDING, style); pup->slideout = but ? ui_block_is_menu(but->block) : false; pup->but = but; uiLayoutSetOperatorContext(pup->layout, WM_OP_INVOKE_REGION_WIN); @@ -2596,7 +2619,7 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut if (!but) { handle->popup = true; - UI_add_popup_handlers(C, &window->modalhandlers, handle, false); + UI_popup_handlers_add(C, &window->modalhandlers, handle, false); WM_event_add_mousemove(C); } @@ -2608,16 +2631,16 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut /******************** Popup Menu API with begin and end ***********************/ /* only return handler, and set optional title */ -uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon) +uiPopupMenu *UI_popup_menu_begin(bContext *C, const char *title, int icon) { - uiStyle *style = UI_GetStyleDraw(); + uiStyle *style = UI_style_get_dpi(); uiPopupMenu *pup = MEM_callocN(sizeof(uiPopupMenu), "popup menu"); uiBut *but; - pup->block = uiBeginBlock(C, NULL, __func__, UI_EMBOSSP); - pup->block->flag |= UI_BLOCK_POPUP_MEMORY; + pup->block = UI_block_begin(C, NULL, __func__, UI_EMBOSS_PULLDOWN); + pup->block->flag |= UI_BLOCK_POPUP_MEMORY | UI_BLOCK_IS_FLIP; pup->block->puphash = ui_popup_menu_hash(title); - pup->layout = uiBlockLayout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, MENU_PADDING, style); + pup->layout = UI_block_layout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, MENU_PADDING, style); /* note, this intentionally differs from the menu & submenu default because many operators * use popups like this to select one of their options - where having invoke doesn't make sense */ @@ -2632,10 +2655,10 @@ uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon) if (icon) { BLI_snprintf(titlestr, sizeof(titlestr), " %s", title); - uiDefIconTextBut(pup->block, LABEL, 0, icon, titlestr, 0, 0, 200, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + uiDefIconTextBut(pup->block, UI_BTYPE_LABEL, 0, icon, titlestr, 0, 0, 200, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); } else { - but = uiDefBut(pup->block, LABEL, 0, title, 0, 0, 200, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + but = uiDefBut(pup->block, UI_BTYPE_LABEL, 0, title, 0, 0, 200, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); but->drawflag = UI_BUT_TEXT_LEFT; } @@ -2646,7 +2669,7 @@ uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon) } /* set the whole structure to work */ -void uiPupMenuEnd(bContext *C, uiPopupMenu *pup) +void UI_popup_menu_end(bContext *C, uiPopupMenu *pup) { wmWindow *window = CTX_wm_window(C); uiPopupBlockHandle *menu; @@ -2658,13 +2681,13 @@ void uiPupMenuEnd(bContext *C, uiPopupMenu *pup) menu = ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_POPUP, pup); menu->popup = true; - UI_add_popup_handlers(C, &window->modalhandlers, menu, false); + UI_popup_handlers_add(C, &window->modalhandlers, menu, false); WM_event_add_mousemove(C); MEM_freeN(pup); } -uiLayout *uiPupMenuLayout(uiPopupMenu *pup) +uiLayout *UI_popup_menu_layout(uiPopupMenu *pup) { return pup->layout; } @@ -2683,11 +2706,11 @@ static uiBlock *ui_block_func_PIE(bContext *UNUSED(C), uiPopupBlockHandle *handl /* in some cases we create the block before the region, * so we set it delayed here if necessary */ if (BLI_findindex(&handle->region->uiblocks, block) == -1) - uiBlockSetRegion(block, handle->region); + UI_block_region_set(block, handle->region); - uiBlockLayoutResolve(block, &width, &height); + UI_block_layout_resolve(block, &width, &height); - uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_NUMSELECT); + UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_NUMSELECT); block->minbounds = minwidth; block->bounds = 1; @@ -2701,13 +2724,13 @@ static uiBlock *ui_block_func_PIE(bContext *UNUSED(C), uiPopupBlockHandle *handl return pie->block_radial; } -static float uiPieTitleWidth(const char *name, int icon) +static float ui_pie_menu_title_width(const char *name, int icon) { - return (UI_GetStringWidth(name) + + return (UI_fontstyle_string_width(name) + (UI_UNIT_X * (1.50f + (icon ? 0.25f : 0.0f)))); } -uiPieMenu *uiPieMenuBegin(struct bContext *C, const char *title, int icon, const wmEvent *event) +uiPieMenu *UI_pie_menu_begin(struct bContext *C, const char *title, int icon, const wmEvent *event) { uiStyle *style; uiPieMenu *pie; @@ -2715,10 +2738,10 @@ uiPieMenu *uiPieMenuBegin(struct bContext *C, const char *title, int icon, const wmWindow *win = CTX_wm_window(C); - style = UI_GetStyleDraw(); + style = UI_style_get_dpi(); pie = MEM_callocN(sizeof(uiPopupMenu), "pie menu"); - pie->block_radial = uiBeginBlock(C, NULL, __func__, UI_EMBOSS); + pie->block_radial = UI_block_begin(C, NULL, __func__, UI_EMBOSS); /* may be useful later to allow spawning pies * from old positions */ /* pie->block_radial->flag |= UI_BLOCK_POPUP_MEMORY; */ @@ -2732,16 +2755,24 @@ uiPieMenu *uiPieMenuBegin(struct bContext *C, const char *title, int icon, const win->lock_pie_event = EVENT_NONE; } else { - if (win->last_pie_event != EVENT_NONE) - event_type = win->last_pie_event; - else + if (win->last_pie_event != EVENT_NONE) { + /* original pie key has been released, so don't propagate the event */ + if (win->lock_pie_event == EVENT_NONE) { + event_type = EVENT_NONE; + pie->block_radial->pie_data.flags |= UI_PIE_CLICK_STYLE; + } + else + event_type = win->last_pie_event; + } + else { event_type = event->type; + } pie->block_radial->pie_data.event = event_type; win->lock_pie_event = event_type; } - pie->layout = uiBlockLayout(pie->block_radial, UI_LAYOUT_VERTICAL, UI_LAYOUT_PIEMENU, 0, 0, 200, 0, 0, style); + pie->layout = UI_block_layout(pie->block_radial, UI_LAYOUT_VERTICAL, UI_LAYOUT_PIEMENU, 0, 0, 200, 0, 0, style); pie->mx = event->x; pie->my = event->y; @@ -2752,12 +2783,12 @@ uiPieMenu *uiPieMenuBegin(struct bContext *C, const char *title, int icon, const int w; if (icon) { BLI_snprintf(titlestr, sizeof(titlestr), " %s", title); - w = uiPieTitleWidth(titlestr, icon); - but = uiDefIconTextBut(pie->block_radial, LABEL, 0, icon, titlestr, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + w = ui_pie_menu_title_width(titlestr, icon); + but = uiDefIconTextBut(pie->block_radial, UI_BTYPE_LABEL, 0, icon, titlestr, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); } else { - w = uiPieTitleWidth(title, 0); - but = uiDefBut(pie->block_radial, LABEL, 0, title, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + w = ui_pie_menu_title_width(title, 0); + but = uiDefBut(pie->block_radial, UI_BTYPE_LABEL, 0, title, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); } /* do not align left */ but->drawflag &= ~UI_BUT_TEXT_LEFT; @@ -2766,7 +2797,7 @@ uiPieMenu *uiPieMenuBegin(struct bContext *C, const char *title, int icon, const return pie; } -void uiPieMenuEnd(bContext *C, uiPieMenu *pie) +void UI_pie_menu_end(bContext *C, uiPieMenu *pie) { wmWindow *window = CTX_wm_window(C); uiPopupBlockHandle *menu; @@ -2775,18 +2806,18 @@ void uiPieMenuEnd(bContext *C, uiPieMenu *pie) menu->popup = true; menu->towardstime = PIL_check_seconds_timer(); - UI_add_popup_handlers(C, &window->modalhandlers, menu, true); + UI_popup_handlers_add(C, &window->modalhandlers, menu, true); WM_event_add_mousemove(C); MEM_freeN(pie); } -uiLayout *uiPieMenuLayout(uiPieMenu *pie) +uiLayout *UI_pie_menu_layout(uiPieMenu *pie) { return pie->layout; } -void uiPieMenuInvoke(struct bContext *C, const char *idname, const wmEvent *event) +int UI_pie_menu_invoke(struct bContext *C, const char *idname, const wmEvent *event) { uiPieMenu *pie; uiLayout *layout; @@ -2795,14 +2826,14 @@ void uiPieMenuInvoke(struct bContext *C, const char *idname, const wmEvent *even if (mt == NULL) { printf("%s: named menu \"%s\" not found\n", __func__, idname); - return; + return OPERATOR_CANCELLED; } if (mt->poll && mt->poll(C, mt) == 0) - return; + return OPERATOR_CANCELLED; - pie = uiPieMenuBegin(C, IFACE_(mt->label), ICON_NONE, event); - layout = uiPieMenuLayout(pie); + pie = UI_pie_menu_begin(C, IFACE_(mt->label), ICON_NONE, event); + layout = UI_pie_menu_layout(pie); menu.layout = layout; menu.type = mt; @@ -2813,26 +2844,30 @@ void uiPieMenuInvoke(struct bContext *C, const char *idname, const wmEvent *even mt->draw(C, &menu); - uiPieMenuEnd(C, pie); + UI_pie_menu_end(C, pie); + + return OPERATOR_INTERFACE; } -void uiPieOperatorEnumInvoke(struct bContext *C, const char *title, const char *opname, - const char *propname, const wmEvent *event) +int UI_pie_menu_invoke_from_operator_enum(struct bContext *C, const char *title, const char *opname, + const char *propname, const wmEvent *event) { uiPieMenu *pie; uiLayout *layout; - pie = uiPieMenuBegin(C, IFACE_(title), ICON_NONE, event); - layout = uiPieMenuLayout(pie); + pie = UI_pie_menu_begin(C, IFACE_(title), ICON_NONE, event); + layout = UI_pie_menu_layout(pie); layout = uiLayoutRadial(layout); uiItemsEnumO(layout, opname, propname); - uiPieMenuEnd(C, pie); + UI_pie_menu_end(C, pie); + + return OPERATOR_INTERFACE; } -void uiPieEnumInvoke(struct bContext *C, const char *title, const char *path, - const wmEvent *event) +int UI_pie_menu_invoke_from_rna_enum(struct bContext *C, const char *title, const char *path, + const wmEvent *event) { PointerRNA ctx_ptr; PointerRNA r_ptr; @@ -2843,29 +2878,31 @@ void uiPieEnumInvoke(struct bContext *C, const char *title, const char *path, RNA_pointer_create(NULL, &RNA_Context, C, &ctx_ptr); if (!RNA_path_resolve(&ctx_ptr, path, &r_ptr, &r_prop)) { - return; + return OPERATOR_CANCELLED; } /* invalid property, only accept enums */ if (RNA_property_type(r_prop) != PROP_ENUM) { BLI_assert(0); - return; + return OPERATOR_CANCELLED; } - pie = uiPieMenuBegin(C, IFACE_(title), ICON_NONE, event); + pie = UI_pie_menu_begin(C, IFACE_(title), ICON_NONE, event); - layout = uiPieMenuLayout(pie); + layout = UI_pie_menu_layout(pie); layout = uiLayoutRadial(layout); uiItemFullR(layout, &r_ptr, r_prop, RNA_NO_INDEX, 0, UI_ITEM_R_EXPAND, NULL, 0); - uiPieMenuEnd(C, pie); + UI_pie_menu_end(C, pie); + + return OPERATOR_INTERFACE; } /*************************** Standard Popup Menus ****************************/ -void uiPupMenuReports(bContext *C, ReportList *reports) +void UI_popup_menu_reports(bContext *C, ReportList *reports) { Report *report; @@ -2886,8 +2923,8 @@ void uiPupMenuReports(bContext *C, ReportList *reports) if (pup == NULL) { char title[UI_MAX_DRAW_STR]; BLI_snprintf(title, sizeof(title), "%s: %s", IFACE_("Report"), report->typestr); - pup = uiPupMenuBegin(C, title, ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, title, ICON_NONE); + layout = UI_popup_menu_layout(pup); } else { uiItemS(layout); @@ -2895,7 +2932,7 @@ void uiPupMenuReports(bContext *C, ReportList *reports) /* split each newline into a label */ msg = report->message; - icon = uiIconFromReportType(report->type); + icon = UI_icon_from_report_type(report->type); do { char buf[UI_MAX_DRAW_STR]; msg_next = strchr(msg, '\n'); @@ -2910,11 +2947,11 @@ void uiPupMenuReports(bContext *C, ReportList *reports) } if (pup) { - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); } } -bool uiPupMenuInvoke(bContext *C, const char *idname, ReportList *reports) +int UI_popup_menu_invoke(bContext *C, const char *idname, ReportList *reports) { uiPopupMenu *pup; uiLayout *layout; @@ -2923,14 +2960,14 @@ bool uiPupMenuInvoke(bContext *C, const char *idname, ReportList *reports) if (mt == NULL) { BKE_reportf(reports, RPT_ERROR, "Menu \"%s\" not found", idname); - return false; + return OPERATOR_CANCELLED; } if (mt->poll && mt->poll(C, mt) == 0) - return false; + return OPERATOR_CANCELLED; - pup = uiPupMenuBegin(C, IFACE_(mt->label), ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, IFACE_(mt->label), ICON_NONE); + layout = UI_popup_menu_layout(pup); menu.layout = layout; menu.type = mt; @@ -2941,15 +2978,15 @@ bool uiPupMenuInvoke(bContext *C, const char *idname, ReportList *reports) mt->draw(C, &menu); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); - return true; + return OPERATOR_INTERFACE; } /*************************** Popup Block API **************************/ -void uiPupBlockO(bContext *C, uiBlockCreateFunc func, void *arg, const char *opname, int opcontext) +void UI_popup_block_invoke_ex(bContext *C, uiBlockCreateFunc func, void *arg, const char *opname, int opcontext) { wmWindow *window = CTX_wm_window(C); uiPopupBlockHandle *handle; @@ -2959,16 +2996,16 @@ void uiPupBlockO(bContext *C, uiBlockCreateFunc func, void *arg, const char *opn handle->optype = (opname) ? WM_operatortype_find(opname, 0) : NULL; handle->opcontext = opcontext; - UI_add_popup_handlers(C, &window->modalhandlers, handle, false); + UI_popup_handlers_add(C, &window->modalhandlers, handle, false); WM_event_add_mousemove(C); } -void uiPupBlock(bContext *C, uiBlockCreateFunc func, void *arg) +void UI_popup_block_invoke(bContext *C, uiBlockCreateFunc func, void *arg) { - uiPupBlockO(C, func, arg, NULL, WM_OP_INVOKE_DEFAULT); + UI_popup_block_invoke_ex(C, func, arg, NULL, WM_OP_INVOKE_DEFAULT); } -void uiPupBlockEx(bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func, void *arg) +void UI_popup_block_ex(bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func, void *arg) { wmWindow *window = CTX_wm_window(C); uiPopupBlockHandle *handle; @@ -2982,7 +3019,7 @@ void uiPupBlockEx(bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_f handle->cancel_func = cancel_func; // handle->opcontext = opcontext; - UI_add_popup_handlers(C, &window->modalhandlers, handle, false); + UI_popup_handlers_add(C, &window->modalhandlers, handle, false); WM_event_add_mousemove(C); } @@ -3001,27 +3038,30 @@ void uiPupBlockOperator(bContext *C, uiBlockCreateFunc func, wmOperator *op, int handle->cancel_func = confirm_cancel_operator; handle->opcontext = opcontext; - UI_add_popup_handlers(C, &window->modalhandlers, handle); + UI_popup_handlers_add(C, &window->modalhandlers, handle); WM_event_add_mousemove(C); } #endif -void uiPupBlockClose(bContext *C, uiBlock *block) +void UI_popup_block_close(bContext *C, uiBlock *block) { if (block->handle) { wmWindow *win = CTX_wm_window(C); /* if loading new .blend while popup is open, window will be NULL */ if (win) { - UI_remove_popup_handlers(&win->modalhandlers, block->handle); + UI_popup_handlers_remove(&win->modalhandlers, block->handle); ui_popup_block_free(C, block->handle); } } } -float *ui_block_hsv_get(uiBlock *block) +ColorPicker *ui_block_colorpicker_create(struct uiBlock *block) { - return block->_hsv; + ColorPicker *cpicker = MEM_callocN(sizeof(ColorPicker), "color_picker"); + BLI_addhead(&block->color_pickers.list, cpicker); + + return cpicker; } void ui_rgb_to_color_picker_compat_v(const float rgb[3], float r_cp[3]) diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index c27789c0fc9..8b2ce90dcf5 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -47,7 +47,9 @@ #include "BLF_api.h" -#include "BLF_translation.h" +#ifdef WITH_INTERNATIONAL +# include "BLF_translation.h" +#endif #include "UI_interface.h" @@ -145,13 +147,13 @@ static uiFont *uifont_to_blfont(int id) /* *************** draw ************************ */ -void uiStyleFontDrawExt(uiFontStyle *fs, const rcti *rect, const char *str, +void UI_fontstyle_draw_ex(uiFontStyle *fs, const rcti *rect, const char *str, size_t len, float *r_xofs, float *r_yofs) { float height; int xofs = 0, yofs; - uiStyleFontSet(fs); + UI_fontstyle_set(fs); height = BLF_ascender(fs->uifont_id); yofs = ceil(0.5f * (BLI_rcti_size_y(rect) - height)); @@ -192,22 +194,22 @@ void uiStyleFontDrawExt(uiFontStyle *fs, const rcti *rect, const char *str, *r_yofs = yofs; } -void uiStyleFontDraw(uiFontStyle *fs, const rcti *rect, const char *str) +void UI_fontstyle_draw(uiFontStyle *fs, const rcti *rect, const char *str) { float xofs, yofs; - uiStyleFontDrawExt(fs, rect, str, + UI_fontstyle_draw_ex(fs, rect, str, BLF_DRAW_STR_DUMMY_MAX, &xofs, &yofs); } /* drawn same as above, but at 90 degree angle */ -void uiStyleFontDrawRotated(uiFontStyle *fs, const rcti *rect, const char *str) +void UI_fontstyle_draw_rotated(uiFontStyle *fs, const rcti *rect, const char *str) { float height; int xofs, yofs; float angle; rcti txtrect; - uiStyleFontSet(fs); + UI_fontstyle_set(fs); height = BLF_ascender(fs->uifont_id); /* becomes x-offset when rotated */ @@ -255,7 +257,7 @@ void uiStyleFontDrawRotated(uiFontStyle *fs, const rcti *rect, const char *str) /* ************** helpers ************************ */ /* XXX: read a style configure */ -uiStyle *UI_GetStyle(void) +uiStyle *UI_style_get(void) { uiStyle *style = NULL; /* offset is two struct uiStyle pointers */ @@ -264,9 +266,9 @@ uiStyle *UI_GetStyle(void) } /* for drawing, scaled with DPI setting */ -uiStyle *UI_GetStyleDraw(void) +uiStyle *UI_style_get_dpi(void) { - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_style_get(); static uiStyle _style; _style = *style; @@ -290,16 +292,16 @@ uiStyle *UI_GetStyleDraw(void) } /* temporarily, does widget font */ -int UI_GetStringWidth(const char *str) +int UI_fontstyle_string_width(const char *str) { - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_style_get(); uiFontStyle *fstyle = &style->widget; int width; if (fstyle->kerning == 1) /* for BLF_width */ BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT); - uiStyleFontSet(fstyle); + UI_fontstyle_set(fstyle); width = BLF_width(fstyle->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX); if (fstyle->kerning == 1) @@ -309,14 +311,14 @@ int UI_GetStringWidth(const char *str) } /* temporarily, does widget font */ -void UI_DrawString(float x, float y, const char *str) +void UI_draw_string(float x, float y, const char *str) { - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_style_get(); if (style->widget.kerning == 1) BLF_enable(style->widget.uifont_id, BLF_KERNING_DEFAULT); - uiStyleFontSet(&style->widget); + UI_fontstyle_set(&style->widget); BLF_position(style->widget.uifont_id, x, y, 0.0f); BLF_draw(style->widget.uifont_id, str, BLF_DRAW_STR_DUMMY_MAX); @@ -451,7 +453,7 @@ void uiStyleInit(void) BLF_size(blf_mono_font_render, 12 * U.pixelsize, 72); } -void uiStyleFontSet(uiFontStyle *fs) +void UI_fontstyle_set(uiFontStyle *fs) { uiFont *font = uifont_to_blfont(fs->uifont_id); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index b0bea42e3bc..9d96513095e 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -31,7 +31,6 @@ #include "MEM_guardedalloc.h" -#include "DNA_dynamicpaint_types.h" #include "DNA_node_types.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" @@ -74,7 +73,6 @@ #include "ED_util.h" #include "RNA_access.h" -#include "RNA_enum_types.h" #include "WM_api.h" #include "WM_types.h" @@ -158,7 +156,7 @@ static void id_search_cb(const bContext *C, void *arg_template, const char *str, iconid = ui_id_icon_get((bContext *)C, id, template->preview); - if (false == uiSearchItemAdd(items, name_ui, id, iconid)) + if (false == UI_search_item_add(items, name_ui, id, iconid)) break; } } @@ -183,8 +181,8 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem) /* get active id for showing first item */ idptr = RNA_property_pointer_get(&template.ptr, template.prop); - block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS); - uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_SEARCH_MENU); + block = UI_block_begin(C, ar, "_popup", UI_EMBOSS); + UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_SEARCH_MENU); /* preview thumbnails */ if (template.prv_rows > 0 && template.prv_cols > 0) { @@ -192,29 +190,29 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem) int h = 4 * U.widget_unit * template.prv_rows + U.widget_unit; /* fake button, it holds space for search items */ - uiDefBut(block, LABEL, 0, "", 10, 15, w, h, NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 15, w, h, NULL, 0, 0, 0, 0, NULL); but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, UI_UNIT_Y, template.prv_rows, template.prv_cols, ""); - uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data); + UI_but_func_search_set(but, id_search_cb, &template, id_search_call_cb, idptr.data); } /* list view */ else { - const int searchbox_width = uiSearchBoxWidth(); - const int searchbox_height = uiSearchBoxHeight(); + const int searchbox_width = UI_searchbox_size_x(); + const int searchbox_height = UI_searchbox_size_y(); /* fake button, it holds space for search items */ - uiDefBut(block, LABEL, 0, "", 10, 15, searchbox_width, searchbox_height, NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 15, searchbox_width, searchbox_height, NULL, 0, 0, 0, 0, NULL); but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, searchbox_width, UI_UNIT_Y - 1, 0, 0, ""); - uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data); + UI_but_func_search_set(but, id_search_cb, &template, id_search_call_cb, idptr.data); } - uiBoundsBlock(block, 0.3f * U.widget_unit); - uiBlockSetDirection(block, UI_DOWN); + UI_block_bounds_set_normal(block, 0.3f * U.widget_unit); + UI_block_direction_set(block, UI_DIR_DOWN); /* give search-field focus */ - uiButSetFocusOnEnter(win, but); + UI_but_focus_on_enter_event(win, but); /* this type of search menu requires undo */ but->flag |= UI_BUT_UNDO; @@ -225,7 +223,7 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem) /* This is for browsing and editing the ID-blocks used */ /* for new/open operators */ -void uiIDContextProperty(bContext *C, PointerRNA *ptr, PropertyRNA **prop) +void UI_context_active_but_prop_get_templateID(bContext *C, PointerRNA *ptr, PropertyRNA **prop) { TemplateID *template; ARegion *ar = CTX_wm_region(C); @@ -268,7 +266,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event) break; case UI_ID_OPEN: case UI_ID_ADD_NEW: - /* these call uiIDContextProperty */ + /* these call UI_context_active_but_prop_get_templateID */ break; case UI_ID_DELETE: memset(&idptr, 0, sizeof(idptr)); @@ -352,6 +350,8 @@ static const char *template_id_browse_tip(StructRNA *type) case ID_BR: return N_("Browse Brush to be linked"); case ID_PA: return N_("Browse Particle Settings to be linked"); case ID_GD: return N_("Browse Grease Pencil Data to be linked"); + case ID_MC: return N_("Browse Movie Clip to be linked"); + case ID_MSK: return N_("Browse Mask to be linked"); case ID_PAL: return N_("Browse Palette Data to be linked"); case ID_PC: return N_("Browse Paint Curve Data to be linked"); } @@ -390,6 +390,10 @@ static const char *template_id_context(StructRNA *type) case ID_BR: return BLF_I18NCONTEXT_ID_BRUSH; case ID_PA: return BLF_I18NCONTEXT_ID_PARTICLESETTINGS; case ID_GD: return BLF_I18NCONTEXT_ID_GPENCIL; + case ID_MC: return BLF_I18NCONTEXT_ID_MOVIECLIP; + case ID_MSK: return BLF_I18NCONTEXT_ID_MASK; + case ID_PAL: return BLF_I18NCONTEXT_ID_PALETTE; + case ID_PC: return BLF_I18NCONTEXT_ID_PAINTCURVE; } } return BLF_I18NCONTEXT_DEFAULT; @@ -412,7 +416,7 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str // lb = template->idlb; block = uiLayoutGetBlock(layout); - uiBlockBeginAlign(block); + UI_block_align_begin(block); if (idptr.type) type = idptr.type; @@ -423,10 +427,10 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6, TIP_(template_id_browse_tip(type))); but->icon = id ? ui_id_icon_get(C, id, true) : RNA_struct_ui_icon(type); - uiButSetFlag(but, UI_HAS_ICON | UI_ICON_PREVIEW); + UI_but_flag_enable(but, UI_HAS_ICON | UI_BUT_ICON_PREVIEW); if ((idfrom && idfrom->lib) || !editable) - uiButSetFlag(but, UI_BUT_DISABLED); + UI_but_flag_enable(but, UI_BUT_DISABLED); uiLayoutRow(layout, true); } @@ -435,12 +439,12 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str TIP_(template_id_browse_tip(type))); but->icon = RNA_struct_ui_icon(type); /* default dragging of icon for id browse buttons */ - uiButSetDragID(but, id); - uiButSetFlag(but, UI_HAS_ICON); - uiButSetDrawFlag(but, UI_BUT_ICON_LEFT); + UI_but_drag_set_id(but, id); + UI_but_flag_enable(but, UI_HAS_ICON); + UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT); if ((idfrom && idfrom->lib) || !editable) - uiButSetFlag(but, UI_BUT_DISABLED); + UI_but_flag_enable(but, UI_BUT_DISABLED); } /* text button with name */ @@ -450,37 +454,39 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str //text_idbutton(id, name); name[0] = '\0'; - but = uiDefButR(block, TEX, 0, name, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, + but = uiDefButR(block, UI_BTYPE_TEXT, 0, name, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, &idptr, "name", -1, 0, 0, -1, -1, RNA_struct_ui_description(type)); - uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME)); - if (user_alert) uiButSetFlag(but, UI_BUT_REDALERT); + UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME)); + if (user_alert) UI_but_flag_enable(but, UI_BUT_REDALERT); if (id->lib) { if (id->flag & LIB_INDIRECT) { - but = uiDefIconBut(block, BUT, 0, ICON_LIBRARY_DATA_INDIRECT, 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_LIBRARY_DATA_INDIRECT, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Indirect library datablock, cannot change")); - uiButSetFlag(but, UI_BUT_DISABLED); + UI_but_flag_enable(but, UI_BUT_DISABLED); } else { - but = uiDefIconBut(block, BUT, 0, ICON_LIBRARY_DATA_DIRECT, 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_LIBRARY_DATA_DIRECT, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Direct linked library datablock, click to make local")); if (!id_make_local(id, true /* test */) || (idfrom && idfrom->lib)) - uiButSetFlag(but, UI_BUT_DISABLED); + UI_but_flag_enable(but, UI_BUT_DISABLED); } - uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_LOCAL)); + UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_LOCAL)); } if (id->us > 1) { char numstr[32]; + short numstr_len; - BLI_snprintf(numstr, sizeof(numstr), "%d", id->us); + numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", id->us); - but = uiDefBut(block, BUT, 0, numstr, 0, 0, UI_UNIT_X + ((id->us < 10) ? 0 : 10), UI_UNIT_Y, - NULL, 0, 0, 0, 0, + but = uiDefBut(block, UI_BTYPE_BUT, 0, numstr, 0, 0, + numstr_len * 0.2f * UI_UNIT_X + UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Display number of users of this data (click to make a single-user copy)")); + but->flag |= UI_BUT_UNDO; - uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ALONE)); + UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ALONE)); if (/* test only */ (id_copy(id, NULL, true) == false) || (idfrom && idfrom->lib) || @@ -488,14 +494,14 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str /* object in editmode - don't change data */ (idfrom && GS(idfrom->name) == ID_OB && (((Object *)idfrom)->mode & OB_MODE_EDIT))) { - uiButSetFlag(but, UI_BUT_DISABLED); + UI_but_flag_enable(but, UI_BUT_DISABLED); } } - if (user_alert) uiButSetFlag(but, UI_BUT_REDALERT); + if (user_alert) UI_but_flag_enable(but, UI_BUT_REDALERT); if (id->lib == NULL && !(ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB))) { - uiDefButR(block, TOG, 0, "F", 0, 0, UI_UNIT_X, UI_UNIT_Y, &idptr, "use_fake_user", -1, 0, 0, -1, -1, NULL); + uiDefButR(block, UI_BTYPE_TOGGLE, 0, "F", 0, 0, UI_UNIT_X, UI_UNIT_Y, &idptr, "use_fake_user", -1, 0, 0, -1, -1, NULL); } } @@ -531,26 +537,26 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str ); if (newop) { - but = uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN, + but = uiDefIconTextButO(block, UI_BTYPE_BUT, newop, WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN, (id) ? "" : CTX_IFACE_(template_id_context(type), "New"), 0, 0, w, UI_UNIT_Y, NULL); - uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW)); + UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW)); } else { - but = uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, (id) ? "" : CTX_IFACE_(template_id_context(type), "New"), + but = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_ZOOMIN, (id) ? "" : CTX_IFACE_(template_id_context(type), "New"), 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); - uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW)); + UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW)); } if ((idfrom && idfrom->lib) || !editable) - uiButSetFlag(but, UI_BUT_DISABLED); + UI_but_flag_enable(but, UI_BUT_DISABLED); } /* Due to space limit in UI - skip the "open" icon for packed data, and allow to unpack. * Only for images, sound and fonts */ if (id && BKE_pack_check(id)) { - but = uiDefIconButO(block, BUT, "FILE_OT_unpack_item", WM_OP_INVOKE_REGION_WIN, ICON_PACKAGE, 0, 0, + but = uiDefIconButO(block, UI_BTYPE_BUT, "FILE_OT_unpack_item", WM_OP_INVOKE_REGION_WIN, ICON_PACKAGE, 0, 0, UI_UNIT_X, UI_UNIT_Y, TIP_("Packed File, click to unpack")); - uiButGetOperatorPtrRNA(but); + UI_but_operator_ptr_get(but); RNA_string_set(but->opptr, "id_name", id->name + 2); RNA_int_set(but->opptr, "id_type", GS(id->name)); @@ -560,18 +566,18 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str int w = id ? UI_UNIT_X : (flag & UI_ID_ADD_NEW) ? UI_UNIT_X * 3 : UI_UNIT_X * 6; if (openop) { - but = uiDefIconTextButO(block, BUT, openop, WM_OP_INVOKE_DEFAULT, ICON_FILESEL, (id) ? "" : IFACE_("Open"), + but = uiDefIconTextButO(block, UI_BTYPE_BUT, openop, WM_OP_INVOKE_DEFAULT, ICON_FILESEL, (id) ? "" : IFACE_("Open"), 0, 0, w, UI_UNIT_Y, NULL); - uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN)); + UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN)); } else { - but = uiDefIconTextBut(block, BUT, 0, ICON_FILESEL, (id) ? "" : IFACE_("Open"), 0, 0, w, UI_UNIT_Y, + but = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_FILESEL, (id) ? "" : IFACE_("Open"), 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); - uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN)); + UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN)); } if ((idfrom && idfrom->lib) || !editable) - uiButSetFlag(but, UI_BUT_DISABLED); + UI_but_flag_enable(but, UI_BUT_DISABLED); } /* delete button */ @@ -581,26 +587,26 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str but = NULL; if (unlinkop) { - but = uiDefIconButO(block, BUT, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL); + but = uiDefIconButO(block, UI_BTYPE_BUT, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL); /* so we can access the template from operators, font unlinking needs this */ - uiButSetNFunc(but, NULL, MEM_dupallocN(template), NULL); + UI_but_funcN_set(but, NULL, MEM_dupallocN(template), NULL); } else { if ((RNA_property_flag(template->prop) & PROP_NEVER_UNLINK) == 0) { - but = uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, + but = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Unlink datablock " "(Shift + Click to set users to zero, data will then not be saved)")); - uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_DELETE)); + UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_DELETE)); if (RNA_property_flag(template->prop) & PROP_NEVER_NULL) { - uiButSetFlag(but, UI_BUT_DISABLED); + UI_but_flag_enable(but, UI_BUT_DISABLED); } } } if (but) { if ((idfrom && idfrom->lib) || !editable) { - uiButSetFlag(but, UI_BUT_DISABLED); + UI_but_flag_enable(but, UI_BUT_DISABLED); } } } @@ -608,7 +614,7 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str if (idcode == ID_TE) uiTemplateTextureShow(layout, C, &template->ptr, template->prop); - uiBlockEndAlign(block); + UI_block_align_end(block); } static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop, @@ -842,26 +848,27 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob, /* VIRTUAL MODIFIER */ /* XXX this is not used now, since these cannot be accessed via RNA */ BLI_snprintf(str, sizeof(str), IFACE_("%s parent deform"), md->name); - uiDefBut(block, LABEL, 0, str, 0, 0, 185, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Modifier name")); + uiDefBut(block, UI_BTYPE_LABEL, 0, str, 0, 0, 185, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Modifier name")); - but = uiDefBut(block, BUT, 0, IFACE_("Make Real"), 0, 0, 80, 16, NULL, 0.0, 0.0, 0.0, 0.0, + but = uiDefBut(block, UI_BTYPE_BUT, 0, IFACE_("Make Real"), 0, 0, 80, 16, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Convert virtual modifier to a real modifier")); - uiButSetFunc(but, modifiers_convertToReal, ob, md); + UI_but_func_set(but, modifiers_convertToReal, ob, md); } else { /* REAL MODIFIER */ row = uiLayoutRow(box, false); block = uiLayoutGetBlock(row); - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); /* Open/Close ................................. */ uiItemR(row, &ptr, "show_expanded", 0, "", ICON_NONE); /* modifier-type icon */ uiItemL(row, "", RNA_struct_ui_icon(ptr.type)); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); /* modifier name */ + md->scene = scene; if (mti->isDisabled && mti->isDisabled(md, 0)) { uiLayoutSetRedAlert(row, true); } @@ -869,7 +876,7 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob, uiLayoutSetRedAlert(row, false); /* mode enabling buttons */ - uiBlockBeginAlign(block); + UI_block_align_begin(block); /* Softbody not allowed in this situation, enforce! */ if (((md->type != eModifierType_Softbody && md->type != eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) && (md->type != eModifierType_Surface) ) @@ -900,10 +907,10 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob, if (ELEM(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) { /* add disabled pre-tessellated button, so users could have * message for this modifiers */ - but = uiDefIconButBitI(block, TOG, eModifierMode_ApplyOnSpline, 0, ICON_SURFACE_DATA, 0, 0, + but = uiDefIconButBitI(block, UI_BTYPE_TOGGLE, eModifierMode_ApplyOnSpline, 0, ICON_SURFACE_DATA, 0, 0, UI_UNIT_X - 2, UI_UNIT_Y, &md->mode, 0.0, 0.0, 0.0, 0.0, TIP_("This modifier can only be applied on splines' points")); - uiButSetFlag(but, UI_BUT_DISABLED); + UI_but_flag_enable(but, UI_BUT_DISABLED); } else if (mti->type != eModifierTypeType_Constructive) { /* constructive modifiers tessellates curve before applying */ @@ -911,23 +918,29 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob, } } - uiBlockEndAlign(block); + UI_block_align_end(block); /* Up/Down + Delete ........................... */ - uiBlockBeginAlign(block); + UI_block_align_begin(block); uiItemO(row, "", ICON_TRIA_UP, "OBJECT_OT_modifier_move_up"); uiItemO(row, "", ICON_TRIA_DOWN, "OBJECT_OT_modifier_move_down"); - uiBlockEndAlign(block); + UI_block_align_end(block); - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); /* When Modifier is a simulation, show button to switch to context rather than the delete button. */ - if (modifier_can_delete(md) && (!modifier_is_simulation(md) || STREQ(scene->r.engine, "BLENDER_GAME"))) + if (modifier_can_delete(md) && + (!modifier_is_simulation(md) || + STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME))) + { uiItemO(row, "", ICON_X, "OBJECT_OT_modifier_remove"); - else if (modifier_is_simulation(md) == 1) + } + else if (modifier_is_simulation(md) == 1) { uiItemStringO(row, "", ICON_BUTS, "WM_OT_properties_context_change", "context", "PHYSICS"); - else if (modifier_is_simulation(md) == 2) + } + else if (modifier_is_simulation(md) == 2) { uiItemStringO(row, "", ICON_BUTS, "WM_OT_properties_context_change", "context", "PARTICLES"); - uiBlockSetEmboss(block, UI_EMBOSS); + } + UI_block_emboss_set(block, UI_EMBOSS); } @@ -939,7 +952,7 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob, if (!ELEM(md->type, eModifierType_Collision, eModifierType_Surface)) { /* only here obdata, the rest of modifiers is ob level */ - uiBlockSetButLock(block, BKE_object_obdata_is_libdata(ob), ERROR_LIBDATA_MESSAGE); + UI_block_lock_set(block, BKE_object_obdata_is_libdata(ob), ERROR_LIBDATA_MESSAGE); if (md->type == eModifierType_ParticleSystem) { ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys; @@ -965,8 +978,8 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob, } } - uiBlockClearButLock(block); - uiBlockSetButLock(block, ob && ob->id.lib, ERROR_LIBDATA_MESSAGE); + UI_block_lock_clear(block); + UI_block_lock_set(block, ob && ob->id.lib, ERROR_LIBDATA_MESSAGE); if (!ELEM(md->type, eModifierType_Fluidsim, eModifierType_Softbody, eModifierType_ParticleSystem, eModifierType_Cloth, eModifierType_Smoke)) @@ -1013,7 +1026,7 @@ uiLayout *uiTemplateModifier(uiLayout *layout, bContext *C, PointerRNA *ptr) return NULL; } - uiBlockSetButLock(uiLayoutGetBlock(layout), (ob && ob->id.lib), ERROR_LIBDATA_MESSAGE); + UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ob->id.lib), ERROR_LIBDATA_MESSAGE); /* find modifier and draw it */ cageIndex = modifiers_getCageIndex(scene, ob, &lastCageIndex, 0); @@ -1107,8 +1120,8 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con) /* unless button has own callback, it adds this callback to button */ block = uiLayoutGetBlock(layout); - uiBlockSetHandleFunc(block, do_constraint_panels, ob); - uiBlockSetFunc(block, constraint_active_func, ob, con); + UI_block_func_handle_set(block, do_constraint_panels, ob); + UI_block_func_set(block, constraint_active_func, ob, con); RNA_pointer_create(&ob->id, &RNA_Constraint, con, &ptr); @@ -1122,12 +1135,12 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con) /* Draw constraint header */ /* open/close */ - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); uiItemR(row, &ptr, "show_expanded", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); /* name */ - uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, + uiDefBut(block, UI_BTYPE_LABEL, B_CONSTRAINT_TEST, typestr, xco + 0.5f * UI_UNIT_X, yco, 5 * UI_UNIT_X, 0.9f * UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, ""); if (con->flag & CONSTRAINT_DISABLE) @@ -1143,15 +1156,15 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con) /* proxy-protected constraints cannot be edited, so hide up/down + close buttons */ if (proxy_protected) { - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); /* draw a ghost icon (for proxy) and also a lock beside it, to show that constraint is "proxy locked" */ - uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_GHOST, xco + 12.2f * UI_UNIT_X, yco, 0.95f * UI_UNIT_X, 0.95f * UI_UNIT_Y, + uiDefIconBut(block, UI_BTYPE_BUT, B_CONSTRAINT_TEST, ICON_GHOST, xco + 12.2f * UI_UNIT_X, yco, 0.95f * UI_UNIT_X, 0.95f * UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Proxy Protected")); - uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_LOCKED, xco + 13.1f * UI_UNIT_X, yco, 0.95f * UI_UNIT_X, 0.95f * UI_UNIT_Y, + uiDefIconBut(block, UI_BTYPE_BUT, B_CONSTRAINT_TEST, ICON_LOCKED, xco + 13.1f * UI_UNIT_X, yco, 0.95f * UI_UNIT_X, 0.95f * UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Proxy Protected")); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); } else { short prev_proxylock, show_upbut, show_downbut; @@ -1177,33 +1190,33 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con) show_downbut = (con->next) ? 1 : 0; /* enabled */ - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); uiItemR(row, &ptr, "mute", 0, "", (con->flag & CONSTRAINT_OFF) ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT); /* up/down */ if (show_upbut || show_downbut) { - uiBlockBeginAlign(block); + UI_block_align_begin(block); if (show_upbut) uiItemO(row, "", ICON_TRIA_UP, "CONSTRAINT_OT_move_up"); if (show_downbut) uiItemO(row, "", ICON_TRIA_DOWN, "CONSTRAINT_OT_move_down"); - uiBlockEndAlign(block); + UI_block_align_end(block); } /* Close 'button' - emboss calls here disable drawing of 'button' behind X */ - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); uiItemO(row, "", ICON_X, "CONSTRAINT_OT_delete"); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); } /* Set but-locks for protected settings (magic numbers are used here!) */ if (proxy_protected) - uiBlockSetButLock(block, true, IFACE_("Cannot edit Proxy-Protected Constraint")); + UI_block_lock_set(block, true, IFACE_("Cannot edit Proxy-Protected Constraint")); /* Draw constraint data */ if ((con->flag & CONSTRAINT_EXPAND) == 0) { @@ -1216,7 +1229,7 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con) } /* clear any locks set up for proxies/lib-linking */ - uiBlockClearButLock(block); + UI_block_lock_clear(block); return result; } @@ -1240,7 +1253,7 @@ uiLayout *uiTemplateConstraint(uiLayout *layout, PointerRNA *ptr) return NULL; } - uiBlockSetButLock(uiLayoutGetBlock(layout), (ob && ob->id.lib), ERROR_LIBDATA_MESSAGE); + UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ob->id.lib), ERROR_LIBDATA_MESSAGE); /* hrms, the temporal constraint should not draw! */ if (con->type == CONSTRAINT_TYPE_KINEMATIC) { @@ -1345,11 +1358,11 @@ void uiTemplatePreview(uiLayout *layout, bContext *C, ID *id, int show_buttons, uiLayoutSetKeepAspect(col, true); /* add preview */ - uiDefBut(block, BUT_EXTRA, 0, "", 0, 0, UI_UNIT_X * 10, ui_preview->height, pid, 0.0, 0.0, 0, 0, ""); - uiBlockSetDrawExtraFunc(block, ED_preview_draw, pparent, slot); - uiBlockSetHandleFunc(block, do_preview_buttons, NULL); + uiDefBut(block, UI_BTYPE_EXTRA, 0, "", 0, 0, UI_UNIT_X * 10, ui_preview->height, pid, 0.0, 0.0, 0, 0, ""); + UI_but_func_drawextra_set(block, ED_preview_draw, pparent, slot); + UI_block_func_handle_set(block, do_preview_buttons, NULL); - uiDefIconButS(block, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &ui_preview->height, + uiDefIconButS(block, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &ui_preview->height, UI_UNIT_Y, UI_UNIT_Y * 50.0f, 0.0f, 0.0f, ""); /* add buttons */ @@ -1371,25 +1384,25 @@ void uiTemplatePreview(uiLayout *layout, bContext *C, ID *id, int show_buttons, RNA_pointer_create(id, &RNA_Texture, tex, &texture_ptr); uiLayoutRow(layout, true); - uiDefButS(block, ROW, B_MATPRV, IFACE_("Texture"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, + uiDefButS(block, UI_BTYPE_ROW, B_MATPRV, IFACE_("Texture"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, pr_texture, 10, TEX_PR_TEXTURE, 0, 0, ""); if (GS(parent->name) == ID_MA) { - uiDefButS(block, ROW, B_MATPRV, IFACE_("Material"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, + uiDefButS(block, UI_BTYPE_ROW, B_MATPRV, IFACE_("Material"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, pr_texture, 10, TEX_PR_OTHER, 0, 0, ""); } else if (GS(parent->name) == ID_LA) { - uiDefButS(block, ROW, B_MATPRV, IFACE_("Lamp"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, + uiDefButS(block, UI_BTYPE_ROW, B_MATPRV, IFACE_("Lamp"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, pr_texture, 10, TEX_PR_OTHER, 0, 0, ""); } else if (GS(parent->name) == ID_WO) { - uiDefButS(block, ROW, B_MATPRV, IFACE_("World"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, + uiDefButS(block, UI_BTYPE_ROW, B_MATPRV, IFACE_("World"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, pr_texture, 10, TEX_PR_OTHER, 0, 0, ""); } else if (GS(parent->name) == ID_LS) { - uiDefButS(block, ROW, B_MATPRV, IFACE_("Line Style"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, + uiDefButS(block, UI_BTYPE_ROW, B_MATPRV, IFACE_("Line Style"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, pr_texture, 10, TEX_PR_OTHER, 0, 0, ""); } - uiDefButS(block, ROW, B_MATPRV, IFACE_("Both"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, + uiDefButS(block, UI_BTYPE_ROW, B_MATPRV, IFACE_("Both"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, pr_texture, 10, TEX_PR_BOTH, 0, 0, ""); /* Alpha button for texture preview */ @@ -1493,28 +1506,28 @@ static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand split = uiLayoutSplit(layout, 0.4f, false); - uiBlockSetEmboss(block, UI_EMBOSSN); - uiBlockBeginAlign(block); + UI_block_emboss_set(block, UI_EMBOSS_NONE); + UI_block_align_begin(block); row = uiLayoutRow(split, false); - bt = uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, "", 0, 0, 2.0f * unit, UI_UNIT_Y, NULL, + bt = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_ZOOMIN, "", 0, 0, 2.0f * unit, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Add a new color stop to the colorband")); - uiButSetNFunc(bt, colorband_add_cb, MEM_dupallocN(cb), coba); + UI_but_funcN_set(bt, colorband_add_cb, MEM_dupallocN(cb), coba); - bt = uiDefIconTextBut(block, BUT, 0, ICON_ZOOMOUT, "", xs + 2.0f * unit, ys + UI_UNIT_Y, 2.0f * unit, UI_UNIT_Y, + bt = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_ZOOMOUT, "", xs + 2.0f * unit, ys + UI_UNIT_Y, 2.0f * unit, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Delete the active position")); - uiButSetNFunc(bt, colorband_del_cb, MEM_dupallocN(cb), coba); + UI_but_funcN_set(bt, colorband_del_cb, MEM_dupallocN(cb), coba); - bt = uiDefIconTextBut(block, BUT, 0, ICON_ARROW_LEFTRIGHT, "", xs + 4.0f * unit, ys + UI_UNIT_Y, 2.0f * unit, UI_UNIT_Y, + bt = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_ARROW_LEFTRIGHT, "", xs + 4.0f * unit, ys + UI_UNIT_Y, 2.0f * unit, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Flip the color ramp")); - uiButSetNFunc(bt, colorband_flip_cb, MEM_dupallocN(cb), coba); - uiBlockEndAlign(block); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_but_funcN_set(bt, colorband_flip_cb, MEM_dupallocN(cb), coba); + UI_block_align_end(block); + UI_block_emboss_set(block, UI_EMBOSS); row = uiLayoutRow(split, false); - uiBlockBeginAlign(block); + UI_block_align_begin(block); uiItemR(row, &ptr, "color_mode", 0, "", ICON_NONE); if (ELEM(coba->color_mode, COLBAND_BLEND_HSV, COLBAND_BLEND_HSL)) { uiItemR(row, &ptr, "hue_interpolation", 0, "", ICON_NONE); @@ -1522,12 +1535,12 @@ static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand else { /* COLBAND_BLEND_RGB */ uiItemR(row, &ptr, "interpolation", 0, "", ICON_NONE); } - uiBlockEndAlign(block); + UI_block_align_end(block); row = uiLayoutRow(layout, false); - bt = uiDefBut(block, BUT_COLORBAND, 0, "", xs, ys, BLI_rctf_size_x(butr), UI_UNIT_Y, coba, 0, 0, 0, 0, ""); - uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + bt = uiDefBut(block, UI_BTYPE_COLORBAND, 0, "", xs, ys, BLI_rctf_size_x(butr), UI_UNIT_Y, coba, 0, 0, 0, 0, ""); + UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL); row = uiLayoutRow(layout, false); @@ -1540,34 +1553,34 @@ static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand split = uiLayoutSplit(layout, 0.3f, false); row = uiLayoutRow(split, false); - uiDefButS(block, NUM, 0, "", 0, 0, 5.0f * UI_UNIT_X, UI_UNIT_Y, &coba->cur, 0.0, (float)(MAX2(0, coba->tot - 1)), + uiDefButS(block, UI_BTYPE_NUM, 0, "", 0, 0, 5.0f * UI_UNIT_X, UI_UNIT_Y, &coba->cur, 0.0, (float)(MAX2(0, coba->tot - 1)), 0, 0, TIP_("Choose active color stop")); row = uiLayoutRow(split, false); uiItemR(row, &ptr, "position", 0, IFACE_("Pos"), ICON_NONE); bt = block->buttons.last; - uiButSetFunc(bt, colorband_update_cb, bt, coba); + UI_but_func_set(bt, colorband_update_cb, bt, coba); row = uiLayoutRow(layout, false); uiItemR(row, &ptr, "color", 0, "", ICON_NONE); bt = block->buttons.last; - uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL); } else { split = uiLayoutSplit(layout, 0.5f, false); subsplit = uiLayoutSplit(split, 0.35f, false); row = uiLayoutRow(subsplit, false); - uiDefButS(block, NUM, 0, "", 0, 0, 5.0f * UI_UNIT_X, UI_UNIT_Y, &coba->cur, 0.0, (float)(MAX2(0, coba->tot - 1)), + uiDefButS(block, UI_BTYPE_NUM, 0, "", 0, 0, 5.0f * UI_UNIT_X, UI_UNIT_Y, &coba->cur, 0.0, (float)(MAX2(0, coba->tot - 1)), 0, 0, TIP_("Choose active color stop")); row = uiLayoutRow(subsplit, false); uiItemR(row, &ptr, "position", UI_ITEM_R_SLIDER, IFACE_("Pos"), ICON_NONE); bt = block->buttons.last; - uiButSetFunc(bt, colorband_update_cb, bt, coba); + UI_but_func_set(bt, colorband_update_cb, bt, coba); row = uiLayoutRow(split, false); uiItemR(row, &ptr, "color", 0, "", ICON_NONE); bt = block->buttons.last; - uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL); } } } @@ -1598,11 +1611,11 @@ void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname block = uiLayoutAbsoluteBlock(layout); id = cptr.id.data; - uiBlockSetButLock(block, (id && id->lib), ERROR_LIBDATA_MESSAGE); + UI_block_lock_set(block, (id && id->lib), ERROR_LIBDATA_MESSAGE); colorband_buttons_layout(layout, block, cptr.data, &rect, cb, expand); - uiBlockClearButLock(block); + UI_block_lock_clear(block); MEM_freeN(cb); } @@ -1611,7 +1624,7 @@ void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname /********************* Icon viewer Template ************************/ /* ID Search browse menu, open */ -static uiBlock *icon_view_menu(bContext *C, ARegion *ar, void *arg_litem) +static uiBlock *ui_icon_view_menu_cb(bContext *C, ARegion *ar, void *arg_litem) { static RNAUpdateCb cb; uiBlock *block; @@ -1627,8 +1640,8 @@ static uiBlock *icon_view_menu(bContext *C, ARegion *ar, void *arg_litem) /* unused */ // icon = RNA_property_enum_get(&cb.ptr, cb.prop); - block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS); - uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_REDRAW); + block = UI_block_begin(C, ar, "_popup", UI_EMBOSS); + UI_block_flag_enable(block, UI_BLOCK_LOOP); RNA_property_enum_items(C, &cb.ptr, cb.prop, &item, NULL, &free); @@ -1641,12 +1654,12 @@ static uiBlock *icon_view_menu(bContext *C, ARegion *ar, void *arg_litem) y = (a / 8) * UI_UNIT_X * 5; icon = item[a].icon; - but = uiDefIconButR_prop(block, ROW, 0, icon, x, y, UI_UNIT_X * 5, UI_UNIT_Y * 5, &cb.ptr, cb.prop, -1, 0, icon, -1, -1, NULL); - uiButSetFlag(but, UI_HAS_ICON | UI_ICON_PREVIEW); + but = uiDefIconButR_prop(block, UI_BTYPE_ROW, 0, icon, x, y, UI_UNIT_X * 5, UI_UNIT_Y * 5, &cb.ptr, cb.prop, -1, 0, icon, -1, -1, NULL); + UI_but_flag_enable(but, UI_HAS_ICON | UI_BUT_ICON_PREVIEW); } - uiBoundsBlock(block, 0.3f * U.widget_unit); - uiBlockSetDirection(block, UI_TOP); + UI_block_bounds_set_normal(block, 0.3f * U.widget_unit); + UI_block_direction_set(block, UI_DIR_UP); if (free) { MEM_freeN(item); @@ -1678,15 +1691,15 @@ void uiTemplateIconView(uiLayout *layout, PointerRNA *ptr, const char *propname) block = uiLayoutAbsoluteBlock(layout); - but = uiDefBlockButN(block, icon_view_menu, MEM_dupallocN(cb), "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6, ""); + but = uiDefBlockButN(block, ui_icon_view_menu_cb, MEM_dupallocN(cb), "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6, ""); -// but = uiDefIconButR_prop(block, ROW, 0, icon, 0, 0, BLI_rctf_size_x(&rect), BLI_rctf_size_y(&rect), ptr, prop, -1, 0, icon, -1, -1, NULL); +// but = uiDefIconButR_prop(block, UI_BTYPE_ROW, 0, icon, 0, 0, BLI_rctf_size_x(&rect), BLI_rctf_size_y(&rect), ptr, prop, -1, 0, icon, -1, -1, NULL); but->icon = icon; - uiButSetFlag(but, UI_HAS_ICON | UI_ICON_PREVIEW); + UI_but_flag_enable(but, UI_HAS_ICON | UI_BUT_ICON_PREVIEW); - uiButSetNFunc(but, rna_update_cb, MEM_dupallocN(cb), NULL); + UI_but_funcN_set(but, rna_update_cb, MEM_dupallocN(cb), NULL); MEM_freeN(cb); } @@ -1719,10 +1732,10 @@ void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname col = uiLayoutColumn(layout, true); block = uiLayoutGetBlock(col); - uiDefBut(block, HISTOGRAM, 0, "", 0, 0, UI_UNIT_X * 10, hist->height, hist, 0, 0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_HISTOGRAM, 0, "", 0, 0, UI_UNIT_X * 10, hist->height, hist, 0, 0, 0, 0, ""); /* Resize grip. */ - uiDefIconButI(block, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &hist->height, + uiDefIconButI(block, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &hist->height, UI_UNIT_Y, UI_UNIT_Y * 20.0f, 0.0f, 0.0f, ""); } @@ -1754,10 +1767,10 @@ void uiTemplateWaveform(uiLayout *layout, PointerRNA *ptr, const char *propname) scopes->wavefrm_height = UI_UNIT_Y * 20; } - uiDefBut(block, WAVEFORM, 0, "", 0, 0, UI_UNIT_X * 10, scopes->wavefrm_height, scopes, 0, 0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_WAVEFORM, 0, "", 0, 0, UI_UNIT_X * 10, scopes->wavefrm_height, scopes, 0, 0, 0, 0, ""); /* Resize grip. */ - uiDefIconButI(block, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &scopes->wavefrm_height, + uiDefIconButI(block, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &scopes->wavefrm_height, UI_UNIT_Y, UI_UNIT_Y * 20.0f, 0.0f, 0.0f, ""); } @@ -1789,10 +1802,10 @@ void uiTemplateVectorscope(uiLayout *layout, PointerRNA *ptr, const char *propna col = uiLayoutColumn(layout, true); block = uiLayoutGetBlock(col); - uiDefBut(block, VECTORSCOPE, 0, "", 0, 0, UI_UNIT_X * 10, scopes->vecscope_height, scopes, 0, 0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_VECTORSCOPE, 0, "", 0, 0, UI_UNIT_X * 10, scopes->vecscope_height, scopes, 0, 0, 0, 0, ""); /* Resize grip. */ - uiDefIconButI(block, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &scopes->vecscope_height, + uiDefIconButI(block, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &scopes->vecscope_height, UI_UNIT_Y, UI_UNIT_Y * 20.0f, 0.0f, 0.0f, ""); } @@ -1879,28 +1892,27 @@ static uiBlock *curvemap_clipping_func(bContext *C, ARegion *ar, void *cumap_v) uiBut *bt; float width = 8 * UI_UNIT_X; - block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); + block = UI_block_begin(C, ar, __func__, UI_EMBOSS); /* use this for a fake extra empy space around the buttons */ - uiDefBut(block, LABEL, 0, "", -4, 16, width + 8, 6 * UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 0, "", -4, 16, width + 8, 6 * UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); - bt = uiDefButBitI(block, TOG, CUMA_DO_CLIP, 1, IFACE_("Use Clipping"), + bt = uiDefButBitI(block, UI_BTYPE_TOGGLE, CUMA_DO_CLIP, 1, IFACE_("Use Clipping"), 0, 5 * UI_UNIT_Y, width, UI_UNIT_Y, &cumap->flag, 0.0, 0.0, 10, 0, ""); - uiButSetFunc(bt, curvemap_buttons_setclip, cumap, NULL); + UI_but_func_set(bt, curvemap_buttons_setclip, cumap, NULL); - uiBlockBeginAlign(block); - uiDefButF(block, NUM, 0, IFACE_("Min X "), 0, 4 * UI_UNIT_Y, width, UI_UNIT_Y, + UI_block_align_begin(block); + uiDefButF(block, UI_BTYPE_NUM, 0, IFACE_("Min X "), 0, 4 * UI_UNIT_Y, width, UI_UNIT_Y, &cumap->clipr.xmin, -100.0, cumap->clipr.xmax, 10, 2, ""); - uiDefButF(block, NUM, 0, IFACE_("Min Y "), 0, 3 * UI_UNIT_Y, width, UI_UNIT_Y, + uiDefButF(block, UI_BTYPE_NUM, 0, IFACE_("Min Y "), 0, 3 * UI_UNIT_Y, width, UI_UNIT_Y, &cumap->clipr.ymin, -100.0, cumap->clipr.ymax, 10, 2, ""); - uiDefButF(block, NUM, 0, IFACE_("Max X "), 0, 2 * UI_UNIT_Y, width, UI_UNIT_Y, + uiDefButF(block, UI_BTYPE_NUM, 0, IFACE_("Max X "), 0, 2 * UI_UNIT_Y, width, UI_UNIT_Y, &cumap->clipr.xmax, cumap->clipr.xmin, 100.0, 10, 2, ""); - uiDefButF(block, NUM, 0, IFACE_("Max Y "), 0, UI_UNIT_Y, width, UI_UNIT_Y, + uiDefButF(block, UI_BTYPE_NUM, 0, IFACE_("Max Y "), 0, UI_UNIT_Y, width, UI_UNIT_Y, &cumap->clipr.ymax, cumap->clipr.ymin, 100.0, 10, 2, ""); - uiBlockSetDirection(block, UI_RIGHT); + UI_block_direction_set(block, UI_DIR_RIGHT); - uiEndBlock(C, block); return block; } @@ -1956,26 +1968,25 @@ static uiBlock *curvemap_tools_posslope_func(bContext *C, ARegion *ar, void *cum uiBlock *block; short yco = 0, menuwidth = 10 * UI_UNIT_X; - block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); - uiBlockSetButmFunc(block, curvemap_tools_dofunc, cumap_v); + block = UI_block_begin(C, ar, __func__, UI_EMBOSS); + UI_block_func_butmenu_set(block, curvemap_tools_dofunc, cumap_v); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset View"), 0, yco -= UI_UNIT_Y, + uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Reset View"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_RESET_VIEW, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Vector Handle"), 0, yco -= UI_UNIT_Y, + uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Vector Handle"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_HANDLE_VECTOR, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Auto Handle"), 0, yco -= UI_UNIT_Y, + uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Auto Handle"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_HANDLE_AUTO, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Extend Horizontal"), 0, yco -= UI_UNIT_Y, + uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Extend Horizontal"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_EXTEND_HOZ, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Extend Extrapolated"), 0, yco -= UI_UNIT_Y, + uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Extend Extrapolated"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_EXTEND_EXP, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset Curve"), 0, yco -= UI_UNIT_Y, + uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Reset Curve"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_RESET_POS, ""); - uiBlockSetDirection(block, UI_RIGHT); - uiTextBoundsBlock(block, 50); + UI_block_direction_set(block, UI_DIR_RIGHT); + UI_block_bounds_set_text(block, 50); - uiEndBlock(C, block); return block; } @@ -1984,26 +1995,25 @@ static uiBlock *curvemap_tools_negslope_func(bContext *C, ARegion *ar, void *cum uiBlock *block; short yco = 0, menuwidth = 10 * UI_UNIT_X; - block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); - uiBlockSetButmFunc(block, curvemap_tools_dofunc, cumap_v); + block = UI_block_begin(C, ar, __func__, UI_EMBOSS); + UI_block_func_butmenu_set(block, curvemap_tools_dofunc, cumap_v); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset View"), 0, yco -= UI_UNIT_Y, + uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Reset View"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_RESET_VIEW, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Vector Handle"), 0, yco -= UI_UNIT_Y, + uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Vector Handle"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_HANDLE_VECTOR, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Auto Handle"), 0, yco -= UI_UNIT_Y, + uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Auto Handle"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_HANDLE_AUTO, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Extend Horizontal"), 0, yco -= UI_UNIT_Y, + uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Extend Horizontal"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_EXTEND_HOZ, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Extend Extrapolated"), 0, yco -= UI_UNIT_Y, + uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Extend Extrapolated"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_EXTEND_EXP, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset Curve"), 0, yco -= UI_UNIT_Y, + uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Reset Curve"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_RESET_NEG, ""); - uiBlockSetDirection(block, UI_RIGHT); - uiTextBoundsBlock(block, 50); + UI_block_direction_set(block, UI_DIR_RIGHT); + UI_block_bounds_set_text(block, 50); - uiEndBlock(C, block); return block; } @@ -2012,22 +2022,21 @@ static uiBlock *curvemap_brush_tools_func(bContext *C, ARegion *ar, void *cumap_ uiBlock *block; short yco = 0, menuwidth = 10 * UI_UNIT_X; - block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); - uiBlockSetButmFunc(block, curvemap_tools_dofunc, cumap_v); + block = UI_block_begin(C, ar, __func__, UI_EMBOSS); + UI_block_func_butmenu_set(block, curvemap_tools_dofunc, cumap_v); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset View"), 0, yco -= UI_UNIT_Y, + uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Reset View"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_RESET_VIEW, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Vector Handle"), 0, yco -= UI_UNIT_Y, + uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Vector Handle"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_HANDLE_VECTOR, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Auto Handle"), 0, yco -= UI_UNIT_Y, + uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Auto Handle"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_HANDLE_AUTO, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset Curve"), 0, yco -= UI_UNIT_Y, + uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Reset Curve"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_RESET_NEG, ""); - uiBlockSetDirection(block, UI_RIGHT); - uiTextBoundsBlock(block, 50); + UI_block_direction_set(block, UI_DIR_RIGHT); + UI_block_bounds_set_text(block, 50); - uiEndBlock(C, block); return block; } @@ -2086,16 +2095,16 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT); if (cumap->cm[0].curve) { - bt = uiDefButI(block, ROW, 0, "X", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, ""); - uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL); + bt = uiDefButI(block, UI_BTYPE_ROW, 0, "X", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, ""); + UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL); } if (cumap->cm[1].curve) { - bt = uiDefButI(block, ROW, 0, "Y", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, ""); - uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL); + bt = uiDefButI(block, UI_BTYPE_ROW, 0, "Y", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, ""); + UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL); } if (cumap->cm[2].curve) { - bt = uiDefButI(block, ROW, 0, "Z", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, ""); - uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL); + bt = uiDefButI(block, UI_BTYPE_ROW, 0, "Z", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, ""); + UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL); } } else if (labeltype == 'c') { @@ -2104,20 +2113,20 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT); if (cumap->cm[3].curve) { - bt = uiDefButI(block, ROW, 0, "C", 0, 0, dx, dx, &cumap->cur, 0.0, 3.0, 0.0, 0.0, ""); - uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL); + bt = uiDefButI(block, UI_BTYPE_ROW, 0, "C", 0, 0, dx, dx, &cumap->cur, 0.0, 3.0, 0.0, 0.0, ""); + UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL); } if (cumap->cm[0].curve) { - bt = uiDefButI(block, ROW, 0, "R", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, ""); - uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL); + bt = uiDefButI(block, UI_BTYPE_ROW, 0, "R", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, ""); + UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL); } if (cumap->cm[1].curve) { - bt = uiDefButI(block, ROW, 0, "G", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, ""); - uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL); + bt = uiDefButI(block, UI_BTYPE_ROW, 0, "G", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, ""); + UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL); } if (cumap->cm[2].curve) { - bt = uiDefButI(block, ROW, 0, "B", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, ""); - uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL); + bt = uiDefButI(block, UI_BTYPE_ROW, 0, "B", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, ""); + UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL); } } else if (labeltype == 'h') { @@ -2126,16 +2135,16 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT); if (cumap->cm[0].curve) { - bt = uiDefButI(block, ROW, 0, "H", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, ""); - uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL); + bt = uiDefButI(block, UI_BTYPE_ROW, 0, "H", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, ""); + UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL); } if (cumap->cm[1].curve) { - bt = uiDefButI(block, ROW, 0, "S", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, ""); - uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL); + bt = uiDefButI(block, UI_BTYPE_ROW, 0, "S", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, ""); + UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL); } if (cumap->cm[2].curve) { - bt = uiDefButI(block, ROW, 0, "V", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, ""); - uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL); + bt = uiDefButI(block, UI_BTYPE_ROW, 0, "V", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, ""); + UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL); } } else @@ -2147,13 +2156,13 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe /* operation buttons */ sub = uiLayoutRow(row, true); - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); - bt = uiDefIconBut(block, BUT, 0, ICON_ZOOMIN, 0, 0, dx, dx, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Zoom in")); - uiButSetFunc(bt, curvemap_buttons_zoom_in, cumap, NULL); + bt = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_ZOOMIN, 0, 0, dx, dx, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Zoom in")); + UI_but_func_set(bt, curvemap_buttons_zoom_in, cumap, NULL); - bt = uiDefIconBut(block, BUT, 0, ICON_ZOOMOUT, 0, 0, dx, dx, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Zoom out")); - uiButSetFunc(bt, curvemap_buttons_zoom_out, cumap, NULL); + bt = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_ZOOMOUT, 0, 0, dx, dx, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Zoom out")); + UI_but_func_set(bt, curvemap_buttons_zoom_out, cumap, NULL); if (brush) bt = uiDefIconBlockBut(block, curvemap_brush_tools_func, cumap, 0, ICON_MODIFIER, 0, 0, dx, dx, TIP_("Tools")); @@ -2164,23 +2173,23 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe bt = uiDefIconBlockBut(block, curvemap_tools_posslope_func, cumap, 0, ICON_MODIFIER, 0, 0, dx, dx, TIP_("Tools")); - uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL); icon = (cumap->flag & CUMA_DO_CLIP) ? ICON_CLIPUV_HLT : ICON_CLIPUV_DEHLT; bt = uiDefIconBlockBut(block, curvemap_clipping_func, cumap, 0, icon, 0, 0, dx, dx, TIP_("Clipping Options")); - uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL); - bt = uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, dx, dx, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Delete points")); - uiButSetNFunc(bt, curvemap_buttons_delete, MEM_dupallocN(cb), cumap); + bt = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_X, 0, 0, dx, dx, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Delete points")); + UI_but_funcN_set(bt, curvemap_buttons_delete, MEM_dupallocN(cb), cumap); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); - uiBlockSetNFunc(block, rna_update_cb, MEM_dupallocN(cb), NULL); + UI_block_funcN_set(block, rna_update_cb, MEM_dupallocN(cb), NULL); /* curve itself */ size = uiLayoutGetWidth(layout); row = uiLayoutRow(layout, false); - uiDefBut(block, BUT_CURVE, 0, "", 0, 0, size, 8.0f * UI_UNIT_X, cumap, 0.0f, 1.0f, bg, 0, ""); + uiDefBut(block, UI_BTYPE_CURVE, 0, "", 0, 0, size, 8.0f * UI_UNIT_X, cumap, 0.0f, 1.0f, bg, 0, ""); /* sliders for selected point */ for (i = 0; i < cm->totpoint; i++) { @@ -2202,10 +2211,10 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe } uiLayoutRow(layout, true); - uiBlockSetNFunc(block, curvemap_buttons_update, MEM_dupallocN(cb), cumap); - uiDefButF(block, NUM, 0, "X", 0, 2 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y, + UI_block_funcN_set(block, curvemap_buttons_update, MEM_dupallocN(cb), cumap); + uiDefButF(block, UI_BTYPE_NUM, 0, "X", 0, 2 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y, &cmp->x, bounds.xmin, bounds.xmax, 1, 5, ""); - uiDefButF(block, NUM, 0, "Y", 0, 1 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y, + uiDefButF(block, UI_BTYPE_NUM, 0, "Y", 0, 1 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y, &cmp->y, bounds.ymin, bounds.ymax, 1, 5, ""); } @@ -2216,12 +2225,12 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe uiItemR(uiLayoutColumn(split, false), ptr, "white_level", UI_ITEM_R_EXPAND, NULL, ICON_NONE); uiLayoutRow(layout, false); - bt = uiDefBut(block, BUT, 0, IFACE_("Reset"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, + bt = uiDefBut(block, UI_BTYPE_BUT, 0, IFACE_("Reset"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, TIP_("Reset Black/White point and curves")); - uiButSetNFunc(bt, curvemap_buttons_reset, MEM_dupallocN(cb), cumap); + UI_but_funcN_set(bt, curvemap_buttons_reset, MEM_dupallocN(cb), cumap); } - uiBlockSetNFunc(block, NULL, NULL, NULL); + UI_block_funcN_set(block, NULL, NULL, NULL); } void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, const char *propname, int type, @@ -2254,11 +2263,11 @@ void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, const char *propn cb->prop = prop; id = cptr.id.data; - uiBlockSetButLock(block, (id && id->lib), ERROR_LIBDATA_MESSAGE); + UI_block_lock_set(block, (id && id->lib), ERROR_LIBDATA_MESSAGE); curvemap_buttons_layout(layout, &cptr, type, levels, brush, neg_slope, cb); - uiBlockClearButLock(block); + UI_block_lock_clear(block); MEM_freeN(cb); } @@ -2275,6 +2284,7 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna uiBlock *block = uiLayoutGetBlock(layout); uiLayout *col, *row; uiBut *but = NULL; + ColorPicker *cpicker = ui_block_colorpicker_create(block); float softmin, softmax, step, precision; if (!prop) { @@ -2289,15 +2299,15 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna switch (U.color_picker_type) { case USER_CP_SQUARE_SV: - but = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop, + but = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop, -1, 0.0, 0.0, UI_GRAD_SV, 0, ""); break; case USER_CP_SQUARE_HS: - but = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop, + but = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop, -1, 0.0, 0.0, UI_GRAD_HS, 0, ""); break; case USER_CP_SQUARE_HV: - but = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop, + but = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop, -1, 0.0, 0.0, UI_GRAD_HV, 0, ""); break; @@ -2305,12 +2315,14 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna case USER_CP_CIRCLE_HSV: case USER_CP_CIRCLE_HSL: default: - but = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop, + but = uiDefButR_prop(block, UI_BTYPE_HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop, -1, 0.0, 0.0, 0, 0, ""); break; } + but->custom_data = cpicker; + if (lock) { but->flag |= UI_BUT_COLOR_LOCK; } @@ -2330,33 +2342,35 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna switch (U.color_picker_type) { case USER_CP_CIRCLE_HSL: uiItemS(row); - uiDefButR_prop(block, HSVCUBE, 0, "", WHEEL_SIZE + 6, 0, 14, WHEEL_SIZE, ptr, prop, - -1, softmin, softmax, UI_GRAD_L_ALT, 0, ""); + but = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", WHEEL_SIZE + 6, 0, 14, WHEEL_SIZE, ptr, prop, + -1, softmin, softmax, UI_GRAD_L_ALT, 0, ""); break; case USER_CP_SQUARE_SV: uiItemS(col); - uiDefButR_prop(block, HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop, - -1, softmin, softmax, UI_GRAD_SV + 3, 0, ""); + but = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop, + -1, softmin, softmax, UI_GRAD_SV + 3, 0, ""); break; case USER_CP_SQUARE_HS: uiItemS(col); - uiDefButR_prop(block, HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop, - -1, softmin, softmax, UI_GRAD_HS + 3, 0, ""); + but = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop, + -1, softmin, softmax, UI_GRAD_HS + 3, 0, ""); break; case USER_CP_SQUARE_HV: uiItemS(col); - uiDefButR_prop(block, HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop, - -1, softmin, softmax, UI_GRAD_HV + 3, 0, ""); + but = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop, + -1, softmin, softmax, UI_GRAD_HV + 3, 0, ""); break; /* user default */ case USER_CP_CIRCLE_HSV: default: uiItemS(row); - uiDefButR_prop(block, HSVCUBE, 0, "", WHEEL_SIZE + 6, 0, 14, WHEEL_SIZE, ptr, prop, - -1, softmin, softmax, UI_GRAD_V_ALT, 0, ""); + but = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", WHEEL_SIZE + 6, 0, 14, WHEEL_SIZE, ptr, prop, + -1, softmin, softmax, UI_GRAD_V_ALT, 0, ""); break; } + + but->custom_data = cpicker; } } @@ -2391,8 +2405,8 @@ void uiTemplatePalette(uiLayout *layout, PointerRNA *ptr, const char *propname, col = uiLayoutColumn(layout, true); uiLayoutRow(col, true); - uiDefIconButO(block, BUT, "PALETTE_OT_color_add", WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL); - uiDefIconButO(block, BUT, "PALETTE_OT_color_delete", WM_OP_INVOKE_DEFAULT, ICON_ZOOMOUT, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL); + uiDefIconButO(block, UI_BTYPE_BUT, "PALETTE_OT_color_add", WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL); + uiDefIconButO(block, UI_BTYPE_BUT, "PALETTE_OT_color_delete", WM_OP_INVOKE_DEFAULT, ICON_ZOOMOUT, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL); col = uiLayoutColumn(layout, true); uiLayoutRow(col, true); @@ -2406,7 +2420,7 @@ void uiTemplatePalette(uiLayout *layout, PointerRNA *ptr, const char *propname, } RNA_pointer_create(&palette->id, &RNA_PaletteColor, color, &ptr); - uiDefButR(block, COLOR, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, &ptr, "color", -1, 0.0, 1.0, + uiDefButR(block, UI_BTYPE_COLOR, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, &ptr, "color", -1, 0.0, 1.0, UI_PALETTE_COLOR, col_id, ""); row_cols++; col_id++; @@ -2502,8 +2516,8 @@ void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, const char *propname, icon = ICON_LAYER_USED; but = uiDefAutoButR(block, ptr, prop, layer, "", icon, 0, 0, UI_UNIT_X / 2, UI_UNIT_Y / 2); - uiButSetFunc(but, handle_layer_buttons, but, SET_INT_IN_POINTER(layer)); - but->type = TOG; + UI_but_func_set(but, handle_layer_buttons, but, SET_INT_IN_POINTER(layer)); + but->type = UI_BTYPE_TOGGLE; } } } @@ -2569,10 +2583,10 @@ void uiTemplateGameStates(uiLayout *layout, PointerRNA *ptr, const char *propnam else if (used_prop && RNA_property_boolean_get_index(used_ptr, used_prop, state)) icon = ICON_LAYER_USED; - but = uiDefIconButR_prop(block, ICONTOG, 0, icon, 0, 0, UI_UNIT_X / 2, UI_UNIT_Y / 2, ptr, prop, + but = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, icon, 0, 0, UI_UNIT_X / 2, UI_UNIT_Y / 2, ptr, prop, state, 0, 0, -1, -1, sca_state_name_get(ob, state)); - uiButSetFunc(but, handle_layer_buttons, but, SET_INT_IN_POINTER(state)); - but->type = TOG; + UI_but_func_set(but, handle_layer_buttons, but, SET_INT_IN_POINTER(state)); + but->type = UI_BTYPE_TOGGLE; } } } @@ -2758,7 +2772,7 @@ typedef struct { int end_idx; /* Index of last item to display + 1. */ } uiListLayoutdata; -static void prepare_list(uiList *ui_list, int len, int activei, int rows, int maxrows, int columns, +static void uilist_prepare(uiList *ui_list, int len, int activei, int rows, int maxrows, int columns, uiListLayoutdata *layoutdata) { uiListDyn *dyn_data = ui_list->dyn_data; @@ -2812,7 +2826,7 @@ static void prepare_list(uiList *ui_list, int len, int activei, int rows, int ma layoutdata->end_idx = min_ii(layoutdata->start_idx + rows * columns, len); } -static void ui_list_resize_update_cb(bContext *UNUSED(C), void *arg1, void *UNUSED(arg2)) +static void uilist_resize_update_cb(bContext *UNUSED(C), void *arg1, void *UNUSED(arg2)) { uiList *ui_list = arg1; uiListDyn *dyn_data = ui_list->dyn_data; @@ -3037,7 +3051,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co col = uiLayoutColumn(row, true); /* init numbers */ - prepare_list(ui_list, len, activei, rows, maxrows, 1, &layoutdata); + uilist_prepare(ui_list, len, activei, rows, maxrows, 1, &layoutdata); if (dataptr->data && prop) { /* create list items */ @@ -3049,12 +3063,12 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co overlap = uiLayoutOverlap(col); - uiBlockSetFlag(subblock, UI_BLOCK_LIST_ITEM); + UI_block_flag_enable(subblock, UI_BLOCK_LIST_ITEM); /* list item behind label & other buttons */ sub = uiLayoutRow(overlap, false); - but = uiDefButR_prop(subblock, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, + but = uiDefButR_prop(subblock, UI_BTYPE_LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, active_dataptr, activeprop, 0, 0, org_i, 0, 0, TIP_("Double click to rename")); sub = uiLayoutRow(overlap, false); @@ -3070,7 +3084,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co ui_layout_list_set_labels_active(sub); } - uiBlockClearFlag(subblock, UI_BLOCK_LIST_ITEM); + UI_block_flag_disable(subblock, UI_BLOCK_LIST_ITEM); } } @@ -3082,7 +3096,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co /* add scrollbar */ if (len > layoutdata.visual_items) { col = uiLayoutColumn(row, false); - uiDefButI(block, SCROLL, 0, "", 0, 0, UI_UNIT_X * 0.75, UI_UNIT_Y * dyn_data->visual_height, + uiDefButI(block, UI_BTYPE_SCROLL, 0, "", 0, 0, UI_UNIT_X * 0.75, UI_UNIT_Y * dyn_data->visual_height, &ui_list->list_scroll, 0, dyn_data->height - dyn_data->visual_height, dyn_data->visual_height, 0, ""); } @@ -3108,10 +3122,10 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co /* next/prev button */ BLI_snprintf(numstr, sizeof(numstr), "%d :", dyn_data->items_shown); - but = uiDefIconTextButR_prop(block, NUM, 0, 0, numstr, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, + but = uiDefIconTextButR_prop(block, UI_BTYPE_NUM, 0, 0, numstr, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, active_dataptr, activeprop, 0, 0, 0, 0, 0, ""); if (dyn_data->items_shown == 0) - uiButSetFlag(but, UI_BUT_DISABLED); + UI_but_flag_enable(but, UI_BUT_DISABLED); break; case UILST_LAYOUT_GRID: box = uiLayoutListBox(layout, ui_list, dataptr, prop, active_dataptr, activeprop); @@ -3120,7 +3134,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co col = uiLayoutColumn(row, true); subrow = NULL; /* Quite gcc warning! */ - prepare_list(ui_list, len, activei, rows, maxrows, columns, &layoutdata); + uilist_prepare(ui_list, len, activei, rows, maxrows, columns, &layoutdata); if (dataptr->data && prop) { /* create list items */ @@ -3136,14 +3150,14 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co subblock = uiLayoutGetBlock(subrow); overlap = uiLayoutOverlap(subrow); - uiBlockSetFlag(subblock, UI_BLOCK_LIST_ITEM); + UI_block_flag_enable(subblock, UI_BLOCK_LIST_ITEM); /* list item behind label & other buttons */ sub = uiLayoutRow(overlap, false); - but = uiDefButR_prop(subblock, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, + but = uiDefButR_prop(subblock, UI_BTYPE_LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, active_dataptr, activeprop, 0, 0, org_i, 0, 0, NULL); - uiButSetDrawFlag(but, UI_BUT_NO_TOOLTIP); + UI_but_drawflag_enable(but, UI_BUT_NO_TOOLTIP); sub = uiLayoutRow(overlap, false); @@ -3156,7 +3170,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co ui_layout_list_set_labels_active(sub); } - uiBlockClearFlag(subblock, UI_BLOCK_LIST_ITEM); + UI_block_flag_disable(subblock, UI_BLOCK_LIST_ITEM); } } @@ -3171,7 +3185,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co /* add scrollbar */ if (len > layoutdata.visual_items) { col = uiLayoutColumn(row, false); - uiDefButI(block, SCROLL, 0, "", 0, 0, UI_UNIT_X * 0.75, UI_UNIT_Y * dyn_data->visual_height, + uiDefButI(block, UI_BTYPE_SCROLL, 0, "", 0, 0, UI_UNIT_X * 0.75, UI_UNIT_Y * dyn_data->visual_height, &ui_list->list_scroll, 0, dyn_data->height - dyn_data->visual_height, dyn_data->visual_height, 0, ""); } @@ -3179,8 +3193,8 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co } if (glob) { - /* About GRIP drag-resize: - * We can't directly use results from GRIP button, since we have a rather complex behavior here + /* About UI_BTYPE_GRIP drag-resize: + * We can't directly use results from a grip button, since we have a rather complex behavior here * (sizing by discrete steps and, overall, autosize feature). * Since we *never* know whether we are grip-resizing or not (because there is no callback for when a * button enters/leaves its "edit mode"), we use the fact that grip-controlled value (dyn_data->resize) @@ -3193,37 +3207,37 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co row = uiLayoutRow(glob, true); subblock = uiLayoutGetBlock(row); - uiBlockSetEmboss(subblock, UI_EMBOSSN); + UI_block_emboss_set(subblock, UI_EMBOSS_NONE); if (ui_list->filter_flag & UILST_FLT_SHOW) { - but = uiDefIconButBitI(subblock, TOG, UILST_FLT_SHOW, 0, ICON_DISCLOSURE_TRI_DOWN, 0, 0, + but = uiDefIconButBitI(subblock, UI_BTYPE_TOGGLE, UILST_FLT_SHOW, 0, ICON_DISCLOSURE_TRI_DOWN, 0, 0, UI_UNIT_X, UI_UNIT_Y * 0.5f, &(ui_list->filter_flag), 0, 0, 0, 0, TIP_("Hide filtering options")); - uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ + UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */ - but = uiDefIconButI(subblock, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10.0f, UI_UNIT_Y * 0.5f, + but = uiDefIconButI(subblock, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10.0f, UI_UNIT_Y * 0.5f, &dyn_data->resize, 0.0, 0.0, 0, 0, ""); - uiButSetFunc(but, ui_list_resize_update_cb, ui_list, NULL); + UI_but_func_set(but, uilist_resize_update_cb, ui_list, NULL); - uiBlockSetEmboss(subblock, UI_EMBOSS); + UI_block_emboss_set(subblock, UI_EMBOSS); col = uiLayoutColumn(glob, false); subblock = uiLayoutGetBlock(col); - uiDefBut(subblock, SEPR, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y * 0.05f, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(subblock, UI_BTYPE_SEPR, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y * 0.05f, NULL, 0.0, 0.0, 0, 0, ""); draw_filter(ui_list, C, col); } else { - but = uiDefIconButBitI(subblock, TOG, UILST_FLT_SHOW, 0, ICON_DISCLOSURE_TRI_RIGHT, 0, 0, + but = uiDefIconButBitI(subblock, UI_BTYPE_TOGGLE, UILST_FLT_SHOW, 0, ICON_DISCLOSURE_TRI_RIGHT, 0, 0, UI_UNIT_X, UI_UNIT_Y * 0.5f, &(ui_list->filter_flag), 0, 0, 0, 0, TIP_("Show filtering options")); - uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ + UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */ - but = uiDefIconButI(subblock, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10.0f, UI_UNIT_Y * 0.5f, + but = uiDefIconButI(subblock, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10.0f, UI_UNIT_Y * 0.5f, &dyn_data->resize, 0.0, 0.0, 0, 0, ""); - uiButSetFunc(but, ui_list_resize_update_cb, ui_list, NULL); + UI_but_func_set(but, uilist_resize_update_cb, ui_list, NULL); - uiBlockSetEmboss(subblock, UI_EMBOSS); + UI_block_emboss_set(subblock, UI_EMBOSS); } } @@ -3244,10 +3258,10 @@ static void operator_call_cb(bContext *C, void *UNUSED(arg1), void *arg2) static void operator_search_cb(const bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items) { - GHashIterator *iter = WM_operatortype_iter(); + GHashIterator iter; - for (; !BLI_ghashIterator_done(iter); BLI_ghashIterator_step(iter)) { - wmOperatorType *ot = BLI_ghashIterator_getValue(iter); + for (WM_operatortype_iter(&iter); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) { + wmOperatorType *ot = BLI_ghashIterator_getValue(&iter); if ((ot->flag & OPTYPE_INTERNAL) && (G.debug & G_DEBUG_WM) == 0) continue; @@ -3269,17 +3283,16 @@ static void operator_search_cb(const bContext *C, void *UNUSED(arg), const char } } - if (false == uiSearchItemAdd(items, name, ot, 0)) + if (false == UI_search_item_add(items, name, ot, 0)) break; } } } - BLI_ghashIterator_free(iter); } -void uiOperatorSearch_But(uiBut *but) +void UI_but_func_operator_search(uiBut *but) { - uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb, NULL); + UI_but_func_search_set(but, operator_search_cb, NULL, operator_call_cb, NULL); } void uiTemplateOperatorSearch(uiLayout *layout) @@ -3289,10 +3302,10 @@ void uiTemplateOperatorSearch(uiLayout *layout) static char search[256] = ""; block = uiLayoutGetBlock(layout); - uiBlockSetCurLayout(block, layout); + UI_block_layout_set_current(block, layout); but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, 0, 0, ""); - uiOperatorSearch_But(but); + UI_but_func_operator_search(but); } /************************* Running Jobs Template **************************/ @@ -3342,9 +3355,9 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C) int handle_event; block = uiLayoutGetBlock(layout); - uiBlockSetCurLayout(block, layout); + UI_block_layout_set_current(block, layout); - uiBlockSetHandleFunc(block, do_running_jobs, NULL); + UI_block_func_handle_set(block, do_running_jobs, NULL); if (sa->spacetype == SPACE_SEQ) { if (WM_jobs_test(wm, sa, WM_JOB_TYPE_ANY)) @@ -3394,18 +3407,18 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C) ui_abs = uiLayoutAbsolute(layout, false); (void)ui_abs; /* UNUSED */ - uiDefIconBut(block, BUT, handle_event, ICON_PANEL_CLOSE, 0, UI_UNIT_Y * 0.1, UI_UNIT_X * 0.8, UI_UNIT_Y * 0.8, + uiDefIconBut(block, UI_BTYPE_BUT, handle_event, ICON_PANEL_CLOSE, 0, UI_UNIT_Y * 0.1, UI_UNIT_X * 0.8, UI_UNIT_Y * 0.8, NULL, 0.0f, 0.0f, 0, 0, TIP_("Stop this job")); - uiDefBut(block, PROGRESSBAR, 0, WM_jobs_name(wm, owner), + uiDefBut(block, UI_BTYPE_PROGRESS_BAR, 0, WM_jobs_name(wm, owner), UI_UNIT_X, 0, UI_UNIT_X * 5.0f, UI_UNIT_Y, NULL, 0.0f, 0.0f, WM_jobs_progress(wm, owner), 0, TIP_("Progress")); uiLayoutRow(layout, false); } if (WM_jobs_test(wm, screen, WM_JOB_TYPE_SCREENCAST)) - uiDefIconTextBut(block, BUT, B_STOPCAST, ICON_CANCEL, IFACE_("Capture"), 0, 0, UI_UNIT_X * 4.25f, UI_UNIT_Y, + uiDefIconTextBut(block, UI_BTYPE_BUT, B_STOPCAST, ICON_CANCEL, IFACE_("Capture"), 0, 0, UI_UNIT_X * 4.25f, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, TIP_("Stop screencast")); if (screen->animtimer) - uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_CANCEL, IFACE_("Anim Player"), 0, 0, UI_UNIT_X * 5.0f, UI_UNIT_Y, + uiDefIconTextBut(block, UI_BTYPE_BUT, B_STOPANIM, ICON_CANCEL, IFACE_("Anim Player"), 0, 0, UI_UNIT_X * 5.0f, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, TIP_("Stop animation playback")); } @@ -3420,7 +3433,7 @@ void uiTemplateReportsBanner(uiLayout *layout, bContext *C) uiLayout *ui_abs; uiBlock *block; uiBut *but; - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_style_get(); int width; int icon; @@ -3439,37 +3452,37 @@ void uiTemplateReportsBanner(uiLayout *layout, bContext *C) width = max_ii(width, 10); /* make a box around the report to make it stand out */ - uiBlockBeginAlign(block); - but = uiDefBut(block, ROUNDBOX, 0, "", 0, 0, UI_UNIT_X + 10, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); - /* set the report's bg color in but->col - ROUNDBOX feature */ + UI_block_align_begin(block); + but = uiDefBut(block, UI_BTYPE_ROUNDBOX, 0, "", 0, 0, UI_UNIT_X + 10, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); + /* set the report's bg color in but->col - UI_BTYPE_ROUNDBOX feature */ rgb_float_to_uchar(but->col, rti->col); but->col[3] = 255; - but = uiDefBut(block, ROUNDBOX, 0, "", UI_UNIT_X + 10, 0, UI_UNIT_X + width, UI_UNIT_Y, + but = uiDefBut(block, UI_BTYPE_ROUNDBOX, 0, "", UI_UNIT_X + 10, 0, UI_UNIT_X + width, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); but->col[0] = but->col[1] = but->col[2] = FTOCHAR(rti->grayscale); but->col[3] = 255; - uiBlockEndAlign(block); + UI_block_align_end(block); /* icon and report message on top */ - icon = uiIconFromReportType(report->type); + icon = UI_icon_from_report_type(report->type); /* XXX: temporary operator to dump all reports to a text block, but only if more than 1 report * to be shown instead of icon when appropriate... */ - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); if (reports->list.first != reports->list.last) - uiDefIconButO(block, BUT, "UI_OT_reports_to_textblock", WM_OP_INVOKE_REGION_WIN, icon, 2, 0, UI_UNIT_X, + uiDefIconButO(block, UI_BTYPE_BUT, "UI_OT_reports_to_textblock", WM_OP_INVOKE_REGION_WIN, icon, 2, 0, UI_UNIT_X, UI_UNIT_Y, TIP_("Click to see the remaining reports in text block: 'Recent Reports'")); else - uiDefIconBut(block, LABEL, 0, icon, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); + uiDefIconBut(block, UI_BTYPE_LABEL, 0, icon, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); - uiDefBut(block, LABEL, 0, report->message, UI_UNIT_X + 10, 0, UI_UNIT_X + width, UI_UNIT_Y, + uiDefBut(block, UI_BTYPE_LABEL, 0, report->message, UI_UNIT_X + 10, 0, UI_UNIT_X + width, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); } @@ -3518,11 +3531,11 @@ static void template_keymap_item_properties(uiLayout *layout, const char *title, if (is_set) { /* unset operator */ uiBlock *block = uiLayoutGetBlock(row); - uiBlockSetEmboss(block, UI_EMBOSSN); - but = uiDefIconButO(block, BUT, "UI_OT_unset_property_button", WM_OP_EXEC_DEFAULT, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL); + UI_block_emboss_set(block, UI_EMBOSS_NONE); + but = uiDefIconButO(block, UI_BTYPE_BUT, "UI_OT_unset_property_button", WM_OP_EXEC_DEFAULT, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL); but->rnapoin = *ptr; but->rnaprop = prop; - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); } } RNA_STRUCT_END; @@ -3542,7 +3555,7 @@ void uiTemplateKeymapItemProperties(uiLayout *layout, PointerRNA *ptr) for (; but; but = but->next) { /* operator buttons may store props for use (file selector, [#36492]) */ if (but->rnaprop) { - uiButSetFunc(but, keymap_item_modified, ptr->data, NULL); + UI_but_func_set(but, keymap_item_modified, ptr->data, NULL); } } } @@ -3617,15 +3630,15 @@ static uiBlock *component_menu(bContext *C, ARegion *ar, void *args_v) uiBlock *block; uiLayout *layout; - block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); - uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN); + block = UI_block_begin(C, ar, __func__, UI_EMBOSS); + UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN); - layout = uiLayoutColumn(uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, 0, UI_GetStyle()), 0); + layout = uiLayoutColumn(UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, 0, UI_style_get()), 0); uiItemR(layout, &args->ptr, args->propname, UI_ITEM_R_EXPAND, "", ICON_NONE); - uiBoundsBlock(block, 6); - uiBlockSetDirection(block, UI_DOWN); + UI_block_bounds_set_normal(block, 6); + UI_block_direction_set(block, UI_DIR_DOWN); return block; } @@ -3639,7 +3652,7 @@ void uiTemplateComponentMenu(uiLayout *layout, PointerRNA *ptr, const char *prop BLI_strncpy(args->propname, propname, sizeof(args->propname)); block = uiLayoutGetBlock(layout); - uiBlockBeginAlign(block); + UI_block_align_begin(block); but = uiDefBlockButN(block, component_menu, args, name, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, ""); /* set rna directly, uiDefBlockButN doesn't do this */ @@ -3647,7 +3660,7 @@ void uiTemplateComponentMenu(uiLayout *layout, PointerRNA *ptr, const char *prop but->rnaprop = RNA_struct_find_property(ptr, propname); but->rnaindex = 0; - uiBlockEndAlign(block); + UI_block_align_end(block); } /************************* Node Socket Icon **************************/ @@ -3658,14 +3671,14 @@ void uiTemplateNodeSocket(uiLayout *layout, bContext *UNUSED(C), float *color) uiBut *but; block = uiLayoutGetBlock(layout); - uiBlockBeginAlign(block); + UI_block_align_begin(block); /* XXX using explicit socket colors is not quite ideal. * Eventually it should be possible to use theme colors for this purpose, * but this requires a better design for extendable color palettes in user prefs. */ - but = uiDefBut(block, NODESOCKET, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); + but = uiDefBut(block, UI_BTYPE_NODE_SOCKET, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); rgba_float_to_uchar(but->col, color); - uiBlockEndAlign(block); + UI_block_align_end(block); } diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index 008ea84b607..6cd5f5a7e05 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -70,11 +70,11 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind return NULL; if (icon && name && name[0] == '\0') - but = uiDefIconButR_prop(block, ICONTOG, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); + but = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else if (icon) - but = uiDefIconTextButR_prop(block, ICONTOG, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); + but = uiDefIconTextButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else - but = uiDefButR_prop(block, OPTION, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); + but = uiDefButR_prop(block, UI_BTYPE_CHECKBOX, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); break; } case PROP_INT: @@ -84,29 +84,29 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind if (arraylen && index == -1) { if (ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA)) - but = uiDefButR_prop(block, COLOR, 0, name, x1, y1, x2, y2, ptr, prop, -1, 0, 0, -1, -1, NULL); + but = uiDefButR_prop(block, UI_BTYPE_COLOR, 0, name, x1, y1, x2, y2, ptr, prop, -1, 0, 0, -1, -1, NULL); } else if (RNA_property_subtype(prop) == PROP_PERCENTAGE || RNA_property_subtype(prop) == PROP_FACTOR) - but = uiDefButR_prop(block, NUMSLI, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); + but = uiDefButR_prop(block, UI_BTYPE_NUM_SLIDER, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else - but = uiDefButR_prop(block, NUM, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); + but = uiDefButR_prop(block, UI_BTYPE_NUM, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); break; } case PROP_ENUM: if (icon && name && name[0] == '\0') - but = uiDefIconButR_prop(block, MENU, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); + but = uiDefIconButR_prop(block, UI_BTYPE_MENU, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else if (icon) - but = uiDefIconTextButR_prop(block, MENU, 0, icon, NULL, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); + but = uiDefIconTextButR_prop(block, UI_BTYPE_MENU, 0, icon, NULL, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else - but = uiDefButR_prop(block, MENU, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); + but = uiDefButR_prop(block, UI_BTYPE_MENU, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); break; case PROP_STRING: if (icon && name && name[0] == '\0') - but = uiDefIconButR_prop(block, TEX, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); + but = uiDefIconButR_prop(block, UI_BTYPE_TEXT, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else if (icon) - but = uiDefIconTextButR_prop(block, TEX, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); + but = uiDefIconTextButR_prop(block, UI_BTYPE_TEXT, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else - but = uiDefButR_prop(block, TEX, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); + but = uiDefButR_prop(block, UI_BTYPE_TEXT, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); break; case PROP_POINTER: { @@ -119,15 +119,15 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind if (icon == ICON_DOT) icon = 0; - but = uiDefIconTextButR_prop(block, SEARCH_MENU, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); + but = uiDefIconTextButR_prop(block, UI_BTYPE_SEARCH_MENU, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); break; } case PROP_COLLECTION: { char text[256]; BLI_snprintf(text, sizeof(text), IFACE_("%d items"), RNA_property_collection_length(ptr, prop)); - but = uiDefBut(block, LABEL, 0, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, NULL); - uiButSetFlag(but, UI_BUT_DISABLED); + but = uiDefBut(block, UI_BTYPE_LABEL, 0, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, NULL); + UI_but_flag_enable(but, UI_BUT_DISABLED); break; } default: @@ -201,7 +201,7 @@ int uiDefAutoButsRNA(uiLayout *layout, PointerRNA *ptr, /***************************** ID Utilities *******************************/ -int uiIconFromID(ID *id) +int UI_icon_from_id(ID *id) { Object *ob; PointerRNA ptr; @@ -219,7 +219,7 @@ int uiIconFromID(ID *id) if (ob->type == OB_EMPTY) return ICON_EMPTY_DATA; else - return uiIconFromID(ob->data); + return UI_icon_from_id(ob->data); } /* otherwise get it through RNA, creating the pointer @@ -230,7 +230,7 @@ int uiIconFromID(ID *id) } /* see: report_type_str */ -int uiIconFromReportType(int type) +int UI_icon_from_report_type(int type) { if (type & RPT_ERROR_ALL) return ICON_ERROR; @@ -247,7 +247,7 @@ int uiIconFromReportType(int type) /** * Returns the best "UI" precision for given floating value, so that e.g. 10.000001 rather gets drawn as '10'... */ -int uiFloatPrecisionCalc(int prec, double value) +int UI_calc_float_precision(int prec, double value) { static const double pow10_neg[UI_PRECISION_FLOAT_MAX + 1] = {1e0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7}; static const double max_pow = 10000000.0; /* pow(10, UI_PRECISION_FLOAT_MAX) */ @@ -390,6 +390,27 @@ void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p) } /** + * Update the pointer for a registered button. + */ +bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *but_src) +{ + uiButStore *bs_handle; + bool found = false; + + for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) { + uiButStoreElem *bs_elem; + for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) { + if (*bs_elem->but_p == but_src) { + *bs_elem->but_p = but_dst; + found = true; + } + } + } + + return found; +} + +/** * NULL all pointers, don't free since the owner needs to be able to inspect. */ void UI_butstore_clear(uiBlock *block) diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 2355d2be9e6..645637d5130 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -59,6 +59,10 @@ #include "interface_intern.h" +#ifdef WITH_INPUT_IME +# include "WM_types.h" +#endif + /* icons are 80% of height of button (16 pixels inside 20 height) */ #define ICON_SIZE_FROM_BUTRECT(rect) (0.8f * BLI_rcti_size_y(rect)) @@ -222,7 +226,7 @@ void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float m for (j = 0; j < WIDGET_AA_JITTER; j++) { glTranslatef(jit[j][0], jit[j][1], 0.0f); - uiDrawBox(mode, minx, miny, maxx, maxy, rad); + UI_draw_roundbox_gl_mode(mode, minx, miny, maxx, maxy, rad); glTranslatef(-jit[j][0], -jit[j][1], 0.0f); } @@ -746,6 +750,8 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) glEnableClientState(GL_VERTEX_ARRAY); for (j = 0; j < WIDGET_AA_JITTER; j++) { + unsigned char emboss[4]; + glTranslatef(jit[j][0], jit[j][1], 0.0f); /* outline */ @@ -753,13 +759,16 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) glVertexPointer(2, GL_FLOAT, 0, quad_strip); glDrawArrays(GL_QUAD_STRIP, 0, wtb->totvert * 2 + 2); - + /* emboss bottom shadow */ if (wtb->emboss) { - glColor4f(1.0f, 1.0f, 1.0f, 0.02f); + UI_GetThemeColor4ubv(TH_WIDGET_EMBOSS, emboss); - glVertexPointer(2, GL_FLOAT, 0, quad_strip_emboss); - glDrawArrays(GL_QUAD_STRIP, 0, wtb->halfwayvert * 2); + if (emboss[3]) { + glColor4ubv(emboss); + glVertexPointer(2, GL_FLOAT, 0, quad_strip_emboss); + glDrawArrays(GL_QUAD_STRIP, 0, wtb->halfwayvert * 2); + } } glTranslatef(-jit[j][0], -jit[j][1], 0.0f); @@ -824,7 +833,7 @@ static void widget_draw_preview(BIFIconID icon, float UNUSED(alpha), const rcti static int ui_but_draw_menu_icon(const uiBut *but) { - return (but->flag & UI_ICON_SUBMENU) && (but->dt == UI_EMBOSSP); + return (but->flag & UI_BUT_ICON_SUBMENU) && (but->dt == UI_EMBOSS_PULLDOWN); } /* icons have been standardized... and this call draws in untransformed coordinates */ @@ -835,7 +844,7 @@ static void widget_draw_icon(const uiBut *but, BIFIconID icon, float alpha, cons float xs = 0.0f, ys = 0.0f; float aspect, height; - if (but->flag & UI_ICON_PREVIEW) { + if (but->flag & UI_BUT_ICON_PREVIEW) { glEnable(GL_BLEND); widget_draw_preview(icon, alpha, rect); glDisable(GL_BLEND); @@ -843,20 +852,20 @@ static void widget_draw_icon(const uiBut *but, BIFIconID icon, float alpha, cons } /* this icon doesn't need draw... */ - if (icon == ICON_BLANK1 && (but->flag & UI_ICON_SUBMENU) == 0) return; + if (icon == ICON_BLANK1 && (but->flag & UI_BUT_ICON_SUBMENU) == 0) return; aspect = but->block->aspect / UI_DPI_FAC; height = ICON_DEFAULT_HEIGHT / aspect; /* calculate blend color */ - if (ELEM(but->type, TOG, ROW, TOGN, LISTROW)) { + if (ELEM(but->type, UI_BTYPE_TOGGLE, UI_BTYPE_ROW, UI_BTYPE_TOGGLE_N, UI_BTYPE_LISTROW)) { if (but->flag & UI_SELECT) {} else if (but->flag & UI_ACTIVE) {} else alpha = 0.5f; } /* extra feature allows more alpha blending */ - if ((but->type == LABEL) && but->a1 == 1.0f) + if ((but->type == UI_BTYPE_LABEL) && but->a1 == 1.0f) alpha *= but->a2; glEnable(GL_BLEND); @@ -866,7 +875,7 @@ static void widget_draw_icon(const uiBut *but, BIFIconID icon, float alpha, cons if (but->drawflag & UI_BUT_ICON_LEFT) { if (but->block->flag & UI_BLOCK_LOOP) { - if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) + if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) xs = rect->xmin + 4.0f * ofs; else xs = rect->xmin + ofs; @@ -967,7 +976,7 @@ static float ui_text_clip_middle_ex(uiFontStyle *fstyle, char *str, float okwidt BLI_assert(str[0]); /* need to set this first */ - uiStyleFontSet(fstyle); + UI_fontstyle_set(fstyle); if (fstyle->kerning == 1) { /* for BLF_width */ BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT); @@ -1065,7 +1074,7 @@ static float ui_text_clip_middle_ex(uiFontStyle *fstyle, char *str, float okwidt static void ui_text_clip_middle(uiFontStyle *fstyle, uiBut *but, const rcti *rect) { /* No margin for labels! */ - const int border = ELEM(but->type, LABEL, MENU) ? 0 : (int)(UI_TEXT_CLIP_MARGIN + 0.5f); + const int border = ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_MENU) ? 0 : (int)(UI_TEXT_CLIP_MARGIN + 0.5f); const float okwidth = (float)max_ii(BLI_rcti_size_x(rect) - border, 0); const size_t max_len = sizeof(but->drawstr); const float minwidth = (float)(UI_DPI_ICON_SIZE) / but->block->aspect * 2.0f; @@ -1081,7 +1090,7 @@ static void ui_text_clip_middle(uiFontStyle *fstyle, uiBut *but, const rcti *rec static void ui_text_clip_middle_protect_right(uiFontStyle *fstyle, uiBut *but, const rcti *rect, const char *rsep) { /* No margin for labels! */ - const int border = ELEM(but->type, LABEL, MENU) ? 0 : (int)(UI_TEXT_CLIP_MARGIN + 0.5f); + const int border = ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_MENU) ? 0 : (int)(UI_TEXT_CLIP_MARGIN + 0.5f); const float okwidth = (float)max_ii(BLI_rcti_size_x(rect) - border, 0); const size_t max_len = sizeof(but->drawstr); const float minwidth = (float)(UI_DPI_ICON_SIZE) / but->block->aspect * 2.0f; @@ -1101,7 +1110,7 @@ static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, const rcti *rec BLI_assert(but->editstr && but->pos >= 0); /* need to set this first */ - uiStyleFontSet(fstyle); + UI_fontstyle_set(fstyle); if (fstyle->kerning == 1) /* for BLF_width */ BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT); @@ -1164,7 +1173,7 @@ static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti const char *cpend = but->drawstr + drawstr_len; /* need to set this first */ - uiStyleFontSet(fstyle); + UI_fontstyle_set(fstyle); if (fstyle->kerning == 1) /* for BLF_width */ BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT); @@ -1226,6 +1235,50 @@ static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT); } +#ifdef WITH_INPUT_IME +static void widget_draw_text_ime_underline( + uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *but, const rcti *rect, + const wmIMEData *ime_data, const char *drawstr) +{ + int ofs_x, width; + int rect_x = BLI_rcti_size_x(rect); + int sel_start = ime_data->sel_start, sel_end = ime_data->sel_end; + + if (drawstr[0] != 0) { + if (but->pos >= but->ofs) { + ofs_x = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->pos - but->ofs); + } + else { + ofs_x = 0; + } + + width = BLF_width(fstyle->uifont_id, drawstr + but->ofs, + ime_data->composite_len + but->pos - but->ofs); + + glColor4ubv((unsigned char *)wcol->text); + UI_draw_text_underline(rect->xmin + ofs_x, rect->ymin + 6 * U.pixelsize, min_ii(width, rect_x - 2) - ofs_x, 1); + + /* draw the thick line */ + if (sel_start != -1 && sel_end != -1) { + sel_end -= sel_start; + sel_start += but->pos; + + if (sel_start >= but->ofs) { + ofs_x = BLF_width(fstyle->uifont_id, drawstr + but->ofs, sel_start - but->ofs); + } + else { + ofs_x = 0; + } + + width = BLF_width(fstyle->uifont_id, drawstr + but->ofs, + sel_end + sel_start - but->ofs); + + UI_draw_text_underline(rect->xmin + ofs_x, rect->ymin + 6 * U.pixelsize, min_ii(width, rect_x - 2) - ofs_x, 2); + } + } +} +#endif /* WITH_INPUT_IME */ + static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *but, rcti *rect) { int drawstr_left_len = UI_MAX_DRAW_STR; @@ -1233,7 +1286,11 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b const char *drawstr_right = NULL; bool use_right_only = false; - uiStyleFontSet(fstyle); +#ifdef WITH_INPUT_IME + const wmIMEData *ime_data; +#endif + + UI_fontstyle_set(fstyle); if (but->editstr || (but->drawflag & UI_BUT_TEXT_LEFT)) fstyle->align = UI_STYLE_TEXT_LEFT; @@ -1249,7 +1306,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b /* Special case: when we're entering text for multiple buttons, * don't draw the text for any of the multi-editing buttons */ if (UNLIKELY(but->flag & UI_BUT_DRAG_MULTI)) { - uiBut *but_edit = ui_get_but_drag_multi_edit(but); + uiBut *but_edit = ui_but_drag_multi_edit_get(but); if (but_edit) { drawstr = but_edit->editstr; fstyle->align = UI_STYLE_TEXT_LEFT; @@ -1260,13 +1317,30 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b /* max length isn't used in this case, * we rely on string being NULL terminated. */ drawstr_left_len = INT_MAX; - drawstr = but->editstr; + +#ifdef WITH_INPUT_IME + /* FIXME, IME is modifying 'const char *drawstr! */ + ime_data = ui_but_get_ime_data(but); + + if (ime_data && ime_data->composite_len) { + /* insert composite string into cursor pos */ + BLI_snprintf((char *)drawstr, UI_MAX_DRAW_STR, "%s%s%s", + but->editstr, ime_data->str_composite, + but->editstr + but->pos); + } + else +#endif + { + drawstr = but->editstr; + } } } - /* text button selection and cursor */ + /* text button selection, cursor, composite underline */ if (but->editstr && but->pos != -1) { + int but_pos_ofs; + int tx, ty; /* text button selection */ if ((but->selend - but->selsta) > 0) { @@ -1292,18 +1366,44 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b } /* text cursor */ + but_pos_ofs = but->pos; + +#ifdef WITH_INPUT_IME + /* if is ime compositing, move the cursor */ + if (ime_data && ime_data->composite_len && ime_data->cursor_pos != -1) { + but_pos_ofs += ime_data->cursor_pos; + } +#endif + if (but->pos >= but->ofs) { int t; if (drawstr[0] != 0) { - t = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->pos - but->ofs); + t = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but_pos_ofs - but->ofs); } else { t = 0; } glColor3f(0.20, 0.6, 0.9); - glRecti(rect->xmin + t, rect->ymin + 2, rect->xmin + t + 2, rect->ymax - 2); + + tx = rect->xmin + t + 2; + ty = rect->ymin + 2; + + /* draw cursor */ + glRecti(rect->xmin + t, ty, tx, rect->ymax - 2); + } + +#ifdef WITH_INPUT_IME + if (ime_data && ime_data->composite_len) { + /* ime cursor following */ + if (but->pos >= but->ofs) { + ui_but_ime_reposition(but, tx + 5, ty + 3, false); + } + + /* composite underline */ + widget_draw_text_ime_underline(fstyle, wcol, but, rect, ime_data, drawstr); } +#endif } if (fstyle->kerning == 1) @@ -1328,7 +1428,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b } #ifdef USE_NUMBUTS_LR_ALIGN - if (!drawstr_right && ELEM(but->type, NUM, NUMSLI) && + if (!drawstr_right && ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER) && /* if we're editing or multi-drag (fake editing), then use left alignment */ (but->editstr == NULL) && (drawstr == but->drawstr)) { @@ -1355,7 +1455,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b /* for underline drawing */ float font_xofs, font_yofs; - uiStyleFontDrawExt(fstyle, rect, drawstr + but->ofs, + UI_fontstyle_draw_ex(fstyle, rect, drawstr + but->ofs, drawstr_left_len - but->ofs, &font_xofs, &font_yofs); if (but->menu_key != '\0') { @@ -1395,7 +1495,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b if (drawstr_right) { fstyle->align = UI_STYLE_TEXT_RIGHT; rect->xmax -= UI_TEXT_CLIP_MARGIN; - uiStyleFontDraw(fstyle, rect, drawstr_right); + UI_fontstyle_draw(fstyle, rect, drawstr_right); } } @@ -1406,10 +1506,10 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB float alpha = (float)wcol->text[3] / 255.0f; char password_str[UI_MAX_DRAW_STR]; - ui_button_text_password_hide(password_str, but, false); + ui_but_text_password_hide(password_str, but, false); /* check for button text label */ - if (but->type == MENU && (but->flag & UI_BUT_NODE_LINK)) { + if (but->type == UI_BTYPE_MENU && (but->flag & UI_BUT_NODE_LINK)) { rcti temp = *rect; temp.xmin = rect->xmax - BLI_rcti_size_y(rect) - 1; widget_draw_icon(but, ICON_LAYER_USED, alpha, &temp, false); @@ -1444,7 +1544,7 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB } /* unlink icon for this button type */ - if ((but->type == SEARCH_MENU_UNLINK) && ui_is_but_search_unlink_visible(but)) { + if ((but->type == UI_BTYPE_SEARCH_MENU_UNLINK) && ui_but_is_search_unlink_visible(but)) { rcti temp = *rect; temp.xmin = temp.xmax - (BLI_rcti_size_y(rect) * 1.08f); @@ -1461,10 +1561,10 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB but->ofs = 0; but->strwidth = 0; } - else if (ELEM(but->type, NUM, NUMSLI)) { + else if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) { ui_text_clip_right_label(fstyle, but, rect); } - else if ((but->block->flag & UI_BLOCK_LOOP) && (but->type == BUT)) { + else if ((but->block->flag & UI_BLOCK_LOOP) && (but->type == UI_BTYPE_BUT)) { /* Clip middle, but protect in all case right part containing the shortcut, if any. */ ui_text_clip_middle_protect_right(fstyle, but, rect, "|"); } @@ -1475,7 +1575,7 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB /* always draw text for textbutton cursor */ widget_draw_text(fstyle, wcol, but, rect); - ui_button_text_password_hide(password_str, but, true); + ui_but_text_password_hide(password_str, but, true); } #undef UI_TEXT_CLIP_MARGIN @@ -2047,11 +2147,11 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir //rect->ymin -= 4.0; //rect->ymax += 4.0; } - else if (direction == UI_DOWN) { + else if (direction == UI_DIR_DOWN) { roundboxalign = (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT); rect->ymin -= 0.1f * U.widget_unit; } - else if (direction == UI_TOP) { + else if (direction == UI_DIR_UP) { roundboxalign = UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT; rect->ymax += 0.1f * U.widget_unit; } @@ -2113,7 +2213,7 @@ void ui_hsvcircle_pos_from_vals(uiBut *but, const rcti *rect, float *hsv, float ang = 2.0f * (float)M_PI * hsv[0] + 0.5f * (float)M_PI; if ((but->flag & UI_BUT_COLOR_CUBIC) && (U.color_picker_type == USER_CP_CIRCLE_HSV)) - radius_t = (1.0f - powf(1.0f - hsv[1], 3.0f)); + radius_t = (1.0f - pow3f(1.0f - hsv[1])); else radius_t = hsv[1]; @@ -2131,14 +2231,15 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti * float radius = (float)min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f; /* gouraud triangle fan */ - const float *hsv_ptr = ui_block_hsv_get(but->block); + ColorPicker *cpicker = but->custom_data; + const float *hsv_ptr = cpicker->color_data; float xpos, ypos, ang = 0.0f; float rgb[3], hsvo[3], hsv[3], col[3], colcent[3]; int a; - bool color_profile = ui_color_picker_use_display_colorspace(but); + bool color_profile = ui_but_is_colorpicker_display_space(but); /* color */ - ui_get_but_vectorf(but, rgb); + ui_but_v3_get(but, rgb); /* since we use compat functions on both 'hsv' and 'hsvo', they need to be initialized */ hsvo[0] = hsv[0] = hsv_ptr[0]; @@ -2146,7 +2247,7 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti * hsvo[2] = hsv[2] = hsv_ptr[2]; if (color_profile) - ui_block_to_display_space_v3(but->block, rgb); + ui_block_cm_to_display_space_v3(but->block, rgb); ui_rgb_to_color_picker_compat_v(rgb, hsv); copy_v3_v3(hsvo, hsv); @@ -2347,7 +2448,7 @@ void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, cons } -bool ui_color_picker_use_display_colorspace(uiBut *but) +bool ui_but_is_colorpicker_display_space(uiBut *but) { bool color_profile = but->block->color_profile; @@ -2398,16 +2499,17 @@ static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect) { float rgb[3]; float x = 0.0f, y = 0.0f; - const float *hsv = ui_block_hsv_get(but->block); + ColorPicker *cpicker = but->custom_data; + float *hsv = cpicker->color_data; float hsv_n[3]; - bool use_display_colorspace = ui_color_picker_use_display_colorspace(but); + bool use_display_colorspace = ui_but_is_colorpicker_display_space(but); copy_v3_v3(hsv_n, hsv); - ui_get_but_vectorf(but, rgb); + ui_but_v3_get(but, rgb); if (use_display_colorspace) - ui_block_to_display_space_v3(but->block, rgb); + ui_block_cm_to_display_space_v3(but->block, rgb); rgb_to_hsv_compat_v(rgb, hsv_n); @@ -2436,10 +2538,10 @@ static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect) if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) color_profile = false; - ui_get_but_vectorf(but, rgb); + ui_but_v3_get(but, rgb); if (color_profile) - ui_block_to_display_space_v3(but->block, rgb); + ui_block_cm_to_display_space_v3(but->block, rgb); if (but->a1 == UI_GRAD_L_ALT) rgb_to_hsl_v(rgb, hsv); @@ -2585,7 +2687,7 @@ void ui_draw_link_bezier(const rcti *rect) } /* function in use for buttons and for view2d sliders */ -void uiWidgetScrollDraw(uiWidgetColors *wcol, const rcti *rect, const rcti *slider, int state) +void UI_draw_widget_scroll(uiWidgetColors *wcol, const rcti *rect, const rcti *slider, int state) { uiWidgetBase wtb; int horizontal; @@ -2671,7 +2773,7 @@ static void widget_scroll(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat int horizontal; /* calculate slider part */ - value = ui_get_but_val(but); + value = ui_but_value_get(but); size = (but->softmax + but->a1 - but->softmin); size = max_ff(size, 2.0f); @@ -2721,7 +2823,7 @@ static void widget_scroll(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat state = UI_SCROLL_PRESSED; else state = 0; - uiWidgetScrollDraw(wcol, rect, &rect1, state); + UI_draw_widget_scroll(wcol, rect, &rect1, state); } static void widget_progressbar(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign)) @@ -2743,7 +2845,7 @@ static void widget_progressbar(uiBut *but, uiWidgetColors *wcol, rcti *rect, int rect_bar.xmax = rect_bar.xmin + w; - uiWidgetScrollDraw(wcol, &rect_prog, &rect_bar, UI_SCROLL_NO_OUTLINE); + UI_draw_widget_scroll(wcol, &rect_prog, &rect_bar, UI_SCROLL_NO_OUTLINE); /* raise text a bit */ rect->ymin += 6 * UI_DPI_FAC; @@ -2802,7 +2904,7 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s rect1 = *rect; - value = ui_get_but_val(but); + value = ui_but_value_get(but); fac = ((float)value - but->softmin) * (BLI_rcti_size_x(&rect1) - offs) / (but->softmax - but->softmin); /* left part of slider, always rounded */ @@ -2873,7 +2975,7 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat rad = 0.25f * U.widget_unit; round_box_edges(&wtb, roundboxalign, rect, rad); - ui_get_but_vectorf(but, col); + ui_but_v3_get(but, col); if (state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_REDALERT)) { /* draw based on state - color for keyed etc */ @@ -2889,7 +2991,7 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat } if (color_profile) - ui_block_to_display_space_v3(but->block, col); + ui_block_cm_to_display_space_v3(but->block, col); rgba_float_to_uchar((unsigned char *)wcol->inner, col); @@ -2918,9 +3020,9 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat } } -static void widget_normal(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign)) +static void widget_unitvec(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign)) { - ui_draw_but_NORMAL(but, wcol, rect); + ui_draw_but_UNITVEC(but, wcol, rect); } static void widget_icon_has_anim(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign) @@ -2937,7 +3039,7 @@ static void widget_icon_has_anim(uiBut *but, uiWidgetColors *wcol, rcti *rect, i round_box_edges(&wtb, UI_CNR_ALL, rect, rad); widgetbase_draw(&wtb, wcol); } - else if (but->type == NUM) { + else if (but->type == UI_BTYPE_NUM) { /* Draw number buttons still with left/right * triangles when field is not embossed */ widget_numbut_embossn(but, wcol, rect, state, roundboxalign); @@ -3270,7 +3372,7 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type) wt.wcol_theme = &btheme->tui.wcol_toggle; break; - case UI_WTYPE_OPTION: + case UI_WTYPE_CHECKBOX: wt.wcol_theme = &btheme->tui.wcol_option; wt.draw = widget_optionbut; break; @@ -3374,8 +3476,8 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type) case UI_WTYPE_RGB_PICKER: break; - case UI_WTYPE_NORMAL: - wt.custom = widget_normal; + case UI_WTYPE_UNITVEC: + wt.custom = widget_unitvec; break; case UI_WTYPE_SCROLL: @@ -3410,7 +3512,7 @@ static int widget_roundbox_set(uiBut *but, rcti *rect) int roundbox = UI_CNR_ALL; /* alignment */ - if ((but->drawflag & UI_BUT_ALIGN) && but->type != PULLDOWN) { + if ((but->drawflag & UI_BUT_ALIGN) && but->type != UI_BTYPE_PULLDOWN) { /* ui_block_position has this correction too, keep in sync */ if (but->drawflag & UI_BUT_ALIGN_TOP) @@ -3451,12 +3553,12 @@ static int widget_roundbox_set(uiBut *but, rcti *rect) /* align with open menu */ if (but->active) { - int direction = ui_button_open_menu_direction(but); + int direction = ui_but_menu_direction(but); - if (direction == UI_TOP) roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_TOP_LEFT); - else if (direction == UI_DOWN) roundbox &= ~(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT); - else if (direction == UI_LEFT) roundbox &= ~(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT); - else if (direction == UI_RIGHT) roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT); + if (direction == UI_DIR_UP) roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_TOP_LEFT); + else if (direction == UI_DIR_DOWN) roundbox &= ~(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT); + else if (direction == UI_DIR_LEFT) roundbox &= ~(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT); + else if (direction == UI_DIR_RIGHT) roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT); } return roundbox; @@ -3488,12 +3590,12 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct uiWidgetType *wt = NULL; /* handle menus separately */ - if (but->dt == UI_EMBOSSP) { + if (but->dt == UI_EMBOSS_PULLDOWN) { switch (but->type) { - case LABEL: + case UI_BTYPE_LABEL: widget_draw_text_icon(&style->widgetlabel, &tui->wcol_menu_back, but, rect); break; - case SEPRLINE: + case UI_BTYPE_SEPR_LINE: ui_draw_separator(rect, &tui->wcol_menu_item); break; default: @@ -3501,17 +3603,18 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct break; } } - else if (but->dt == UI_EMBOSSN) { + else if (but->dt == UI_EMBOSS_NONE) { /* "nothing" */ wt = widget_type(UI_WTYPE_ICON); } - else if (but->dt == UI_EMBOSSR) { + else if (but->dt == UI_EMBOSS_RADIAL) { wt = widget_type(UI_WTYPE_MENU_ITEM_RADIAL); } else { - + BLI_assert(but->dt == UI_EMBOSS); + switch (but->type) { - case LABEL: + case UI_BTYPE_LABEL: if (but->block->flag & UI_BLOCK_LOOP) widget_draw_text_icon(&style->widgetlabel, &tui->wcol_menu_back, but, rect); else { @@ -3520,51 +3623,51 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct } break; - case SEPR: - case SEPRLINE: + case UI_BTYPE_SEPR: + case UI_BTYPE_SEPR_LINE: break; - case BUT: + case UI_BTYPE_BUT: wt = widget_type(UI_WTYPE_EXEC); break; - case NUM: + case UI_BTYPE_NUM: wt = widget_type(UI_WTYPE_NUMBER); break; - case NUMSLI: + case UI_BTYPE_NUM_SLIDER: wt = widget_type(UI_WTYPE_SLIDER); break; - case ROW: + case UI_BTYPE_ROW: wt = widget_type(UI_WTYPE_RADIO); break; - case LISTROW: + case UI_BTYPE_LISTROW: wt = widget_type(UI_WTYPE_LISTITEM); break; - case TEX: + case UI_BTYPE_TEXT: wt = widget_type(UI_WTYPE_NAME); break; - case SEARCH_MENU_UNLINK: - case SEARCH_MENU: + case UI_BTYPE_SEARCH_MENU_UNLINK: + case UI_BTYPE_SEARCH_MENU: wt = widget_type(UI_WTYPE_NAME); if (but->block->flag & UI_BLOCK_LOOP) wt->wcol_theme = &btheme->tui.wcol_menu_back; break; - case TOGBUT: - case TOG: - case TOGN: + case UI_BTYPE_BUT_TOGGLE: + case UI_BTYPE_TOGGLE: + case UI_BTYPE_TOGGLE_N: wt = widget_type(UI_WTYPE_TOGGLE); break; - case OPTION: - case OPTIONN: + case UI_BTYPE_CHECKBOX: + case UI_BTYPE_CHECKBOX_N: if (!(but->flag & UI_HAS_ICON)) { - wt = widget_type(UI_WTYPE_OPTION); + wt = widget_type(UI_WTYPE_CHECKBOX); but->drawflag |= UI_BUT_TEXT_LEFT; } else @@ -3576,8 +3679,8 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct break; - case MENU: - case BLOCK: + case UI_BTYPE_MENU: + case UI_BTYPE_BLOCK: if (but->flag & UI_BUT_NODE_LINK) { /* new node-link button, not active yet XXX */ wt = widget_type(UI_WTYPE_MENU_NODE_LINK); @@ -3589,7 +3692,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct * add updown arrows if there is room. */ if ((!but->str[0] && but->icon && (BLI_rcti_size_x(rect) < BLI_rcti_size_y(rect) + 2)) || /* disable for brushes also */ - (but->flag & UI_ICON_PREVIEW)) + (but->flag & UI_BUT_ICON_PREVIEW)) { /* no arrows */ wt = widget_type(UI_WTYPE_MENU_ICON_RADIO); @@ -3600,35 +3703,35 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct } break; - case PULLDOWN: + case UI_BTYPE_PULLDOWN: wt = widget_type(UI_WTYPE_PULLDOWN); break; - case BUTM: + case UI_BTYPE_BUT_MENU: wt = widget_type(UI_WTYPE_MENU_ITEM); break; - case COLOR: + case UI_BTYPE_COLOR: wt = widget_type(UI_WTYPE_SWATCH); break; - case ROUNDBOX: - case LISTBOX: + case UI_BTYPE_ROUNDBOX: + case UI_BTYPE_LISTBOX: wt = widget_type(UI_WTYPE_BOX); break; - case LINK: - case INLINK: + case UI_BTYPE_LINK: + case UI_BTYPE_INLINK: wt = widget_type(UI_WTYPE_ICON); wt->custom = widget_link; break; - case BUT_EXTRA: + case UI_BTYPE_EXTRA: widget_draw_extra_mask(C, but, widget_type(UI_WTYPE_BOX), rect); break; - case HSVCUBE: + case UI_BTYPE_HSVCUBE: if (ELEM(but->a1, UI_GRAD_V_ALT, UI_GRAD_L_ALT)) { /* vertical V slider, uses new widget draw now */ ui_draw_but_HSV_v(but, rect); } @@ -3637,56 +3740,56 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct } break; - case HSVCIRCLE: + case UI_BTYPE_HSVCIRCLE: ui_draw_but_HSVCIRCLE(but, &tui->wcol_regular, rect); break; - case BUT_COLORBAND: + case UI_BTYPE_COLORBAND: ui_draw_but_COLORBAND(but, &tui->wcol_regular, rect); break; - case BUT_NORMAL: - wt = widget_type(UI_WTYPE_NORMAL); + case UI_BTYPE_UNITVEC: + wt = widget_type(UI_WTYPE_UNITVEC); break; - case BUT_IMAGE: + case UI_BTYPE_IMAGE: ui_draw_but_IMAGE(ar, but, &tui->wcol_regular, rect); break; - case HISTOGRAM: + case UI_BTYPE_HISTOGRAM: ui_draw_but_HISTOGRAM(ar, but, &tui->wcol_regular, rect); break; - case WAVEFORM: + case UI_BTYPE_WAVEFORM: ui_draw_but_WAVEFORM(ar, but, &tui->wcol_regular, rect); break; - case VECTORSCOPE: + case UI_BTYPE_VECTORSCOPE: ui_draw_but_VECTORSCOPE(ar, but, &tui->wcol_regular, rect); break; - case BUT_CURVE: + case UI_BTYPE_CURVE: ui_draw_but_CURVE(ar, but, &tui->wcol_regular, rect); break; - case PROGRESSBAR: + case UI_BTYPE_PROGRESS_BAR: wt = widget_type(UI_WTYPE_PROGRESSBAR); fstyle = &style->widgetlabel; break; - case SCROLL: + case UI_BTYPE_SCROLL: wt = widget_type(UI_WTYPE_SCROLL); break; - case GRIP: + case UI_BTYPE_GRIP: wt = widget_type(UI_WTYPE_ICON); break; - case TRACKPREVIEW: + case UI_BTYPE_TRACK_PREVIEW: ui_draw_but_TRACKPREVIEW(ar, but, &tui->wcol_regular, rect); break; - case NODESOCKET: + case UI_BTYPE_NODE_SOCKET: ui_draw_but_NODESOCKET(ar, but, &tui->wcol_regular, rect); break; @@ -3706,13 +3809,13 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct state = but->flag; if ((but->editstr) || - (UNLIKELY(but->flag & UI_BUT_DRAG_MULTI) && ui_get_but_drag_multi_edit(but))) + (UNLIKELY(but->flag & UI_BUT_DRAG_MULTI) && ui_but_drag_multi_edit_get(but))) { state |= UI_TEXTINPUT; } if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) - if (but->dt != UI_EMBOSSP) + if (but->dt != UI_EMBOSS_PULLDOWN) disabled = true; if (disabled) @@ -3731,7 +3834,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct glDisable(GL_BLEND); // if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) -// if (but->dt != UI_EMBOSSP) +// if (but->dt != UI_EMBOSS_PULLDOWN) // widget_disabled(&disablerect); } } @@ -3750,12 +3853,12 @@ void ui_draw_menu_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect) if (block->flag & UI_BLOCK_CLIPTOP) { /* XXX no scaling for UI here yet */ glColor3ubv((unsigned char *)wt->wcol.text); - UI_DrawTriIcon(BLI_rcti_cent_x(rect), rect->ymax - 8, 't'); + UI_draw_icon_tri(BLI_rcti_cent_x(rect), rect->ymax - 8, 't'); } if (block->flag & UI_BLOCK_CLIPBOTTOM) { /* XXX no scaling for UI here yet */ glColor3ubv((unsigned char *)wt->wcol.text); - UI_DrawTriIcon(BLI_rcti_cent_x(rect), rect->ymin + 10, 'v'); + UI_draw_icon_tri(BLI_rcti_cent_x(rect), rect->ymin + 10, 'v'); } } } @@ -3838,8 +3941,6 @@ void ui_draw_pie_center(uiBlock *block) float pie_radius_internal = U.pixelsize * U.pie_menu_threshold; float pie_radius_external = U.pixelsize * (U.pie_menu_threshold + 7.0f); - float pie_confirm_radius = U.pixelsize * (U.pie_menu_confirm); - float pie_confirm_external = U.pixelsize * (U.pie_menu_confirm + 2.0f); int subd = 40; @@ -3876,10 +3977,14 @@ void ui_draw_pie_center(uiBlock *block) glutil_draw_lined_arc(0.0f, (float)M_PI * 2.0f, pie_radius_internal, subd); glutil_draw_lined_arc(0.0f, (float)M_PI * 2.0f, pie_radius_external, subd); - if (pie_confirm_radius > pie_radius_external) { + if (U.pie_menu_confirm > 0 && !(block->pie_data.flags & (UI_PIE_INVALID_DIR | UI_PIE_CLICK_STYLE))) { + float pie_confirm_radius = U.pixelsize * (pie_radius_internal + U.pie_menu_confirm); + float pie_confirm_external = U.pixelsize * (pie_radius_internal + U.pie_menu_confirm + 7.0f); + glColor4ub(btheme->tui.wcol_pie_menu.text_sel[0], btheme->tui.wcol_pie_menu.text_sel[1], btheme->tui.wcol_pie_menu.text_sel[2], 64); draw_disk_shaded(angle - range / 2.0f, range, pie_confirm_radius, pie_confirm_external, subd, NULL, NULL, false); } + glDisable(GL_BLEND); glPopMatrix(); } @@ -3927,7 +4032,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic wt->state(wt, state); wt->draw(&wt->wcol, rect, 0, 0); - uiStyleFontSet(fstyle); + UI_fontstyle_set(fstyle); fstyle->align = UI_STYLE_TEXT_LEFT; /* text location offset */ @@ -3941,7 +4046,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic *cpoin = 0; /* need to set this first */ - uiStyleFontSet(fstyle); + UI_fontstyle_set(fstyle); if (fstyle->kerning == 1) { /* for BLF_width */ BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT); @@ -3965,7 +4070,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic ui_text_clip_middle_ex(fstyle, drawstr, okwidth, minwidth, max_len, NULL); glColor4ubv((unsigned char *)wt->wcol.text); - uiStyleFontDraw(fstyle, rect, drawstr); + UI_fontstyle_draw(fstyle, rect, drawstr); } /* part text right aligned */ @@ -3973,7 +4078,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic if (cpoin) { fstyle->align = UI_STYLE_TEXT_RIGHT; rect->xmax = _rect.xmax - 5; - uiStyleFontDraw(fstyle, rect, cpoin + 1); + UI_fontstyle_draw(fstyle, rect, cpoin + 1); *cpoin = UI_SEP_CHAR; } } @@ -4040,6 +4145,6 @@ void ui_draw_preview_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ui_text_clip_middle_ex(fstyle, drawstr, okwidth, minwidth, max_len, NULL); glColor4ubv((unsigned char *)wt->wcol.text); - uiStyleFontDraw(fstyle, &trect, drawstr); + UI_fontstyle_draw(fstyle, &trect, drawstr); } } diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index bcd85333709..a0af914e0bc 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -45,6 +45,7 @@ #include "BLI_utildefines.h" #include "BLI_math.h" +#include "BKE_appdir.h" #include "BKE_DerivedMesh.h" #include "BKE_global.h" #include "BKE_main.h" @@ -619,6 +620,9 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo cp = ts->nla_sound_sel; break; + case TH_WIDGET_EMBOSS: + cp = btheme->tui.widget_emboss; break; + case TH_AXIS_X: cp = btheme->tui.xaxis; break; case TH_AXIS_Y: @@ -815,6 +819,10 @@ void ui_theme_init_default(void) btheme->tui.panel.show_header = false; rgba_char_args_set(btheme->tui.panel.header, 0, 0, 0, 25); + rgba_char_args_set(btheme->tui.wcol_tooltip.text, 255, 255, 255, 255); + + rgba_char_args_set_fl(btheme->tui.widget_emboss, 1.0f, 1.0f, 1.0f, 0.02f); + rgba_char_args_set(btheme->tui.xaxis, 220, 0, 0, 255); rgba_char_args_set(btheme->tui.yaxis, 0, 220, 0, 255); rgba_char_args_set(btheme->tui.zaxis, 0, 0, 220, 255); @@ -1527,7 +1535,7 @@ void init_userdef_do_versions(void) } if (U.mixbufsize == 0) U.mixbufsize = 2048; if (strcmp(U.tempdir, "/") == 0) { - BLI_system_temporary_dir(U.tempdir); + BKE_tempdir_system_init(U.tempdir); } if (U.autokey_mode == 0) { /* 'add/replace' but not on */ @@ -2491,6 +2499,13 @@ void init_userdef_do_versions(void) } } + if (U.versionfile < 272 || (U.versionfile == 272 && U.subversionfile < 3)) { + bTheme *btheme; + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + rgba_char_args_set_fl(btheme->tui.widget_emboss, 1.0f, 1.0f, 1.0f, 0.02f); + } + } + if (U.pixelsize == 0.0f) U.pixelsize = 1.0f; diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index d48faa34618..f42e35945d7 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -206,7 +206,7 @@ static void view2d_masks(View2D *v2d, int check_scrollers) void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy) { bool tot_changed = false, do_init; - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_style_get(); do_init = (v2d->flag & V2D_IS_INITIALISED) == 0; @@ -1099,7 +1099,7 @@ void UI_view2d_view_ortho(View2D *v2d) /* Set view matrices to only use one axis of 'cur' only * - xaxis = if non-zero, only use cur x-axis, otherwise use cur-yaxis (mostly this will be used for x) */ -void UI_view2d_view_orthoSpecial(ARegion *ar, View2D *v2d, short xaxis) +void UI_view2d_view_orthoSpecial(ARegion *ar, View2D *v2d, const bool xaxis) { rctf curmasked; float xofs, yofs; @@ -1719,7 +1719,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v glRecti(v2d->hor.xmin, v2d->hor.ymin, v2d->hor.xmax, v2d->hor.ymax); } - uiWidgetScrollDraw(&wcol, &hor, &slider, state); + UI_draw_widget_scroll(&wcol, &hor, &slider, state); /* scale indicators */ if ((scroll & V2D_SCROLL_SCALE_HORIZONTAL) && (vs->grid)) { @@ -1820,7 +1820,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v glRecti(v2d->vert.xmin, v2d->vert.ymin, v2d->vert.xmax, v2d->vert.ymax); } - uiWidgetScrollDraw(&wcol, &vert, &slider, state); + UI_draw_widget_scroll(&wcol, &vert, &slider, state); /* scale indiators */ diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 2b84c0678ae..297d8d0f258 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -1951,7 +1951,7 @@ static void VIEW2D_OT_scroller_activate(wmOperatorType *ot) static int reset_exec(bContext *C, wmOperator *UNUSED(op)) { - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_style_get(); ARegion *ar = CTX_wm_region(C); View2D *v2d = &ar->v2d; int winx, winy; diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c index bbf4447dd72..3ea2fba1f3b 100644 --- a/source/blender/editors/io/io_collada.c +++ b/source/blender/editors/io/io_collada.c @@ -365,6 +365,9 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op) { char filename[FILE_MAX]; int import_units; + int find_chains; + int fix_orientation; + int min_chain_length; if (!RNA_struct_property_is_set(op->ptr, "filepath")) { BKE_report(op->reports, RPT_ERROR, "No filename given"); @@ -372,10 +375,19 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op) } /* Options panel */ - import_units = RNA_boolean_get(op->ptr, "import_units"); + import_units = RNA_boolean_get(op->ptr, "import_units"); + find_chains = RNA_boolean_get(op->ptr, "find_chains"); + fix_orientation = RNA_boolean_get(op->ptr, "fix_orientation"); + min_chain_length = RNA_int_get(op->ptr, "min_chain_length"); RNA_string_get(op->ptr, "filepath", filename); - if (collada_import(C, filename, import_units)) { + if (collada_import( + C, filename, + import_units, + find_chains, + fix_orientation, + min_chain_length)) + { return OPERATOR_FINISHED; } else { @@ -395,6 +407,19 @@ static void uiCollada_importSettings(uiLayout *layout, PointerRNA *imfptr) row = uiLayoutRow(box, false); uiItemR(row, imfptr, "import_units", 0, NULL, ICON_NONE); + + box = uiLayoutBox(layout); + row = uiLayoutRow(box, false); + uiItemL(row, IFACE_("Armature Options:"), ICON_MESH_DATA); + + row = uiLayoutRow(box, false); + uiItemR(row, imfptr, "fix_orientation", 0, NULL, ICON_NONE); + + row = uiLayoutRow(box, false); + uiItemR(row, imfptr, "find_chains", 0, NULL, ICON_NONE); + + row = uiLayoutRow(box, false); + uiItemR(row, imfptr, "min_chain_length", 0, NULL, ICON_NONE); } static void wm_collada_import_draw(bContext *UNUSED(C), wmOperator *op) @@ -423,9 +448,27 @@ void WM_OT_collada_import(wmOperatorType *ot) WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); RNA_def_boolean(ot->srna, - "import_units", 0, "Import Units", - "If disabled match import to Blender's current Unit settings, " - "otherwise use the settings from the Imported scene"); + "import_units", 0, "Import Units", + "If disabled match import to Blender's current Unit settings, " + "otherwise use the settings from the Imported scene"); + + RNA_def_boolean(ot->srna, + "fix_orientation", 0, "Fix Leaf Bones", + "Fix Orientation of Leaf Bones (Collada does only support Joints)"); + + RNA_def_boolean(ot->srna, + "find_chains", 0, "Find Bone Chains", + "Find best matching Bone Chains and ensure bones in chain are connected"); + + RNA_def_int(ot->srna, + "min_chain_length", + 0, + 0, + INT_MAX, + "Minimum Chain Length", + "When searching Bone Chains disregard chains of length below this value", + 0, + INT_MAX); } #endif diff --git a/source/blender/editors/io/io_ops.c b/source/blender/editors/io/io_ops.c index a33340cc39a..a70a51a60be 100644 --- a/source/blender/editors/io/io_ops.c +++ b/source/blender/editors/io/io_ops.c @@ -28,16 +28,13 @@ * \ingroup collada */ - -#include "io_collada.h" - -#include "BLI_utildefines.h" - -#include "WM_types.h" -#include "WM_api.h" - #include "io_ops.h" /* own include */ +#ifdef WITH_COLLADA +# include "io_collada.h" +# include "WM_api.h" +#endif + void ED_operatortypes_io(void) { #ifdef WITH_COLLADA diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 93e59f3244e..929c4f74b2f 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -784,7 +784,7 @@ static int slide_point_invoke(bContext *C, wmOperator *op, const wmEvent *event) SlidePointData *slidedata; if (mask == NULL) { - return OPERATOR_CANCELLED; + return OPERATOR_PASS_THROUGH; } slidedata = slide_point_customdata(C, op, event); @@ -1286,7 +1286,7 @@ static int slide_spline_curvature_invoke(bContext *C, wmOperator *op, const wmEv SlideSplineCurvatureData *slide_data; if (mask == NULL) { - return OPERATOR_CANCELLED; + return OPERATOR_PASS_THROUGH; } /* Be sure we don't conflict with point slide here. */ diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c index e02561d839c..4e0aa8f84ae 100644 --- a/source/blender/editors/mask/mask_relationships.c +++ b/source/blender/editors/mask/mask_relationships.c @@ -39,7 +39,6 @@ #include "BKE_tracking.h" #include "DNA_mask_types.h" -#include "DNA_object_types.h" /* SELECT */ #include "WM_api.h" #include "WM_types.h" diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 87b429f1165..113f0f71b53 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -31,8 +31,6 @@ #include "BLI_math.h" #include "BLI_bitmap.h" -#include "BLF_translation.h" - #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" diff --git a/source/blender/editors/mesh/editmesh_intersect.c b/source/blender/editors/mesh/editmesh_intersect.c index df6776950d7..e2e4638254b 100644 --- a/source/blender/editors/mesh/editmesh_intersect.c +++ b/source/blender/editors/mesh/editmesh_intersect.c @@ -38,7 +38,6 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "WM_api.h" #include "WM_types.h" #include "ED_mesh.h" @@ -334,7 +333,7 @@ static int edbm_face_split_by_edges_exec(bContext *C, wmOperator *UNUSED(op)) BMVert *v_other = BM_edge_other_vert(e, v); float e_dir[3]; - /* we wan't closest to zero */ + /* we want closest to zero */ float dot_best = FLT_MAX; sub_v3_v3v3(e_dir, v_other->co, v->co); diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index f5a7e82a8a8..e9b4e32c39e 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -97,7 +97,7 @@ typedef struct KnifeVert { float co[3], cageco[3], sco[2]; /* sco is screen coordinates for cageco */ bool is_face, in_space; - bool draw; + bool is_cut; /* along a cut created by user input (will draw too) */ } KnifeVert; typedef struct Ref { @@ -111,7 +111,7 @@ typedef struct KnifeEdge { ListBase faces; BMEdge *e /* , *e_old */; /* non-NULL if this is an original edge */ - bool draw; + bool is_cut; /* along a cut created by user input (will draw too) */ } KnifeEdge; typedef struct KnifeLineHit { @@ -174,8 +174,10 @@ typedef struct KnifeTool_OpData { KnifeLineHit *linehits; int totlinehit; - /* Data for mouse-position-derived data (cur) and previous click (prev) */ - KnifePosData curr, prev; + /* Data for mouse-position-derived data */ + KnifePosData curr; /* current point under the cursor */ + KnifePosData prev; /* last added cut (a line draws from the cursor to this) */ + KnifePosData init; /* the first point in the cut-list, used for closing the loop */ int totkedge, totkvert; @@ -206,6 +208,7 @@ typedef struct KnifeTool_OpData { MODE_CONNECT, MODE_PANNING } mode; + bool is_drag_hold; int prevmode; bool snap_midpoints; @@ -526,7 +529,7 @@ static KnifeVert *knife_split_edge( newkfe->v1 = kfe->v1; newkfe->v2 = new_knife_vert(kcd, co, cageco); - newkfe->v2->draw = 1; + newkfe->v2->is_cut = true; if (kfe->e) { knife_add_edge_faces_to_vert(kcd, newkfe->v2, kfe->e); } @@ -551,7 +554,7 @@ static KnifeVert *knife_split_edge( knife_add_to_vert_edges(kcd, newkfe); - newkfe->draw = kfe->draw; + newkfe->is_cut = kfe->is_cut; newkfe->e = kfe->e; *r_kfe = newkfe; @@ -559,6 +562,16 @@ static KnifeVert *knife_split_edge( return newkfe->v2; } +static void linehit_to_knifepos(KnifePosData *kpos, KnifeLineHit *lh) +{ + kpos->bmface = lh->f; + kpos->vert = lh->v; + kpos->edge = lh->kfe; + copy_v3_v3(kpos->cage, lh->cagehit); + copy_v3_v3(kpos->co, lh->hit); + copy_v2_v2(kpos->mval, lh->schit); +} + /* primary key: lambda along cut * secondary key: lambda along depth * tertiary key: pointer comparisons of verts if both snapped to verts @@ -590,6 +603,7 @@ static void prepare_linehits_for_cut(KnifeTool_OpData *kcd) { KnifeLineHit *linehits, *lhi, *lhj; int i, j, n; + bool is_double = false; n = kcd->totlinehit; linehits = kcd->linehits; @@ -613,7 +627,11 @@ static void prepare_linehits_for_cut(KnifeTool_OpData *kcd) { break; } - lhj->l = -1.0f; + + if (lhi->kfe == lhj->kfe) { + lhj->l = -1.0f; + is_double = true; + } } for (j = i + 1; j < n; j++) { lhj = &linehits[j]; @@ -622,37 +640,42 @@ static void prepare_linehits_for_cut(KnifeTool_OpData *kcd) { break; } - if (lhj->kfe || lhi->v == lhj->v) { + if ((lhj->kfe && (lhi->kfe == lhj->kfe)) || + (lhi->v == lhj->v)) + { lhj->l = -1.0f; + is_double = true; } } } } - /* delete-in-place loop: copying from pos j to pos i+1 */ - i = 0; - j = 1; - while (j < n) { - lhi = &linehits[i]; - lhj = &linehits[j]; - if (lhj->l == -1.0f) { - j++; /* skip copying this one */ - } - else { - /* copy unless a no-op */ - if (lhi->l == -1.0f) { - /* could happen if linehits[0] is being deleted */ - memcpy(&linehits[i], &linehits[j], sizeof(KnifeLineHit)); + if (is_double) { + /* delete-in-place loop: copying from pos j to pos i+1 */ + i = 0; + j = 1; + while (j < n) { + lhi = &linehits[i]; + lhj = &linehits[j]; + if (lhj->l == -1.0f) { + j++; /* skip copying this one */ } else { - if (i + 1 != j) - memcpy(&linehits[i + 1], &linehits[j], sizeof(KnifeLineHit)); - i++; + /* copy unless a no-op */ + if (lhi->l == -1.0f) { + /* could happen if linehits[0] is being deleted */ + memcpy(&linehits[i], &linehits[j], sizeof(KnifeLineHit)); + } + else { + if (i + 1 != j) + memcpy(&linehits[i + 1], &linehits[j], sizeof(KnifeLineHit)); + i++; + } + j++; } - j++; } + kcd->totlinehit = i + 1; } - kcd->totlinehit = i + 1; } /* Add hit to list of hits in facehits[f], where facehits is a map, if not already there */ @@ -670,6 +693,7 @@ static void add_hit_to_facehits(KnifeTool_OpData *kcd, GHash *facehits, BMFace * static void knife_add_single_cut(KnifeTool_OpData *kcd, KnifeLineHit *lh1, KnifeLineHit *lh2, BMFace *f) { KnifeEdge *kfe, *kfe2; + BMEdge *e_base; if ((lh1->v && lh1->v == lh2->v) || (lh1->kfe && lh1->kfe == lh2->kfe)) @@ -677,15 +701,25 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd, KnifeLineHit *lh1, Knife return; } + /* if the cut is on an edge, just tag that its a cut and return */ + if ((lh1->v && lh2->v) && + (lh1->v->v && lh2->v && lh2->v->v) && + (e_base = BM_edge_exists(lh1->v->v, lh2->v->v))) + { + kfe = get_bm_knife_edge(kcd, e_base); + kfe->is_cut = true; + kfe->e = e_base; + return; + } /* Check if edge actually lies within face (might not, if this face is concave) */ - if ((lh1->v && !lh1->kfe) && (lh2->v && !lh2->kfe)) { + else if ((lh1->v && !lh1->kfe) && (lh2->v && !lh2->kfe)) { if (!knife_verts_edge_in_face(lh1->v, lh2->v, f)) { return; } } kfe = new_knife_edge(kcd); - kfe->draw = true; + kfe->is_cut = true; kfe->basef = f; if (lh1->v) { @@ -698,7 +732,7 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd, KnifeLineHit *lh1, Knife else { BLI_assert(lh1->f); kfe->v1 = new_knife_vert(kcd, lh1->hit, lh1->cagehit); - kfe->v1->draw = true; + kfe->v1->is_cut = true; kfe->v1->is_face = true; knife_append_list(kcd, &kfe->v1->faces, lh1->f); lh1->v = kfe->v1; /* record the KnifeVert for this hit */ @@ -714,7 +748,7 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd, KnifeLineHit *lh1, Knife else { BLI_assert(lh2->f); kfe->v2 = new_knife_vert(kcd, lh2->hit, lh2->cagehit); - kfe->v2->draw = true; + kfe->v2->is_cut = true; kfe->v2->is_face = true; knife_append_list(kcd, &kfe->v2->faces, lh2->f); lh2->v = kfe->v2; /* record the KnifeVert for this hit */ @@ -735,23 +769,13 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd, KnifeLineHit *lh1, Knife static void knife_cut_face(KnifeTool_OpData *kcd, BMFace *f, ListBase *hits) { Ref *r; - KnifeLineHit *lh, *prevlh; - int n; - (void) kcd; - - n = BLI_countlist(hits); - if (n < 2) + if (BLI_listbase_count_ex(hits, 2) != 2) return; - prevlh = NULL; - for (r = hits->first; r; r = r->next) { - lh = (KnifeLineHit *)r->ref; - if (prevlh) - knife_add_single_cut(kcd, prevlh, lh, f); - prevlh = lh; + for (r = hits->first; r->next; r = r->next) { + knife_add_single_cut(kcd, r->ref, r->next->ref, f); } - } /* User has just left-clicked after the first time. @@ -771,7 +795,9 @@ static void knife_add_cut(KnifeTool_OpData *kcd) prepare_linehits_for_cut(kcd); if (kcd->totlinehit == 0) { - kcd->prev = kcd->curr; + if (kcd->is_drag_hold == false) { + kcd->prev = kcd->curr; + } return; } @@ -806,10 +832,20 @@ static void knife_add_cut(KnifeTool_OpData *kcd) /* set up for next cut */ kcd->prev = kcd->curr; + + if (kcd->prev.bmface) { + KnifeLineHit *lh; /* was "in face" but now we have a KnifeVert it is snapped to */ + lh = &kcd->linehits[kcd->totlinehit - 1]; + + if (kcd->is_drag_hold) { + linehit_to_knifepos(&kcd->prev, lh); + } + else { + kcd->prev.vert = lh->v; + } kcd->prev.bmface = NULL; - kcd->prev.vert = kcd->linehits[kcd->totlinehit - 1].v; } BLI_ghash_free(facehits, NULL, NULL); @@ -1055,7 +1091,7 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) BLI_mempool_iternew(kcd->kedges, &iter); for (kfe = BLI_mempool_iterstep(&iter); kfe; kfe = BLI_mempool_iterstep(&iter)) { - if (!kfe->draw) + if (!kfe->is_cut) continue; glColor3ubv(kcd->colors.line); @@ -1077,7 +1113,7 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) glBegin(GL_POINTS); BLI_mempool_iternew(kcd->kverts, &iter); for (kfv = BLI_mempool_iterstep(&iter); kfv; kfv = BLI_mempool_iterstep(&iter)) { - if (!kfv->draw) + if (!kfv->is_cut) continue; glColor3ubv(kcd->colors.point); @@ -1274,6 +1310,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd) SmallHashIter hiter; KnifeLineHit hit; void *val; + void **val_p; float plane_cos[12]; float s[2], se1[2], se2[2], sint[2]; float r1[3], r2[3]; @@ -1281,10 +1318,12 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd) float vert_tol, vert_tol_sq; float line_tol, line_tol_sq; float face_tol, face_tol_sq; - float eps_scale; + float eps_scale, eps_scale_px; int isect_kind; unsigned int tot; int i; + const bool use_hit_prev = true; + const bool use_hit_curr = (kcd->is_drag_hold == false); bgl_get_mats(&mats); @@ -1360,6 +1399,11 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd) ls = (BMLoop **)kcd->em->looptris[result->indexA]; f = ls[0]->f; set_lowest_face_tri(kcd, f, result->indexA); + + /* occlude but never cut unselected faces (when only_select is used) */ + if (kcd->only_select && !BM_elem_flag_test(f, BM_ELEM_SELECT)) { + continue; + } /* for faces, store index of lowest hit looptri in hash */ if (BLI_smallhash_haskey(&faces, (uintptr_t)f)) { continue; @@ -1374,11 +1418,9 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd) continue; BLI_smallhash_insert(&kfes, (uintptr_t)kfe, kfe); v = kfe->v1; - if (!BLI_smallhash_haskey(&kfvs, (uintptr_t)v)) - BLI_smallhash_insert(&kfvs, (uintptr_t)v, v); + BLI_smallhash_reinsert(&kfvs, (uintptr_t)v, v); v = kfe->v2; - if (!BLI_smallhash_haskey(&kfvs, (uintptr_t)v)) - BLI_smallhash_insert(&kfvs, (uintptr_t)v, v); + BLI_smallhash_reinsert(&kfvs, (uintptr_t)v, v); } } @@ -1387,13 +1429,15 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd) { /* Scale the epsilon by the zoom level * to compensate for projection imprecision, see T41164 */ - float zoom_xy[2] = {kcd->vc.rv3d->winmat[0][0], - kcd->vc.rv3d->winmat[1][1]}; + const float zoom_xy[2] = { + kcd->vc.rv3d->winmat[0][0], + kcd->vc.rv3d->winmat[1][1]}; eps_scale = len_v2(zoom_xy); + eps_scale_px = eps_scale * (kcd->is_interactive ? KNIFE_FLT_EPS_PX : KNIFE_FLT_EPSBIG); } - vert_tol = KNIFE_FLT_EPS_PX * eps_scale; - line_tol = KNIFE_FLT_EPS_PX * eps_scale; + vert_tol = eps_scale_px; + line_tol = eps_scale_px; face_tol = max_ff(vert_tol, line_tol); vert_tol_sq = vert_tol * vert_tol; @@ -1403,30 +1447,59 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd) /* Assume these tolerances swamp floating point rounding errors in calculations below */ /* first look for vertex hits */ - for (val = BLI_smallhash_iternew(&kfvs, &hiter, (uintptr_t *)&v); val; - val = BLI_smallhash_iternext(&hiter, (uintptr_t *)&v)) + for (val_p = BLI_smallhash_iternew_p(&kfvs, &hiter, (uintptr_t *)&v); val_p; + val_p = BLI_smallhash_iternext_p(&hiter, (uintptr_t *)&v)) { knife_project_v2(kcd, v->cageco, s); d = dist_squared_to_line_segment_v2(s, s1, s2); - if (d <= vert_tol_sq) { - if (point_is_visible(kcd, v->cageco, s, &mats)) { - memset(&hit, 0, sizeof(hit)); - hit.v = v; - copy_v3_v3(hit.hit, v->co); - copy_v3_v3(hit.cagehit, v->cageco); - copy_v2_v2(hit.schit, s); - set_linehit_depth(kcd, &hit); - BLI_array_append(linehits, hit); + if ((d <= vert_tol_sq) && + point_is_visible(kcd, v->cageco, s, &mats)) + { + memset(&hit, 0, sizeof(hit)); + hit.v = v; + + /* If this isn't from an existing BMVert, it may have been added to a BMEdge originally. + * knowing if the hit comes from an edge is important for edge-in-face checks later on + * see: #knife_add_single_cut -> #knife_verts_edge_in_face, T42611 */ + if (v->v == NULL) { + for (ref = v->edges.first; ref; ref = ref->next) { + kfe = ref->ref; + if (kfe->e) { + hit.kfe = kfe; + break; + } + } } + + copy_v3_v3(hit.hit, v->co); + copy_v3_v3(hit.cagehit, v->cageco); + copy_v2_v2(hit.schit, s); + set_linehit_depth(kcd, &hit); + BLI_array_append(linehits, hit); + } + else { + /* note that these vertes aren't used */ + *val_p = NULL; } } + /* now edge hits; don't add if a vertex at end of edge should have hit */ for (val = BLI_smallhash_iternew(&kfes, &hiter, (uintptr_t *)&kfe); val; val = BLI_smallhash_iternext(&hiter, (uintptr_t *)&kfe)) { + int kfe_verts_in_cut; + /* if we intersect both verts, don't attempt to intersect the edge */ + + kfe_verts_in_cut = (BLI_smallhash_lookup(&kfvs, (intptr_t)kfe->v1) != NULL) + + (BLI_smallhash_lookup(&kfvs, (intptr_t)kfe->v2) != NULL); + + if (kfe_verts_in_cut == 2) { + continue; + } + knife_project_v2(kcd, kfe->v1->cageco, se1); knife_project_v2(kcd, kfe->v2->cageco, se2); - isect_kind = isect_seg_seg_v2_point(s1, s2, se1, se2, sint); + isect_kind = (kfe_verts_in_cut) ? -1 : isect_seg_seg_v2_point(s1, s2, se1, se2, sint); if (isect_kind == -1) { /* isect_seg_seg_v2 doesn't do tolerance test around ends of s1-s2 */ closest_to_line_segment_v2(sint, s1, se1, se2); @@ -1477,7 +1550,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd) { float p[3], p_cage[3]; - if (knife_ray_intersect_face(kcd, s1, v1, v3, f, face_tol_sq, p, p_cage)) { + if (use_hit_prev && knife_ray_intersect_face(kcd, s1, v1, v3, f, face_tol_sq, p, p_cage)) { if (point_is_visible(kcd, p_cage, s1, &mats)) { memset(&hit, 0, sizeof(hit)); hit.f = f; @@ -1488,7 +1561,8 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd) BLI_array_append(linehits, hit); } } - if (knife_ray_intersect_face(kcd, s2, v2, v4, f, face_tol_sq, p, p_cage)) { + + if (use_hit_curr && knife_ray_intersect_face(kcd, s2, v2, v4, f, face_tol_sq, p, p_cage)) { if (point_is_visible(kcd, p_cage, s2, &mats)) { memset(&hit, 0, sizeof(hit)); hit.f = f; @@ -1551,6 +1625,10 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float f = BKE_bmbvh_ray_cast(kcd->bmbvh, origin, ray, 0.0f, NULL, co, cageco); + if (f && kcd->only_select && BM_elem_flag_test(f, BM_ELEM_SELECT) == 0) { + f = NULL; + } + if (is_space) *is_space = !f; @@ -1913,7 +1991,10 @@ static int knife_update_active(KnifeTool_OpData *kcd) kcd->curr.vert = knife_find_closest_vert(kcd, kcd->curr.co, kcd->curr.cage, &kcd->curr.bmface, &kcd->curr.is_space); - if (!kcd->curr.vert) { + if (!kcd->curr.vert && + /* no edge snapping while dragging (edges are too sticky when cuts are immediate) */ + !kcd->is_drag_hold) + { kcd->curr.edge = knife_find_closest_edge(kcd, kcd->curr.co, kcd->curr.cage, &kcd->curr.bmface, &kcd->curr.is_space); } @@ -2063,7 +2144,7 @@ static ListBase *find_chain(KnifeTool_OpData *kcd, ListBase *fedges) break; } if (ans) { - BLI_assert(BLI_countlist(ans) > 0); + BLI_assert(!BLI_listbase_is_empty(ans)); for (r = ans->first; r; r = r->next) { ref = find_ref(fedges, r->ref); BLI_assert(ref != NULL); @@ -2171,7 +2252,7 @@ static bool find_hole_chains(KnifeTool_OpData *kcd, ListBase *hole, BMFace *f, L int besti[2], bestj[2]; float dist_sq, dist_best_sq; - nh = BLI_countlist(hole); + nh = BLI_listbase_count(hole); nf = f->len; if (nh < 2 || nf < 3) return false; @@ -2300,13 +2381,22 @@ static bool knife_verts_edge_in_face(KnifeVert *v1, KnifeVert *v2, BMFace *f) { bool v1_inside, v2_inside; bool v1_inface, v2_inface; + BMLoop *l1, *l2; if (!f || !v1 || !v2) return false; + l1 = v1->v ? BM_face_vert_share_loop(f, v1->v) : NULL; + l2 = v2->v ? BM_face_vert_share_loop(f, v2->v) : NULL; + + if ((l1 && l2) && BM_loop_is_adjacent(l1, l2)) { + /* boundary-case, always false to avoid edge-in-face checks below */ + return false; + } + /* find out if v1 and v2, if set, are part of the face */ - v1_inface = v1->v ? BM_vert_in_face(f, v1->v) : false; - v2_inface = v2->v ? BM_vert_in_face(f, v2->v) : false; + v1_inface = (l1 != NULL); + v2_inface = (l2 != NULL); /* BM_face_point_inside_test uses best-axis projection so this isn't most accurate test... */ v1_inside = v1_inface ? false : BM_face_point_inside_test(f, v1->co); @@ -2348,7 +2438,7 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha KnifeVert *kfv, *kfvprev; BMLoop *l_new, *l_iter; int i; - int nco = BLI_countlist(chain) - 1; + int nco = BLI_listbase_count(chain) - 1; float (*cos)[3] = BLI_array_alloca(cos, nco); KnifeVert **kverts = BLI_array_alloca(kverts, nco); @@ -2421,7 +2511,7 @@ static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMFace *f, ListBase *kfe Ref *ref, *refnext; int count, oldcount; - oldcount = BLI_countlist(kfedges); + oldcount = BLI_listbase_count(kfedges); while ((chain = find_chain(kcd, kfedges)) != NULL) { ListBase fnew_kfedges; knife_make_chain_cut(kcd, f, chain, &fnew); @@ -2450,7 +2540,7 @@ static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMFace *f, ListBase *kfe /* find_chain should always remove edges if it returns true, * but guard against infinite loop anyway */ - count = BLI_countlist(kfedges); + count = BLI_listbase_count(kfedges); if (count >= oldcount) { BLI_assert(!"knife find_chain infinite loop"); return; @@ -2518,7 +2608,7 @@ static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMFace *f, ListBase *kfe break; /* find_hole should always remove edges if it returns true, * but guard against infinite loop anyway */ - count = BLI_countlist(kfedges); + count = BLI_listbase_count(kfedges); if (count >= oldcount) { BLI_assert(!"knife find_hole infinite loop"); return; @@ -2550,6 +2640,14 @@ static void knife_make_cuts(KnifeTool_OpData *kcd) /* put list of cutting edges for a face into fhash, keyed by face */ BLI_mempool_iternew(kcd->kedges, &iter); for (kfe = BLI_mempool_iterstep(&iter); kfe; kfe = BLI_mempool_iterstep(&iter)) { + + /* select edges that lie directly on the cut */ + if (kcd->select_result) { + if (kfe->e && kfe->is_cut) { + BM_edge_select_set(bm, kfe->e, true); + } + } + f = kfe->basef; if (!f || kfe->e) continue; @@ -2718,10 +2816,11 @@ static void knifetool_init(bContext *C, KnifeTool_OpData *kcd, kcd->cagecos = (const float (*)[3])BKE_editmesh_vertexCos_get(kcd->em, scene, NULL); - kcd->bmbvh = BKE_bmbvh_new_from_editmesh(kcd->em, - BMBVH_RETURN_ORIG | - (only_select ? BMBVH_RESPECT_SELECT : BMBVH_RESPECT_HIDDEN), - kcd->cagecos, false); + kcd->bmbvh = BKE_bmbvh_new_from_editmesh( + kcd->em, + BMBVH_RETURN_ORIG | + ((only_select && cut_through) ? BMBVH_RESPECT_SELECT : BMBVH_RESPECT_HIDDEN), + kcd->cagecos, false); kcd->arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 15), "knife"); kcd->vthresh = KMAXDIST - 1; @@ -2809,7 +2908,8 @@ enum { KNF_MODAL_ADD_CUT, KNF_MODAL_ANGLE_SNAP_TOGGLE, KNF_MODAL_CUT_THROUGH_TOGGLE, - KNF_MODAL_PANNING + KNF_MODAL_PANNING, + KNF_MODAL_ADD_CUT_CLOSED, }; wmKeyMap *knifetool_modal_keymap(wmKeyConfig *keyconf) @@ -2840,7 +2940,8 @@ wmKeyMap *knifetool_modal_keymap(wmKeyConfig *keyconf) /* items for modal map */ WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, KNF_MODAL_CANCEL); WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_ANY, KM_ANY, 0, KNF_MODAL_PANNING); - WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_ANY, 0, KNF_MODAL_ADD_CUT); + WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_DBL_CLICK, KM_ANY, 0, KNF_MODAL_ADD_CUT_CLOSED); + WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_ANY, KM_ANY, 0, KNF_MODAL_ADD_CUT); WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_PRESS, KM_ANY, 0, KNF_MODAL_CANCEL); WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, KNF_MODAL_CONFIRM); WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, KNF_MODAL_CONFIRM); @@ -2951,16 +3052,53 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event) case KNF_MODAL_ADD_CUT: knife_recalc_projmat(kcd); - if (kcd->mode == MODE_DRAGGING) { - knife_add_cut(kcd); + /* get the value of the event which triggered this one */ + if (event->prevval != KM_RELEASE) { + if (kcd->mode == MODE_DRAGGING) { + knife_add_cut(kcd); + } + else if (kcd->mode != MODE_PANNING) { + knife_start_cut(kcd); + kcd->mode = MODE_DRAGGING; + kcd->init = kcd->curr; + } + + /* freehand drawing is incompatible with cut-through */ + if (kcd->cut_through == false) { + kcd->is_drag_hold = true; + } } - else if (kcd->mode != MODE_PANNING) { - knife_start_cut(kcd); - kcd->mode = MODE_DRAGGING; + else { + kcd->is_drag_hold = false; + + /* needed because the last face 'hit' is ignored when dragging */ + knifetool_update_mval(kcd, kcd->curr.mval); } ED_region_tag_redraw(kcd->ar); break; + case KNF_MODAL_ADD_CUT_CLOSED: + if (kcd->mode == MODE_DRAGGING) { + + /* shouldn't be possible with default key-layout, just incase... */ + if (kcd->is_drag_hold) { + kcd->is_drag_hold = false; + knifetool_update_mval(kcd, kcd->curr.mval); + } + + kcd->prev = kcd->curr; + kcd->curr = kcd->init; + + knife_project_v2(kcd, kcd->curr.cage, kcd->curr.mval); + knifetool_update_mval(kcd, kcd->curr.mval); + + knife_add_cut(kcd); + + /* KNF_MODAL_NEW_CUT */ + knife_finish_cut(kcd); + kcd->mode = MODE_IDLE; + } + break; case KNF_MODAL_PANNING: if (event->val != KM_RELEASE) { if (kcd->mode != MODE_PANNING) { @@ -2987,6 +3125,12 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event) case MOUSEMOVE: /* mouse moved somewhere to select another loop */ if (kcd->mode != MODE_PANNING) { knifetool_update_mval_i(kcd, event->mval); + + if (kcd->is_drag_hold) { + if (kcd->totlinehit >= 2) { + knife_add_cut(kcd); + } + } } break; @@ -3034,16 +3178,14 @@ void MESH_OT_knife_tool(wmOperatorType *ot) * tessellation here seems way overkill, * but without this its very hard to know of a point is inside the face */ -static void edvm_mesh_knife_face_point(BMFace *f, float r_cent[3]) +static void edbm_mesh_knife_face_point(BMFace *f, float r_cent[3]) { const int tottri = f->len - 2; BMLoop **loops = BLI_array_alloca(loops, f->len); unsigned int (*index)[3] = BLI_array_alloca(index, tottri); int j; - - const float *best_co[3] = {NULL}; - float best_area = -1.0f; - bool ok = false; + int j_best = 0; /* use as fallback when unset */ + float area_best = -1.0f; BM_face_calc_tessellation(f, loops, index); @@ -3056,49 +3198,34 @@ static void edvm_mesh_knife_face_point(BMFace *f, float r_cent[3]) float cross[3]; cross_v3_v3v3(cross, p2, p3); area = fabsf(dot_v3v3(p1, cross)); - if (area > best_area) { - best_co[0] = p1; - best_co[1] = p2; - best_co[2] = p3; - best_area = area; - ok = true; + if (area > area_best) { + j_best = j; + area_best = area; } } - if (ok) { - mid_v3_v3v3v3(r_cent, best_co[0], best_co[1], best_co[2]); - } - else { - mid_v3_v3v3v3(r_cent, loops[0]->v->co, loops[1]->v->co, loops[2]->v->co); - } + mid_v3_v3v3v3( + r_cent, + loops[index[j_best][0]]->v->co, + loops[index[j_best][1]]->v->co, + loops[index[j_best][2]]->v->co); } -static bool edbm_mesh_knife_face_isect(ARegion *ar, LinkNode *polys, BMFace *f, float projmat[4][4]) +static bool edbm_mesh_knife_point_isect(LinkNode *polys, const float cent_ss[2]) { - float cent_ss[2]; - float cent[3]; + LinkNode *p = polys; + int isect = 0; - edvm_mesh_knife_face_point(f, cent); - - ED_view3d_project_float_v2_m4(ar, cent, cent_ss, projmat); - - /* check */ - { - LinkNode *p = polys; - int isect = 0; - - while (p) { - const float (*mval_fl)[2] = p->link; - const int mval_tot = MEM_allocN_len(mval_fl) / sizeof(*mval_fl); - isect += (int)isect_point_poly_v2(cent_ss, mval_fl, mval_tot - 1, false); - p = p->next; - } - - if (isect % 2) { - return true; - } + while (p) { + const float (*mval_fl)[2] = p->link; + const int mval_tot = MEM_allocN_len(mval_fl) / sizeof(*mval_fl); + isect += (int)isect_point_poly_v2(cent_ss, mval_fl, mval_tot - 1, false); + p = p->next; } + if (isect % 2) { + return true; + } return false; } @@ -3108,6 +3235,7 @@ static bool edbm_mesh_knife_face_isect(ARegion *ar, LinkNode *polys, BMFace *f, void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_through) { KnifeTool_OpData *kcd; + bglMats mats; view3d_operator_needs_opengl(C); @@ -3126,6 +3254,10 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug if (use_tag) { BM_mesh_elem_hflag_enable_all(kcd->em->bm, BM_EDGE, BM_ELEM_TAG, false); } + + if (kcd->cut_through == false) { + bgl_get_mats(&mats); + } } /* execute */ @@ -3190,7 +3322,10 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug BMFace *f; BMIter fiter; BM_ITER_ELEM (f, &fiter, e, BM_FACES_OF_EDGE) { - if (edbm_mesh_knife_face_isect(kcd->ar, polys, f, projmat)) { + float cent[3], cent_ss[2]; + edbm_mesh_knife_face_point(f, cent); + knife_project_v2(kcd, cent, cent_ss); + if (edbm_mesh_knife_point_isect(polys, cent_ss)) { BM_elem_flag_enable(f, BM_ELEM_TAG); } } @@ -3223,7 +3358,12 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug } while ((l_iter = l_iter->next) != l_first && (found == false)); if (found) { - if (edbm_mesh_knife_face_isect(kcd->ar, polys, f, projmat)) { + float cent[3], cent_ss[2]; + edbm_mesh_knife_face_point(f, cent); + knife_project_v2(kcd, cent, cent_ss); + if ((kcd->cut_through || point_is_visible(kcd, cent, cent_ss, &mats)) && + edbm_mesh_knife_point_isect(polys, cent_ss)) + { BM_elem_flag_enable(f, BM_ELEM_TAG); keep_search = true; } diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index b5508ef8b82..3d93210382c 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -412,7 +412,7 @@ static void ringsel_finish(bContext *C, wmOperator *op) BM_mesh_esubdivide(em->bm, BM_ELEM_SELECT, smoothness, smooth_falloff, true, 0.0f, 0.0f, - cuts, seltype, SUBD_PATH, 0, true, + cuts, seltype, SUBD_CORNER_PATH, 0, true, use_only_quads, 0); /* when used in a macro tessface is already re-recalculated */ diff --git a/source/blender/editors/mesh/editmesh_path.c b/source/blender/editors/mesh/editmesh_path.c index 44d03da93a2..4eaac6cc1d3 100644 --- a/source/blender/editors/mesh/editmesh_path.c +++ b/source/blender/editors/mesh/editmesh_path.c @@ -32,9 +32,12 @@ #include "DNA_scene_types.h" #include "DNA_object_types.h" #include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" #include "DNA_windowmanager_types.h" +#ifdef WITH_FREESTYLE +# include "DNA_meshdata_types.h" +#endif + #include "BLI_math.h" #include "BLI_linklist.h" @@ -99,7 +102,7 @@ static bool mouse_mesh_shortest_path_vert(ViewContext *vc) if (v_act && (v_act != v_dst)) { if ((path = BM_mesh_calc_path_vert(bm, v_act, v_dst, use_length, - &user_data, verttag_filter_cb))) + verttag_filter_cb, &user_data))) { BM_select_history_remove(bm, v_act); } @@ -267,7 +270,7 @@ static bool mouse_mesh_shortest_path_edge(ViewContext *vc) if (e_act && (e_act != e_dst)) { if ((path = BM_mesh_calc_path_edge(bm, e_act, e_dst, use_length, - &user_data, edgetag_filter_cb))) + edgetag_filter_cb, &user_data))) { BM_select_history_remove(bm, e_act); } @@ -388,7 +391,7 @@ static bool mouse_mesh_shortest_path_face(ViewContext *vc) if (f_act) { if (f_act != f_dst) { if ((path = BM_mesh_calc_path_face(bm, f_act, f_dst, use_length, - &user_data, facetag_filter_cb))) + facetag_filter_cb, &user_data))) { BM_select_history_remove(bm, f_act); } @@ -513,11 +516,6 @@ void MESH_OT_shortest_path_pick(wmOperatorType *ot) /* -------------------------------------------------------------------- */ /* Select path between existing selection */ -static bool ele_filter_visible_cb(BMElem *ele, void *UNUSED(user_data)) -{ - return !BM_elem_flag_test(ele, BM_ELEM_HIDDEN); -} - static int edbm_shortest_path_select_exec(bContext *C, wmOperator *op) { Object *ob = CTX_data_edit_object(C); @@ -577,17 +575,17 @@ static int edbm_shortest_path_select_exec(bContext *C, wmOperator *op) case BM_VERT: path = BM_mesh_calc_path_vert( bm, (BMVert *)ele_src, (BMVert *)ele_dst, use_length, - NULL, (bool (*)(BMVert *, void *))ele_filter_visible_cb); + BM_elem_cb_check_hflag_disabled_simple(BMVert *, BM_ELEM_HIDDEN)); break; case BM_EDGE: path = BM_mesh_calc_path_edge( bm, (BMEdge *)ele_src, (BMEdge *)ele_dst, use_length, - NULL, (bool (*)(BMEdge *, void *))ele_filter_visible_cb); + BM_elem_cb_check_hflag_disabled_simple(BMEdge *, BM_ELEM_HIDDEN)); break; case BM_FACE: path = BM_mesh_calc_path_face( bm, (BMFace *)ele_src, (BMFace *)ele_dst, use_length, - NULL, (bool (*)(BMFace *, void *))ele_filter_visible_cb); + BM_elem_cb_check_hflag_disabled_simple(BMFace *, BM_ELEM_HIDDEN)); break; } diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 4f149bf2c52..ead243d6de8 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -626,7 +626,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve * split off vertex if... * - we cant find an edge - this means we are ripping a faces vert that is connected to other * geometry only at the vertex. - * - the boundary edge total is greater then 2, + * - the boundary edge total is greater than 2, * in this case edge split _can_ work but we get far nicer results if we use this special case. * - there are only 2 edges but we are a wire vert. */ if ((is_wire == false && totboundary_edge > 2) || diff --git a/source/blender/editors/mesh/editmesh_rip_edge.c b/source/blender/editors/mesh/editmesh_rip_edge.c index 5daf33fae3b..a501dfc8c2c 100644 --- a/source/blender/editors/mesh/editmesh_rip_edge.c +++ b/source/blender/editors/mesh/editmesh_rip_edge.c @@ -24,8 +24,6 @@ * based on mouse cursor position, split of vertices along the closest edge. */ -#include "MEM_guardedalloc.h" - #include "DNA_object_types.h" #include "BLI_math.h" @@ -34,9 +32,6 @@ #include "BKE_report.h" #include "BKE_editmesh.h" -#include "RNA_define.h" -#include "RNA_access.h" - #include "WM_types.h" #include "ED_mesh.h" @@ -177,7 +172,7 @@ static int edbm_rip_edge_invoke(bContext *C, wmOperator *UNUSED(op), const wmEve ED_view3d_project_float_v2_m4(ar, v_other->co, v_other_sco, projectMat); - /* avoid comparing with view-axis aligned edges (less then a pixel) */ + /* avoid comparing with view-axis aligned edges (less than a pixel) */ if (len_squared_v2v2(v_sco, v_other_sco) > 1.0f) { float v_dir[2]; diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 473da4c9756..9d30bc3a2c2 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -38,7 +38,6 @@ #include "BLI_math.h" #include "BLI_rand.h" #include "BLI_array.h" -#include "BLI_smallhash.h" #include "BKE_context.h" #include "BKE_report.h" @@ -62,8 +61,6 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" -#include "GPU_extensions.h" - #include "UI_resources.h" #include "bmesh_tools.h" @@ -386,8 +383,6 @@ static void findnearestvert__doClosest(void *userData, BMVert *eve, const float } - - static bool findnearestvert__backbufIndextest(void *handle, unsigned int index) { BMEditMesh *em = (BMEditMesh *)handle; @@ -2473,12 +2468,13 @@ void MESH_OT_select_mirror(wmOperatorType *ot) /* ******************** **************** */ -static int edbm_select_more_exec(bContext *C, wmOperator *UNUSED(op)) +static int edbm_select_more_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); + const bool use_face_step = RNA_boolean_get(op->ptr, "use_face_step"); - EDBM_select_more(em); + EDBM_select_more(em, use_face_step); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit); return OPERATOR_FINISHED; @@ -2497,14 +2493,17 @@ void MESH_OT_select_more(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "use_face_step", true, "Face Step", "Connected faces (instead of edges)"); } -static int edbm_select_less_exec(bContext *C, wmOperator *UNUSED(op)) +static int edbm_select_less_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); + const bool use_face_step = RNA_boolean_get(op->ptr, "use_face_step"); - EDBM_select_less(em); + EDBM_select_less(em, use_face_step); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit); return OPERATOR_FINISHED; @@ -2523,6 +2522,8 @@ void MESH_OT_select_less(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "use_face_step", true, "Face Step", "Connected faces (instead of edges)"); } /** diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 20c7f4eb521..a480b2051cc 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -90,9 +90,9 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op) const float along_normal = RNA_float_get(op->ptr, "fractal_along_normal"); if (RNA_boolean_get(op->ptr, "quadtri") && - RNA_enum_get(op->ptr, "quadcorner") == SUBD_STRAIGHT_CUT) + RNA_enum_get(op->ptr, "quadcorner") == SUBD_CORNER_STRAIGHT_CUT) { - RNA_enum_set(op->ptr, "quadcorner", SUBD_INNERVERT); + RNA_enum_set(op->ptr, "quadcorner", SUBD_CORNER_INNERVERT); } BM_mesh_esubdivide(em->bm, BM_ELEM_SELECT, @@ -110,10 +110,10 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op) /* Note, these values must match delete_mesh() event values */ static EnumPropertyItem prop_mesh_cornervert_types[] = { - {SUBD_INNERVERT, "INNERVERT", 0, "Inner Vert", ""}, - {SUBD_PATH, "PATH", 0, "Path", ""}, - {SUBD_STRAIGHT_CUT, "STRAIGHT_CUT", 0, "Straight Cut", ""}, - {SUBD_FAN, "FAN", 0, "Fan", ""}, + {SUBD_CORNER_INNERVERT, "INNERVERT", 0, "Inner Vert", ""}, + {SUBD_CORNER_PATH, "PATH", 0, "Path", ""}, + {SUBD_CORNER_STRAIGHT_CUT, "STRAIGHT_CUT", 0, "Straight Cut", ""}, + {SUBD_CORNER_FAN, "FAN", 0, "Fan", ""}, {0, NULL, 0, NULL, NULL} }; @@ -141,7 +141,7 @@ void MESH_OT_subdivide(wmOperatorType *ot) RNA_def_float(ot->srna, "smoothness", 0.0f, 0.0f, FLT_MAX, "Smoothness", "Smoothness factor", 0.0f, 1.0f); RNA_def_boolean(ot->srna, "quadtri", 0, "Quad/Tri Mode", "Tries to prevent ngons"); - RNA_def_enum(ot->srna, "quadcorner", prop_mesh_cornervert_types, SUBD_STRAIGHT_CUT, + RNA_def_enum(ot->srna, "quadcorner", prop_mesh_cornervert_types, SUBD_CORNER_STRAIGHT_CUT, "Quad Corner Type", "How to subdivide quad corners (anything other than Straight Cut will prevent ngons)"); RNA_def_float(ot->srna, "fractal", 0.0f, 0.0f, FLT_MAX, "Fractal", "Fractal randomness factor", 0.0f, 1000.0f); @@ -877,23 +877,50 @@ static int edbm_vert_connect_exec(bContext *C, wmOperator *op) BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; BMOperator bmop; - const bool is_pair = (bm->totvertsel == 2); - int len; - + bool is_pair = (bm->totvertsel == 2); + int len = 0; + bool check_degenerate = true; + const int verts_len = bm->totvertsel; + BMVert **verts; + + + verts = MEM_mallocN(sizeof(*verts) * verts_len, __func__); + { + BMIter iter; + BMVert *v; + int i = 0; + + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { + verts[i++] = v; + } + } + + if (is_pair) { + if (BM_vert_pair_share_face_check_cb( + verts[0], verts[1], + BM_elem_cb_check_hflag_disabled_simple(BMFace *, BM_ELEM_HIDDEN))) + { + check_degenerate = false; + is_pair = false; + } + } + } + if (is_pair) { if (!EDBM_op_init(em, &bmop, op, - "connect_vert_pair verts=%hv verts_exclude=%hv faces_exclude=%hf", - BM_ELEM_SELECT, BM_ELEM_HIDDEN, BM_ELEM_HIDDEN)) + "connect_vert_pair verts=%eb verts_exclude=%hv faces_exclude=%hf", + verts, verts_len, BM_ELEM_HIDDEN, BM_ELEM_HIDDEN)) { - return OPERATOR_CANCELLED; + goto finally; } } else { if (!EDBM_op_init(em, &bmop, op, - "connect_verts verts=%hv faces_exclude=%hf check_degenerate=%b", - BM_ELEM_SELECT, BM_ELEM_HIDDEN, true)) + "connect_verts verts=%eb faces_exclude=%hf check_degenerate=%b", + verts, verts_len, BM_ELEM_HIDDEN, check_degenerate)) { - return OPERATOR_CANCELLED; + goto finally; } } @@ -908,15 +935,18 @@ static int edbm_vert_connect_exec(bContext *C, wmOperator *op) } if (!EDBM_op_finish(em, &bmop, op, true)) { - return OPERATOR_CANCELLED; + len = 0; } else { EDBM_selectmode_flush(em); /* so newly created edges get the selection state from the vertex */ EDBM_update_generic(em, true, true); - - return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } + + +finally: + MEM_freeN(verts); + return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } void MESH_OT_vert_connect(wmOperatorType *ot) @@ -2509,7 +2539,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) if (mode == KNIFE_MIDPOINT) numcuts = 1; BMO_slot_int_set(bmop.slots_in, "cuts", numcuts); - BMO_slot_int_set(bmop.slots_in, "quad_corner_type", SUBD_STRAIGHT_CUT); + BMO_slot_int_set(bmop.slots_in, "quad_corner_type", SUBD_CORNER_STRAIGHT_CUT); BMO_slot_bool_set(bmop.slots_in, "use_single_edge", false); BMO_slot_bool_set(bmop.slots_in, "use_grid_fill", false); @@ -2929,7 +2959,14 @@ static int edbm_fill_exec(bContext *C, wmOperator *op) BMEditMesh *em = BKE_editmesh_from_object(obedit); const bool use_beauty = RNA_boolean_get(op->ptr, "use_beauty"); BMOperator bmop; - + const int totface_orig = em->bm->totface; + int ret; + + if (em->bm->totedgesel == 0) { + BKE_report(op->reports, RPT_WARNING, "No edges selected"); + return OPERATOR_CANCELLED; + } + if (!EDBM_op_init(em, &bmop, op, "triangle_fill edges=%he use_beauty=%b", BM_ELEM_SELECT, use_beauty)) @@ -2939,17 +2976,24 @@ static int edbm_fill_exec(bContext *C, wmOperator *op) BMO_op_exec(em->bm, &bmop); - /* select new geometry */ - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_FACE | BM_EDGE, BM_ELEM_SELECT, true); - - if (!EDBM_op_finish(em, &bmop, op, true)) { - return OPERATOR_CANCELLED; + if (totface_orig != em->bm->totface) { + /* select new geometry */ + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_FACE | BM_EDGE, BM_ELEM_SELECT, true); + + EDBM_update_generic(em, true, true); + + ret = OPERATOR_FINISHED; + } + else { + BKE_report(op->reports, RPT_WARNING, "No faces filled"); + ret = OPERATOR_CANCELLED; } - EDBM_update_generic(em, true, true); - - return OPERATOR_FINISHED; + if (!EDBM_op_finish(em, &bmop, op, true)) { + ret = OPERATOR_CANCELLED; + } + return ret; } void MESH_OT_fill(wmOperatorType *ot) @@ -3472,10 +3516,16 @@ void MESH_OT_tris_convert_to_quads(wmOperatorType *ot) /* -------------------------------------------------------------------- */ /* Dissolve */ -static void edbm_dissolve_prop__use_verts(wmOperatorType *ot) +static void edbm_dissolve_prop__use_verts(wmOperatorType *ot, bool value, int flag) { - RNA_def_boolean(ot->srna, "use_verts", 0, "Dissolve Verts", - "Dissolve remaining vertices"); + PropertyRNA *prop; + + prop = RNA_def_boolean(ot->srna, "use_verts", value, "Dissolve Verts", + "Dissolve remaining vertices"); + + if (flag) { + RNA_def_property_flag(prop, flag); + } } static void edbm_dissolve_prop__use_face_split(wmOperatorType *ot) { @@ -3560,7 +3610,7 @@ void MESH_OT_dissolve_edges(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - edbm_dissolve_prop__use_verts(ot); + edbm_dissolve_prop__use_verts(ot, true, 0); edbm_dissolve_prop__use_face_split(ot); } @@ -3599,7 +3649,7 @@ void MESH_OT_dissolve_faces(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - edbm_dissolve_prop__use_verts(ot); + edbm_dissolve_prop__use_verts(ot, false, 0); } @@ -3607,6 +3657,15 @@ static int edbm_dissolve_mode_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); + PropertyRNA *prop; + + prop = RNA_struct_find_property(op->ptr, "use_verts"); + if (!RNA_property_is_set(op->ptr, prop)) { + /* always enable in edge-mode */ + if ((em->selectmode & SCE_SELECT_FACE) == 0) { + RNA_property_boolean_set(op->ptr, prop, true); + } + } if (em->selectmode & SCE_SELECT_VERTEX) { return edbm_dissolve_verts_exec(C, op); @@ -3633,7 +3692,7 @@ void MESH_OT_dissolve_mode(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - edbm_dissolve_prop__use_verts(ot); + edbm_dissolve_prop__use_verts(ot, false, PROP_SKIP_SAVE); edbm_dissolve_prop__use_face_split(ot); edbm_dissolve_prop__use_boundary_tear(ot); } diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index c7d1d883537..86cd75eed7a 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -33,9 +33,11 @@ #include "DNA_mesh_types.h" #include "DNA_object_types.h" +#include "DNA_key_types.h" #include "BLI_math.h" #include "BLI_alloca.h" +#include "BLI_listbase.h" #include "BKE_DerivedMesh.h" #include "BKE_context.h" @@ -230,7 +232,7 @@ bool EDBM_op_finish(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const bool else { em->emcopyusers--; if (em->emcopyusers < 0) { - printf("warning: em->emcopyusers was less then zero.\n"); + printf("warning: em->emcopyusers was less than zero.\n"); } if (em->emcopyusers <= 0) { @@ -381,6 +383,12 @@ void EDBM_mesh_load(Object *ob) Mesh *me = ob->data; BMesh *bm = me->edit_btmesh->bm; + /* Workaround for T42360, 'ob->shapenr' should be 1 in this case. + * however this isn't synchronized between objects at the moment. */ + if (UNLIKELY((ob->shapenr == 0) && (me->key && !BLI_listbase_is_empty(&me->key->block)))) { + bm->shapenr = 1; + } + BM_mesh_bm_to_me(bm, me, false); #ifdef USE_TESSFACE_DEFAULT @@ -432,14 +440,14 @@ void EDBM_select_flush(BMEditMesh *em) BM_mesh_select_flush(em->bm); } -void EDBM_select_more(BMEditMesh *em) +void EDBM_select_more(BMEditMesh *em, const bool use_face_step) { BMOperator bmop; - int use_faces = em->selectmode == SCE_SELECT_FACE; + const bool use_faces = (em->selectmode == SCE_SELECT_FACE); BMO_op_initf(em->bm, &bmop, BMO_FLAG_DEFAULTS, - "region_extend geom=%hvef use_constrict=%b use_faces=%b", - BM_ELEM_SELECT, false, use_faces); + "region_extend geom=%hvef use_contract=%b use_faces=%b use_face_step=%b", + BM_ELEM_SELECT, false, use_faces, use_face_step); BMO_op_exec(em->bm, &bmop); /* don't flush selection in edge/vertex mode */ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, use_faces ? true : false); @@ -448,14 +456,14 @@ void EDBM_select_more(BMEditMesh *em) EDBM_selectmode_flush(em); } -void EDBM_select_less(BMEditMesh *em) +void EDBM_select_less(BMEditMesh *em, const bool use_face_step) { BMOperator bmop; - int use_faces = em->selectmode == SCE_SELECT_FACE; + const bool use_faces = (em->selectmode == SCE_SELECT_FACE); BMO_op_initf(em->bm, &bmop, BMO_FLAG_DEFAULTS, - "region_extend geom=%hvef use_constrict=%b use_faces=%b", - BM_ELEM_SELECT, true, use_faces); + "region_extend geom=%hvef use_contract=%b use_faces=%b use_face_step=%b", + BM_ELEM_SELECT, true, use_faces, use_face_step); BMO_op_exec(em->bm, &bmop); /* don't flush selection in edge/vertex mode */ BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, use_faces ? true : false); @@ -524,30 +532,56 @@ static void *editbtMesh_to_undoMesh(void *emv, void *obdata) return um; } -static void undoMesh_to_editbtMesh(void *umv, void *em_v, void *UNUSED(obdata)) +static void undoMesh_to_editbtMesh(void *umv, void *em_v, void *obdata) { BMEditMesh *em = em_v, *em_tmp; Object *ob = em->ob; UndoMesh *um = umv; BMesh *bm; + Key *key = ((Mesh *) obdata)->key; const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(&um->me); - ob->shapenr = em->bm->shapenr = um->shapenr; + em->bm->shapenr = um->shapenr; EDBM_mesh_free(em); bm = BM_mesh_create(&allocsize); - BM_mesh_bm_from_me(bm, &um->me, true, false, ob->shapenr); + BM_mesh_bm_from_me(bm, &um->me, true, false, um->shapenr); em_tmp = BKE_editmesh_create(bm, true); *em = *em_tmp; - + em->selectmode = um->selectmode; bm->selectmode = um->selectmode; em->ob = ob; + /* T35170: Restore the active key on the RealMesh. Otherwise 'fake' offset propagation happens + * if the active is a basis for any other. */ + if (key && (key->type == KEY_RELATIVE)) { + /* Since we can't add, remove or reorder keyblocks in editmode, it's safe to assume + * shapenr from restored bmesh and keyblock indices are in sync. */ + const int kb_act_idx = ob->shapenr - 1; + + /* If it is, let's patch the current mesh key block to its restored value. + * Else, the offsets won't be computed and it won't matter. */ + if (BKE_keyblock_is_basis(key, kb_act_idx)) { + KeyBlock *kb_act = BLI_findlink(&key->block, kb_act_idx); + + if (kb_act->totelem != um->me.totvert) { + /* The current mesh has some extra/missing verts compared to the undo, adjust. */ + MEM_SAFE_FREE(kb_act->data); + kb_act->data = MEM_mallocN((size_t)(key->elemsize * bm->totvert), __func__); + kb_act->totelem = um->me.totvert; + } + + BKE_keyblock_update_from_mesh(&um->me, kb_act); + } + } + + ob->shapenr = um->shapenr; + MEM_freeN(em_tmp); } diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 68471bfc2ba..152d055d239 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -43,7 +43,6 @@ #include "BKE_context.h" #include "BKE_depsgraph.h" -#include "BKE_image.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_mesh.h" @@ -51,7 +50,6 @@ #include "BKE_report.h" #include "BKE_editmesh.h" -#include "RNA_access.h" #include "RNA_define.h" #include "WM_api.h" @@ -336,6 +334,26 @@ int ED_mesh_uv_texture_add(Mesh *me, const char *name, const bool active_set) return layernum_dst; } +void ED_mesh_uv_texture_ensure(struct Mesh *me, const char *name) +{ + BMEditMesh *em; + int layernum_dst; + + if (me->edit_btmesh) { + em = me->edit_btmesh; + + layernum_dst = CustomData_number_of_layers(&em->bm->pdata, CD_MTEXPOLY); + if (layernum_dst == 0) + ED_mesh_uv_texture_add(me, name, true); + } + else { + layernum_dst = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY); + if (layernum_dst == 0) + ED_mesh_uv_texture_add(me, name, true); + } +} + + bool ED_mesh_uv_texture_remove_index(Mesh *me, const int n) { CustomData *pdata = GET_CD_DATA(me, pdata), *ldata = GET_CD_DATA(me, ldata); @@ -551,24 +569,13 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, const wmEvent *e return OPERATOR_CANCELLED; } - /* check input variables */ - if (RNA_struct_property_is_set(op->ptr, "filepath")) { - char path[FILE_MAX]; - - RNA_string_get(op->ptr, "filepath", path); - ima = BKE_image_load_exists(path); - } - else { - char name[MAX_ID_NAME - 2]; - RNA_string_get(op->ptr, "name", name); - ima = (Image *)BKE_libblock_find_name(ID_IM, name); - } - + ima = (Image *)WM_operator_drop_load_path(C, op, ID_IM); if (!ima) { - BKE_report(op->reports, RPT_ERROR, "Not an image"); return OPERATOR_CANCELLED; } - + /* handled below */ + id_us_min((ID *)ima); + /* put mesh in editmode */ obedit = base->object; @@ -619,6 +626,7 @@ void MESH_OT_drop_named_image(wmOperatorType *ot) /* properties */ RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Image name to assign"); RNA_def_string(ot->srna, "filepath", "Path", FILE_MAX, "Filepath", "Path to image file"); + RNA_def_boolean(ot->srna, "relative_path", true, "Relative Path", "Select the file relative to the blend file"); } static int mesh_uv_texture_remove_exec(bContext *C, wmOperator *UNUSED(op)) diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 16f4f61f92b..19040062fda 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -627,7 +627,7 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op) /* first key added, so it was the basis. initialize it with the existing mesh */ kb = BKE_keyblock_add(key, NULL); - BKE_key_convert_from_mesh(me, kb); + BKE_keyblock_convert_from_mesh(me, kb); } /* now ready to add new keys from selected meshes */ diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index f6a54beb8c8..57daec49465 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -47,7 +47,6 @@ #include "RNA_define.h" #include "RNA_access.h" -#include "RNA_enum_types.h" #include "BKE_depsgraph.h" #include "BKE_context.h" diff --git a/source/blender/editors/metaball/mball_ops.c b/source/blender/editors/metaball/mball_ops.c index b7822200d98..0723bb4e62d 100644 --- a/source/blender/editors/metaball/mball_ops.c +++ b/source/blender/editors/metaball/mball_ops.c @@ -30,8 +30,6 @@ #include "DNA_scene_types.h" -#include "BLI_utildefines.h" - #include "RNA_access.h" #include "WM_api.h" diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 8972dd7cf08..c3edd63b2d4 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -69,7 +69,6 @@ #include "BKE_effect.h" #include "BKE_font.h" #include "BKE_group.h" -#include "BKE_image.h" #include "BKE_lamp.h" #include "BKE_lattice.h" #include "BKE_library.h" @@ -97,7 +96,6 @@ #include "ED_armature.h" #include "ED_curve.h" -#include "ED_lattice.h" #include "ED_mball.h" #include "ED_mesh.h" #include "ED_node.h" @@ -108,7 +106,6 @@ #include "ED_transform.h" #include "ED_view3d.h" -#include "UI_interface.h" #include "UI_resources.h" #include "GPU_material.h" @@ -449,14 +446,23 @@ static int object_add_exec(bContext *C, wmOperator *op) Object *ob; bool enter_editmode; unsigned int layer; - float loc[3], rot[3]; + float loc[3], rot[3], radius; WM_operator_view3d_unit_defaults(C, op); if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, &enter_editmode, &layer, NULL)) return OPERATOR_CANCELLED; + radius = RNA_float_get(op->ptr, "radius"); ob = ED_object_add_type(C, RNA_enum_get(op->ptr, "type"), loc, rot, enter_editmode, layer); - BKE_object_obdata_size_init(ob, RNA_float_get(op->ptr, "radius")); + + if (ob->type == OB_LATTICE) { + /* lattice is a special case! + * we never want to scale the obdata since that is the rest-state */ + copy_v3_fl(ob->size, radius); + } + else { + BKE_object_obdata_size_init(ob, radius); + } return OPERATOR_FINISHED; } @@ -824,24 +830,12 @@ static int empty_drop_named_image_invoke(bContext *C, wmOperator *op, const wmEv Image *ima = NULL; Object *ob = NULL; - /* check image input variables */ - if (RNA_struct_property_is_set(op->ptr, "filepath")) { - char path[FILE_MAX]; - - RNA_string_get(op->ptr, "filepath", path); - ima = BKE_image_load_exists(path); - } - else if (RNA_struct_property_is_set(op->ptr, "name")) { - char name[MAX_ID_NAME - 2]; - - RNA_string_get(op->ptr, "name", name); - ima = (Image *)BKE_libblock_find_name(ID_IM, name); - } - - if (ima == NULL) { - BKE_report(op->reports, RPT_ERROR, "Not an image"); + ima = (Image *)WM_operator_drop_load_path(C, op, ID_IM); + if (!ima) { return OPERATOR_CANCELLED; } + /* handled below */ + id_us_min((ID *)ima); base = ED_view3d_give_base_under_cursor(C, event->mval); @@ -893,6 +887,8 @@ void OBJECT_OT_drop_named_image(wmOperatorType *ot) /* properties */ prop = RNA_def_string(ot->srna, "filepath", NULL, FILE_MAX, "Filepath", "Path to image file"); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + RNA_def_boolean(ot->srna, "relative_path", true, "Relative Path", "Select the file relative to the blend file"); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); prop = RNA_def_string(ot->srna, "name", NULL, MAX_ID_NAME - 2, "Name", "Image name to assign"); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); ED_object_add_generic_props(ot, false); @@ -981,8 +977,11 @@ static int group_instance_add_exec(bContext *C, wmOperator *op) if (0 == RNA_struct_property_is_set(op->ptr, "location")) { wmEvent *event = CTX_wm_window(C)->eventstate; + ARegion *ar = CTX_wm_region(C); + const int mval[2] = {event->x - ar->winrct.xmin, + event->y - ar->winrct.ymin}; ED_object_location_from_view(C, loc); - ED_view3d_cursor3d_position(C, loc, event->mval); + ED_view3d_cursor3d_position(C, loc, mval); RNA_float_set_array(op->ptr, "location", loc); } } @@ -1290,6 +1289,44 @@ static void copy_object_set_idnew(bContext *C, int dupflag) /********************* Make Duplicates Real ************************/ +/** + * \note regarding hashing dupli-objects, skip the first member of #DupliObject.persistent_id + * since its a unique index and we only want to know if the group objects are from the same dupli-group instance. + */ +static unsigned int dupliobject_hash(const void *ptr) +{ + const DupliObject *dob = ptr; + unsigned int hash = BLI_ghashutil_ptrhash(dob->ob); + unsigned int i; + for (i = 1; (i < MAX_DUPLI_RECUR) && dob->persistent_id[i] != INT_MAX; i++) { + hash ^= (dob->persistent_id[i] ^ i); + } + return hash; +} + +static bool dupliobject_cmp(const void *a_, const void *b_) +{ + const DupliObject *a = a_; + const DupliObject *b = b_; + unsigned int i; + + if (a->ob != b->ob) { + return true; + } + + for (i = 1; (i < MAX_DUPLI_RECUR); i++) { + if (a->persistent_id[i] != b->persistent_id[i]) { + return true; + } + else if (a->persistent_id[i] == INT_MAX) { + break; + } + } + + /* matching */ + return false; +} + static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, const bool use_base_parent, const bool use_hierarchy) @@ -1306,8 +1343,8 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, lb = object_duplilist(bmain->eval_ctx, scene, base->object); if (use_hierarchy || use_base_parent) { - dupli_gh = BLI_ghash_ptr_new("make_object_duplilist_real dupli_gh"); - parent_gh = BLI_ghash_pair_new("make_object_duplilist_real parent_gh"); + dupli_gh = BLI_ghash_ptr_new(__func__); + parent_gh = BLI_ghash_new(dupliobject_hash, dupliobject_cmp, __func__); } for (dob = lb->first; dob; dob = dob->next) { @@ -1347,7 +1384,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, if (dupli_gh) BLI_ghash_insert(dupli_gh, dob, ob); if (parent_gh) - BLI_ghash_insert(parent_gh, BLI_ghashutil_pairalloc(dob->ob, SET_INT_IN_POINTER(dob->persistent_id[0])), ob); + BLI_ghash_insert(parent_gh, dob, ob); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } @@ -1363,9 +1400,14 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, /* find parent that was also made real */ if (ob_src_par) { - GHashPair *pair = BLI_ghashutil_pairalloc(ob_src_par, SET_INT_IN_POINTER(dob->persistent_id[0])); - ob_dst_par = BLI_ghash_lookup(parent_gh, pair); - BLI_ghashutil_pairfree(pair); + /* OK to keep most of the members uninitialized, + * they won't be read, this is simply for a hash lookup. */ + DupliObject dob_key; + dob_key.ob = ob_src_par; + memcpy(&dob_key.persistent_id[1], + &dob->persistent_id[1], + sizeof(dob->persistent_id[1]) * (MAX_DUPLI_RECUR - 1)); + ob_dst_par = BLI_ghash_lookup(parent_gh, &dob_key); } if (ob_dst_par) { @@ -1428,7 +1470,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, if (dupli_gh) BLI_ghash_free(dupli_gh, NULL, NULL); if (parent_gh) - BLI_ghash_free(parent_gh, BLI_ghashutil_pairfree, NULL); + BLI_ghash_free(parent_gh, NULL, NULL); copy_object_set_idnew(C, 0); @@ -2270,7 +2312,7 @@ static int add_named_exec(bContext *C, wmOperator *op) MEM_freeN(base); - WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); + WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT | ND_OB_ACTIVE, scene); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index b8957514159..758f4d180b9 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -45,8 +45,6 @@ #include "BLI_blenlib.h" #include "BLI_threads.h" #include "BLI_utildefines.h" -#include "BLI_math.h" -#include "BLI_math_geom.h" #include "BKE_blender.h" #include "BKE_screen.h" @@ -71,7 +69,6 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#include "IMB_colormanagement.h" #include "GPU_draw.h" /* GPU_free_image */ @@ -438,7 +435,7 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa MultiresBakeJob *bkj = bkv; int baked_objects = 0, tot_obj; - tot_obj = BLI_countlist(&bkj->data); + tot_obj = BLI_listbase_count(&bkj->data); if (bkj->bake_clear) { /* clear images */ for (data = bkj->data.first; data; data = data->next) { diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index 5746f9efd56..57fabcb06cf 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -768,7 +768,7 @@ static int bake( normalize_m4_m4(highpoly[i].rotmat, highpoly[i].imat); zero_v3(highpoly[i].rotmat[3]); if (is_negative_m4(highpoly[i].rotmat)) - negate_m3(highpoly[i].rotmat); + negate_mat3_m4(highpoly[i].rotmat); i++; } diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 92ed84b7f5e..2596ea0a064 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -233,7 +233,7 @@ static void set_constraint_nth_target(bConstraint *con, Object *target, const ch if (cti && cti->get_constraint_targets) { cti->get_constraint_targets(con, &targets); - num_targets = BLI_countlist(&targets); + num_targets = BLI_listbase_count(&targets); if (index < 0) { if (abs(index) < num_targets) @@ -1399,6 +1399,8 @@ static int pose_constraint_copy_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); bPoseChannel *pchan = CTX_data_active_pose_bone(C); + ListBase lb; + CollectionPointerLink *link; /* don't do anything if bone doesn't exist or doesn't have any constraints */ if (ELEM(NULL, pchan, pchan->constraints.first)) { @@ -1407,16 +1409,22 @@ static int pose_constraint_copy_exec(bContext *C, wmOperator *op) } /* copy all constraints from active posebone to all selected posebones */ - CTX_DATA_BEGIN (C, bPoseChannel *, chan, selected_pose_bones) - { + CTX_data_selected_pose_bones(C, &lb); + for (link = lb.first; link; link = link->next) { + Object *ob = link->ptr.id.data; + bPoseChannel *chan = link->ptr.data; + /* if we're not handling the object we're copying from, copy all constraints over */ if (pchan != chan) { BKE_constraints_copy(&chan->constraints, &pchan->constraints, true); /* update flags (need to add here, not just copy) */ chan->constflag |= pchan->constflag; + + ob->pose->flag |= POSE_RECALC; + DAG_id_tag_update((ID *)ob, OB_RECALC_DATA); } } - CTX_DATA_END; + BLI_freelistN(&lb); /* force depsgraph to get recalculated since new relationships added */ DAG_relations_tag_update(bmain); @@ -1889,8 +1897,8 @@ static int pose_ik_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED } /* prepare popup menu to choose targetting options */ - pup = uiPupMenuBegin(C, IFACE_("Add IK"), ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, IFACE_("Add IK"), ICON_NONE); + layout = UI_popup_menu_layout(pup); /* the type of targets we'll set determines the menu entries to show... */ if (get_new_constraint_target(C, CONSTRAINT_TYPE_KINEMATIC, &tar_ob, &tar_pchan, 0)) { @@ -1909,9 +1917,9 @@ static int pose_ik_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED } /* finish building the menu, and process it (should result in calling self again) */ - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } /* call constraint_add_exec() to add the IK constraint */ diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index c24a127ed8b..b577dab8a77 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -100,7 +100,7 @@ void make_editLatt(Object *obedit) actkey = BKE_keyblock_from_object(obedit); if (actkey) - BKE_key_convert_to_lattice(actkey, lt); + BKE_keyblock_convert_to_lattice(actkey, lt); lt->editlatt = MEM_callocN(sizeof(EditLatt), "editlatt"); lt->editlatt->latt = MEM_dupallocN(lt); diff --git a/source/blender/editors/object/object_lod.c b/source/blender/editors/object/object_lod.c index 48e980015a7..ced306178b8 100644 --- a/source/blender/editors/object/object_lod.c +++ b/source/blender/editors/object/object_lod.c @@ -32,18 +32,22 @@ #include "DNA_object_types.h" #include "BKE_context.h" -#include "BKE_object.h" #include "WM_api.h" #include "WM_types.h" #include "RNA_access.h" #include "RNA_define.h" -#include "RNA_enum_types.h" #include "ED_screen.h" #include "ED_object.h" +#ifdef WITH_GAMEENGINE +# include "BKE_object.h" + +# include "RNA_enum_types.h" +#endif + #include "object_intern.h" static int object_lod_add_exec(bContext *C, wmOperator *UNUSED(op)) diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index b05840b5823..7ef8bb13de3 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -68,6 +68,7 @@ #include "BKE_multires.h" #include "BKE_report.h" #include "BKE_object.h" +#include "BKE_object_deform.h" #include "BKE_ocean.h" #include "BKE_paint.h" #include "BKE_particle.h" @@ -560,7 +561,7 @@ static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, M /* if that was the first key block added, then it was the basis. * Initialize it with the mesh, and add another for the modifier */ kb = BKE_keyblock_add(key, NULL); - BKE_key_convert_from_mesh(me, kb); + BKE_keyblock_convert_from_mesh(me, kb); } kb = BKE_keyblock_add(key, md->name); @@ -1667,7 +1668,7 @@ static void skin_armature_bone_create(Object *skin_ob, BLI_snprintf(bone->name, sizeof(bone->name), "Bone.%.2d", endx); /* add bDeformGroup */ - if ((dg = ED_vgroup_add_name(skin_ob, bone->name))) { + if ((dg = BKE_object_defgroup_add_name(skin_ob, bone->name))) { ED_vgroup_vert_add(skin_ob, dg, parent_v, 1, WEIGHT_REPLACE); ED_vgroup_vert_add(skin_ob, dg, v, 1, WEIGHT_REPLACE); } diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 7cf661de52c..2062b85fe4b 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -40,7 +40,6 @@ #include "BKE_context.h" #include "RNA_access.h" -#include "RNA_define.h" #include "WM_api.h" #include "WM_types.h" @@ -320,6 +319,7 @@ void ED_keymap_object(wmKeyConfig *keyconf) ED_keymap_proportional_cycle(keyconf, keymap); ED_keymap_proportional_obmode(keyconf, keymap); + /* game-engine only, leave free for users to define */ WM_keymap_add_item(keymap, "VIEW3D_OT_game_start", PKEY, KM_PRESS, 0, 0); kmi = WM_keymap_add_item(keymap, "OBJECT_OT_select_all", AKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index c8a009e4129..48e617eda11 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -300,23 +300,25 @@ static int make_proxy_invoke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_CANCELLED; } else if (ob->id.lib) { - uiPopupMenu *pup = uiPupMenuBegin(C, IFACE_("OK?"), ICON_QUESTION); - uiLayout *layout = uiPupMenuLayout(pup); + uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("OK?"), ICON_QUESTION); + uiLayout *layout = UI_popup_menu_layout(pup); /* create operator menu item with relevant properties filled in */ uiItemFullO_ptr(layout, op->type, op->type->name, ICON_NONE, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); /* present the menu and be done... */ - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); + + /* this invoke just calls another instance of this operator... */ + return OPERATOR_INTERFACE; } else { /* error.. cannot continue */ BKE_report(op->reports, RPT_ERROR, "Can only make proxy for a referenced object or group"); + return OPERATOR_CANCELLED; } - /* this invoke just calls another instance of this operator... */ - return OPERATOR_CANCELLED; } static int make_proxy_exec(bContext *C, wmOperator *op) @@ -699,6 +701,9 @@ bool ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object if (md) { ((CurveModifierData *)md)->object = par; } + if (par->curve_cache && par->curve_cache->path == NULL) { + DAG_id_tag_update(&par->id, OB_RECALC_DATA); + } } break; case PAR_LATTICE: /* lattice deform */ @@ -876,8 +881,8 @@ static int parent_set_exec(bContext *C, wmOperator *op) static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event)) { Object *ob = ED_object_active_context(C); - uiPopupMenu *pup = uiPupMenuBegin(C, IFACE_("Set Parent To"), ICON_NONE); - uiLayout *layout = uiPupMenuLayout(pup); + uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Set Parent To"), ICON_NONE); + uiLayout *layout = UI_popup_menu_layout(pup); wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_parent_set", true); PointerRNA opptr; @@ -918,9 +923,9 @@ static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent uiItemEnumO_ptr(layout, ot, NULL, 0, "type", PAR_VERTEX_TRI); } - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } static bool parent_set_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) @@ -2472,7 +2477,7 @@ static int object_unlink_data_exec(bContext *C, wmOperator *op) ID *id; PropertyPointerRNA pprop; - uiIDContextProperty(C, &pprop.ptr, &pprop.prop); + UI_context_active_but_prop_get_templateID(C, &pprop.ptr, &pprop.prop); if (pprop.prop == NULL) { BKE_report(op->reports, RPT_ERROR, "Incorrect context for running object data unlink"); diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index e295a63848a..65ce0c8d520 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -618,15 +618,15 @@ static bool select_grouped_group(bContext *C, Object *ob) /* Select objects in } /* build the menu. */ - pup = uiPupMenuBegin(C, IFACE_("Select Group"), ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, IFACE_("Select Group"), ICON_NONE); + layout = UI_popup_menu_layout(pup); for (i = 0; i < group_count; i++) { group = ob_groups[i]; uiItemStringO(layout, group->id.name + 2, 0, "OBJECT_OT_select_same_group", "group", group->id.name + 2); } - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); return changed; /* The operator already handle this! */ } diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index 85104c14395..6bb23a4a7f0 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -133,14 +133,14 @@ static bool ED_object_shape_key_remove(Main *bmain, Object *ob) /* apply new basis key on original data */ switch (ob->type) { case OB_MESH: - BKE_key_convert_to_mesh(key->refkey, ob->data); + BKE_keyblock_convert_to_mesh(key->refkey, ob->data); break; case OB_CURVE: case OB_SURF: - BKE_key_convert_to_curve(key->refkey, ob->data, BKE_curve_nurbs_get(ob->data)); + BKE_keyblock_convert_to_curve(key->refkey, ob->data, BKE_curve_nurbs_get(ob->data)); break; case OB_LATTICE: - BKE_key_convert_to_lattice(key->refkey, ob->data); + BKE_keyblock_convert_to_lattice(key->refkey, ob->data); break; } } @@ -301,6 +301,16 @@ static int shape_key_mode_exists_poll(bContext *C) (BKE_keyblock_from_object(ob) != NULL); } +static int shape_key_move_poll(bContext *C) +{ + /* Same as shape_key_mode_exists_poll above, but ensure we have at least two shapes! */ + Object *ob = ED_object_context(C); + ID *data = (ob) ? ob->data : NULL; + Key *key = BKE_key_from_object(ob); + + return (ob && !ob->id.lib && data && !data->lib && ob->mode != OB_MODE_EDIT && key && key->totkey > 1); +} + static int shape_key_poll(bContext *C) { Object *ob = ED_object_context(C); @@ -369,7 +379,6 @@ void OBJECT_OT_shape_key_remove(wmOperatorType *ot) ot->description = "Remove shape key from the object"; /* api callbacks */ - ot->poll = shape_key_mode_poll; ot->poll = shape_key_mode_exists_poll; ot->exec = shape_key_remove_exec; @@ -482,86 +491,40 @@ void OBJECT_OT_shape_key_mirror(wmOperatorType *ot) } +enum { + KB_MOVE_TOP = -2, + KB_MOVE_UP = -1, + KB_MOVE_DOWN = 1, + KB_MOVE_BOTTOM = 2, +}; + static int shape_key_move_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); - Key *key = BKE_key_from_object(ob); - if (!key) { - return OPERATOR_CANCELLED; + Key *key = BKE_key_from_object(ob); + const int type = RNA_enum_get(op->ptr, "type"); + const int totkey = key->totkey; + const int act_index = ob->shapenr - 1; + int new_index; + + switch (type) { + case KB_MOVE_TOP: + /* Replace the ref key only if we're at the top already (only for relative keys) */ + new_index = (ELEM(act_index, 0, 1) || key->type == KEY_NORMAL) ? 0 : 1; + break; + case KB_MOVE_BOTTOM: + new_index = totkey - 1; + break; + case KB_MOVE_UP: + case KB_MOVE_DOWN: + default: + new_index = (totkey + act_index + type) % totkey; + break; } - { - KeyBlock *kb, *kb_other, *kb_iter; - const int type = RNA_enum_get(op->ptr, "type"); - const int shape_tot = key->totkey; - const int shapenr_act = ob->shapenr - 1; - const int shapenr_swap = (shape_tot + shapenr_act + type) % shape_tot; - - kb = BLI_findlink(&key->block, shapenr_act); - if (!kb || shape_tot == 1) { - return OPERATOR_CANCELLED; - } - - if (type == -1) { - /* move back */ - kb_other = kb->prev; - BLI_remlink(&key->block, kb); - BLI_insertlinkbefore(&key->block, kb_other, kb); - } - else { - /* move next */ - kb_other = kb->next; - BLI_remlink(&key->block, kb); - BLI_insertlinkafter(&key->block, kb_other, kb); - } - - ob->shapenr = shapenr_swap + 1; - - /* for relative shape keys */ - if (kb_other) { - for (kb_iter = key->block.first; kb_iter; kb_iter = kb_iter->next) { - if (kb_iter->relative == shapenr_act) { - kb_iter->relative = shapenr_swap; - } - else if (kb_iter->relative == shapenr_swap) { - kb_iter->relative = shapenr_act; - } - } - } - /* First key became last, or vice-versa, we have to change all keys' relative value. */ - else { - for (kb_iter = key->block.first; kb_iter; kb_iter = kb_iter->next) { - if (kb_iter->relative == shapenr_act) { - kb_iter->relative = shapenr_swap; - } - else { - kb_iter->relative += type; - } - } - } - - /* for absolute shape keys */ - if (kb_other) { - SWAP(float, kb_other->pos, kb->pos); - } - /* First key became last, or vice-versa, we have to change all keys' pos value. */ - else { - float pos = kb->pos; - if (type == -1) { - for (kb_iter = key->block.first; kb_iter; kb_iter = kb_iter->next) { - SWAP(float, kb_iter->pos, pos); - } - } - else { - for (kb_iter = key->block.last; kb_iter; kb_iter = kb_iter->prev) { - SWAP(float, kb_iter->pos, pos); - } - } - } - - /* First key is refkey, matches interface and BKE_key_sort */ - key->refkey = key->block.first; + if (!BKE_keyblock_move(ob, act_index, new_index)) { + return OPERATOR_CANCELLED; } DAG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -573,9 +536,11 @@ static int shape_key_move_exec(bContext *C, wmOperator *op) void OBJECT_OT_shape_key_move(wmOperatorType *ot) { static EnumPropertyItem slot_move[] = { - {-1, "UP", 0, "Up", ""}, - {1, "DOWN", 0, "Down", ""}, - {0, NULL, 0, NULL, NULL} + {KB_MOVE_TOP, "TOP", 0, "Top", "Top of the list"}, + {KB_MOVE_UP, "UP", 0, "Up", ""}, + {KB_MOVE_DOWN, "DOWN", 0, "Down", ""}, + {KB_MOVE_BOTTOM, "BOTTOM", 0, "Bottom", "Bottom of the list"}, + { 0, NULL, 0, NULL, NULL } }; /* identifiers */ @@ -584,7 +549,7 @@ void OBJECT_OT_shape_key_move(wmOperatorType *ot) ot->description = "Move the active shape key up/down in the list"; /* api callbacks */ - ot->poll = shape_key_mode_poll; + ot->poll = shape_key_move_poll; ot->exec = shape_key_move_exec; /* flags */ diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index f19765a5344..92fe5ded4dd 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -33,9 +33,7 @@ #include "DNA_anim_types.h" #include "DNA_armature_types.h" -#include "DNA_key_types.h" #include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" #include "DNA_meta_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -69,7 +67,6 @@ #include "ED_armature.h" #include "ED_keyframing.h" -#include "ED_mball.h" #include "ED_mesh.h" #include "ED_screen.h" #include "ED_view3d.h" diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 777bbabb6e8..a0c5b037c1f 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -36,16 +36,13 @@ #include "MEM_guardedalloc.h" -#include "DNA_cloth_types.h" #include "DNA_curve_types.h" #include "DNA_lattice_types.h" #include "DNA_meshdata_types.h" #include "DNA_mesh_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" -#include "DNA_object_force.h" #include "DNA_scene_types.h" -#include "DNA_particle_types.h" #include "BLI_alloca.h" #include "BLI_array.h" @@ -54,7 +51,6 @@ #include "BLI_utildefines.h" #include "BLI_linklist_stack.h" -#include "BLF_translation.h" #include "BKE_context.h" #include "BKE_customdata.h" @@ -85,11 +81,6 @@ #include "object_intern.h" /************************ Exported Functions **********************/ -static void vgroup_remap_update_users(Object *ob, int *map); -static void vgroup_delete_edit_mode(Object *ob, bDeformGroup *defgroup); -static void vgroup_delete_object_mode(Object *ob, bDeformGroup *dg); -static void vgroup_delete_all(Object *ob); - static bool vertex_group_use_vert_sel(Object *ob) { if (ob->mode == OB_MODE_EDIT) { @@ -126,81 +117,6 @@ bool ED_vgroup_sync_from_pose(Object *ob) return false; } -bool ED_vgroup_object_is_edit_mode(Object *ob) -{ - if (ob->type == OB_MESH) - return (BKE_editmesh_from_object(ob) != NULL); - else if (ob->type == OB_LATTICE) - return (((Lattice *)ob->data)->editlatt != NULL); - - return false; -} - -bDeformGroup *ED_vgroup_add_name(Object *ob, const char *name) -{ - bDeformGroup *defgroup; - - if (!ob || !OB_TYPE_SUPPORT_VGROUP(ob->type)) - return NULL; - - defgroup = BKE_defgroup_new(ob, name); - - ob->actdef = BLI_countlist(&ob->defbase); - - return defgroup; -} - -bDeformGroup *ED_vgroup_add(Object *ob) -{ - return ED_vgroup_add_name(ob, DATA_("Group")); -} - -void ED_vgroup_delete(Object *ob, bDeformGroup *defgroup) -{ - BLI_assert(BLI_findindex(&ob->defbase, defgroup) != -1); - - if (ED_vgroup_object_is_edit_mode(ob)) - vgroup_delete_edit_mode(ob, defgroup); - else - vgroup_delete_object_mode(ob, defgroup); -} - -void ED_vgroup_clear(Object *ob) -{ - bDeformGroup *dg = (bDeformGroup *)ob->defbase.first; - int edit_mode = ED_vgroup_object_is_edit_mode(ob); - - while (dg) { - bDeformGroup *next_dg = dg->next; - - if (edit_mode) - vgroup_delete_edit_mode(ob, dg); - else - vgroup_delete_object_mode(ob, dg); - - dg = next_dg; - } -} - -bool ED_vgroup_data_create(ID *id) -{ - /* create deform verts */ - - if (GS(id->name) == ID_ME) { - Mesh *me = (Mesh *)id; - me->dvert = CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert); - return true; - } - else if (GS(id->name) == ID_LT) { - Lattice *lt = (Lattice *)id; - lt->dvert = MEM_callocN(sizeof(MDeformVert) * lt->pntsu * lt->pntsv * lt->pntsw, "lattice deformVert"); - return true; - } - else { - return false; - } -} - /** * Removes out of range MDeformWeights */ @@ -465,34 +381,6 @@ void ED_vgroup_parray_remove_zero(MDeformVert **dvert_array, const int dvert_tot } } -/* returns true if the id type supports weights */ -bool ED_vgroup_array_get(ID *id, MDeformVert **dvert_arr, int *dvert_tot) -{ - if (id) { - switch (GS(id->name)) { - case ID_ME: - { - Mesh *me = (Mesh *)id; - *dvert_arr = me->dvert; - *dvert_tot = me->totvert; - return true; - } - case ID_LT: - { - Lattice *lt = (Lattice *)id; - lt = (lt->editlatt) ? lt->editlatt->latt : lt; - *dvert_arr = lt->dvert; - *dvert_tot = lt->pntsu * lt->pntsv * lt->pntsw; - return true; - } - } - } - - *dvert_arr = NULL; - *dvert_tot = 0; - return false; -} - /* matching index only */ bool ED_vgroup_array_copy(Object *ob, Object *ob_from) { @@ -501,8 +389,8 @@ bool ED_vgroup_array_copy(Object *ob, Object *ob_from) int dvert_tot_from; int dvert_tot; int i; - int defbase_tot_from = BLI_countlist(&ob_from->defbase); - int defbase_tot = BLI_countlist(&ob->defbase); + int defbase_tot_from = BLI_listbase_count(&ob_from->defbase); + int defbase_tot = BLI_listbase_count(&ob->defbase); bool new_vgroup = false; if (ob == ob_from) @@ -511,7 +399,7 @@ bool ED_vgroup_array_copy(Object *ob, Object *ob_from) ED_vgroup_parray_alloc(ob_from->data, &dvert_array_from, &dvert_tot_from, false); ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, false); - if ((dvert_array == NULL) && (dvert_array_from != NULL) && ED_vgroup_data_create(ob->data)) { + if ((dvert_array == NULL) && (dvert_array_from != NULL) && BKE_object_defgroup_data_create(ob->data)) { ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, false); new_vgroup = true; } @@ -523,7 +411,7 @@ bool ED_vgroup_array_copy(Object *ob, Object *ob_from) if (new_vgroup == true) { /* free the newly added vgroup since it wasn't compatible */ - vgroup_delete_all(ob); + BKE_object_defgroup_remove_all(ob); } /* if true: both are 0 and nothing needs changing, consider this a success */ @@ -541,7 +429,7 @@ bool ED_vgroup_array_copy(Object *ob, Object *ob_from) for (i = 0; i <= defbase_tot_from; i++) remap[i] = i; for (; i <= defbase_tot; i++) remap[i] = 0; /* can't use these, so disable */ - vgroup_remap_update_users(ob, remap); + BKE_object_defgroup_remap_update_users(ob, remap); MEM_freeN(remap); } @@ -682,7 +570,7 @@ static void vgroup_normalize_active(Object *ob, eVGroupSelect subset_type) return; } - vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); defvert_normalize_subset(dvert_act, vgroup_validmap, vgroup_tot); MEM_freeN((void *)vgroup_validmap); @@ -703,7 +591,7 @@ static void vgroup_copy_active_to_sel(Object *ob, eVGroupSelect subset_type) BMEditMesh *em = me->edit_btmesh; MDeformVert *dvert_act; int i, vgroup_tot, subset_count; - const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); if (em) { @@ -925,7 +813,7 @@ static bool ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGro } /* Create data in memory when nothing there.*/ - if (!me_dst->dvert) ED_vgroup_data_create(&me_dst->id); + if (!me_dst->dvert) BKE_object_defgroup_data_create(&me_dst->id); /* Get vertex group for destination mesh */ ED_vgroup_parray_alloc(&me_dst->id, &dv_array_dst, &dv_tot_dst, use_vert_sel); @@ -962,7 +850,7 @@ static bool ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGro dv_array_src == NULL || dv_array_dst == NULL) { if (is_dg_dst_new) { - ED_vgroup_delete(ob_dst, dg_dst); + BKE_object_defgroup_remove(ob_dst, dg_dst); } if (dv_array_src) MEM_freeN(dv_array_src); @@ -1175,7 +1063,7 @@ static void ED_vgroup_nr_vert_add(Object *ob, int tot; /* get the vert */ - ED_vgroup_array_get(ob->data, &dvert, &tot); + BKE_object_defgroup_array_get(ob->data, &dvert, &tot); if (dvert == NULL) return; @@ -1208,7 +1096,7 @@ static void ED_vgroup_nr_vert_add(Object *ob, break; case WEIGHT_SUBTRACT: dw->weight -= weight; - /* if the weight is zero or less then + /* if the weight is zero or less than * remove the vert from the deform group */ if (dw->weight <= 0.0f) { @@ -1261,8 +1149,8 @@ void ED_vgroup_vert_add(Object *ob, bDeformGroup *dg, int vertnum, float weight, /* if there's no deform verts then create some, */ - if (ED_vgroup_array_get(ob->data, &dv, &tot) && dv == NULL) - ED_vgroup_data_create(ob->data); + if (BKE_object_defgroup_array_get(ob->data, &dv, &tot) && dv == NULL) + BKE_object_defgroup_data_create(ob->data); /* call another function to do the work */ @@ -1287,7 +1175,7 @@ void ED_vgroup_vert_remove(Object *ob, bDeformGroup *dg, int vertnum) /* get the deform vertices corresponding to the * vertnum */ - ED_vgroup_array_get(ob->data, &dvert, &tot); + BKE_object_defgroup_array_get(ob->data, &dvert, &tot); if (dvert) { MDeformVert *dv = &dvert[vertnum]; @@ -1476,7 +1364,7 @@ static void vgroup_duplicate(Object *ob) BLI_addtail(&ob->defbase, cdg); idg = (ob->actdef - 1); - ob->actdef = BLI_countlist(&ob->defbase); + ob->actdef = BLI_listbase_count(&ob->defbase); icdg = (ob->actdef - 1); /* TODO, we might want to allow only copy selected verts here? - campbell */ @@ -1498,86 +1386,6 @@ static void vgroup_duplicate(Object *ob) } } -/** - * Return the subset type of the Vertex Group Selection - */ -bool *ED_vgroup_subset_from_select_type(Object *ob, eVGroupSelect subset_type, int *r_vgroup_tot, int *r_subset_count) -{ - bool *vgroup_validmap = NULL; - *r_vgroup_tot = BLI_countlist(&ob->defbase); - - switch (subset_type) { - case WT_VGROUP_ACTIVE: - { - const int def_nr_active = ob->actdef - 1; - vgroup_validmap = MEM_mallocN(*r_vgroup_tot * sizeof(*vgroup_validmap), __func__); - memset(vgroup_validmap, false, *r_vgroup_tot * sizeof(*vgroup_validmap)); - if ((def_nr_active >= 0) && (def_nr_active < *r_vgroup_tot)) { - *r_subset_count = 1; - vgroup_validmap[def_nr_active] = true; - } - else { - *r_subset_count = 0; - } - break; - } - case WT_VGROUP_BONE_SELECT: - { - vgroup_validmap = BKE_objdef_selected_get(ob, *r_vgroup_tot, r_subset_count); - break; - } - case WT_VGROUP_BONE_DEFORM: - { - int i; - vgroup_validmap = BKE_objdef_validmap_get(ob, *r_vgroup_tot); - *r_subset_count = 0; - for (i = 0; i < *r_vgroup_tot; i++) { - if (vgroup_validmap[i] == true) { - *r_subset_count += 1; - } - } - break; - } - case WT_VGROUP_BONE_DEFORM_OFF: - { - int i; - vgroup_validmap = BKE_objdef_validmap_get(ob, *r_vgroup_tot); - *r_subset_count = 0; - for (i = 0; i < *r_vgroup_tot; i++) { - vgroup_validmap[i] = !vgroup_validmap[i]; - if (vgroup_validmap[i] == true) { - *r_subset_count += 1; - } - } - break; - } - case WT_VGROUP_ALL: - default: - { - vgroup_validmap = MEM_mallocN(*r_vgroup_tot * sizeof(*vgroup_validmap), __func__); - memset(vgroup_validmap, true, *r_vgroup_tot * sizeof(*vgroup_validmap)); - *r_subset_count = *r_vgroup_tot; - break; - } - } - - return vgroup_validmap; -} - -/** - * store indices from the vgroup_validmap (faster lookups in some cases) - */ -void ED_vgroup_subset_to_index_array(const bool *vgroup_validmap, const int vgroup_tot, - int *r_vgroup_subset_map) -{ - int i, j = 0; - for (i = 0; i < vgroup_tot; i++) { - if (vgroup_validmap[i]) { - r_vgroup_subset_map[j++] = i; - } - } -} - static void vgroup_normalize(Object *ob) { MDeformWeight *dw; @@ -2051,8 +1859,8 @@ static void vgroup_normalize_all(Object *ob, ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, use_vert_sel); if (dvert_array) { - const int defbase_tot = BLI_countlist(&ob->defbase); - bool *lock_flags = BKE_objdef_lock_flags_get(ob, defbase_tot); + const int defbase_tot = BLI_listbase_count(&ob->defbase); + bool *lock_flags = BKE_object_defgroup_lock_flags_get(ob, defbase_tot); if ((lock_active == true) && (lock_flags != NULL) && @@ -2205,7 +2013,7 @@ static void vgroup_blend_subset(Object *ob, const bool *vgroup_validmap, const i BLI_SMALLSTACK_DECLARE(dv_stack, MDeformVert *); - ED_vgroup_subset_to_index_array(vgroup_validmap, vgroup_tot, vgroup_subset_map); + BKE_object_defgroup_subset_to_index_array(vgroup_validmap, vgroup_tot, vgroup_subset_map); ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, false); memset(vgroup_subset_weights, 0, sizeof(*vgroup_subset_weights) * subset_count); @@ -2725,298 +2533,13 @@ cleanup: } -static void vgroup_remap_update_users(Object *ob, int *map) -{ - ExplodeModifierData *emd; - ModifierData *md; - ParticleSystem *psys; - ClothModifierData *clmd; - ClothSimSettings *clsim; - int a; - - /* these cases don't use names to refer to vertex groups, so when - * they get deleted the numbers get out of sync, this corrects that */ - - if (ob->soft) - ob->soft->vertgroup = map[ob->soft->vertgroup]; - - for (md = ob->modifiers.first; md; md = md->next) { - if (md->type == eModifierType_Explode) { - emd = (ExplodeModifierData *)md; - emd->vgroup = map[emd->vgroup]; - } - else if (md->type == eModifierType_Cloth) { - clmd = (ClothModifierData *)md; - clsim = clmd->sim_parms; - - if (clsim) { - clsim->vgroup_mass = map[clsim->vgroup_mass]; - clsim->vgroup_bend = map[clsim->vgroup_bend]; - clsim->vgroup_struct = map[clsim->vgroup_struct]; - } - } - } - - for (psys = ob->particlesystem.first; psys; psys = psys->next) { - for (a = 0; a < PSYS_TOT_VG; a++) - psys->vgroup[a] = map[psys->vgroup[a]]; - } -} - - -static void vgroup_delete_update_users(Object *ob, int id) -{ - int i, defbase_tot = BLI_countlist(&ob->defbase) + 1; - int *map = MEM_mallocN(sizeof(int) * defbase_tot, "vgroup del"); - - map[id] = map[0] = 0; - for (i = 1; i < id; i++) map[i] = i; - for (i = id + 1; i < defbase_tot; i++) map[i] = i - 1; - - vgroup_remap_update_users(ob, map); - MEM_freeN(map); -} - - -static void vgroup_delete_object_mode(Object *ob, bDeformGroup *dg) -{ - MDeformVert *dvert_array = NULL; - int dvert_tot = 0; - const int def_nr = BLI_findindex(&ob->defbase, dg); - - BLI_assert(def_nr != -1); - - ED_vgroup_array_get(ob->data, &dvert_array, &dvert_tot); - - if (dvert_array) { - int i, j; - MDeformVert *dv; - for (i = 0, dv = dvert_array; i < dvert_tot; i++, dv++) { - MDeformWeight *dw; - - dw = defvert_find_index(dv, def_nr); - defvert_remove_group(dv, dw); /* dw can be NULL */ - - /* inline, make into a function if anything else needs to do this */ - for (j = 0; j < dv->totweight; j++) { - if (dv->dw[j].def_nr > def_nr) { - dv->dw[j].def_nr--; - } - } - /* done */ - } - } - - vgroup_delete_update_users(ob, def_nr + 1); - - /* Remove the group */ - BLI_freelinkN(&ob->defbase, dg); - - /* Update the active deform index if necessary */ - if (ob->actdef > def_nr) - ob->actdef--; - if (ob->actdef < 1 && ob->defbase.first) - ob->actdef = 1; - - /* remove all dverts */ - if (BLI_listbase_is_empty(&ob->defbase)) { - if (ob->type == OB_MESH) { - Mesh *me = ob->data; - CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); - me->dvert = NULL; - } - else if (ob->type == OB_LATTICE) { - Lattice *lt = ob->data; - if (lt->dvert) { - MEM_freeN(lt->dvert); - lt->dvert = NULL; - } - } - } -} - -/* only in editmode */ -/* removes from active defgroup, if allverts==0 only selected vertices */ -static bool vgroup_active_remove_verts(Object *ob, const bool allverts, bDeformGroup *dg) -{ - MDeformVert *dv; - const int def_nr = BLI_findindex(&ob->defbase, dg); - bool changed = false; - - if (ob->type == OB_MESH) { - Mesh *me = ob->data; - - if (me->edit_btmesh) { - BMEditMesh *em = me->edit_btmesh; - const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); - - if (cd_dvert_offset != -1) { - BMVert *eve; - BMIter iter; - - BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { - dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); - - if (dv && dv->dw && (allverts || BM_elem_flag_test(eve, BM_ELEM_SELECT))) { - MDeformWeight *dw = defvert_find_index(dv, def_nr); - defvert_remove_group(dv, dw); /* dw can be NULL */ - changed = true; - } - } - } - } - else { - if (me->dvert) { - MVert *mv; - int i; - - mv = me->mvert; - dv = me->dvert; - - for (i = 0; i < me->totvert; i++, mv++, dv++) { - if (mv->flag & SELECT) { - if (dv->dw && (allverts || (mv->flag & SELECT))) { - MDeformWeight *dw = defvert_find_index(dv, def_nr); - defvert_remove_group(dv, dw); /* dw can be NULL */ - changed = true; - } - } - } - } - } - } - else if (ob->type == OB_LATTICE) { - Lattice *lt = vgroup_edit_lattice(ob); - - if (lt->dvert) { - BPoint *bp; - int i, tot = lt->pntsu * lt->pntsv * lt->pntsw; - - for (i = 0, bp = lt->def; i < tot; i++, bp++) { - if (allverts || (bp->f1 & SELECT)) { - MDeformWeight *dw; - - dv = <->dvert[i]; - - dw = defvert_find_index(dv, def_nr); - defvert_remove_group(dv, dw); /* dw can be NULL */ - changed = true; - } - } - } - } - - return changed; -} - -static void vgroup_delete_edit_mode(Object *ob, bDeformGroup *dg) -{ - int i; - const int dg_index = BLI_findindex(&ob->defbase, dg); - - BLI_assert(dg_index != -1); - - /* Make sure that no verts are using this group */ - if (vgroup_active_remove_verts(ob, true, dg) == false) { - /* do nothing */ - } - /* Make sure that any verts with higher indices are adjusted accordingly */ - else if (ob->type == OB_MESH) { - Mesh *me = ob->data; - BMEditMesh *em = me->edit_btmesh; - const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); - - BMIter iter; - BMVert *eve; - MDeformVert *dvert; - - BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { - dvert = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); - - if (dvert) - for (i = 0; i < dvert->totweight; i++) - if (dvert->dw[i].def_nr > dg_index) - dvert->dw[i].def_nr--; - } - } - else if (ob->type == OB_LATTICE) { - Lattice *lt = vgroup_edit_lattice(ob); - BPoint *bp; - MDeformVert *dvert = lt->dvert; - int a, tot; - - if (dvert) { - tot = lt->pntsu * lt->pntsv * lt->pntsw; - for (a = 0, bp = lt->def; a < tot; a++, bp++, dvert++) { - for (i = 0; i < dvert->totweight; i++) { - if (dvert->dw[i].def_nr > dg_index) - dvert->dw[i].def_nr--; - } - } - } - } - - vgroup_delete_update_users(ob, dg_index + 1); - - /* Remove the group */ - BLI_freelinkN(&ob->defbase, dg); - - /* Update the active deform index if necessary */ - if (ob->actdef > dg_index) - ob->actdef--; - if (ob->actdef < 1 && ob->defbase.first) - ob->actdef = 1; - - /* remove all dverts */ - if (BLI_listbase_is_empty(&ob->defbase)) { - if (ob->type == OB_MESH) { - Mesh *me = ob->data; - CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); - me->dvert = NULL; - } - else if (ob->type == OB_LATTICE) { - Lattice *lt = vgroup_edit_lattice(ob); - if (lt->dvert) { - MEM_freeN(lt->dvert); - lt->dvert = NULL; - } - } - } -} - -static void vgroup_delete(Object *ob) +static void vgroup_delete_active(Object *ob) { bDeformGroup *dg = BLI_findlink(&ob->defbase, ob->actdef - 1); if (!dg) return; - if (BKE_object_is_in_editmode_vgroup(ob)) - vgroup_delete_edit_mode(ob, dg); - else - vgroup_delete_object_mode(ob, dg); -} - -static void vgroup_delete_all(Object *ob) -{ - /* Remove all DVerts */ - if (ob->type == OB_MESH) { - Mesh *me = ob->data; - CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); - me->dvert = NULL; - } - else if (ob->type == OB_LATTICE) { - Lattice *lt = vgroup_edit_lattice(ob); - if (lt->dvert) { - MEM_freeN(lt->dvert); - lt->dvert = NULL; - } - } - - /* Remove all DefGroups */ - BLI_freelistN(&ob->defbase); - - /* Fix counters/indices */ - ob->actdef = 0; + BKE_object_defgroup_remove(ob, dg); } /* only in editmode */ @@ -3061,7 +2584,7 @@ static void vgroup_assign_verts(Object *ob, const float weight) int i; if (!me->dvert) { - ED_vgroup_data_create(&me->id); + BKE_object_defgroup_data_create(&me->id); } mv = me->mvert; @@ -3085,7 +2608,7 @@ static void vgroup_assign_verts(Object *ob, const float weight) int a, tot; if (lt->dvert == NULL) - ED_vgroup_data_create(<->id); + BKE_object_defgroup_data_create(<->id); dv = lt->dvert; @@ -3103,22 +2626,6 @@ static void vgroup_assign_verts(Object *ob, const float weight) } } -/* only in editmode */ -/* removes from all defgroup, if allverts==0 only selected vertices */ -static bool vgroup_remove_verts(Object *ob, int allverts) -{ - bool changed = false; - /* To prevent code redundancy, we just use vgroup_active_remove_verts, but that - * only operates on the active vgroup. So we iterate through all groups, by changing - * active group index - */ - bDeformGroup *dg; - for (dg = ob->defbase.first; dg; dg = dg->next) { - changed |= vgroup_active_remove_verts(ob, allverts, dg); - } - return changed; -} - /********************** vertex group operators *********************/ static int vertex_group_poll(bContext *C) @@ -3226,7 +2733,7 @@ static int vertex_group_add_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = ED_object_context(C); - ED_vgroup_add(ob); + BKE_object_defgroup_add(ob); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob->data); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); @@ -3254,9 +2761,9 @@ static int vertex_group_remove_exec(bContext *C, wmOperator *op) Object *ob = ED_object_context(C); if (RNA_boolean_get(op->ptr, "all")) - vgroup_delete_all(ob); + BKE_object_defgroup_remove_all(ob); else - vgroup_delete(ob); + vgroup_delete_active(ob); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob->data); @@ -3321,7 +2828,7 @@ static int vertex_group_assign_new_exec(bContext *C, wmOperator *op) { /* create new group... */ Object *ob = ED_object_context(C); - ED_vgroup_add(ob); + BKE_object_defgroup_add(ob); /* assign selection to new group */ return vertex_group_assign_exec(C, op); @@ -3353,14 +2860,14 @@ static int vertex_group_remove_from_exec(bContext *C, wmOperator *op) Object *ob = ED_object_context(C); if (use_all_groups) { - if (vgroup_remove_verts(ob, 0) == false) { + if (BKE_object_defgroup_clear_all(ob, true) == false) { return OPERATOR_CANCELLED; } } else { bDeformGroup *dg = BLI_findlink(&ob->defbase, ob->actdef - 1); - if ((dg == NULL) || (vgroup_active_remove_verts(ob, use_all_verts, dg) == false)) { + if ((dg == NULL) || (BKE_object_defgroup_clear(ob, dg, !use_all_verts) == false)) { return OPERATOR_CANCELLED; } } @@ -3486,7 +2993,7 @@ static int vertex_group_levels_exec(bContext *C, wmOperator *op) int subset_count, vgroup_tot; - const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); vgroup_levels_subset(ob, vgroup_validmap, vgroup_tot, subset_count, offset, gain); MEM_freeN((void *)vgroup_validmap); @@ -3552,7 +3059,7 @@ static int vertex_group_normalize_all_exec(bContext *C, wmOperator *op) int subset_count, vgroup_tot; - const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); vgroup_normalize_all(ob, vgroup_validmap, vgroup_tot, subset_count, lock_active); MEM_freeN((void *)vgroup_validmap); @@ -3674,7 +3181,7 @@ static int vertex_group_invert_exec(bContext *C, wmOperator *op) int subset_count, vgroup_tot; - const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); vgroup_invert_subset(ob, vgroup_validmap, vgroup_tot, subset_count, auto_assign, auto_remove); MEM_freeN((void *)vgroup_validmap); @@ -3715,7 +3222,7 @@ static int vertex_group_blend_exec(bContext *C, wmOperator *op) int subset_count, vgroup_tot; - const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); vgroup_blend_subset(ob, vgroup_validmap, vgroup_tot, subset_count, fac); MEM_freeN((void *)vgroup_validmap); @@ -3791,7 +3298,7 @@ static int vertex_group_clean_exec(bContext *C, wmOperator *op) int subset_count, vgroup_tot; - const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); vgroup_clean_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit, keep_single); MEM_freeN((void *)vgroup_validmap); @@ -3832,7 +3339,7 @@ static int vertex_group_quantize_exec(bContext *C, wmOperator *op) int subset_count, vgroup_tot; - const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); vgroup_quantize_subset(ob, vgroup_validmap, vgroup_tot, subset_count, steps); MEM_freeN((void *)vgroup_validmap); @@ -3870,7 +3377,7 @@ static int vertex_group_limit_total_exec(bContext *C, wmOperator *op) int subset_count, vgroup_tot; - const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); int remove_tot = vgroup_limit_total_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit); MEM_freeN((void *)vgroup_validmap); @@ -3934,7 +3441,7 @@ void OBJECT_OT_vertex_group_mirror(wmOperatorType *ot) /* identifiers */ ot->name = "Mirror Vertex Group"; ot->idname = "OBJECT_OT_vertex_group_mirror"; - ot->description = "Mirror all vertex groups, flip weights and/or names, editing only selected vertices, " + ot->description = "Mirror vertex group, flip weights and/or names, editing only selected vertices, " "flipping when both sides are selected otherwise copy from unselected"; /* api callbacks */ @@ -3983,7 +3490,7 @@ void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot) /* identifiers */ ot->name = "Copy Vertex Groups to Linked"; ot->idname = "OBJECT_OT_vertex_group_copy_to_linked"; - ot->description = "Copy vertex groups to all users of the same geometry data"; + ot->description = "Replace vertex groups of all users of the same geometry data by vertex groups of active object"; /* api callbacks */ ot->poll = vertex_group_poll; @@ -4022,7 +3529,7 @@ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) /* identifiers */ ot->name = "Copy Vertex Group to Selected"; ot->idname = "OBJECT_OT_vertex_group_copy_to_selected"; - ot->description = "Copy vertex groups to other selected objects with matching indices"; + ot->description = "Replace vertex groups of selected objects by vertex groups of active object"; /* api callbacks */ ot->poll = vertex_group_poll; @@ -4237,7 +3744,7 @@ void OBJECT_OT_vertex_group_set_active(wmOperatorType *ot) static char *vgroup_init_remap(Object *ob) { bDeformGroup *def; - int defbase_tot = BLI_countlist(&ob->defbase); + int defbase_tot = BLI_listbase_count(&ob->defbase); char *name_array = MEM_mallocN(MAX_VGROUP_NAME * sizeof(char) * defbase_tot, "sort vgroups"); char *name; @@ -4254,7 +3761,7 @@ static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op) { MDeformVert *dvert = NULL; bDeformGroup *def; - int defbase_tot = BLI_countlist(&ob->defbase); + int defbase_tot = BLI_listbase_count(&ob->defbase); /* needs a dummy index at the start*/ int *sort_map_update = MEM_mallocN(sizeof(int) * (defbase_tot + 1), "sort vgroups"); @@ -4297,7 +3804,7 @@ static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op) else { int dvert_tot = 0; - ED_vgroup_array_get(ob->data, &dvert, &dvert_tot); + BKE_object_defgroup_array_get(ob->data, &dvert, &dvert_tot); /*create as necessary*/ if (dvert) { @@ -4314,7 +3821,7 @@ static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op) sort_map[i]++; sort_map_update[0] = 0; - vgroup_remap_update_users(ob, sort_map_update); + BKE_object_defgroup_remap_update_users(ob, sort_map_update); BLI_assert(sort_map_update[ob->actdef] >= 0); ob->actdef = sort_map_update[ob->actdef]; @@ -4378,7 +3885,7 @@ static int vertex_group_sort_exec(bContext *C, wmOperator *op) /*sort vgroup names*/ switch (sort_type) { case SORT_TYPE_NAME: - BLI_sortlist(&ob->defbase, vgroup_sort_name); + BLI_listbase_sort(&ob->defbase, vgroup_sort_name); break; case SORT_TYPE_BONEHIERARCHY: vgroup_sort_bone_hierarchy(ob, NULL); diff --git a/source/blender/editors/object/object_warp.c b/source/blender/editors/object/object_warp.c index 8016dabf3a3..7413bb07c4c 100644 --- a/source/blender/editors/object/object_warp.c +++ b/source/blender/editors/object/object_warp.c @@ -31,7 +31,6 @@ #include "BLI_math.h" -#include "BKE_utildefines.h" #include "BKE_context.h" #include "RNA_access.h" diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c index 637af5d6536..d864934171b 100644 --- a/source/blender/editors/physics/dynamicpaint_ops.c +++ b/source/blender/editors/physics/dynamicpaint_ops.c @@ -40,6 +40,7 @@ #include "BKE_blender.h" #include "BKE_context.h" #include "BKE_deform.h" +#include "BKE_object_deform.h" #include "BKE_depsgraph.h" #include "BKE_dynamicpaint.h" #include "BKE_global.h" @@ -235,11 +236,11 @@ static int output_toggle_exec(bContext *C, wmOperator *op) /* Vertex Weight Layer */ else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) { if (!exists) { - ED_vgroup_add_name(ob, name); + BKE_object_defgroup_add_name(ob, name); } else { bDeformGroup *defgroup = defgroup_find_name(ob, name); - if (defgroup) ED_vgroup_delete(ob, defgroup); + if (defgroup) BKE_object_defgroup_remove(ob, defgroup); } } } diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c index b53891f4880..b5adf38527b 100644 --- a/source/blender/editors/physics/physics_fluid.c +++ b/source/blender/editors/physics/physics_fluid.c @@ -72,8 +72,6 @@ #include "DNA_scene_types.h" #include "DNA_mesh_types.h" -#include "PIL_time.h" - static float get_fluid_viscosity(FluidsimSettings *settings) { diff --git a/source/blender/editors/physics/physics_ops.c b/source/blender/editors/physics/physics_ops.c index ff89909b124..03d32bc052d 100644 --- a/source/blender/editors/physics/physics_ops.c +++ b/source/blender/editors/physics/physics_ops.c @@ -29,10 +29,6 @@ #include <stdlib.h> -#include "DNA_scene_types.h" - -#include "BLI_utildefines.h" - #include "RNA_access.h" #include "WM_api.h" diff --git a/source/blender/editors/physics/rigidbody_constraint.c b/source/blender/editors/physics/rigidbody_constraint.c index dd0816e509d..85b059d5574 100644 --- a/source/blender/editors/physics/rigidbody_constraint.c +++ b/source/blender/editors/physics/rigidbody_constraint.c @@ -37,8 +37,6 @@ #include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" -#include "BLI_math.h" - #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_global.h" diff --git a/source/blender/editors/physics/rigidbody_object.c b/source/blender/editors/physics/rigidbody_object.c index 13a3d7a523f..9b4f128ef86 100644 --- a/source/blender/editors/physics/rigidbody_object.c +++ b/source/blender/editors/physics/rigidbody_object.c @@ -33,16 +33,12 @@ #include <stdlib.h> #include <string.h> -#include "MEM_guardedalloc.h" -#include "DNA_group_types.h" #include "DNA_object_types.h" -#include "DNA_mesh_types.h" #include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" #include "BLI_blenlib.h" -#include "BLI_math.h" #include "BLF_translation.h" @@ -50,7 +46,6 @@ #include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_group.h" -#include "BKE_object.h" #include "BKE_report.h" #include "BKE_rigidbody.h" diff --git a/source/blender/editors/physics/rigidbody_world.c b/source/blender/editors/physics/rigidbody_world.c index 1c893992cf2..73443e72afb 100644 --- a/source/blender/editors/physics/rigidbody_world.c +++ b/source/blender/editors/physics/rigidbody_world.c @@ -37,8 +37,6 @@ #include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" -#include "BLI_math.h" - #ifdef WITH_BULLET # include "RBI_api.h" #endif @@ -48,8 +46,6 @@ #include "BKE_rigidbody.h" #include "RNA_access.h" -#include "RNA_define.h" -#include "RNA_enum_types.h" #include "WM_api.h" #include "WM_types.h" diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index baf25a49f7c..fcc90fa57d5 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -75,10 +75,8 @@ #include "RE_engine.h" #include "IMB_colormanagement.h" -#include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -#include "GPU_extensions.h" #include "BIF_gl.h" #include "BIF_glutil.h" @@ -86,7 +84,6 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "wm_window.h" #include "render_intern.h" @@ -343,7 +340,11 @@ static void render_freejob(void *rjv) } /* str is IMA_MAX_RENDER_TEXT in size */ -static void make_renderinfo_string(RenderStats *rs, Scene *scene, bool v3d_override, char *str) +static void make_renderinfo_string(const RenderStats *rs, + const Scene *scene, + const bool v3d_override, + const char *error, + char *str) { char info_time_str[32]; // used to be extern to header_info.c uintptr_t mem_in_use, mmap_in_use, peak_memory; @@ -416,8 +417,12 @@ static void make_renderinfo_string(RenderStats *rs, Scene *scene, bool v3d_overr spos += sprintf(spos, IFACE_("| Full Sample %d "), rs->curfsa); /* extra info */ - if (rs->infostr && rs->infostr[0]) + if (rs->infostr && rs->infostr[0]) { spos += sprintf(spos, "| %s ", rs->infostr); + } + else if (error && error[0]) { + spos += sprintf(spos, "| %s ", error); + } /* very weak... but 512 characters is quite safe */ if (spos >= str + IMA_MAX_RENDER_TEXT) @@ -438,7 +443,8 @@ static void image_renderinfo_cb(void *rjv, RenderStats *rs) if (rr->text == NULL) rr->text = MEM_callocN(IMA_MAX_RENDER_TEXT, "rendertext"); - make_renderinfo_string(rs, rj->scene, rj->v3d_override, rr->text); + make_renderinfo_string(rs, rj->scene, rj->v3d_override, + rr->error, rr->text); } RE_ReleaseResult(rj->re); @@ -1121,7 +1127,7 @@ static void render_view3d_renderinfo_cb(void *rjp, RenderStats *rs) *rp->stop = 1; } else { - make_renderinfo_string(rs, rp->scene, false, rp->engine->text); + make_renderinfo_string(rs, rp->scene, false, NULL, rp->engine->text); /* make jobs timer to send notifier */ *(rp->do_update) = true; @@ -1551,10 +1557,10 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C) RE_ReleaseResultImage(re); } -void ED_viewport_render_kill_jobs(const bContext *C, bool free_database) +void ED_viewport_render_kill_jobs(wmWindowManager *wm, + Main *bmain, + bool free_database) { - wmWindowManager *wm = CTX_wm_manager(C); - Main *bmain = CTX_data_main(C); bScreen *sc; ScrArea *sa; ARegion *ar; diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 559c86bf48c..cd569365381 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -69,7 +69,6 @@ #include "GPU_extensions.h" #include "GPU_glew.h" -#include "wm_window.h" #include "render_intern.h" @@ -187,7 +186,9 @@ static void screen_opengl_render_apply(OGLRender *oglrender) wmOrtho2(0, sizex, 0, sizey); glTranslatef(sizex / 2, sizey / 2, 0.0f); - ED_gpencil_draw_ex(gpd, sizex, sizey, scene->r.cfra); + G.f |= G_RENDER_OGL; + ED_gpencil_draw_ex(scene, gpd, sizex, sizey, scene->r.cfra, SPACE_SEQ); + G.f &= ~G_RENDER_OGL; gp_rect = MEM_mallocN(sizex * sizey * sizeof(unsigned char) * 4, "offscreen rect"); GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, gp_rect); @@ -271,7 +272,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender) /* shouldnt suddenly give errors mid-render but possible */ char err_out[256] = "unknown"; ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey, - IB_rect, OB_SOLID, false, true, + IB_rect, OB_SOLID, false, true, true, (draw_sky) ? R_ADDSKY : R_ALPHAPREMUL, err_out); camera = scene->camera; diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 16782026cdf..e29d89d0119 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -60,6 +60,7 @@ #include "DNA_brush_types.h" #include "DNA_screen_types.h" +#include "BKE_appdir.h" #include "BKE_brush.h" #include "BKE_context.h" #include "BKE_colortools.h" @@ -78,14 +79,11 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -#include "IMB_colormanagement.h" -#include "GPU_extensions.h" #include "BIF_gl.h" #include "BIF_glutil.h" -#include "PIL_time.h" #include "RE_pipeline.h" #include "RE_engine.h" @@ -96,9 +94,7 @@ #include "ED_datafiles.h" #include "ED_render.h" -#include "UI_interface.h" -#include "render_intern.h" ImBuf *get_brush_icon(Brush *brush) { @@ -121,7 +117,7 @@ ImBuf *get_brush_icon(Brush *brush) // otherwise lets try to find it in other directories if (!(brush->icon_imbuf)) { - folder = BLI_get_folder(BLENDER_DATAFILES, "brushicons"); + folder = BKE_appdir_folder_id(BLENDER_DATAFILES, "brushicons"); BLI_make_file_string(G.main->name, path, folder, brush->icon_filepath); @@ -315,7 +311,7 @@ static Scene *preview_prepare_scene(Render *re, * seems commonly used render engines does not support * such kind of rendering. */ - BLI_strncpy(sce->r.engine, "BLENDER_RENDER", sizeof(sce->r.engine)); + BLI_strncpy(sce->r.engine, RE_engine_id_BLENDER_RENDER, sizeof(sce->r.engine)); } else { BLI_strncpy(sce->r.engine, scene->r.engine, sizeof(sce->r.engine)); @@ -532,7 +528,7 @@ static Scene *preview_prepare_scene(Render *re, } /* new UI convention: draw is in pixel space already. */ -/* uses ROUNDBOX button in block to get the rect */ +/* uses UI_BTYPE_ROUNDBOX button in block to get the rect */ static bool ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect, rcti *newrect) { Render *re; @@ -572,8 +568,9 @@ static bool ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect, unsigned char *rect_byte = MEM_mallocN(rres.rectx * rres.recty * sizeof(int), "ed_preview_draw_rect"); float fx = rect->xmin + offx; float fy = rect->ymin; + if (re) + RE_AcquiredResultGet32(re, &rres, (unsigned int *)rect_byte); - RE_AcquiredResultGet32(re, &rres, (unsigned int *)rect_byte); glaDrawPixelsSafe(fx, fy, rres.rectx, rres.recty, rres.rectx, GL_RGBA, GL_UNSIGNED_BYTE, rect_byte); MEM_freeN(rect_byte); @@ -1187,12 +1184,11 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M WM_jobs_start(CTX_wm_manager(C), wm_job); } -void ED_preview_kill_jobs(const struct bContext *C) +void ED_preview_kill_jobs(wmWindowManager *wm, Main *bmain) { - wmWindowManager *wm = CTX_wm_manager(C); if (wm) WM_jobs_kill(wm, NULL, common_preview_startjob); - - ED_viewport_render_kill_jobs(C, false); + + ED_viewport_render_kill_jobs(wm, bmain, false); } diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 6c996bcbd67..5bbe11bd5ac 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -51,7 +51,6 @@ #include "BKE_curve.h" #include "BKE_depsgraph.h" #include "BKE_font.h" -#include "BKE_freestyle.h" #include "BKE_global.h" #include "BKE_image.h" #include "BKE_library.h" @@ -65,17 +64,15 @@ #include "BKE_world.h" #include "BKE_editmesh.h" -#include "IMB_imbuf.h" -#include "IMB_imbuf_types.h" -#include "GPU_material.h" #ifdef WITH_FREESTYLE +# include "BKE_freestyle.h" # include "FRS_freestyle.h" +# include "RNA_enum_types.h" #endif #include "RNA_access.h" -#include "RNA_enum_types.h" #include "WM_api.h" #include "WM_types.h" @@ -408,7 +405,7 @@ static int new_material_exec(bContext *C, wmOperator *UNUSED(op)) } /* hook into UI */ - uiIDContextProperty(C, &ptr, &prop); + UI_context_active_but_prop_get_templateID(C, &ptr, &prop); if (prop) { /* when creating new ID blocks, use is already 1, but RNA @@ -457,7 +454,7 @@ static int new_texture_exec(bContext *C, wmOperator *UNUSED(op)) } /* hook into UI */ - uiIDContextProperty(C, &ptr, &prop); + UI_context_active_but_prop_get_templateID(C, &ptr, &prop); if (prop) { /* when creating new ID blocks, use is already 1, but RNA @@ -520,7 +517,7 @@ static int new_world_exec(bContext *C, wmOperator *UNUSED(op)) } /* hook into UI */ - uiIDContextProperty(C, &ptr, &prop); + UI_context_active_but_prop_get_templateID(C, &ptr, &prop); if (prop) { /* when creating new ID blocks, use is already 1, but RNA @@ -558,7 +555,7 @@ static int render_layer_add_exec(bContext *C, wmOperator *UNUSED(op)) Scene *scene = CTX_data_scene(C); BKE_scene_add_render_layer(scene, NULL); - scene->r.actlay = BLI_countlist(&scene->r.layers) - 1; + scene->r.actlay = BLI_listbase_count(&scene->r.layers) - 1; DAG_id_tag_update(&scene->id, 0); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index df7ca9f11b2..be42e2ed518 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -41,11 +41,11 @@ #include "DNA_world_types.h" #include "DNA_windowmanager_types.h" +#include "BLI_listbase.h" #include "BLI_threads.h" #include "BLI_utildefines.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" #include "BKE_DerivedMesh.h" #include "BKE_icons.h" #include "BKE_main.h" @@ -85,7 +85,11 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated) /* don't call this recursively for frame updates */ if (recursive_check) return; - + + /* Do not call if no WM available, see T42688. */ + if (BLI_listbase_is_empty(&bmain->wm)) + return; + recursive_check = true; C = CTX_create(); @@ -276,7 +280,7 @@ static void material_changed(Main *bmain, Material *ma) /* glsl */ if (ma->gpumaterial.first) - GPU_material_free(ma); + GPU_material_free(&ma->gpumaterial); /* find node materials using this */ for (parent = bmain->mat.first; parent; parent = parent->id.next) { @@ -290,7 +294,7 @@ static void material_changed(Main *bmain, Material *ma) BKE_icon_changed(BKE_icon_getid(&parent->id)); if (parent->gpumaterial.first) - GPU_material_free(parent); + GPU_material_free(&parent->gpumaterial); } /* find if we have a scene with textured display */ @@ -336,10 +340,10 @@ static void lamp_changed(Main *bmain, Lamp *la) for (ma = bmain->mat.first; ma; ma = ma->id.next) if (ma->gpumaterial.first) - GPU_material_free(ma); + GPU_material_free(&ma->gpumaterial); if (defmaterial.gpumaterial.first) - GPU_material_free(&defmaterial); + GPU_material_free(&defmaterial.gpumaterial); } static int material_uses_texture(Material *ma, Tex *tex) @@ -377,7 +381,7 @@ static void texture_changed(Main *bmain, Tex *tex) BKE_icon_changed(BKE_icon_getid(&ma->id)); if (ma->gpumaterial.first) - GPU_material_free(ma); + GPU_material_free(&ma->gpumaterial); } /* find lamps */ @@ -406,6 +410,9 @@ static void texture_changed(Main *bmain, Tex *tex) } BKE_icon_changed(BKE_icon_getid(&wo->id)); + + if (wo->gpumaterial.first) + GPU_material_free(&wo->gpumaterial); } /* find compositing nodes */ @@ -451,14 +458,17 @@ static void world_changed(Main *bmain, World *wo) /* icons */ BKE_icon_changed(BKE_icon_getid(&wo->id)); - + /* glsl */ for (ma = bmain->mat.first; ma; ma = ma->id.next) if (ma->gpumaterial.first) - GPU_material_free(ma); + GPU_material_free(&ma->gpumaterial); if (defmaterial.gpumaterial.first) - GPU_material_free(&defmaterial); + GPU_material_free(&defmaterial.gpumaterial); + + if (wo->gpumaterial.first) + GPU_material_free(&wo->gpumaterial); } static void image_changed(Main *bmain, Image *ima) @@ -478,6 +488,7 @@ static void scene_changed(Main *bmain, Scene *scene) { Object *ob; Material *ma; + World *wo; /* glsl */ for (ob = bmain->object.first; ob; ob = ob->id.next) { @@ -487,16 +498,20 @@ static void scene_changed(Main *bmain, Scene *scene) if (ob->mode & OB_MODE_TEXTURE_PAINT) { BKE_texpaint_slots_refresh_object(scene, ob); BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); - GPU_drawobject_free(ob->derivedFinal); + GPU_drawobject_free(ob->derivedFinal); } } for (ma = bmain->mat.first; ma; ma = ma->id.next) if (ma->gpumaterial.first) - GPU_material_free(ma); + GPU_material_free(&ma->gpumaterial); + for (wo = bmain->world.first; wo; wo = wo->id.next) + if (wo->gpumaterial.first) + GPU_material_free(&wo->gpumaterial); + if (defmaterial.gpumaterial.first) - GPU_material_free(&defmaterial); + GPU_material_free(&defmaterial.gpumaterial); } void ED_render_id_flush_update(Main *bmain, ID *id) @@ -538,7 +553,7 @@ void ED_render_id_flush_update(Main *bmain, ID *id) void ED_render_internal_init(void) { - RenderEngineType *ret = RE_engines_find("BLENDER_RENDER"); + RenderEngineType *ret = RE_engines_find(RE_engine_id_BLENDER_RENDER); ret->view_update = render_view3d_update; ret->view_draw = render_view3d_draw; diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c index 0beb5737ec7..ab28f5fa675 100644 --- a/source/blender/editors/render/render_view.c +++ b/source/blender/editors/render/render_view.c @@ -252,7 +252,7 @@ static int render_view_cancel_exec(bContext *C, wmOperator *UNUSED(op)) } else if (sima->flag & SI_FULLWINDOW) { sima->flag &= ~SI_FULLWINDOW; - ED_screen_full_toggle(C, win, sa); + ED_screen_state_toggle(C, win, sa, SCREENMAXIMIZED); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 752f388c338..23b15ea46f4 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -41,7 +41,6 @@ #include "BLI_utildefines.h" #include "BLI_linklist_stack.h" -#include "BLF_translation.h" #include "BKE_context.h" #include "BKE_global.h" @@ -63,6 +62,7 @@ #include "BLF_api.h" #include "UI_interface.h" +#include "UI_interface_icons.h" #include "UI_resources.h" #include "UI_view2d.h" @@ -149,6 +149,45 @@ void ED_area_do_refresh(bContext *C, ScrArea *sa) } /** + * \brief Corner widget use for quitting fullscreen. + */ +static void area_draw_azone_fullscreen(short x1, short y1, short x2, short y2, float alpha) +{ + int x = x2 - ((float) x2 - x1) * 0.5f / UI_DPI_FAC; + int y = y2 - ((float) y2 - y1) * 0.5f / UI_DPI_FAC; + + /* adjust the icon distance from the corner */ + x += 36.0f / UI_DPI_FAC; + y += 36.0f / UI_DPI_FAC; + + /* draws from the left bottom corner of the icon */ + x -= UI_DPI_ICON_SIZE; + y -= UI_DPI_ICON_SIZE; + + alpha = min_ff(alpha, 0.75f); + + UI_icon_draw_aspect(x, y, ICON_FULLSCREEN_EXIT, 0.7f / UI_DPI_FAC, alpha); + + /* debug drawing : + * The click_rect is the same as defined in fullscreen_click_rcti_init + * Keep them both in sync */ + + if (G.debug_value == 1) { + rcti click_rect; + float icon_size = UI_DPI_ICON_SIZE + 7 * UI_DPI_FAC; + char alpha_debug = 255 * alpha; + + BLI_rcti_init(&click_rect, x, x + icon_size, y, y + icon_size); + + glColor4ub(255, 0, 0, alpha_debug); + fdrawbox(click_rect.xmin, click_rect.ymin, click_rect.xmax, click_rect.ymax); + glColor4ub(0, 255, 255, alpha_debug); + fdrawline(click_rect.xmin, click_rect.ymin, click_rect.xmax, click_rect.ymax); + fdrawline(click_rect.xmin, click_rect.ymax, click_rect.xmax, click_rect.ymin); + } +} + +/** * \brief Corner widgets use for dragging and splitting the view. */ static void area_draw_azone(short x1, short y1, short x2, short y2) @@ -231,21 +270,21 @@ static void region_draw_azone_tab_plus(AZone *az) /* add code to draw region hidden as 'too small' */ switch (az->edge) { case AE_TOP_TO_BOTTOMRIGHT: - uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT); + UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT); break; case AE_BOTTOM_TO_TOPLEFT: - uiSetRoundBox(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT); + UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT); break; case AE_LEFT_TO_TOPRIGHT: - uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT); + UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT); break; case AE_RIGHT_TO_TOPLEFT: - uiSetRoundBox(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT); + UI_draw_roundbox_corner_set(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT); break; } glColor4f(0.05f, 0.05f, 0.05f, 0.4f); - uiRoundBox((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f); + UI_draw_roundbox((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f); glEnable(GL_BLEND); @@ -266,32 +305,32 @@ static void region_draw_azone_tab(AZone *az) /* add code to draw region hidden as 'too small' */ switch (az->edge) { case AE_TOP_TO_BOTTOMRIGHT: - uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT | UI_RB_ALPHA); + UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT | UI_RB_ALPHA); - uiDrawBoxShade(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f); + UI_draw_roundbox_shade_x(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f); glColor4ub(0, 0, 0, 255); - uiRoundRect((float)az->x1, 0.3f + (float)az->y1, (float)az->x2, 0.3f + (float)az->y2, 4.0f); + UI_draw_roundbox_unfilled((float)az->x1, 0.3f + (float)az->y1, (float)az->x2, 0.3f + (float)az->y2, 4.0f); break; case AE_BOTTOM_TO_TOPLEFT: - uiSetRoundBox(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT | UI_RB_ALPHA); + UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT | UI_RB_ALPHA); - uiDrawBoxShade(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f); + UI_draw_roundbox_shade_x(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f); glColor4ub(0, 0, 0, 255); - uiRoundRect((float)az->x1, 0.3f + (float)az->y1, (float)az->x2, 0.3f + (float)az->y2, 4.0f); + UI_draw_roundbox_unfilled((float)az->x1, 0.3f + (float)az->y1, (float)az->x2, 0.3f + (float)az->y2, 4.0f); break; case AE_LEFT_TO_TOPRIGHT: - uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT | UI_RB_ALPHA); + UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT | UI_RB_ALPHA); - uiDrawBoxShade(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f); + UI_draw_roundbox_shade_x(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f); glColor4ub(0, 0, 0, 255); - uiRoundRect((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f); + UI_draw_roundbox_unfilled((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f); break; case AE_RIGHT_TO_TOPLEFT: - uiSetRoundBox(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT | UI_RB_ALPHA); + UI_draw_roundbox_corner_set(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT | UI_RB_ALPHA); - uiDrawBoxShade(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f); + UI_draw_roundbox_shade_x(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f); glColor4ub(0, 0, 0, 255); - uiRoundRect((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f); + UI_draw_roundbox_unfilled((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f); break; } @@ -365,6 +404,9 @@ static void region_draw_azones(ScrArea *sa, ARegion *ar) } } } + else if (az->type == AZONE_FULLSCREEN) { + area_draw_azone_fullscreen(az->x1, az->y1, az->x2, az->y2, az->alpha); + } } } @@ -454,10 +496,11 @@ void ED_region_do_draw(bContext *C, ARegion *ar) ar->do_draw = 0; memset(&ar->drawrct, 0, sizeof(ar->drawrct)); - uiFreeInactiveBlocks(C, &ar->uiblocks); + UI_blocklist_free_inactive(C, &ar->uiblocks); - if (sa) + if (sa && (win->screen->state != SCREENFULL)) { region_draw_emboss(ar, &ar->winrct); + } } /* ********************************** @@ -567,10 +610,10 @@ static void area_azone_initialize(wmWindow *win, bScreen *screen, ScrArea *sa) { AZone *az; - /* reinitalize entirely, regions add azones too */ + /* reinitalize entirely, regions and fullscreen add azones too */ BLI_freelistN(&sa->actionzones); - if (screen->full != SCREENNORMAL) { + if (screen->state != SCREENNORMAL) { return; } @@ -602,6 +645,26 @@ static void area_azone_initialize(wmWindow *win, bScreen *screen, ScrArea *sa) BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); } +static void fullscreen_azone_initialize(ScrArea *sa, ARegion *ar) +{ + AZone *az; + + if (ar->regiontype != RGN_TYPE_WINDOW) + return; + + az = (AZone *)MEM_callocN(sizeof(AZone), "fullscreen action zone"); + BLI_addtail(&(sa->actionzones), az); + az->type = AZONE_FULLSCREEN; + az->ar = ar; + az->alpha = 0.0f; + + az->x1 = ar->winrct.xmax - (AZONEFADEOUT - 1); + az->y1 = ar->winrct.ymax - (AZONEFADEOUT - 1); + az->x2 = ar->winrct.xmax; + az->y2 = ar->winrct.ymax; + BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); +} + #define AZONEPAD_EDGE (0.1f * U.widget_unit) #define AZONEPAD_ICON (0.45f * U.widget_unit) static void region_azone_edge(AZone *az, ARegion *ar) @@ -830,25 +893,30 @@ static void region_azone_tria(ScrArea *sa, AZone *az, ARegion *ar) } -static void region_azone_initialize(ScrArea *sa, ARegion *ar, AZEdge edge) +static void region_azone_initialize(ScrArea *sa, ARegion *ar, AZEdge edge, const bool is_fullscreen) { AZone *az; + const bool is_hidden = (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) == 0; - az = (AZone *)MEM_callocN(sizeof(AZone), "actionzone"); - BLI_addtail(&(sa->actionzones), az); - az->type = AZONE_REGION; - az->ar = ar; - az->edge = edge; + if (is_hidden || !is_fullscreen) { + az = (AZone *)MEM_callocN(sizeof(AZone), "actionzone"); + BLI_addtail(&(sa->actionzones), az); + az->type = AZONE_REGION; + az->ar = ar; + az->edge = edge; + } if (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) { - if (G.debug_value == 3) - region_azone_icon(sa, az, ar); - else if (G.debug_value == 2) - region_azone_tria(sa, az, ar); - else if (G.debug_value == 1) - region_azone_tab(sa, az, ar); - else - region_azone_tab_plus(sa, az, ar); + if (!is_fullscreen) { + if (G.debug_value == 3) + region_azone_icon(sa, az, ar); + else if (G.debug_value == 2) + region_azone_tria(sa, az, ar); + else if (G.debug_value == 1) + region_azone_tab(sa, az, ar); + else + region_azone_tab_plus(sa, az, ar); + } } else { region_azone_edge(az, ar); @@ -859,18 +927,18 @@ static void region_azone_initialize(ScrArea *sa, ARegion *ar, AZEdge edge) /* *************************************************************** */ -static void region_azone_add(ScrArea *sa, ARegion *ar, int alignment) +static void region_azone_add(ScrArea *sa, ARegion *ar, const int alignment, const bool is_fullscreen) { /* edge code (t b l r) is along which area edge azone will be drawn */ if (alignment == RGN_ALIGN_TOP) - region_azone_initialize(sa, ar, AE_BOTTOM_TO_TOPLEFT); + region_azone_initialize(sa, ar, AE_BOTTOM_TO_TOPLEFT, is_fullscreen); else if (alignment == RGN_ALIGN_BOTTOM) - region_azone_initialize(sa, ar, AE_TOP_TO_BOTTOMRIGHT); + region_azone_initialize(sa, ar, AE_TOP_TO_BOTTOMRIGHT, is_fullscreen); else if (alignment == RGN_ALIGN_RIGHT) - region_azone_initialize(sa, ar, AE_LEFT_TO_TOPRIGHT); + region_azone_initialize(sa, ar, AE_LEFT_TO_TOPRIGHT, is_fullscreen); else if (alignment == RGN_ALIGN_LEFT) - region_azone_initialize(sa, ar, AE_RIGHT_TO_TOPLEFT); + region_azone_initialize(sa, ar, AE_RIGHT_TO_TOPLEFT, is_fullscreen); } /* dir is direction to check, not the splitting edge direction! */ @@ -1188,7 +1256,13 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti * must be minimum '4' */ } else { - region_azone_add(sa, ar, alignment); + if (ELEM(win->screen->state, SCREENNORMAL, SCREENMAXIMIZED)) { + region_azone_add(sa, ar, alignment, false); + } + else { + region_azone_add(sa, ar, alignment, true); + fullscreen_azone_initialize(sa, ar); + } } region_rect_recursive(win, sa, ar->next, remainder, quad); @@ -1240,7 +1314,7 @@ static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ListBase *hand /* XXX it would be good to have boundbox checks for some of these... */ if (flag & ED_KEYMAP_UI) { /* user interface widgets */ - UI_add_region_handlers(handlers); + UI_region_handlers_add(handlers); } if (flag & ED_KEYMAP_VIEW2D) { /* 2d-viewport handling+manipulation */ @@ -1256,7 +1330,7 @@ static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ListBase *hand ARegion *ar; /* same local check for all areas */ static rcti rect = {0, 10000, 0, -1}; - rect.ymax = (30 * UI_DPI_FAC); + rect.ymax = UI_MARKER_MARGIN_Y; ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); if (ar) { WM_event_add_keymap_handler_bb(handlers, keymap, &rect, &ar->winrct); @@ -1277,8 +1351,18 @@ static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ListBase *hand } if (flag & ED_KEYMAP_GPENCIL) { /* grease pencil */ - wmKeyMap *keymap = WM_keymap_find(wm->defaultconf, "Grease Pencil", 0, 0); - WM_event_add_keymap_handler(handlers, keymap); + /* NOTE: This is now 2 keymaps - One for basic functionality, + * and one that only applies when "Edit Mode" is enabled + * for strokes. + * + * For now, it's easier to just include both, + * since you hardly want one without the other. + */ + wmKeyMap *keymap_general = WM_keymap_find(wm->defaultconf, "Grease Pencil", 0, 0); + wmKeyMap *keymap_edit = WM_keymap_find(wm->defaultconf, "Grease Pencil Stroke Edit Mode", 0, 0); + + WM_event_add_keymap_handler(handlers, keymap_general); + WM_event_add_keymap_handler(handlers, keymap_edit); } if (flag & ED_KEYMAP_HEADER) { /* standard keymap for headers regions */ @@ -1334,7 +1418,7 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa) } else { /* prevent uiblocks to run */ - uiFreeBlocks(NULL, &ar->uiblocks); + UI_blocklist_free(NULL, &ar->uiblocks); } } } @@ -1577,7 +1661,7 @@ int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco) RNA_pointer_create(&(scr->id), &RNA_Area, sa, &areaptr); - uiDefButR(block, MENU, 0, "", xco, yco, 1.5 * U.widget_unit, U.widget_unit, + uiDefButR(block, UI_BTYPE_MENU, 0, "", xco, yco, 1.5 * U.widget_unit, U.widget_unit, &areaptr, "type", 0, 0.0f, 0.0f, 0.0f, 0.0f, ""); return xco + 1.7 * U.widget_unit; @@ -1588,7 +1672,7 @@ int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco) void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *context, int contextnr) { ScrArea *sa = CTX_wm_area(C); - uiStyle *style = UI_GetStyleDraw(); + uiStyle *style = UI_style_get_dpi(); uiBlock *block; PanelType *pt; Panel *panel; @@ -1686,16 +1770,16 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * w -= margin_x; /* create panels */ - uiBeginPanels(C, ar); + UI_panels_begin(C, ar); - /* set view2d view matrix - uiBeginBlock() stores it */ + /* set view2d view matrix - UI_block_begin() stores it */ UI_view2d_view_ortho(v2d); BLI_SMALLSTACK_ITER_BEGIN(pt_stack, pt) { bool open; - panel = uiPanelFindByType(ar, pt); + panel = UI_panel_find_by_type(ar, pt); if (use_category_tabs && pt->category[0] && !STREQ(category, pt->category)) { if ((panel == NULL) || ((panel->flag & PNL_PIN) == 0)) { @@ -1704,20 +1788,21 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * } /* draw panel */ - block = uiBeginBlock(C, ar, pt->idname, UI_EMBOSS); - panel = uiBeginPanel(sa, ar, block, pt, panel, &open); + block = UI_block_begin(C, ar, pt->idname, UI_EMBOSS); + panel = UI_panel_begin(sa, ar, block, pt, panel, &open); /* bad fixed values */ triangle = (int)(UI_UNIT_Y * 1.1f); if (pt->draw_header && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) { /* for enabled buttons */ - panel->layout = uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, - triangle, (UI_UNIT_Y * 1.1f) + style->panelspace, UI_UNIT_Y, 1, 0, style); + panel->layout = UI_block_layout( + block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, + triangle, (UI_UNIT_Y * 1.1f) + style->panelspace, UI_UNIT_Y, 1, 0, style); pt->draw_header(C, panel); - uiBlockLayoutResolve(block, &xco, &yco); + UI_block_layout_resolve(block, &xco, &yco); panel->labelofs = xco - triangle; panel->layout = NULL; } @@ -1734,28 +1819,29 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * else panelContext = UI_LAYOUT_PANEL; - panel->layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, panelContext, - style->panelspace, 0, w - 2 * style->panelspace, em, 0, style); + panel->layout = UI_block_layout( + block, UI_LAYOUT_VERTICAL, panelContext, + style->panelspace, 0, w - 2 * style->panelspace, em, 0, style); pt->draw(C, panel); - uiBlockLayoutResolve(block, &xco, &yco); + UI_block_layout_resolve(block, &xco, &yco); panel->layout = NULL; yco -= 2 * style->panelspace; - uiEndPanel(block, w, -yco); + UI_panel_end(block, w, -yco); } else { yco = 0; - uiEndPanel(block, w, 0); + UI_panel_end(block, w, 0); } - uiEndBlock(C, block); + UI_block_end(C, block); } BLI_SMALLSTACK_ITER_END; /* align panels and return size */ - uiEndPanels(C, ar, &x, &y); + UI_panels_end(C, ar, &x, &y); /* before setting the view */ if (vertical) { @@ -1780,7 +1866,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * * flip +1 or -1 pixel compared to redoing the entire layout again. * Leaving in commented code for future tests */ #if 0 - uiScalePanels(ar, BLI_rctf_size_x(&v2d->cur)); + UI_panels_scale(ar, BLI_rctf_size_x(&v2d->cur)); break; #endif } @@ -1808,7 +1894,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * UI_view2d_view_ortho(v2d); /* draw panels */ - uiDrawPanels(C, ar); + UI_panels_draw(C, ar); /* restore view matrix */ UI_view2d_view_restore(C); @@ -1835,7 +1921,7 @@ void ED_region_panels_init(wmWindowManager *wm, ARegion *ar) void ED_region_header(const bContext *C, ARegion *ar) { - uiStyle *style = UI_GetStyleDraw(); + uiStyle *style = UI_style_get_dpi(); uiBlock *block; uiLayout *layout; HeaderType *ht; @@ -1855,8 +1941,8 @@ void ED_region_header(const bContext *C, ARegion *ar) /* draw all headers types */ for (ht = ar->type->headertypes.first; ht; ht = ht->next) { - block = uiBeginBlock(C, ar, ht->idname, UI_EMBOSS); - layout = uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, yco, UI_UNIT_Y, 1, 0, style); + block = UI_block_begin(C, ar, ht->idname, UI_EMBOSS); + layout = UI_block_layout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, yco, UI_UNIT_Y, 1, 0, style); if (ht->draw) { header.type = ht; @@ -1869,14 +1955,14 @@ void ED_region_header(const bContext *C, ARegion *ar) maxco = xco; } - uiBlockLayoutResolve(block, &xco, &yco); + UI_block_layout_resolve(block, &xco, &yco); /* for view2d */ if (xco > maxco) maxco = xco; - uiEndBlock(C, block); - uiDrawBlock(C, block); + UI_block_end(C, block); + UI_block_draw(C, block); } /* always as last */ @@ -1900,7 +1986,7 @@ int ED_area_headersize(void) void ED_region_info_draw(ARegion *ar, const char *text, int block, float fill_color[4]) { const int header_height = UI_UNIT_Y; - uiStyle *style = UI_GetStyleDraw(); + uiStyle *style = UI_style_get_dpi(); int fontid = style->widget.uifont_id; GLint scissor[4]; rcti rect; @@ -2040,7 +2126,7 @@ void ED_region_cache_draw_background(const ARegion *ar) void ED_region_cache_draw_curfra_label(const int framenr, const float x, const float y) { - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_style_get(); int fontid = style->widget.uifont_id; char numstr[32]; float font_dims[2] = {0.0f, 0.0f}; diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index c095dfe7792..134feb59d55 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -45,7 +45,6 @@ #include "BIF_gl.h" #include "BIF_glutil.h" -#include "GPU_extensions.h" #include "IMB_colormanagement.h" #include "IMB_imbuf_types.h" diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 7c8987ae778..ce9c608247b 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -26,12 +26,13 @@ * \ingroup edscr */ - +#include <stdio.h> #include <stdlib.h> #include <string.h> #include "DNA_object_types.h" #include "DNA_armature_types.h" +#include "DNA_gpencil_types.h" #include "DNA_sequence_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" @@ -45,11 +46,13 @@ #include "BKE_object.h" #include "BKE_action.h" #include "BKE_armature.h" +#include "BKE_gpencil.h" #include "BKE_sequencer.h" #include "RNA_access.h" #include "ED_armature.h" +#include "ED_gpencil.h" #include "WM_api.h" #include "UI_interface.h" @@ -66,12 +69,16 @@ const char *screen_context_dir[] = { "sculpt_object", "vertex_paint_object", "weight_paint_object", "image_paint_object", "particle_edit_object", "sequences", "selected_sequences", "selected_editable_sequences", /* sequencer */ + "gpencil_data", "gpencil_data_owner", /* grease pencil data */ + "visible_gpencil_layers", "editable_gpencil_layers", "editable_gpencil_strokes", + "active_gpencil_layer", "active_gpencil_frame", "active_operator", NULL}; int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result) { bScreen *sc = CTX_wm_screen(C); + ScrArea *sa = CTX_wm_area(C); Scene *scene = sc->scene; Base *base; unsigned int lay = scene->lay; @@ -392,6 +399,112 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult return 1; } } + else if (CTX_data_equals(member, "gpencil_data")) { + /* FIXME: for some reason, CTX_data_active_object(C) returns NULL when called from these situations + * (as outlined above - see Campbell's #ifdefs). That causes the get_active function to fail when + * called from context. For that reason, we end up using an alternative where we pass everything in! + */ + bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); + + if (gpd) { + CTX_data_id_pointer_set(result, &gpd->id); + return 1; + } + } + else if (CTX_data_equals(member, "gpencil_data_owner")) { + /* pointer to which data/datablock owns the reference to the Grease Pencil data being used (as gpencil_data) + * XXX: see comment for gpencil_data case... + */ + bGPdata **gpd_ptr = NULL; + PointerRNA ptr; + + /* get pointer to Grease Pencil Data */ + gpd_ptr = ED_gpencil_data_get_pointers_direct((ID *)sc, scene, sa, obact, &ptr); + + if (gpd_ptr) { + CTX_data_pointer_set(result, ptr.id.data, ptr.type, ptr.data); + return 1; + } + } + else if (CTX_data_equals(member, "active_gpencil_layer")) { + /* XXX: see comment for gpencil_data case... */ + bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); + + if (gpd) { + bGPDlayer *gpl = gpencil_layer_getactive(gpd); + + if (gpl) { + CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilLayer, gpl); + return 1; + } + } + } + else if (CTX_data_equals(member, "active_gpencil_frame")) { + /* XXX: see comment for gpencil_data case... */ + bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); + + if (gpd) { + bGPDlayer *gpl = gpencil_layer_getactive(gpd); + + if (gpl) { + CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilLayer, gpl->actframe); + return 1; + } + } + } + else if (CTX_data_equals(member, "visible_gpencil_layers")) { + /* XXX: see comment for gpencil_data case... */ + bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); + + if (gpd) { + bGPDlayer *gpl; + + for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { + if ((gpl->flag & GP_LAYER_HIDE) == 0) { + CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl); + } + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + } + else if (CTX_data_equals(member, "editable_gpencil_layers")) { + /* XXX: see comment for gpencil_data case... */ + bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); + + if (gpd) { + bGPDlayer *gpl; + + for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { + if ((gpl->flag & (GP_LAYER_HIDE | GP_LAYER_LOCKED)) == 0) { + CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl); + } + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + } + else if (CTX_data_equals(member, "editable_gpencil_strokes")) { + /* XXX: see comment for gpencil_data case... */ + bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); + + if (gpd) { + bGPDlayer *gpl; + + for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { + if ((gpl->flag & (GP_LAYER_HIDE | GP_LAYER_LOCKED)) == 0 && (gpl->actframe)) { + bGPDframe *gpf = gpl->actframe; + bGPDstroke *gps; + + for (gps = gpf->strokes.first; gps; gps = gps->next) { + CTX_data_list_add(result, &gpd->id, &RNA_GPencilStroke, gps); + } + } + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + } else if (CTX_data_equals(member, "active_operator")) { wmOperator *op = NULL; @@ -399,8 +512,8 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult if (sfile) { op = sfile->op; } - else if ((op = uiContextActiveOperator(C))) { - /* do nothign */ + else if ((op = UI_context_active_operator_get(C))) { + /* do nothing */ } else { /* note, this checks poll, could be a problem, but this also diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 12236e3779d..c179cfc464c 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1058,7 +1058,7 @@ bScreen *ED_screen_duplicate(wmWindow *win, bScreen *sc) { bScreen *newsc; - if (sc->full != SCREENNORMAL) return NULL; /* XXX handle this case! */ + if (sc->state != SCREENNORMAL) return NULL; /* XXX handle this case! */ /* make new empty screen: */ newsc = ED_screen_add(win, sc->scene, sc->id.name + 2); @@ -1439,7 +1439,7 @@ void ED_screen_set_subwinactive(bContext *C, wmEvent *event) /* this used to be a notifier, but needs to be done immediate * because it can undo setting the right button as active due * to delayed notifier handling */ - uiFreeActiveButtons(C, win->screen); + UI_screen_free_active_but(C, win->screen); } else region_cursor_set(win, scr->subwinactive, false); @@ -1485,7 +1485,7 @@ void ED_screen_set(bContext *C, bScreen *sc) return; - if (sc->full) { /* find associated full */ + if (sc->state == SCREENFULL) { /* find associated full */ bScreen *sc1; for (sc1 = bmain->screen.first; sc1; sc1 = sc1->id.next) { ScrArea *sa = sc1->areabase.first; @@ -1586,7 +1586,7 @@ void ED_screen_delete(bContext *C, bScreen *sc) int delete = 1; /* don't allow deleting temp fullscreens for now */ - if (sc->full == SCREENFULL) { + if (ELEM(sc->state, SCREENMAXIMIZED, SCREENFULL)) { return; } @@ -1730,11 +1730,11 @@ ScrArea *ED_screen_full_newspace(bContext *C, ScrArea *sa, int type) ScrArea *newsa = NULL; if (!sa || sa->full == NULL) { - newsa = ED_screen_full_toggle(C, win, sa); + newsa = ED_screen_state_toggle(C, win, sa, SCREENMAXIMIZED); } if (!newsa) { - if (sa->full) { + if (sa->full && (screen->state == SCREENMAXIMIZED)) { /* if this has been called from the temporary info header generated in * temp fullscreen layouts, find the correct fullscreen area to change * to create a new space inside */ @@ -1760,7 +1760,7 @@ void ED_screen_full_prevspace(bContext *C, ScrArea *sa) ED_area_prevspace(C, sa); if (sa->full) - ED_screen_full_toggle(C, win, sa); + ED_screen_state_toggle(C, win, sa, SCREENMAXIMIZED); } /* restore a screen / area back to default operation, after temp fullscreen modes */ @@ -1768,6 +1768,8 @@ void ED_screen_full_restore(bContext *C, ScrArea *sa) { wmWindow *win = CTX_wm_window(C); SpaceLink *sl = sa->spacedata.first; + bScreen *screen = CTX_wm_screen(C); + short state = (screen ? screen->state : SCREENMAXIMIZED); /* if fullscreen area has a secondary space (such as a file browser or fullscreen render * overlaid on top of a existing setup) then return to the previous space */ @@ -1785,23 +1787,23 @@ void ED_screen_full_restore(bContext *C, ScrArea *sa) ED_screen_full_prevspace(C, sa); } else - ED_screen_full_toggle(C, win, sa); + ED_screen_state_toggle(C, win, sa, state); } else if (sl->spacetype == SPACE_FILE) { ED_screen_full_prevspace(C, sa); } else { - ED_screen_full_toggle(C, win, sa); + ED_screen_state_toggle(C, win, sa, state); } } /* otherwise just tile the area again */ else { - ED_screen_full_toggle(C, win, sa); + ED_screen_state_toggle(C, win, sa, state); } } -/* this function toggles: if area is full then the parent will be restored */ -ScrArea *ED_screen_full_toggle(bContext *C, wmWindow *win, ScrArea *sa) +/* this function toggles: if area is maximized/full then the parent will be restored */ +ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const short state) { bScreen *sc, *oldscreen; ARegion *ar; @@ -1811,24 +1813,21 @@ ScrArea *ED_screen_full_toggle(bContext *C, wmWindow *win, ScrArea *sa) * switching screens with tooltip open because region and tooltip * are no longer in the same screen */ for (ar = sa->regionbase.first; ar; ar = ar->next) - uiFreeBlocks(C, &ar->uiblocks); - + UI_blocklist_free(C, &ar->uiblocks); + /* prevent hanging header prints */ ED_area_headerprint(sa, NULL); } if (sa && sa->full) { + /* restoring back to SCREENNORMAL */ ScrArea *old; - /*short fulltype;*/ /*UNUSED*/ sc = sa->full; /* the old screen to restore */ oldscreen = win->screen; /* the one disappearing */ - /*fulltype = sc->full;*/ - sc->full = 0; + sc->state = SCREENNORMAL; - /* removed: SCREENAUTOPLAY exception here */ - /* find old area */ for (old = sc->areabase.first; old; old = old->next) if (old->full) break; @@ -1838,6 +1837,13 @@ ScrArea *ED_screen_full_toggle(bContext *C, wmWindow *win, ScrArea *sa) return NULL; } + if (state == SCREENFULL) { + /* restore the old side panels/header visibility */ + for (ar = sa->regionbase.first; ar; ar = ar->next) { + ar->flag = ar->flagfullscreen; + } + } + ED_area_data_swap(old, sa); if (sa->flag & AREA_TEMP_INFO) sa->flag &= ~AREA_TEMP_INFO; old->full = NULL; @@ -1853,44 +1859,66 @@ ScrArea *ED_screen_full_toggle(bContext *C, wmWindow *win, ScrArea *sa) } else { + /* change from SCREENNORMAL to new state */ ScrArea *newa; char newname[MAX_ID_NAME - 2]; oldscreen = win->screen; - /* nothing wrong with having only 1 area, as far as I can see... - * is there only 1 area? */ -#if 0 - if (oldscreen->areabase.first == oldscreen->areabase.last) - return NULL; -#endif - - oldscreen->full = SCREENFULL; - BLI_snprintf(newname, sizeof(newname), "%s-%s", oldscreen->id.name + 2, "full"); + oldscreen->state = state; + BLI_snprintf(newname, sizeof(newname), "%s-%s", oldscreen->id.name + 2, "nonnormal"); sc = ED_screen_add(win, oldscreen->scene, newname); - sc->full = SCREENFULL; // XXX + sc->state = state; /* timer */ sc->animtimer = oldscreen->animtimer; oldscreen->animtimer = NULL; - /* returns the top small area */ - newa = area_split(sc, (ScrArea *)sc->areabase.first, 'h', 0.99f, 1); - ED_area_newspace(C, newa, SPACE_INFO); - /* use random area when we have no active one, e.g. when the * mouse is outside of the window and we open a file browser */ if (!sa) sa = oldscreen->areabase.first; - /* copy area */ - newa = newa->prev; - ED_area_data_swap(newa, sa); - sa->flag |= AREA_TEMP_INFO; + if (state == SCREENMAXIMIZED) { + /* returns the top small area */ + newa = area_split(sc, (ScrArea *)sc->areabase.first, 'h', 0.99f, 1); + ED_area_newspace(C, newa, SPACE_INFO); + + /* copy area */ + newa = newa->prev; + ED_area_data_swap(newa, sa); + sa->flag |= AREA_TEMP_INFO; + + sa->full = oldscreen; + newa->full = oldscreen; + newa->next->full = oldscreen; // XXX + } + else if (state == SCREENFULL) { + newa = (ScrArea *)sc->areabase.first; + + /* copy area */ + ED_area_data_swap(newa, sa); + newa->flag = sa->flag; /* mostly for AREA_FLAG_WASFULLSCREEN */ + + /* temporarily hide the side panels/header */ + for (ar = newa->regionbase.first; ar; ar = ar->next) { + ar->flagfullscreen = ar->flag; + + if (ELEM(ar->regiontype, + RGN_TYPE_UI, + RGN_TYPE_HEADER, + RGN_TYPE_TOOLS)) + { + ar->flag |= RGN_FLAG_HIDDEN; + } + } - sa->full = oldscreen; - newa->full = oldscreen; - newa->next->full = oldscreen; // XXX + sa->full = oldscreen; + newa->full = oldscreen; + } + else { + BLI_assert(false); + } ED_screen_set(C, sc); } diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h index 9e0421b6e99..79036d3356f 100644 --- a/source/blender/editors/screen/screen_intern.h +++ b/source/blender/editors/screen/screen_intern.h @@ -36,6 +36,8 @@ struct wmWindow; struct Scene; #define AZONESPOT (0.6f * U.widget_unit) +#define AZONEFADEIN (5.0f * U.widget_unit) /* when azone is totally visible */ +#define AZONEFADEOUT (6.5f * U.widget_unit) /* when we start seeing the azone */ /* area.c */ void ED_area_data_copy(ScrArea *sa_dst, ScrArea *sa_src, const bool do_free); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 7c7574b3af3..39321ec0770 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -43,6 +43,7 @@ #include "DNA_lattice_types.h" #include "DNA_object_types.h" #include "DNA_curve_types.h" +#include "DNA_gpencil_types.h" #include "DNA_scene_types.h" #include "DNA_meta_types.h" #include "DNA_mask_types.h" @@ -81,8 +82,6 @@ #include "UI_interface.h" #include "UI_resources.h" -#include "wm_window.h" - #include "screen_intern.h" /* own module include */ #define KM_MODAL_CANCEL 1 @@ -129,13 +128,31 @@ static int screen_active_editable(bContext *C) { if (ED_operator_screenactive(C)) { /* no full window splitting allowed */ - if (CTX_wm_screen(C)->full != SCREENNORMAL) + if (CTX_wm_screen(C)->state != SCREENNORMAL) return 0; return 1; } return 0; } +static ARegion *screen_find_region_type(bContext *C, int type) +{ + ARegion *ar = CTX_wm_region(C); + + /* find the header region + * - try context first, but upon failing, search all regions in area... + */ + if ((ar == NULL) || (ar->regiontype != type)) { + ScrArea *sa = CTX_wm_area(C); + ar = BKE_area_find_region_type(sa, type); + } + else { + ar = NULL; + } + + return ar; +} + /* when mouse is over area-edge */ int ED_operator_screen_mainwinactive(bContext *C) { @@ -394,7 +411,7 @@ int ED_operator_posemode_exclusive(bContext *C) } /* allows for pinned pose objects to be used in the object buttons - * and the the non-active pose object to be used in the 3D view */ + * and the non-active pose object to be used in the 3D view */ int ED_operator_posemode_context(bContext *C) { Object *obpose = ED_pose_object_from_context(C); @@ -611,6 +628,24 @@ static int actionzone_area_poll(bContext *C) return 0; } +/* the debug drawing of the click_rect is in area_draw_azone_fullscreen, keep both in sync */ +static void fullscreen_click_rcti_init(rcti *rect, const short x1, const short y1, const short x2, const short y2) +{ + int x = x2 - ((float) x2 - x1) * 0.5f / UI_DPI_FAC; + int y = y2 - ((float) y2 - y1) * 0.5f / UI_DPI_FAC; + float icon_size = UI_DPI_ICON_SIZE + 7 * UI_DPI_FAC; + + /* adjust the icon distance from the corner */ + x += 36.0f / UI_DPI_FAC; + y += 36.0f / UI_DPI_FAC; + + /* draws from the left bottom corner of the icon */ + x -= UI_DPI_ICON_SIZE; + y -= UI_DPI_ICON_SIZE; + + BLI_rcti_init(rect, x, x + icon_size, y, y + icon_size); +} + AZone *is_in_area_actionzone(ScrArea *sa, const int xy[2]) { AZone *az = NULL; @@ -627,6 +662,42 @@ AZone *is_in_area_actionzone(ScrArea *sa, const int xy[2]) else if (az->type == AZONE_REGION) { break; } + else if (az->type == AZONE_FULLSCREEN) { + int mouse_radius, spot_radius, fadein_radius, fadeout_radius; + rcti click_rect; + + fullscreen_click_rcti_init(&click_rect, az->x1, az->y1, az->x2, az->y2); + + if (BLI_rcti_isect_pt_v(&click_rect, xy)) { + az->alpha = 1.0f; + } + else { + mouse_radius = (xy[0] - az->x2) * (xy[0] - az->x2) + (xy[1] - az->y2) * (xy[1] - az->y2); + spot_radius = AZONESPOT * AZONESPOT; + fadein_radius = AZONEFADEIN * AZONEFADEIN; + fadeout_radius = AZONEFADEOUT * AZONEFADEOUT; + + if (mouse_radius < spot_radius) { + az->alpha = 1.0f; + } + else if (mouse_radius < fadein_radius) { + az->alpha = 1.0f; + } + else if (mouse_radius < fadeout_radius) { + az->alpha = 1.0f - ((float)(mouse_radius - fadein_radius)) / ((float)(fadeout_radius - fadein_radius)); + } + else { + az->alpha = 0.0f; + } + + /* fade in/out but no click */ + az = NULL; + } + + /* XXX force redraw to show/hide the action zone */ + ED_area_tag_redraw(sa); + break; + } } } @@ -654,8 +725,11 @@ static void actionzone_apply(bContext *C, wmOperator *op, int type) if (type == AZONE_AREA) event.type = EVT_ACTIONZONE_AREA; + else if (type == AZONE_FULLSCREEN) + event.type = EVT_ACTIONZONE_FULLSCREEN; else event.type = EVT_ACTIONZONE_REGION; + event.val = 0; event.customdata = op->customdata; event.customdatafree = true; @@ -680,8 +754,8 @@ static int actionzone_invoke(bContext *C, wmOperator *op, const wmEvent *event) sad->x = event->x; sad->y = event->y; /* region azone directly reacts on mouse clicks */ - if (sad->az->type == AZONE_REGION) { - actionzone_apply(C, op, AZONE_REGION); + if (ELEM(sad->az->type, AZONE_REGION, AZONE_FULLSCREEN)) { + actionzone_apply(C, op, sad->az->type); actionzone_exit(op); return OPERATOR_FINISHED; } @@ -1462,7 +1536,7 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event) int dir; /* no full window splitting allowed */ - if (sc->full != SCREENNORMAL) + if (sc->state != SCREENNORMAL) return OPERATOR_CANCELLED; if (event->type == EVT_ACTIONZONE_AREA) { @@ -2075,6 +2149,7 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); + bGPdata *gpd = CTX_data_gpencil_data(C); bDopeSheet ads = {NULL}; DLRBT_Tree keys; ActKeyColumn *ak; @@ -2102,7 +2177,9 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op) if (ob) ob_to_keylist(&ads, ob, &keys, NULL); - + + gpencil_to_keylist(&ads, gpd, &keys); + { Mask *mask = CTX_data_edit_mask(C); if (mask) { @@ -2231,8 +2308,8 @@ static void SCREEN_OT_marker_jump(wmOperatorType *ot) static bool screen_set_is_ok(bScreen *screen, bScreen *screen_prev) { - return ((screen->winid == 0) && - (screen->full == 0) && + return ((screen->winid == 0) && + (screen->state == SCREENNORMAL) && (screen != screen_prev) && (screen->id.name[2] != '.' || !(U.uiflag & USER_HIDE_DOT))); } @@ -2245,7 +2322,7 @@ static int screen_set_exec(bContext *C, wmOperator *op) bScreen *screen_prev = screen; ScrArea *sa = CTX_wm_area(C); - int tot = BLI_countlist(&bmain->screen); + int tot = BLI_listbase_count(&bmain->screen); int delta = RNA_int_get(op->ptr, "delta"); /* temp screens are for userpref or render display */ @@ -2303,10 +2380,11 @@ static void SCREEN_OT_screen_set(wmOperatorType *ot) /* function to be called outside UI context, or for redo */ -static int screen_full_area_exec(bContext *C, wmOperator *UNUSED(op)) +static int screen_maximize_area_exec(bContext *C, wmOperator *op) { bScreen *screen = CTX_wm_screen(C); ScrArea *sa = NULL; + const bool hide_panels = RNA_boolean_get(op->ptr, "use_hide_panels"); /* search current screen for 'fullscreen' areas */ /* prevents restoring info header, when mouse is over it */ @@ -2314,25 +2392,41 @@ static int screen_full_area_exec(bContext *C, wmOperator *UNUSED(op)) if (sa->full) break; } - if (sa == NULL) sa = CTX_wm_area(C); + if (sa == NULL) { + sa = CTX_wm_area(C); + } - ED_screen_full_toggle(C, CTX_wm_window(C), sa); + if (hide_panels) { + if (!ELEM(screen->state, SCREENNORMAL, SCREENFULL)) { + return OPERATOR_CANCELLED; + } + ED_screen_state_toggle(C, CTX_wm_window(C), sa, SCREENFULL); + } + else { + if (!ELEM(screen->state, SCREENNORMAL, SCREENMAXIMIZED)) { + return OPERATOR_CANCELLED; + } + ED_screen_state_toggle(C, CTX_wm_window(C), sa, SCREENMAXIMIZED); + } + return OPERATOR_FINISHED; } static void SCREEN_OT_screen_full_area(wmOperatorType *ot) { - ot->name = "Toggle Full Screen"; - ot->description = "Toggle display selected area as fullscreen"; + PropertyRNA *prop; + + ot->name = "Toggle Fullscreen Area"; + ot->description = "Toggle display selected area as fullscreen/maximized"; ot->idname = "SCREEN_OT_screen_full_area"; - ot->exec = screen_full_area_exec; + ot->exec = screen_maximize_area_exec; ot->poll = ED_operator_areaactive; ot->flag = 0; - -} - + prop = RNA_def_boolean(ot->srna, "use_hide_panels", false, "Hide Panels", "Hide all the panels"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); +} /* ************** join area operator ********************************************** */ @@ -2645,8 +2739,8 @@ static int screen_area_options_invoke(bContext *C, wmOperator *op, const wmEvent if (actedge == NULL) return OPERATOR_CANCELLED; - pup = uiPupMenuBegin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE); + layout = UI_popup_menu_layout(pup); WM_operator_properties_create(&ptr1, "SCREEN_OT_area_join"); @@ -2665,9 +2759,9 @@ static int screen_area_options_invoke(bContext *C, wmOperator *op, const wmEvent uiItemFullO(layout, "SCREEN_OT_area_split", NULL, ICON_NONE, ptr2.data, WM_OP_INVOKE_DEFAULT, 0); uiItemFullO(layout, "SCREEN_OT_area_join", NULL, ICON_NONE, ptr1.data, WM_OP_INVOKE_DEFAULT, 0); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } static void SCREEN_OT_area_options(wmOperatorType *ot) @@ -2703,7 +2797,7 @@ static int spacedata_cleanup_exec(bContext *C, wmOperator *op) SpaceLink *sl = sa->spacedata.first; BLI_remlink(&sa->spacedata, sl); - tot += BLI_countlist(&sa->spacedata); + tot += BLI_listbase_count(&sa->spacedata); BKE_spacedata_freelist(&sa->spacedata); BLI_addtail(&sa->spacedata, sl); } @@ -2761,20 +2855,20 @@ static int repeat_history_invoke(bContext *C, wmOperator *op, const wmEvent *UNU uiLayout *layout; int items, i; - items = BLI_countlist(&wm->operators); + items = BLI_listbase_count(&wm->operators); if (items == 0) return OPERATOR_CANCELLED; - pup = uiPupMenuBegin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE); + layout = UI_popup_menu_layout(pup); for (i = items - 1, lastop = wm->operators.last; lastop; lastop = lastop->prev, i--) if (WM_operator_repeat_check(C, lastop)) uiItemIntO(layout, RNA_struct_ui_name(lastop->type->srna), ICON_NONE, op->type->idname, "index", i); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } static int repeat_history_exec(bContext *C, wmOperator *op) @@ -3027,23 +3121,44 @@ static void SCREEN_OT_region_flip(wmOperatorType *ot) ot->flag = 0; } +/* ************** header operator ***************************** */ +static int header_exec(bContext *C, wmOperator *UNUSED(op)) +{ + ARegion *ar = screen_find_region_type(C, RGN_TYPE_HEADER); + + if (ar == NULL) { + return OPERATOR_CANCELLED; + } + + ar->flag ^= RGN_FLAG_HIDDEN; + + ED_area_tag_redraw(CTX_wm_area(C)); + + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +static void SCREEN_OT_header(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Header"; + ot->description = "Display header"; + ot->idname = "SCREEN_OT_header"; + + /* api callbacks */ + ot->exec = header_exec; +} + /* ************** header flip operator ***************************** */ /* flip a header region alignment */ static int header_flip_exec(bContext *C, wmOperator *UNUSED(op)) { - ARegion *ar = CTX_wm_region(C); - - /* find the header region - * - try context first, but upon failing, search all regions in area... - */ - if ((ar == NULL) || (ar->regiontype != RGN_TYPE_HEADER)) { - ScrArea *sa = CTX_wm_area(C); - ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER); + ARegion *ar = screen_find_region_type(C, RGN_TYPE_HEADER); - /* don't do anything if no region */ - if (ar == NULL) - return OPERATOR_CANCELLED; + if (ar == NULL) { + return OPERATOR_CANCELLED; } /* copied from SCREEN_OT_region_flip */ @@ -3142,14 +3257,14 @@ static int header_toolbox_invoke(bContext *C, wmOperator *UNUSED(op), const wmEv uiPopupMenu *pup; uiLayout *layout; - pup = uiPupMenuBegin(C, IFACE_("Header"), ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, IFACE_("Header"), ICON_NONE); + layout = UI_popup_menu_layout(pup); ED_screens_header_tools_menu_create(C, layout, NULL); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } static void SCREEN_OT_header_toolbox(wmOperatorType *ot) @@ -3410,12 +3525,14 @@ static void SCREEN_OT_animation_step(wmOperatorType *ot) /* find window that owns the animation timer */ bScreen *ED_screen_animation_playing(const wmWindowManager *wm) { - wmWindow *window; + wmWindow *win; + + for (win = wm->windows.first; win; win = win->next) { + if (win->screen->animtimer) { + return win->screen; + } + } - for (window = wm->windows.first; window; window = window->next) - if (window->screen->animtimer) - return window->screen; - return NULL; } @@ -3945,6 +4062,7 @@ void ED_operatortypes_screen(void) WM_operatortype_append(SCREEN_OT_region_scale); WM_operatortype_append(SCREEN_OT_region_flip); WM_operatortype_append(SCREEN_OT_header_flip); + WM_operatortype_append(SCREEN_OT_header); WM_operatortype_append(SCREEN_OT_header_toggle_menus); WM_operatortype_append(SCREEN_OT_header_toolbox); WM_operatortype_append(SCREEN_OT_screen_set); @@ -4047,6 +4165,7 @@ void ED_keymap_screen(wmKeyConfig *keyconf) WM_keymap_verify_item(keymap, "SCREEN_OT_area_options", RIGHTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "SCREEN_OT_header", F9KEY, KM_PRESS, KM_ALT, 0); /* Header Editing ------------------------------------------------ */ keymap = WM_keymap_find(keyconf, "Header", 0, 0); @@ -4066,6 +4185,11 @@ void ED_keymap_screen(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", UPARROWKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", DOWNARROWKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", SPACEKEY, KM_PRESS, KM_SHIFT, 0); + kmi = WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", F10KEY, KM_PRESS, KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "use_hide_panels", true); + kmi = WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", EVT_ACTIONZONE_FULLSCREEN, 0, 0, 0); + RNA_boolean_set(kmi->ptr, "use_hide_panels", true); + WM_keymap_add_item(keymap, "SCREEN_OT_screenshot", F3KEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "SCREEN_OT_screencast", F3KEY, KM_PRESS, KM_ALT, 0); diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c index be5fd48b41a..bb256147d09 100644 --- a/source/blender/editors/screen/screendump.c +++ b/source/blender/editors/screen/screendump.c @@ -65,7 +65,6 @@ #include "PIL_time.h" -#include "ED_screen_types.h" #include "screen_intern.h" diff --git a/source/blender/editors/sculpt_paint/paint_curve.c b/source/blender/editors/sculpt_paint/paint_curve.c index 8c7c3b102e3..1f5ee708ad0 100644 --- a/source/blender/editors/sculpt_paint/paint_curve.c +++ b/source/blender/editors/sculpt_paint/paint_curve.c @@ -329,7 +329,7 @@ void PAINTCURVE_OT_add_point(wmOperatorType *ot) { /* identifiers */ ot->name = "Add New Paint Curve Point"; - ot->description = "Add new paint curve point"; + ot->description = ot->name; ot->idname = "PAINTCURVE_OT_add_point"; /* api callbacks */ @@ -410,8 +410,8 @@ static int paintcurve_delete_point_exec(bContext *C, wmOperator *op) void PAINTCURVE_OT_delete_point(wmOperatorType *ot) { /* identifiers */ - ot->name = "Add New Paint Curve Point"; - ot->description = "Add new paint curve point"; + ot->name = "Remove Paint Curve Point"; + ot->description = ot->name; ot->idname = "PAINTCURVE_OT_delete_point"; /* api callbacks */ diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 51baeb76da9..4f6e4e4e9a9 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -45,13 +45,11 @@ #include "BLI_utildefines.h" #include "BLI_threads.h" -#include "PIL_time.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" #include "DNA_brush_types.h" -#include "DNA_mesh_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" @@ -62,15 +60,9 @@ #include "BKE_image.h" #include "BKE_main.h" #include "BKE_material.h" -#include "BKE_mesh.h" #include "BKE_node.h" #include "BKE_paint.h" -#include "BKE_report.h" -#include "BKE_scene.h" #include "BKE_texture.h" -#include "BKE_colortools.h" - -#include "BKE_editmesh.h" #include "UI_view2d.h" @@ -85,7 +77,6 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "RNA_enum_types.h" #include "GPU_draw.h" #include "GPU_buffers.h" @@ -1317,6 +1308,7 @@ static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event) data->sample_palette = true; sample_color_update_header(data, C); } + WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush); } break; } diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c index 5530f947b8c..44d562bbc7b 100644 --- a/source/blender/editors/sculpt_paint/paint_image_2d.c +++ b/source/blender/editors/sculpt_paint/paint_image_2d.c @@ -38,9 +38,7 @@ #include "DNA_space_types.h" #include "DNA_object_types.h" -#include "BLI_math.h" -#include "BLI_rect.h" #include "BLI_math_color_blend.h" #include "BLI_stack.h" #include "BLI_bitmap.h" @@ -65,7 +63,6 @@ #include "UI_view2d.h" -#include "RE_shader_ext.h" #include "GPU_draw.h" @@ -1619,6 +1616,7 @@ void paint_2d_gradient_fill( } do_colorband(br->gradient, f, color_f); + linearrgb_to_srgb_v3_v3(color_f, color_f); rgba_float_to_uchar((unsigned char *)&color_b, color_f); ((unsigned char *)&color_b)[3] *= br->alpha; IMB_blend_color_byte((unsigned char *)(ibuf->rect + y_px * ibuf->x + x_px), diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index e440f660c65..0e337e96336 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -50,7 +50,6 @@ #include "BLF_translation.h" -#include "PIL_time.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -62,7 +61,6 @@ #include "DNA_object_types.h" #include "BKE_camera.h" -#include "BKE_colortools.h" #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_DerivedMesh.h" @@ -80,10 +78,8 @@ #include "BKE_scene.h" #include "BKE_texture.h" -#include "UI_view2d.h" #include "UI_interface.h" -#include "ED_image.h" #include "ED_mesh.h" #include "ED_node.h" #include "ED_paint.h" @@ -101,10 +97,12 @@ #include "RNA_enum_types.h" #include "GPU_draw.h" -#include "GPU_buffers.h" #include "IMB_colormanagement.h" +#include "bmesh.h" +//#include "bmesh_tools.h" + #include "paint_intern.h" /* Defines and Structs */ @@ -994,11 +992,19 @@ static bool check_seam(const ProjPaintState *ps, return 1; } +#define SMALL_NUMBER 1.e-6f +BLI_INLINE float shell_v2v2_normal_dir_to_dist(float n[2], float d[2]) +{ + const float angle_cos = (normalize_v2(n) < SMALL_NUMBER) ? fabsf(dot_v2v2(d, n)) : 0.0f; + return (UNLIKELY(angle_cos < SMALL_NUMBER)) ? 1.0f : (1.0f / angle_cos); +} +#undef SMALL_NUMBER + /* Calculate outset UV's, this is not the same as simply scaling the UVs, * since the outset coords are a margin that keep an even distance from the original UV's, * note that the image aspect is taken into account */ static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const float scaler, - const int ibuf_x, const int ibuf_y, const bool is_quad) + const int ibuf_x, const int ibuf_y, const bool is_quad, const bool cw) { float a1, a2, a3, a4 = 0.0f; float puv[4][2]; /* pixelspace uv's */ @@ -1042,26 +1048,34 @@ static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const fl } if (is_quad) { - a1 = shell_v2v2_mid_normalized_to_dist(dir4, dir1); - a2 = shell_v2v2_mid_normalized_to_dist(dir1, dir2); - a3 = shell_v2v2_mid_normalized_to_dist(dir2, dir3); - a4 = shell_v2v2_mid_normalized_to_dist(dir3, dir4); - } - else { - a1 = shell_v2v2_mid_normalized_to_dist(dir3, dir1); - a2 = shell_v2v2_mid_normalized_to_dist(dir1, dir2); - a3 = shell_v2v2_mid_normalized_to_dist(dir2, dir3); - } + /* here we just use the orthonormality property (a1, a2) dot (a2, -a1) = 0 + * to get normals from the edge directions based on the winding */ + if (cw) { + no1[0] = -dir4[1] - dir1[1]; + no1[1] = dir4[0] + dir1[0]; + no2[0] = -dir1[1] - dir2[1]; + no2[1] = dir1[0] + dir2[0]; + no3[0] = -dir2[1] - dir3[1]; + no3[1] = dir2[0] + dir3[0]; + no4[0] = -dir3[1] - dir4[1]; + no4[1] = dir3[0] + dir4[0]; + } + else { + no1[0] = dir4[1] + dir1[1]; + no1[1] = -dir4[0] - dir1[0]; + no2[0] = dir1[1] + dir2[1]; + no2[1] = -dir1[0] - dir2[0]; + no3[0] = dir2[1] + dir3[1]; + no3[1] = -dir2[0] - dir3[0]; + no4[0] = dir3[1] + dir4[1]; + no4[1] = -dir3[0] - dir4[0]; + } + + a1 = shell_v2v2_normal_dir_to_dist(no1, dir4); + a2 = shell_v2v2_normal_dir_to_dist(no2, dir1); + a3 = shell_v2v2_normal_dir_to_dist(no3, dir2); + a4 = shell_v2v2_normal_dir_to_dist(no4, dir3); - if (is_quad) { - sub_v2_v2v2(no1, dir4, dir1); - sub_v2_v2v2(no2, dir1, dir2); - sub_v2_v2v2(no3, dir2, dir3); - sub_v2_v2v2(no4, dir3, dir4); - normalize_v2(no1); - normalize_v2(no2); - normalize_v2(no3); - normalize_v2(no4); mul_v2_fl(no1, a1 * scaler); mul_v2_fl(no2, a2 * scaler); mul_v2_fl(no3, a3 * scaler); @@ -1076,12 +1090,27 @@ static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const fl mul_v2_v2(outset_uv[3], ibuf_inv); } else { - sub_v2_v2v2(no1, dir3, dir1); - sub_v2_v2v2(no2, dir1, dir2); - sub_v2_v2v2(no3, dir2, dir3); - normalize_v2(no1); - normalize_v2(no2); - normalize_v2(no3); + if (cw) { + no1[0] = -dir3[1] - dir1[1]; + no1[1] = dir3[0] + dir1[0]; + no2[0] = -dir1[1] - dir2[1]; + no2[1] = dir1[0] + dir2[0]; + no3[0] = -dir2[1] - dir3[1]; + no3[1] = dir2[0] + dir3[0]; + } + else { + no1[0] = dir3[1] + dir1[1]; + no1[1] = -dir3[0] - dir1[0]; + no2[0] = dir1[1] + dir2[1]; + no2[1] = -dir1[0] - dir2[0]; + no3[0] = dir2[1] + dir3[1]; + no3[1] = -dir2[0] - dir3[0]; + } + + a1 = shell_v2v2_normal_dir_to_dist(no1, dir3); + a2 = shell_v2v2_normal_dir_to_dist(no2, dir1); + a3 = shell_v2v2_normal_dir_to_dist(no3, dir2); + mul_v2_fl(no1, a1 * scaler); mul_v2_fl(no2, a2 * scaler); mul_v2_fl(no3, a3 * scaler); @@ -1507,6 +1536,7 @@ static ProjPixel *project_paint_uvpixel_init( project_face_pixel(tf_other, ibuf_other, w, side, NULL, rgba); premul_to_straight_v4(rgba); linearrgb_to_srgb_uchar3(((ProjPixelClone *)projPixel)->clonepx.ch, rgba); + ((ProjPixelClone *)projPixel)->clonepx.ch[3] = rgba[3] * 255; } else { /* char to char */ project_face_pixel(tf_other, ibuf_other, w, side, ((ProjPixelClone *)projPixel)->clonepx.ch, NULL); @@ -1932,25 +1962,63 @@ static int float_z_sort(const void *p1, const void *p2) return (((float *)p1)[2] < ((float *)p2)[2] ? -1 : 1); } +/* assumes one point is within the rectangle */ +static void line_rect_clip( + rctf *rect, + const float l1[4], const float l2[4], + const float uv1[2], const float uv2[2], + float uv[2], bool is_ortho) +{ + float min = FLT_MAX, tmp; + if ((l1[0] - rect->xmin) * (l2[0] - rect->xmin) < 0) { + tmp = rect->xmin; + min = min_ff((tmp - l1[0]) / (l2[0] - l1[0]), min); + } + else if ((l1[0] - rect->xmax) * (l2[0] - rect->xmax) < 0) { + tmp = rect->xmax; + min = min_ff((tmp - l1[0]) / (l2[0] - l1[0]), min); + } + if ((l1[1] - rect->ymin) * (l2[1] - rect->ymin) < 0) { + tmp = rect->ymin; + min = min_ff((tmp - l1[1]) / (l2[1] - l1[1]), min); + } + else if ((l1[1] - rect->ymax) * (l2[1] - rect->ymax) < 0) { + tmp = rect->ymax; + min = min_ff((tmp - l1[1]) / (l2[1] - l1[1]), min); + } + + tmp = (is_ortho) ? 1.0f : (l1[3] + min * (l2[3] - l1[3])); + + uv[0] = (uv1[0] + min * (uv2[0] - uv1[0])) / tmp; + uv[1] = (uv1[1] + min * (uv2[1] - uv1[1])) / tmp; +} + + static void project_bucket_clip_face( const bool is_ortho, rctf *bucket_bounds, float *v1coSS, float *v2coSS, float *v3coSS, const float *uv1co, const float *uv2co, const float *uv3co, float bucket_bounds_uv[8][2], - int *tot) + int *tot, bool cull) { int inside_bucket_flag = 0; int inside_face_flag = 0; const int flip = ((line_point_side_v2(v1coSS, v2coSS, v3coSS) > 0.0f) != (line_point_side_v2(uv1co, uv2co, uv3co) > 0.0f)); - + bool colinear = false; + float bucket_bounds_ss[4][2]; + /* detect pathological case where face the three vertices are almost colinear in screen space. + * mostly those will be culled but when flood filling or with smooth shading */ + if (dist_squared_to_line_v2(v1coSS, v2coSS, v3coSS) < PROJ_PIXEL_TOLERANCE) + colinear = true; + /* get the UV space bounding box */ inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v1coSS); inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v2coSS) << 1; inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v3coSS) << 2; - + if (inside_bucket_flag == ISECT_ALL3) { /* all screenspace points are inside the bucket bounding box, this means we don't need to clip and can simply return the UVs */ if (flip) { /* facing the back? */ @@ -1962,9 +2030,59 @@ static void project_bucket_clip_face( copy_v2_v2(bucket_bounds_uv[0], uv1co); copy_v2_v2(bucket_bounds_uv[1], uv2co); copy_v2_v2(bucket_bounds_uv[2], uv3co); + } + + *tot = 3; + return; + } + /* handle pathological case here, no need for further intersections below since tringle area is almost zero */ + if (colinear) { + int flag; + + (*tot) = 0; + + if (cull) + return; + + if (inside_bucket_flag & ISECT_1) { copy_v2_v2(bucket_bounds_uv[*tot], uv1co); (*tot)++; } + + flag = inside_bucket_flag & (ISECT_1 | ISECT_2); + if (flag && flag != (ISECT_1 | ISECT_2)) { + line_rect_clip(bucket_bounds, v1coSS, v2coSS, uv1co, uv2co, bucket_bounds_uv[*tot], is_ortho); + (*tot)++; + } + + if (inside_bucket_flag & ISECT_2) { copy_v2_v2(bucket_bounds_uv[*tot], uv2co); (*tot)++; } + + flag = inside_bucket_flag & (ISECT_2 | ISECT_3); + if (flag && flag != (ISECT_2 | ISECT_3)) { + line_rect_clip(bucket_bounds, v2coSS, v3coSS, uv2co, uv3co, bucket_bounds_uv[*tot], is_ortho); + (*tot)++; } - *tot = 3; + if (inside_bucket_flag & ISECT_3) { copy_v2_v2(bucket_bounds_uv[*tot], uv3co); (*tot)++; } + + flag = inside_bucket_flag & (ISECT_3 | ISECT_1); + if (flag && flag != (ISECT_3 | ISECT_1)) { + line_rect_clip(bucket_bounds, v3coSS, v1coSS, uv3co, uv1co, bucket_bounds_uv[*tot], is_ortho); + (*tot)++; + } + + if ((*tot) < 3) { /* no intersections to speak of */ + *tot = 0; + return; + } + + /* at this point we have all uv points needed in a row. all that's needed is to invert them if necessary */ + if (flip) { + /* flip only to the middle of the array */ + int i, max = *tot / 2; + for (i = 0; i < max; i++) { + SWAP(float, bucket_bounds_uv[i][0], bucket_bounds_uv[max - i][0]); + SWAP(float, bucket_bounds_uv[i][1], bucket_bounds_uv[max - i][1]); + } + } + return; } @@ -2093,47 +2211,32 @@ static void project_bucket_clip_face( if (flip) qsort(isectVCosSS, *tot, sizeof(float) * 3, float_z_sort_flip); else qsort(isectVCosSS, *tot, sizeof(float) * 3, float_z_sort); - /* remove doubles */ - /* first/last check */ - if (fabsf(isectVCosSS[0][0] - isectVCosSS[(*tot) - 1][0]) < PROJ_PIXEL_TOLERANCE && - fabsf(isectVCosSS[0][1] - isectVCosSS[(*tot) - 1][1]) < PROJ_PIXEL_TOLERANCE) - { - (*tot)--; - } - - /* its possible there is only a few left after remove doubles */ - if ((*tot) < 3) { - // printf("removed too many doubles A\n"); - *tot = 0; - return; - } - doubles = true; while (doubles == true) { doubles = false; - for (i = 1; i < (*tot); i++) { - if (fabsf(isectVCosSS[i - 1][0] - isectVCosSS[i][0]) < PROJ_PIXEL_TOLERANCE && - fabsf(isectVCosSS[i - 1][1] - isectVCosSS[i][1]) < PROJ_PIXEL_TOLERANCE) + + for (i = 0; i < (*tot); i++) { + if (fabsf(isectVCosSS[(i + 1) % *tot][0] - isectVCosSS[i][0]) < PROJ_PIXEL_TOLERANCE && + fabsf(isectVCosSS[(i + 1) % *tot][1] - isectVCosSS[i][1]) < PROJ_PIXEL_TOLERANCE) { int j; - for (j = i + 1; j < (*tot); j++) { - isectVCosSS[j - 1][0] = isectVCosSS[j][0]; - isectVCosSS[j - 1][1] = isectVCosSS[j][1]; + for (j = i; j < (*tot) - 1; j++) { + isectVCosSS[j][0] = isectVCosSS[j + 1][0]; + isectVCosSS[j][1] = isectVCosSS[j + 1][1]; } doubles = true; /* keep looking for more doubles */ (*tot)--; } } + + /* its possible there is only a few left after remove doubles */ + if ((*tot) < 3) { + // printf("removed too many doubles B\n"); + *tot = 0; + return; + } } - /* its possible there is only a few left after remove doubles */ - if ((*tot) < 3) { - // printf("removed too many doubles B\n"); - *tot = 0; - return; - } - - if (is_ortho) { for (i = 0; i < (*tot); i++) { barycentric_weights_v2(v1coSS, v2coSS, v3coSS, isectVCosSS[i], w); @@ -2371,8 +2474,8 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i is_ortho, bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, - uv_clip, &uv_clip_tot - ); + uv_clip, &uv_clip_tot, + ps->do_backfacecull || ps->do_occlude); /* sometimes this happens, better just allow for 8 intersectiosn even though there should be max 6 */ #if 0 @@ -2510,9 +2613,8 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i float seam_subsection[4][2]; float fac1, fac2, ftot; - if (outset_uv[0][0] == FLT_MAX) /* first time initialize */ - uv_image_outset(tf_uv_pxoffset, outset_uv, ps->seam_bleed_px, ibuf->x, ibuf->y, mf->v4 != 0); + uv_image_outset(tf_uv_pxoffset, outset_uv, ps->seam_bleed_px, ibuf->x, ibuf->y, mf->v4 != 0, (ps->faceWindingFlags[face_index] & PROJ_FACE_WINDING_CW) == 0); /* ps->faceSeamUVs cant be modified when threading, now this is done we can unlock */ if (threaded) @@ -2787,7 +2889,7 @@ static bool project_bucket_face_isect(ProjPaintState *ps, int bucket_x, int buck int fidx; project_bucket_bounds(ps, bucket_x, bucket_y, &bucket_bounds); - + /* Is one of the faces verts in the bucket bounds? */ fidx = mf->v4 ? 3 : 2; @@ -3058,7 +3160,7 @@ static void project_paint_begin(ProjPaintState *ps) invert_m4_m4(ps->ob->imat, ps->ob->obmat); - if (ps->source == PROJ_SRC_VIEW) { + if (ELEM(ps->source, PROJ_SRC_VIEW, PROJ_SRC_VIEW_FILL)) { /* normal drawing */ ps->winx = ps->ar->winx; ps->winy = ps->ar->winy; @@ -3178,7 +3280,7 @@ static void project_paint_begin(ProjPaintState *ps) } /* If this border is not added we get artifacts for faces that - * have a parallel edge and at the bounds of the the 2D projected verts eg + * have a parallel edge and at the bounds of the 2D projected verts eg * - a single screen aligned quad */ projMargin = (ps->screenMax[0] - ps->screenMin[0]) * 0.000001f; ps->screenMax[0] += projMargin; @@ -3196,7 +3298,7 @@ static void project_paint_begin(ProjPaintState *ps) CLAMP(ps->screenMax[1], (float)(-diameter), (float)(ps->winy + diameter)); #endif } - else { /* re-projection, use bounds */ + else if (ps->source != PROJ_SRC_VIEW_FILL) { /* re-projection, use bounds */ ps->screenMin[0] = 0; ps->screenMax[0] = (float)(ps->winx); @@ -3392,8 +3494,8 @@ static void project_paint_begin(ProjPaintState *ps) #ifdef PROJ_DEBUG_WINCLIP /* ignore faces outside the view */ - if ( - (v1coSS[0] < ps->screenMin[0] && + if ((ps->source != PROJ_SRC_VIEW_FILL) && + ((v1coSS[0] < ps->screenMin[0] && v2coSS[0] < ps->screenMin[0] && v3coSS[0] < ps->screenMin[0] && (mf->v4 && v4coSS[0] < ps->screenMin[0])) || @@ -3411,7 +3513,7 @@ static void project_paint_begin(ProjPaintState *ps) (v1coSS[1] > ps->screenMax[1] && v2coSS[1] > ps->screenMax[1] && v3coSS[1] > ps->screenMax[1] && - (mf->v4 && v4coSS[1] > ps->screenMax[1])) + (mf->v4 && v4coSS[1] > ps->screenMax[1]))) ) { continue; @@ -3761,10 +3863,9 @@ static void do_projectpaint_clone_f(ProjPaintState *ps, ProjPixel *projPixel, fl } } -/* do_projectpaint_smear* - * - * note, mask is used to modify the alpha here, this is not correct since it allows - * accumulation of color greater then 'projPixel->mask' however in the case of smear its not +/** + * \note mask is used to modify the alpha here, this is not correct since it allows + * accumulation of color greater than 'projPixel->mask' however in the case of smear its not * really that important to be correct as it is with clone and painting */ static void do_projectpaint_smear(ProjPaintState *ps, ProjPixel *projPixel, float mask, @@ -4103,6 +4204,7 @@ static void *do_projectpaint_thread(void *ph_v) color_f, ps->blend); } else { + linearrgb_to_srgb_v3_v3(color_f, color_f); rgba_float_to_uchar(projPixel->newColor.ch, color_f); IMB_blend_color_byte(projPixel->pixel.ch_pt, projPixel->origColor.ch_pt, projPixel->newColor.ch, ps->blend); @@ -4591,7 +4693,7 @@ void *paint_proj_new_stroke(bContext *C, Object *ob, const float mouse[2], int m paint_brush_init_tex(ps->brush); - ps->source = PROJ_SRC_VIEW; + ps->source = (ps->tool == PAINT_TOOL_FILL) ? PROJ_SRC_VIEW_FILL : PROJ_SRC_VIEW; if (ps->ob == NULL || !(ps->ob->lay & ps->v3d->lay)) { MEM_freeN(ps); @@ -4614,10 +4716,6 @@ void *paint_proj_new_stroke(bContext *C, Object *ob, const float mouse[2], int m paint_proj_begin_clone(ps, mouse); - /* special full screen draw mode for fill tool */ - if (ps->tool == PAINT_TOOL_FILL) - ps->source = PROJ_SRC_VIEW_FILL; - return ps; } @@ -5025,7 +5123,7 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); Scene *scene = CTX_data_scene(C); Material *ma; - bool is_bi = BKE_scene_uses_blender_internal(scene); + bool is_bi = BKE_scene_uses_blender_internal(scene) || BKE_scene_uses_blender_game(scene); Image *ima = NULL; if (!ob) @@ -5084,9 +5182,8 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op) ima = mtex->tex->ima = proj_paint_image_create(op, bmain); } - WM_event_add_notifier(C, NC_TEXTURE, CTX_data_scene(C)); + WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, mtex->tex); } - WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, mtex->tex); } if (ima) { @@ -5096,6 +5193,8 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op) DAG_id_tag_update(&ma->id, 0); ED_area_tag_redraw(CTX_wm_area(C)); + BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); + return true; } } @@ -5158,7 +5257,7 @@ void PAINT_OT_add_texture_paint_slot(wmOperatorType *ot) ot->poll = ED_operator_region_view3d_active; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_UNDO; /* properties */ prop = RNA_def_enum(ot->srna, "type", layer_type_items, 0, "Type", "Merge method to use"); @@ -5182,7 +5281,7 @@ static int texture_paint_delete_texture_paint_slot_exec(bContext *C, wmOperator Object *ob = CTX_data_active_object(C); Scene *scene = CTX_data_scene(C); Material *ma; - bool is_bi = BKE_scene_uses_blender_internal(scene); + bool is_bi = BKE_scene_uses_blender_internal(scene) || BKE_scene_uses_blender_game(scene); TexPaintSlot *slot; /* not supported for node-based engines */ @@ -5203,9 +5302,9 @@ static int texture_paint_delete_texture_paint_slot_exec(bContext *C, wmOperator BKE_texpaint_slot_refresh_cache(scene, ma); DAG_id_tag_update(&ma->id, 0); - WM_event_add_notifier(C, NC_MATERIAL, CTX_data_scene(C)); + WM_event_add_notifier(C, NC_MATERIAL, ma); /* we need a notifier for data change since we change the displayed modifier uvs */ - WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); return OPERATOR_FINISHED; } @@ -5224,3 +5323,66 @@ void PAINT_OT_delete_texture_paint_slot(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } + +static int add_simple_uvs_exec(bContext *C, wmOperator *UNUSED(op)) +{ + /* no checks here, poll function does them for us */ + Object *ob = CTX_data_active_object(C); + Scene *scene = CTX_data_scene(C); + Mesh *me = ob->data; + bool synch_selection = (scene->toolsettings->uv_flag & UV_SYNC_SELECTION) != 0; + + BMesh *bm = BM_mesh_create(&bm_mesh_allocsize_default); + + /* turn synch selection off, since we are not in edit mode we need to ensure only the uv flags are tested */ + scene->toolsettings->uv_flag &= ~UV_SYNC_SELECTION; + + ED_mesh_uv_texture_ensure(me, NULL); + + BM_mesh_bm_from_me(bm, me, true, false, 0); + + /* select all uv loops first - pack parameters needs this to make sure charts are registered */ + ED_uvedit_select_all(bm); + ED_uvedit_unwrap_cube_project(ob, bm, 1.0, false); + /* set the margin really quickly before the packing operation*/ + scene->toolsettings->uvcalc_margin = 0.001f; + ED_uvedit_pack_islands(scene, ob, bm, false, false, true); + BM_mesh_bm_to_me(bm, me, false); + BM_mesh_free(bm); + + if (synch_selection) + scene->toolsettings->uv_flag |= UV_SYNC_SELECTION; + + BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); + + DAG_id_tag_update(ob->data, 0); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, scene); + return OPERATOR_FINISHED; +} + +static int add_simple_uvs_poll(bContext *C) +{ + Object *ob = CTX_data_active_object(C); + + if (!ob || ob->type != OB_MESH || ob->mode != OB_MODE_TEXTURE_PAINT) + return false; + + return true; +} + +void PAINT_OT_add_simple_uvs(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add simple UVs"; + ot->description = "Add cube map uvs on mesh"; + ot->idname = "PAINT_OT_add_simple_uvs"; + + /* api callbacks */ + ot->exec = add_simple_uvs_exec; + ot->poll = add_simple_uvs_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index c3b7ec60e71..9e558092f73 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -184,6 +184,7 @@ void PAINT_OT_image_from_view(struct wmOperatorType *ot); void PAINT_OT_add_texture_paint_slot(struct wmOperatorType *ot); void PAINT_OT_delete_texture_paint_slot(struct wmOperatorType *ot); void PAINT_OT_image_paint(struct wmOperatorType *ot); +void PAINT_OT_add_simple_uvs(struct wmOperatorType *ot); /* uv sculpting */ int uv_sculpt_poll(struct bContext *C); @@ -244,6 +245,18 @@ typedef enum BrushStrokeMode { BRUSH_STROKE_SMOOTH } BrushStrokeMode; +/* paint_ops.c */ +typedef enum { + RC_COLOR = 1, + RC_ROTATION = 2, + RC_ZOOM = 4, + RC_WEIGHT = 8, + RC_SECONDARY_ROTATION = 16 +} RCFlags; + +void set_brush_rc_props(struct PointerRNA *ptr, const char *paint, const char *prop, const char *secondary_prop, + RCFlags flags); + /* paint_undo.c */ struct ListBase *undo_paint_push_get_list(int type); void undo_paint_push_count_alloc(int type, int size); diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index dc6be9caa53..ea5f77acc5b 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -1085,6 +1085,7 @@ void ED_operatortypes_paint(void) WM_operatortype_append(PAINT_OT_brush_colors_flip); WM_operatortype_append(PAINT_OT_add_texture_paint_slot); WM_operatortype_append(PAINT_OT_delete_texture_paint_slot); + WM_operatortype_append(PAINT_OT_add_simple_uvs); /* weight */ WM_operatortype_append(PAINT_OT_weight_paint_toggle); @@ -1148,14 +1149,6 @@ static void ed_keymap_paint_brush_size(wmKeyMap *keymap, const char *UNUSED(path RNA_float_set(kmi->ptr, "scalar", 10.0 / 9.0); // 1.1111.... } -typedef enum { - RC_COLOR = 1, - RC_ROTATION = 2, - RC_ZOOM = 4, - RC_WEIGHT = 8, - RC_SECONDARY_ROTATION = 16 -} RCFlags; - static void set_brush_rc_path(PointerRNA *ptr, const char *brush_path, const char *output_name, const char *input_name) { @@ -1166,9 +1159,9 @@ static void set_brush_rc_path(PointerRNA *ptr, const char *brush_path, MEM_freeN(path); } -static void set_brush_rc_props(PointerRNA *ptr, const char *paint, - const char *prop, const char *secondary_prop, - RCFlags flags) +void set_brush_rc_props(PointerRNA *ptr, const char *paint, + const char *prop, const char *secondary_prop, + RCFlags flags) { const char *ups_path = "tool_settings.unified_paint_settings"; char *brush_path; @@ -1324,9 +1317,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf) * * This should be improved further, perhaps by showing a triangle * grid rather than brush alpha */ - kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", DKEY, KM_PRESS, KM_SHIFT, 0); - set_brush_rc_props(kmi->ptr, "sculpt", "detail_size", NULL, 0); - RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.sculpt.detail_size"); + kmi = WM_keymap_add_item(keymap, "SCULPT_OT_set_detail_size", DKEY, KM_PRESS, KM_SHIFT, 0); /* multires switch */ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_subdivision_set", PAGEUPKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index e03c8a5f106..12e7e811355 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -48,15 +48,12 @@ #include "BLF_translation.h" -#include "BKE_scene.h" #include "BKE_brush.h" #include "BKE_context.h" #include "BKE_DerivedMesh.h" -#include "BKE_material.h" #include "BKE_image.h" #include "BKE_paint.h" #include "BKE_report.h" -#include "BKE_image.h" #include "RNA_access.h" #include "RNA_define.h" @@ -66,16 +63,12 @@ #include "IMB_colormanagement.h" #include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" -#include "RE_shader_ext.h" #include "RE_render_ext.h" #include "ED_view3d.h" #include "ED_screen.h" -#include "ED_uvedit.h" - -#include "IMB_imbuf_types.h" -#include "IMB_imbuf.h" #include "BLI_sys_types.h" #include "ED_mesh.h" /* for face mask functions */ @@ -292,6 +285,7 @@ static void imapaint_pick_uv(Scene *scene, Object *ob, unsigned int faceindex, c MVert mv[4]; float matrix[4][4], proj[4][4]; GLint view[4]; + ImagePaintMode mode = scene->toolsettings->imapaint.mode; /* compute barycentric coordinates */ @@ -320,19 +314,25 @@ static void imapaint_pick_uv(Scene *scene, Object *ob, unsigned int faceindex, c if (findex == faceindex) { dm->getTessFace(dm, a, &mf); - ma = dm->mat[mf.mat_nr]; - slot = &ma->texpaintslot[ma->paint_active_slot]; - dm->getVert(dm, mf.v1, &mv[0]); dm->getVert(dm, mf.v2, &mv[1]); dm->getVert(dm, mf.v3, &mv[2]); if (mf.v4) dm->getVert(dm, mf.v4, &mv[3]); - if (!(slot && slot->uvname && (tf_base = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, slot->uvname)))) - tf_base = CustomData_get_layer(&dm->faceData, CD_MTFACE); + if (mode == IMAGEPAINT_MODE_MATERIAL) { + ma = dm->mat[mf.mat_nr]; + slot = &ma->texpaintslot[ma->paint_active_slot]; + + if (!(slot && slot->uvname && (tf_base = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, slot->uvname)))) + tf_base = CustomData_get_layer(&dm->faceData, CD_MTFACE); - tf = &tf_base[a]; + tf = &tf_base[a]; + } + else { + tf_base = CustomData_get_layer(&dm->faceData, CD_MTFACE); + tf = &tf_base[a]; + } p[0] = xy[0]; p[1] = xy[1]; diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 431dd54b3c0..fe38fd4806c 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -66,8 +66,6 @@ #include "WM_api.h" #include "WM_types.h" -#include "GPU_buffers.h" - #include "ED_armature.h" #include "ED_object.h" #include "ED_mesh.h" @@ -382,12 +380,12 @@ static int wpaint_mirror_vgroup_ensure(Object *ob, const int vgroup_active) mirrdef = defgroup_name_index(ob, name_flip); if (mirrdef == -1) { if (BKE_defgroup_new(ob, name_flip)) { - mirrdef = BLI_countlist(&ob->defbase) - 1; + mirrdef = BLI_listbase_count(&ob->defbase) - 1; } } /* curdef should never be NULL unless this is - * a lamp and ED_vgroup_add_name fails */ + * a lamp and BKE_object_defgroup_add_name fails */ return mirrdef; } @@ -1177,7 +1175,7 @@ static EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, PointerRNA me = BKE_mesh_from_object(vc.obact); if (me && me->dvert && vc.v3d && vc.rv3d && vc.obact->defbase.first) { - const int defbase_tot = BLI_countlist(&vc.obact->defbase); + const int defbase_tot = BLI_listbase_count(&vc.obact->defbase); const int use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; int *groups = MEM_callocN(defbase_tot * sizeof(int), "groups"); bool found = false; @@ -2159,7 +2157,7 @@ static bool wpaint_ensure_data(bContext *C, wmOperator *op) /* if nothing was added yet, we make dverts and a vertex deform group */ if (!me->dvert) { - ED_vgroup_data_create(&me->id); + BKE_object_defgroup_data_create(&me->id); WM_event_add_notifier(C, NC_GEOM | ND_DATA, me); } @@ -2174,7 +2172,7 @@ static bool wpaint_ensure_data(bContext *C, wmOperator *op) if (pchan) { bDeformGroup *dg = defgroup_find_name(ob, pchan->name); if (dg == NULL) { - dg = ED_vgroup_add_name(ob, pchan->name); /* sets actdef */ + dg = BKE_object_defgroup_add_name(ob, pchan->name); /* sets actdef */ } else { int actdef = 1 + BLI_findindex(&ob->defbase, dg); @@ -2186,7 +2184,7 @@ static bool wpaint_ensure_data(bContext *C, wmOperator *op) } } if (BLI_listbase_is_empty(&ob->defbase)) { - ED_vgroup_add(ob); + BKE_object_defgroup_add(ob); } /* ensure we don't try paint onto an invalid group */ @@ -2235,10 +2233,10 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UN /* set up auto-normalize, and generate map for detecting which * vgroups affect deform bones */ - wpd->defbase_tot = BLI_countlist(&ob->defbase); - wpd->lock_flags = BKE_objdef_lock_flags_get(ob, wpd->defbase_tot); + wpd->defbase_tot = BLI_listbase_count(&ob->defbase); + wpd->lock_flags = BKE_object_defgroup_lock_flags_get(ob, wpd->defbase_tot); if (ts->auto_normalize || ts->multipaint || wpd->lock_flags) { - wpd->vgroup_validmap = BKE_objdef_validmap_get(ob, wpd->defbase_tot); + wpd->vgroup_validmap = BKE_object_defgroup_validmap_get(ob, wpd->defbase_tot); } /* painting on subsurfs should give correct points too, this returns me->totvert amount */ @@ -2318,7 +2316,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P /* *** setup WeightPaintInfo - pass onto do_weight_paint_vertex *** */ wpi.defbase_tot = wpd->defbase_tot; - wpi.defbase_sel = BKE_objdef_selected_get(ob, wpi.defbase_tot, &wpi.defbase_tot_sel); + wpi.defbase_sel = BKE_object_defgroup_selected_get(ob, wpi.defbase_tot, &wpi.defbase_tot_sel); if (wpi.defbase_tot_sel == 0 && ob->actdef > 0) { wpi.defbase_tot_sel = 1; } @@ -3024,7 +3022,7 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P * avoid this if we can! */ DAG_id_tag_update(ob->data, 0); } - else if (!GPU_buffer_legacy(ob->derivedFinal)) { + else { /* If using new VBO drawing, mark mcol as dirty to force colors gpu buffer refresh! */ ob->derivedFinal->dirty |= DM_DIRTY_MCOL_UPDATE_DRAW; } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 7aaa28e04c4..8e865e0388a 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -40,7 +40,6 @@ #include "BLI_dial.h" #include "BLI_utildefines.h" #include "BLI_ghash.h" -#include "BLI_threads.h" #include "BLF_translation.h" @@ -56,7 +55,6 @@ #include "BKE_brush.h" #include "BKE_ccg.h" #include "BKE_context.h" -#include "BKE_crazyspace.h" #include "BKE_depsgraph.h" #include "BKE_image.h" #include "BKE_key.h" @@ -85,7 +83,6 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "RE_render_ext.h" #include "GPU_buffers.h" @@ -106,6 +103,8 @@ #if defined(__APPLE__) && defined _OPENMP #include <sys/sysctl.h> +#include "BLI_threads.h" + /* Query how many cores not counting HT aka physical cores we've got. */ static int system_physical_thread_count(void) { @@ -2917,19 +2916,13 @@ void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]) { Mesh *me = (Mesh *)ob->data; float (*ofs)[3] = NULL; - int a, is_basis = 0; + int a; + const int kb_act_idx = ob->shapenr - 1; KeyBlock *currkey; /* for relative keys editing of base should update other keys */ - if (me->key->type == KEY_RELATIVE) - for (currkey = me->key->block.first; currkey; currkey = currkey->next) - if (ob->shapenr - 1 == currkey->relative) { - is_basis = 1; - break; - } - - if (is_basis) { - ofs = BKE_key_convert_to_vertcos(ob, kb); + if (BKE_keyblock_is_basis(me->key, kb_act_idx)) { + ofs = BKE_keyblock_convert_to_vertcos(ob, kb); /* calculate key coord offsets (from previous location) */ for (a = 0; a < me->totvert; a++) { @@ -2937,14 +2930,10 @@ void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]) } /* apply offsets on other keys */ - currkey = me->key->block.first; - while (currkey) { - int apply_offset = ((currkey != kb) && (ob->shapenr - 1 == currkey->relative)); - - if (apply_offset) - BKE_key_convert_from_offset(ob, currkey, ofs); - - currkey = currkey->next; + for (currkey = me->key->block.first; currkey; currkey = currkey->next) { + if ((currkey != kb) && (currkey->relative == kb_act_idx)) { + BKE_keyblock_update_from_offset(ob, currkey, ofs); + } } MEM_freeN(ofs); @@ -2960,8 +2949,8 @@ void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]) BKE_mesh_calc_normals(me); } - /* apply new coords on active key block */ - BKE_key_convert_from_vertcos(ob, kb, vertCos); + /* apply new coords on active key block, no need to re-allocate kb->data here! */ + BKE_keyblock_update_from_vertcos(ob, kb, vertCos); } /* Note: we do the topology update before any brush actions to avoid @@ -4718,8 +4707,8 @@ static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(o static int dyntopo_warning_popup(bContext *C, wmOperatorType *ot, bool vdata, bool modifiers) { - uiPopupMenu *pup = uiPupMenuBegin(C, IFACE_("Warning!"), ICON_ERROR); - uiLayout *layout = uiPupMenuLayout(pup); + uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Warning!"), ICON_ERROR); + uiLayout *layout = UI_popup_menu_layout(pup); if (vdata) { const char *msg_error = TIP_("Vertex Data Detected!"); @@ -4740,9 +4729,9 @@ static int dyntopo_warning_popup(bContext *C, wmOperatorType *ot, bool vdata, bo uiItemFullO_ptr(layout, ot, IFACE_("OK"), ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } @@ -5192,6 +5181,46 @@ static void SCULPT_OT_sample_detail_size(wmOperatorType *ot) RNA_def_int_array(ot->srna, "location", 2, NULL, 0, SHRT_MAX, "Location", "Screen Coordinates of sampling", 0, SHRT_MAX); } + +static int sculpt_set_detail_size_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Sculpt *sd = CTX_data_tool_settings(C)->sculpt; + + PointerRNA props_ptr; + wmOperatorType *ot = WM_operatortype_find("WM_OT_radial_control", true); + + WM_operator_properties_create_ptr(&props_ptr, ot); + + if (sd->flags & SCULPT_DYNTOPO_DETAIL_CONSTANT) { + set_brush_rc_props(&props_ptr, "sculpt", "constant_detail", NULL, 0); + RNA_string_set(&props_ptr, "data_path_primary", "tool_settings.sculpt.constant_detail"); + } + else { + set_brush_rc_props(&props_ptr, "sculpt", "detail_size", NULL, 0); + RNA_string_set(&props_ptr, "data_path_primary", "tool_settings.sculpt.detail_size"); + } + + WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr); + + WM_operator_properties_free(&props_ptr); + + return OPERATOR_FINISHED; +} + +static void SCULPT_OT_set_detail_size(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Set Detail Size"; + ot->idname = "SCULPT_OT_set_detail_size"; + ot->description = "Set the mesh detail (either relative or constant one, depending on current dyntopo mode)"; + + /* api callbacks */ + ot->exec = sculpt_set_detail_size_exec; + ot->poll = sculpt_and_dynamic_topology_poll; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + void ED_operatortypes_sculpt(void) { WM_operatortype_append(SCULPT_OT_brush_stroke); @@ -5202,4 +5231,5 @@ void ED_operatortypes_sculpt(void) WM_operatortype_append(SCULPT_OT_symmetrize); WM_operatortype_append(SCULPT_OT_detail_flood_fill); WM_operatortype_append(SCULPT_OT_sample_detail_size); + WM_operatortype_append(SCULPT_OT_set_detail_size); } diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index 91f80a4fc40..4e9d23d3d97 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -127,7 +127,7 @@ static int sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoNo if (ss->kb) { float (*vertCos)[3]; - vertCos = BKE_key_convert_to_vertcos(ob, ss->kb); + vertCos = BKE_keyblock_convert_to_vertcos(ob, ss->kb); for (i = 0; i < unode->totvert; i++) { if (ss->modifiers_active) { diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c index d90eaafa379..7122b374462 100644 --- a/source/blender/editors/sculpt_paint/sculpt_uv.c +++ b/source/blender/editors/sculpt_paint/sculpt_uv.c @@ -60,7 +60,6 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "RNA_enum_types.h" #include "paint_intern.h" #include "uvedit_intern.h" diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 619fbd7f4c8..2f5dc0ccdc4 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -72,7 +72,6 @@ #include "ED_sound.h" #include "ED_util.h" -#include "sound_intern.h" /******************** open sound operator ********************/ @@ -87,7 +86,7 @@ static void sound_open_init(bContext *C, wmOperator *op) PropertyPointerRNA *pprop; op->customdata = pprop = MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA"); - uiIDContextProperty(C, &pprop->ptr, &pprop->prop); + UI_context_active_but_prop_get_templateID(C, &pprop->ptr, &pprop->prop); } #ifdef WITH_AUDASPACE diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c index 335949e8495..a17cfa4d87c 100644 --- a/source/blender/editors/space_action/action_draw.c +++ b/source/blender/editors/space_action/action_draw.c @@ -112,7 +112,7 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar) } } { /* second pass: widgets */ - uiBlock *block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); + uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS); size_t channel_index = 0; y = (float)ACHANNEL_FIRST; @@ -134,8 +134,8 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar) channel_index++; } - uiEndBlock(C, block); - uiDrawBlock(C, block); + UI_block_end(C, block); + UI_block_draw(C, block); } /* free tempolary channels */ diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 091d3fe56b4..47a29426192 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -85,7 +85,7 @@ static int act_new_exec(bContext *C, wmOperator *UNUSED(op)) PropertyRNA *prop; /* hook into UI */ - uiIDContextProperty(C, &ptr, &prop); + UI_context_active_but_prop_get_templateID(C, &ptr, &prop); if (prop) { bAction *action = NULL, *oldact = NULL; @@ -965,8 +965,11 @@ static int actkeys_clean_exec(bContext *C, wmOperator *op) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) + + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { + BKE_report(op->reports, RPT_ERROR, "Not implemented"); return OPERATOR_PASS_THROUGH; + } /* get cleaning threshold */ thresh = RNA_float_get(op->ptr, "threshold"); @@ -1025,15 +1028,18 @@ static void sample_action_keys(bAnimContext *ac) /* ------------------- */ -static int actkeys_sample_exec(bContext *C, wmOperator *UNUSED(op)) +static int actkeys_sample_exec(bContext *C, wmOperator *op) { bAnimContext ac; /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) + + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { + BKE_report(op->reports, RPT_ERROR, "Not implemented"); return OPERATOR_PASS_THROUGH; + } /* sample keyframes */ sample_action_keys(&ac); @@ -1138,8 +1144,11 @@ static int actkeys_expo_exec(bContext *C, wmOperator *op) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) + + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { + BKE_report(op->reports, RPT_ERROR, "Not implemented"); return OPERATOR_PASS_THROUGH; + } /* get handle setting mode */ mode = RNA_enum_get(op->ptr, "type"); @@ -1209,8 +1218,11 @@ static int actkeys_ipo_exec(bContext *C, wmOperator *op) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) + + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { + BKE_report(op->reports, RPT_ERROR, "Not implemented"); return OPERATOR_PASS_THROUGH; + } /* get handle setting mode */ mode = RNA_enum_get(op->ptr, "type"); @@ -1288,8 +1300,11 @@ static int actkeys_handletype_exec(bContext *C, wmOperator *op) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) + + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { + BKE_report(op->reports, RPT_ERROR, "Not implemented"); return OPERATOR_PASS_THROUGH; + } /* get handle setting mode */ mode = RNA_enum_get(op->ptr, "type"); @@ -1324,7 +1339,7 @@ void ACTION_OT_handle_type(wmOperatorType *ot) /* ******************** Set Keyframe-Type Operator *********************** */ -/* this function is responsible for setting interpolation mode for keyframes */ +/* this function is responsible for setting keyframe type for keyframes */ static void setkeytype_action_keys(bAnimContext *ac, short mode) { ListBase anim_data = {NULL, NULL}; @@ -1349,6 +1364,29 @@ static void setkeytype_action_keys(bAnimContext *ac, short mode) ANIM_animdata_freelist(&anim_data); } +/* this function is responsible for setting the keyframe type for Grease Pencil frames */ +static void setkeytype_gpencil_keys(bAnimContext *ac, short mode) +{ + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + + /* filter data */ + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + + /* loop through each layer */ + for (ale = anim_data.first; ale; ale = ale->next) { + if (ale->type == ANIMTYPE_GPLAYER) { + ED_gplayer_frames_keytype_set(ale->data, mode); + ale->update |= ANIM_UPDATE_DEPS; + } + } + + ANIM_animdata_update(ac, &anim_data); + ANIM_animdata_freelist(&anim_data); +} + /* ------------------- */ static int actkeys_keytype_exec(bContext *C, wmOperator *op) @@ -1359,14 +1397,22 @@ static int actkeys_keytype_exec(bContext *C, wmOperator *op) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) + + if (ac.datatype == ANIMCONT_MASK) { + BKE_report(op->reports, RPT_ERROR, "Not implemented for Masks"); return OPERATOR_PASS_THROUGH; + } /* get handle setting mode */ mode = RNA_enum_get(op->ptr, "type"); /* set handle type */ - setkeytype_action_keys(&ac, mode); + if (ac.datatype == ANIMCONT_GPENCIL) { + setkeytype_gpencil_keys(&ac, mode); + } + else { + setkeytype_action_keys(&ac, mode); + } /* set notifier that keyframe properties have changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL); diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c index b99419dec20..364434ee0ce 100644 --- a/source/blender/editors/space_action/action_ops.c +++ b/source/blender/editors/space_action/action_ops.c @@ -35,7 +35,6 @@ #include "DNA_space_types.h" -#include "BLI_utildefines.h" #include "ED_anim_api.h" #include "ED_markers.h" @@ -44,7 +43,6 @@ #include "action_intern.h" #include "RNA_access.h" -#include "RNA_define.h" #include "WM_api.h" #include "WM_types.h" diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index 7ca8968a705..5d0b34a2e0c 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -197,8 +197,8 @@ static void action_main_area_draw(const bContext *C, ARegion *ar) /* markers */ UI_view2d_view_orthoSpecial(ar, v2d, 1); - flag = (ac.markers && (ac.markers != &ac.scene->markers)) ? DRAW_MARKERS_LOCAL : 0; - draw_markers_time(C, flag); + flag = ((ac.markers && (ac.markers != &ac.scene->markers)) ? DRAW_MARKERS_LOCAL : 0) | DRAW_MARKERS_MARGIN; + ED_markers_draw(C, flag); /* preview range */ UI_view2d_view_ortho(v2d); diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index c8431d58bf5..01f0d1ae54f 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -32,7 +32,6 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" -#include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_windowmanager_types.h" @@ -61,7 +60,6 @@ #include "ED_space_api.h" #include "ED_sound.h" #include "ED_uvedit.h" -#include "ED_view3d.h" #include "ED_mball.h" #include "ED_logic.h" #include "ED_clip.h" @@ -122,7 +120,7 @@ void ED_spacetypes_init(void) ED_operatortypes_io(); ED_operatortypes_view2d(); - UI_buttons_operatortypes(); + ED_button_operatortypes(); /* register operators */ spacetypes = BKE_spacetypes_list(); @@ -155,6 +153,7 @@ void ED_spacemacros_init(void) ED_operatormacros_mask(); ED_operatormacros_sequencer(); ED_operatormacros_paint(); + ED_operatormacros_gpencil(); /* register dropboxes (can use macros) */ spacetypes = BKE_spacetypes_list(); @@ -318,7 +317,3 @@ void ED_spacetype_xxx(void) } /* ****************************** end template *********************** */ - - - - diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 524a42ba388..73091e7f261 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -1103,11 +1103,11 @@ void buttons_context_draw(const bContext *C, uiLayout *layout) uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT); block = uiLayoutGetBlock(row); - uiBlockSetEmboss(block, UI_EMBOSSN); - but = uiDefIconButBitC(block, ICONTOG, SB_PIN_CONTEXT, 0, ICON_UNPINNED, 0, 0, UI_UNIT_X, UI_UNIT_Y, &sbuts->flag, + UI_block_emboss_set(block, UI_EMBOSS_NONE); + but = uiDefIconButBitC(block, UI_BTYPE_ICON_TOGGLE, SB_PIN_CONTEXT, 0, ICON_UNPINNED, 0, 0, UI_UNIT_X, UI_UNIT_Y, &sbuts->flag, 0, 0, 0, 0, TIP_("Follow context or keep fixed datablock displayed")); - uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ - uiButSetFunc(but, pin_cb, NULL, NULL); + UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */ + UI_but_func_set(but, pin_cb, NULL, NULL); for (a = 0; a < path->len; a++) { ptr = &path->ptr[a]; diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index b651d684bf6..0b643cd7858 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -72,12 +72,12 @@ static int toolbox_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UN RNA_pointer_create(&sc->id, &RNA_SpaceProperties, sbuts, &ptr); - pup = uiPupMenuBegin(C, IFACE_("Align"), ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, IFACE_("Align"), ICON_NONE); + layout = UI_popup_menu_layout(pup); uiItemsEnumR(layout, &ptr, "align"); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } void BUTTONS_OT_toolbox(wmOperatorType *ot) @@ -176,7 +176,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_CANCELLED; } - uiFileBrowseContextProperty(C, &ptr, &prop); + UI_context_active_but_prop_get_filebrowser(C, &ptr, &prop); if (!prop) return OPERATOR_CANCELLED; @@ -186,6 +186,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event) /* useful yet irritating feature, Shift+Click to open the file * Alt+Click to browse a folder in the OS's browser */ if (event->shift || event->alt) { + wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true); PointerRNA props_ptr; if (event->alt) { @@ -195,9 +196,9 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event) } - WM_operator_properties_create(&props_ptr, "WM_OT_path_open"); + WM_operator_properties_create_ptr(&props_ptr, ot); RNA_string_set(&props_ptr, "filepath", str); - WM_operator_name_call(C, "WM_OT_path_open", WM_OP_EXEC_DEFAULT, &props_ptr); + WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &props_ptr); WM_operator_properties_free(&props_ptr); MEM_freeN(str); diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c index 020d477fc39..a67af289f59 100644 --- a/source/blender/editors/space_buttons/buttons_texture.c +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -61,7 +61,9 @@ #include "BKE_paint.h" #include "BKE_particle.h" #include "BKE_scene.h" -#include "BKE_freestyle.h" +#ifdef WITH_FREESTYLE +# include "BKE_freestyle.h" +#endif #include "RNA_access.h" @@ -256,7 +258,7 @@ static void buttons_texture_user_property_add(ListBase *users, ID *id, user->category = category; user->icon = icon; user->name = name; - user->index = BLI_countlist(users); + user->index = BLI_listbase_count(users); BLI_addtail(users, user); } @@ -273,7 +275,7 @@ static void buttons_texture_user_node_add(ListBase *users, ID *id, user->category = category; user->icon = icon; user->name = name; - user->index = BLI_countlist(users); + user->index = BLI_listbase_count(users); BLI_addtail(users, user); } @@ -468,7 +470,7 @@ void buttons_texture_context_compute(const bContext *C, SpaceButs *sbuts) } else { /* set one user as active based on active index */ - if (ct->index >= BLI_countlist(&ct->users)) + if (ct->index == BLI_listbase_count_ex(&ct->users, ct->index + 1)) ct->index = 0; ct->user = BLI_findlink(&ct->users, ct->index); @@ -576,9 +578,9 @@ static void template_texture_user_menu(bContext *C, uiLayout *layout, void *UNUS else BLI_snprintf(name, UI_MAX_NAME_STR, " %s", user->name); - but = uiDefIconTextBut(block, BUT, 0, user->icon, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, + but = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, user->icon, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, ""); - uiButSetNFunc(but, template_texture_select, MEM_dupallocN(user), NULL); + UI_but_funcN_set(but, template_texture_select, MEM_dupallocN(user), NULL); last_category = user->category; } @@ -620,9 +622,9 @@ void uiTemplateTextureUser(uiLayout *layout, bContext *C) } /* some cosmetic tweaks */ - uiButSetMenuFromPulldown(but); + UI_but_type_set_menu_from_pulldown(but); - but->flag &= ~UI_ICON_SUBMENU; + but->flag &= ~UI_BUT_ICON_SUBMENU; } /************************* Texture Show **************************/ @@ -675,9 +677,9 @@ void uiTemplateTextureShow(uiLayout *layout, bContext *C, PointerRNA *ptr, Prope uiBlock *block = uiLayoutGetBlock(layout); uiBut *but; - but = uiDefIconBut(block, BUT, 0, ICON_BUTS, 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_BUTS, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Show texture in texture tab"); - uiButSetFunc(but, template_texture_show, user->ptr.data, user->prop); + UI_but_func_set(but, template_texture_show, user->ptr.data, user->prop); } } diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 4d62f528915..a778df4b783 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -28,7 +28,6 @@ * \ingroup spbuttons */ - #include <string.h> #include <stdio.h> @@ -46,10 +45,6 @@ #include "WM_api.h" #include "WM_types.h" -#include "UI_resources.h" -#include "UI_view2d.h" - - #include "buttons_intern.h" /* own include */ /* ******************** default callbacks for buttons space ***************** */ diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c index 889613b5d13..f8299a8d335 100644 --- a/source/blender/editors/space_clip/clip_buttons.c +++ b/source/blender/editors/space_clip/clip_buttons.c @@ -69,26 +69,9 @@ /* Panels */ -static int clip_grease_pencil_panel_poll(const bContext *C, PanelType *UNUSED(pt)) +void ED_clip_buttons_register(ARegionType *UNUSED(art)) { - SpaceClip *sc = CTX_wm_space_clip(C); - return sc->view == SC_VIEW_CLIP; -} - -void ED_clip_buttons_register(ARegionType *art) -{ - PanelType *pt; - - pt = MEM_callocN(sizeof(PanelType), "spacetype clip panel gpencil"); - strcpy(pt->idname, "CLIP_PT_gpencil"); - strcpy(pt->label, N_("Grease Pencil")); - strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA); - pt->draw_header = ED_gpencil_panel_standard_header; - pt->draw = ED_gpencil_panel_standard; - pt->flag |= PNL_DEFAULT_CLOSED; - pt->poll = clip_grease_pencil_panel_poll; - BLI_addtail(&art->paneltypes, pt); } /********************* MovieClip Template ************************/ @@ -130,7 +113,7 @@ void uiTemplateMovieClip(uiLayout *layout, bContext *C, PointerRNA *ptr, const c row = uiLayoutRow(layout, false); block = uiLayoutGetBlock(row); - uiDefBut(block, LABEL, 0, IFACE_("File Path:"), 0, 19, 145, 19, NULL, 0, 0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("File Path:"), 0, 19, 145, 19, NULL, 0, 0, 0, 0, ""); row = uiLayoutRow(layout, false); split = uiLayoutSplit(row, 0.0f, false); @@ -183,10 +166,10 @@ void uiTemplateTrack(uiLayout *layout, PointerRNA *ptr, const char *propname) col = uiLayoutColumn(layout, true); block = uiLayoutGetBlock(col); - uiDefBut(block, TRACKPREVIEW, 0, "", 0, 0, UI_UNIT_X * 10, scopes->track_preview_height, scopes, 0, 0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_TRACK_PREVIEW, 0, "", 0, 0, UI_UNIT_X * 10, scopes->track_preview_height, scopes, 0, 0, 0, 0, ""); /* Resize grip. */ - uiDefIconButI(block, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.8f), + uiDefIconButI(block, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.8f), &scopes->track_preview_height, UI_UNIT_Y, UI_UNIT_Y * 20.0f, 0.0f, 0.0f, ""); } @@ -403,9 +386,9 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P else tip = TIP_("Marker is enabled at current frame"); - bt = uiDefIconButBitI(block, TOGN, MARKER_DISABLED, 0, ICON_RESTRICT_VIEW_OFF, 0, 0, UI_UNIT_X, UI_UNIT_Y, + bt = uiDefIconButBitI(block, UI_BTYPE_TOGGLE_N, MARKER_DISABLED, 0, ICON_RESTRICT_VIEW_OFF, 0, 0, UI_UNIT_X, UI_UNIT_Y, &cb->marker_flag, 0, 0, 1, 0, tip); - uiButSetNFunc(bt, marker_update_cb, cb, NULL); + UI_but_funcN_set(bt, marker_update_cb, cb, NULL); } else { int width, height, step, digits; @@ -417,7 +400,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P if (track->flag & TRACK_LOCKED) { uiLayoutSetActive(layout, false); block = uiLayoutAbsoluteBlock(layout); - uiDefBut(block, LABEL, 0, IFACE_("Track is locked"), 0, 0, UI_UNIT_X * 15.0f, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Track is locked"), 0, 0, UI_UNIT_X * 15.0f, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); return; } @@ -442,53 +425,53 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P cb->marker_flag = marker->flag; block = uiLayoutAbsoluteBlock(layout); - uiBlockSetHandleFunc(block, marker_block_handler, cb); - uiBlockSetNFunc(block, marker_update_cb, cb, NULL); + UI_block_func_handle_set(block, marker_block_handler, cb); + UI_block_funcN_set(block, marker_update_cb, cb, NULL); if (cb->marker_flag & MARKER_DISABLED) tip = TIP_("Marker is disabled at current frame"); else tip = TIP_("Marker is enabled at current frame"); - uiDefButBitI(block, OPTIONN, MARKER_DISABLED, B_MARKER_FLAG, IFACE_("Enabled"), 0.5 * UI_UNIT_X, 9.5 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, + uiDefButBitI(block, UI_BTYPE_CHECKBOX_N, MARKER_DISABLED, B_MARKER_FLAG, IFACE_("Enabled"), 0.5 * UI_UNIT_X, 9.5 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_flag, 0, 0, 0, 0, tip); col = uiLayoutColumn(layout, true); uiLayoutSetActive(col, (cb->marker_flag & MARKER_DISABLED) == 0); block = uiLayoutAbsoluteBlock(col); - uiBlockBeginAlign(block); + UI_block_align_begin(block); - uiDefBut(block, LABEL, 0, IFACE_("Position:"), 0, 10 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); - uiDefButF(block, NUM, B_MARKER_POS, IFACE_("X:"), 0.5 * UI_UNIT_X, 9 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_pos[0], + uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Position:"), 0, 10 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); + uiDefButF(block, UI_BTYPE_NUM, B_MARKER_POS, IFACE_("X:"), 0.5 * UI_UNIT_X, 9 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_pos[0], -10 * width, 10.0 * width, step, digits, TIP_("X-position of marker at frame in screen coordinates")); - uiDefButF(block, NUM, B_MARKER_POS, IFACE_("Y:"), 8.25 * UI_UNIT_X, 9 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_pos[1], + uiDefButF(block, UI_BTYPE_NUM, B_MARKER_POS, IFACE_("Y:"), 8.25 * UI_UNIT_X, 9 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_pos[1], -10 * height, 10.0 * height, step, digits, TIP_("Y-position of marker at frame in screen coordinates")); - uiDefBut(block, LABEL, 0, IFACE_("Offset:"), 0, 8 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); - uiDefButF(block, NUM, B_MARKER_OFFSET, IFACE_("X:"), 0.5 * UI_UNIT_X, 7 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->track_offset[0], + uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Offset:"), 0, 8 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); + uiDefButF(block, UI_BTYPE_NUM, B_MARKER_OFFSET, IFACE_("X:"), 0.5 * UI_UNIT_X, 7 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->track_offset[0], -10 * width, 10.0 * width, step, digits, TIP_("X-offset to parenting point")); - uiDefButF(block, NUM, B_MARKER_OFFSET, IFACE_("Y:"), 8.25 * UI_UNIT_X, 7 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->track_offset[1], + uiDefButF(block, UI_BTYPE_NUM, B_MARKER_OFFSET, IFACE_("Y:"), 8.25 * UI_UNIT_X, 7 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->track_offset[1], -10 * height, 10.0 * height, step, digits, TIP_("Y-offset to parenting point")); - uiDefBut(block, LABEL, 0, IFACE_("Pattern Area:"), 0, 6 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); - uiDefButF(block, NUM, B_MARKER_PAT_DIM, IFACE_("Width:"), 0.5 * UI_UNIT_X, 5 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_pat[0], 3.0f, + uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Pattern Area:"), 0, 6 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); + uiDefButF(block, UI_BTYPE_NUM, B_MARKER_PAT_DIM, IFACE_("Width:"), 0.5 * UI_UNIT_X, 5 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_pat[0], 3.0f, 10.0 * width, step, digits, TIP_("Width of marker's pattern in screen coordinates")); - uiDefButF(block, NUM, B_MARKER_PAT_DIM, IFACE_("Height:"), 0.5 * UI_UNIT_X, 4 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_pat[1], 3.0f, + uiDefButF(block, UI_BTYPE_NUM, B_MARKER_PAT_DIM, IFACE_("Height:"), 0.5 * UI_UNIT_X, 4 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_pat[1], 3.0f, 10.0 * height, step, digits, TIP_("Height of marker's pattern in screen coordinates")); - uiDefBut(block, LABEL, 0, IFACE_("Search Area:"), 0, 3 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); - uiDefButF(block, NUM, B_MARKER_SEARCH_POS, IFACE_("X:"), 0.5 * UI_UNIT_X, 2 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_search_pos[0], + uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Search Area:"), 0, 3 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); + uiDefButF(block, UI_BTYPE_NUM, B_MARKER_SEARCH_POS, IFACE_("X:"), 0.5 * UI_UNIT_X, 2 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_search_pos[0], -width, width, step, digits, TIP_("X-position of search at frame relative to marker's position")); - uiDefButF(block, NUM, B_MARKER_SEARCH_POS, IFACE_("Y:"), 8.25 * UI_UNIT_X, 2 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_search_pos[1], + uiDefButF(block, UI_BTYPE_NUM, B_MARKER_SEARCH_POS, IFACE_("Y:"), 8.25 * UI_UNIT_X, 2 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_search_pos[1], -height, height, step, digits, TIP_("Y-position of search at frame relative to marker's position")); - uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, IFACE_("Width:"), 0.5 * UI_UNIT_X, 1 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_search[0], 3.0f, + uiDefButF(block, UI_BTYPE_NUM, B_MARKER_SEARCH_DIM, IFACE_("Width:"), 0.5 * UI_UNIT_X, 1 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_search[0], 3.0f, 10.0 * width, step, digits, TIP_("Width of marker's search in screen coordinates")); - uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, IFACE_("Height:"), 0.5 * UI_UNIT_X, 0 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_search[1], 3.0f, + uiDefButF(block, UI_BTYPE_NUM, B_MARKER_SEARCH_DIM, IFACE_("Height:"), 0.5 * UI_UNIT_X, 0 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_search[1], 3.0f, 10.0 * height, step, digits, TIP_("Height of marker's search in screen coordinates")); - uiBlockEndAlign(block); + UI_block_align_end(block); } } diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index 2a457bf503f..4bf4c1e7baa 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -30,7 +30,6 @@ */ #include "DNA_movieclip_types.h" -#include "DNA_object_types.h" /* SELECT */ #include "DNA_scene_types.h" #include "BLI_utildefines.h" @@ -283,7 +282,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar) MovieTracking *tracking; MovieTrackingDopesheet *dopesheet; MovieTrackingDopesheetChannel *channel; - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_style_get(); uiBlock *block; int fontid = style->widget.uifont_id; int height; @@ -348,7 +347,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar) } /* second pass: widgets */ - block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); + block = UI_block_begin(C, ar, __func__, UI_EMBOSS); y = (float) CHANNEL_FIRST; /* get RNA properties (once) */ @@ -370,11 +369,11 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar) RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, &ptr); - uiBlockSetEmboss(block, UI_EMBOSSN); - uiDefIconButR_prop(block, ICONTOG, 1, icon, + UI_block_emboss_set(block, UI_EMBOSS_NONE); + uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 1, icon, v2d->cur.xmax - UI_UNIT_X - CHANNEL_PAD, y - UI_UNIT_Y / 2.0f, UI_UNIT_X, UI_UNIT_Y, &ptr, chan_prop_lock, 0, 0, 0, 0, 0, NULL); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); } /* adjust y-position for next one */ @@ -382,6 +381,6 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar) } glDisable(GL_BLEND); - uiEndBlock(C, block); - uiDrawBlock(C, block); + UI_block_end(C, block); + UI_block_draw(C, block); } diff --git a/source/blender/editors/space_clip/clip_dopesheet_ops.c b/source/blender/editors/space_clip/clip_dopesheet_ops.c index 7ae5eda7139..d2f2fdd0b46 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_ops.c +++ b/source/blender/editors/space_clip/clip_dopesheet_ops.c @@ -29,7 +29,6 @@ * \ingroup spclip */ -#include "DNA_object_types.h" /* SELECT */ #include "DNA_scene_types.h" #include "BLI_utildefines.h" diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index a35251e71ef..6f63979b8fa 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -63,7 +63,6 @@ #include "UI_resources.h" #include "UI_view2d.h" -#include "RNA_access.h" #include "BLF_api.h" diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index f25f035db32..89693a403fe 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -57,7 +57,6 @@ #include "BKE_tracking.h" #include "BKE_library.h" -#include "GPU_extensions.h" #include "IMB_colormanagement.h" #include "IMB_imbuf_types.h" diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c index 723c8bd144a..2c3b8acf672 100644 --- a/source/blender/editors/space_clip/clip_graph_draw.c +++ b/source/blender/editors/space_clip/clip_graph_draw.c @@ -50,7 +50,6 @@ #include "UI_resources.h" #include "UI_view2d.h" -#include "BLF_api.h" #include "clip_intern.h" // own include diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c index d1e2c770ade..2a2f15c94bb 100644 --- a/source/blender/editors/space_clip/clip_graph_ops.c +++ b/source/blender/editors/space_clip/clip_graph_ops.c @@ -45,8 +45,6 @@ #include "ED_screen.h" #include "ED_clip.h" -#include "UI_interface.h" - #include "RNA_access.h" #include "RNA_define.h" diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index 9f7bcae800a..9f9ac66de60 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -168,7 +168,7 @@ static void open_init(bContext *C, wmOperator *op) PropertyPointerRNA *pprop; op->customdata = pprop = MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA"); - uiIDContextProperty(C, &pprop->ptr, &pprop->prop); + UI_context_active_but_prop_get_templateID(C, &pprop->ptr, &pprop->prop); } static void open_cancel(bContext *UNUSED(C), wmOperator *op) @@ -1307,7 +1307,14 @@ static void proxy_endjob(void *pjv) if (pj->index_context) IMB_anim_index_rebuild_finish(pj->index_context, pj->stop); - BKE_movieclip_reload(pj->clip); + if (pj->clip->source == MCLIP_SRC_MOVIE) { + /* Timecode might have changed, so do a full reload to deal with this. */ + BKE_movieclip_reload(pj->clip); + } + else { + /* For image sequences we'll preserve original cache. */ + BKE_movieclip_clear_proxy_cache(pj->clip); + } WM_main_add_notifier(NC_MOVIECLIP | ND_DISPLAY, pj->clip); } diff --git a/source/blender/editors/space_clip/clip_toolbar.c b/source/blender/editors/space_clip/clip_toolbar.c index 55b78219770..608c1136070 100644 --- a/source/blender/editors/space_clip/clip_toolbar.c +++ b/source/blender/editors/space_clip/clip_toolbar.c @@ -242,7 +242,7 @@ static void clip_panel_operator_redo(const bContext *C, Panel *pa) uiLayoutSetEnabled(pa->layout, false); /* note, blockfunc is a default but->func, use Handle func to allow button callbacks too */ - uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, op); + UI_block_func_handle_set(block, ED_undo_operator_repeat_cb_evt, op); clip_panel_operator_redo_operator(C, pa, op); } diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c index a79ac1f7b82..5f919c9b51d 100644 --- a/source/blender/editors/space_clip/clip_utils.c +++ b/source/blender/editors/space_clip/clip_utils.c @@ -30,12 +30,10 @@ */ #include "DNA_scene_types.h" -#include "DNA_object_types.h" /* SELECT */ #include "MEM_guardedalloc.h" #include "BLI_utildefines.h" -#include "BLI_math.h" #include "BLI_listbase.h" #include "BLI_string.h" @@ -54,8 +52,6 @@ #include "ED_screen.h" #include "ED_clip.h" -#include "RNA_access.h" -#include "RNA_define.h" #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index a797a60f74c..fc2c0d3d45c 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -55,7 +55,7 @@ #include "ED_screen.h" #include "ED_clip.h" #include "ED_transform.h" -#include "ED_uvedit.h" /* just for draw_image_cursor */ +#include "ED_uvedit.h" /* just for ED_image_draw_cursor */ #include "IMB_imbuf.h" @@ -420,6 +420,9 @@ static void clip_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn) clip_scopes_check_gpencil_change(sa); ED_area_tag_redraw(sa); } + else if (wmn->data & ND_GPENCIL_EDITMODE) { + ED_area_tag_redraw(sa); + } break; } } @@ -1159,7 +1162,7 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar) /* if tracking is in progress, we should synchronize framenr from clipuser * so latest tracked frame would be shown */ if (clip && clip->tracking_context) - BKE_tracking_context_sync_user(clip->tracking_context, &sc->user); + BKE_autotrack_context_sync_user(clip->tracking_context, &sc->user); if (sc->flag & SC_LOCK_SELECTION) { ImBuf *tmpibuf = NULL; @@ -1218,7 +1221,7 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar) glScalef(zoomx, zoomy, 0); glMultMatrixf(sc->stabmat); glScalef(width, height, 0); - draw_image_cursor(ar, sc->cursor); + ED_image_draw_cursor(ar, sc->cursor); glPopMatrix(); } @@ -1245,6 +1248,8 @@ static void clip_main_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), AR case NC_GPENCIL: if (wmn->action == NA_EDITED) ED_region_tag_redraw(ar); + else if (wmn->data & ND_GPENCIL_EDITMODE) + ED_region_tag_redraw(ar); break; } } @@ -1495,7 +1500,7 @@ static void clip_properties_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(s /* context changes */ switch (wmn->category) { case NC_GPENCIL: - if (wmn->data == ND_DATA) + if (ELEM(wmn->data, ND_DATA, ND_GPENCIL_EDITMODE)) ED_region_tag_redraw(ar); break; case NC_BRUSH: diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index fb6b1a0033c..742e58d80dd 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -41,7 +41,6 @@ #include "BLI_utildefines.h" #include "BLI_math.h" #include "BLI_listbase.h" -#include "BLI_rect.h" #include "BLI_blenlib.h" #include "BKE_main.h" @@ -65,7 +64,6 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#include "UI_interface.h" #include "RNA_access.h" #include "RNA_define.h" @@ -74,7 +72,6 @@ #include "PIL_time.h" -#include "UI_view2d.h" #include "clip_intern.h" // own include @@ -1083,7 +1080,7 @@ void CLIP_OT_slide_marker(wmOperatorType *ot) /********************** track operator *********************/ typedef struct TrackMarkersJob { - struct MovieTrackingContext *context; /* tracking context */ + struct AutoTrackContext *context; /* tracking context */ int sfra, efra, lastfra; /* Start, end and recently tracked frames */ int backwards; /* Backwards tracking flag */ MovieClip *clip; /* Clip which is tracking */ @@ -1231,7 +1228,7 @@ static int track_markers_initjob(bContext *C, TrackMarkersJob *tmj, int backward tmj->delay /= 2; } - tmj->context = BKE_tracking_context_new(clip, &sc->user, backwards, 1); + tmj->context = BKE_autotrack_context_new(clip, &sc->user, backwards, 1); clip->tracking_context = tmj->context; @@ -1265,14 +1262,14 @@ static void track_markers_startjob(void *tmv, short *stop, short *do_update, flo double start_time = PIL_check_seconds_timer(), exec_time; - if (!BKE_tracking_context_step(tmj->context)) + if (!BKE_autotrack_context_step(tmj->context)) break; exec_time = PIL_check_seconds_timer() - start_time; if (tmj->delay > (float)exec_time) PIL_sleep_ms(tmj->delay - (float)exec_time); } - else if (!BKE_tracking_context_step(tmj->context)) + else if (!BKE_autotrack_context_step(tmj->context)) break; *do_update = true; @@ -1296,7 +1293,7 @@ static void track_markers_updatejob(void *tmv) { TrackMarkersJob *tmj = (TrackMarkersJob *)tmv; - BKE_tracking_context_sync(tmj->context); + BKE_autotrack_context_sync(tmj->context); } static void track_markers_endjob(void *tmv) @@ -1310,8 +1307,8 @@ static void track_markers_endjob(void *tmv) ED_update_for_newframe(tmj->main, tmj->scene, 0); } - BKE_tracking_context_sync(tmj->context); - BKE_tracking_context_finish(tmj->context); + BKE_autotrack_context_sync(tmj->context); + BKE_autotrack_context_finish(tmj->context); WM_main_add_notifier(NC_SCENE | ND_FRAME, tmj->scene); } @@ -1319,7 +1316,7 @@ static void track_markers_endjob(void *tmv) static void track_markers_freejob(void *tmv) { TrackMarkersJob *tmj = (TrackMarkersJob *)tmv; - BKE_tracking_context_free(tmj->context); + BKE_autotrack_context_free(tmj->context); MEM_freeN(tmj); } @@ -1328,7 +1325,7 @@ static int track_markers_exec(bContext *C, wmOperator *op) SpaceClip *sc; MovieClip *clip; Scene *scene = CTX_data_scene(C); - struct MovieTrackingContext *context; + struct AutoTrackContext *context; MovieClipUser *user, fake_user = {0}; int framenr, sfra, efra; const bool backwards = RNA_boolean_get(op->ptr, "backwards"); @@ -1388,10 +1385,10 @@ static int track_markers_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; /* do not disable tracks due to threshold when tracking frame-by-frame */ - context = BKE_tracking_context_new(clip, user, backwards, sequence); + context = BKE_autotrack_context_new(clip, user, backwards, sequence); while (framenr != efra) { - if (!BKE_tracking_context_step(context)) + if (!BKE_autotrack_context_step(context)) break; if (backwards) framenr--; @@ -1401,9 +1398,9 @@ static int track_markers_exec(bContext *C, wmOperator *op) break; } - BKE_tracking_context_sync(context); - BKE_tracking_context_finish(context); - BKE_tracking_context_free(context); + BKE_autotrack_context_sync(context); + BKE_autotrack_context_finish(context); + BKE_autotrack_context_free(context); /* update scene current frame to the lastes tracked frame */ scene->r.cfra = BKE_movieclip_remap_clip_to_scene_frame(clip, framenr); diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c index 860d9dc6b3c..bc6ac507f03 100644 --- a/source/blender/editors/space_clip/tracking_select.c +++ b/source/blender/editors/space_clip/tracking_select.c @@ -36,7 +36,6 @@ #include "BLI_utildefines.h" #include "BLI_math.h" -#include "BLI_listbase.h" #include "BLI_rect.h" #include "BLI_lasso.h" @@ -49,16 +48,9 @@ #include "ED_screen.h" #include "ED_clip.h" -#include "IMB_imbuf_types.h" -#include "IMB_imbuf.h" - -#include "UI_interface.h" - #include "RNA_access.h" #include "RNA_define.h" -#include "PIL_time.h" - #include "UI_view2d.h" #include "clip_intern.h" // own include diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c index 635d5ea07fd..d206ce4699e 100644 --- a/source/blender/editors/space_console/console_draw.c +++ b/source/blender/editors/space_console/console_draw.c @@ -30,7 +30,6 @@ #include <sys/stat.h> #include <limits.h> -#include "BLF_api.h" #include "BLI_blenlib.h" #include "BLI_utildefines.h" diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index b44e942527c..2d5e5c6e0f2 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -95,7 +95,7 @@ static void console_scrollback_limit(SpaceConsole *sc) if (U.scrollback < 32) U.scrollback = 256; // XXX - save in user defaults - for (tot = BLI_countlist(&sc->scrollback); tot > U.scrollback; tot--) + for (tot = BLI_listbase_count(&sc->scrollback); tot > U.scrollback; tot--) console_scrollback_free(sc, sc->scrollback.first); } @@ -136,7 +136,7 @@ static void console_lb_debug__internal(ListBase *lb) { ConsoleLine *cl; - printf("%d: ", BLI_countlist(lb)); + printf("%d: ", BLI_listbase_count(lb)); for (cl = lb->first; cl; cl = cl->next) printf("<%s> ", cl->line); printf("\n"); diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 3e099b43a4b..2b2fa04c4a6 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -47,7 +47,6 @@ #include "BKE_global.h" #include "BKE_main.h" -#include "BLF_api.h" #include "BLF_translation.h" #include "IMB_imbuf_types.h" @@ -67,7 +66,6 @@ #include "WM_types.h" -#include "fsmenu.h" #include "filelist.h" #include "file_intern.h" // own include @@ -116,7 +114,7 @@ void file_draw_buttons(const bContext *C, ARegion *ar) /* Initialize UI block. */ BLI_snprintf(uiblockstr, sizeof(uiblockstr), "win %p", (void *)ar); - block = uiBeginBlock(C, ar, uiblockstr, UI_EMBOSS); + block = UI_block_begin(C, ar, uiblockstr, UI_EMBOSS); /* exception to make space for collapsed region icon */ for (artmp = CTX_wm_area(C)->regionbase.first; artmp; artmp = artmp->next) { @@ -128,12 +126,9 @@ void file_draw_buttons(const bContext *C, ARegion *ar) } /* Is there enough space for the execute / cancel buttons? */ - loadbutton = UI_GetStringWidth(sfile->params->title) + btn_margin; - if (loadbutton < btn_minw) { - loadbutton = MAX2(btn_minw, - btn_margin + UI_GetStringWidth(params->title)); - } - + loadbutton = UI_fontstyle_string_width(params->title) + btn_margin; + CLAMP_MIN(loadbutton, btn_minw); + if (available_w <= loadbutton + separator + input_minw || params->title[0] == 0) { loadbutton = 0; } @@ -155,80 +150,80 @@ void file_draw_buttons(const bContext *C, ARegion *ar) if (available_w > 0) { int overwrite_alert = file_draw_check_exists(sfile); /* callbacks for operator check functions */ - uiBlockSetFunc(block, file_draw_check_cb, NULL, NULL); + UI_block_func_set(block, file_draw_check_cb, NULL, NULL); - but = uiDefBut(block, TEX, -1, "", + but = uiDefBut(block, UI_BTYPE_TEXT, -1, "", min_x, line1_y, line1_w - chan_offs, btn_h, params->dir, 0.0, (float)FILE_MAX, 0, 0, TIP_("File path")); - uiButSetCompleteFunc(but, autocomplete_directory, NULL); - uiButSetFlag(but, UI_BUT_NO_UTF8); - uiButClearFlag(but, UI_BUT_UNDO); - uiButSetNFunc(but, file_directory_enter_handle, NULL, but); + UI_but_func_complete_set(but, autocomplete_directory, NULL); + UI_but_flag_enable(but, UI_BUT_NO_UTF8); + UI_but_flag_disable(but, UI_BUT_UNDO); + UI_but_funcN_set(but, file_directory_enter_handle, NULL, but); /* TODO, directory editing is non-functional while a library is loaded * until this is properly supported just disable it. */ if (sfile->files && filelist_lib(sfile->files)) - uiButSetFlag(but, UI_BUT_DISABLED); + UI_but_flag_enable(but, UI_BUT_DISABLED); if ((params->flag & FILE_DIRSEL_ONLY) == 0) { - but = uiDefBut(block, TEX, -1, "", + but = uiDefBut(block, UI_BTYPE_TEXT, -1, "", min_x, line2_y, line2_w - chan_offs, btn_h, params->file, 0.0, (float)FILE_MAXFILE, 0, 0, TIP_(overwrite_alert ? N_("File name, overwrite existing") : N_("File name"))); - uiButSetCompleteFunc(but, autocomplete_file, NULL); - uiButSetFlag(but, UI_BUT_NO_UTF8); - uiButClearFlag(but, UI_BUT_UNDO); + UI_but_func_complete_set(but, autocomplete_file, NULL); + UI_but_flag_enable(but, UI_BUT_NO_UTF8); + UI_but_flag_disable(but, UI_BUT_UNDO); /* silly workaround calling NFunc to ensure this does not get called * immediate ui_apply_but_func but only after button deactivates */ - uiButSetNFunc(but, file_filename_enter_handle, NULL, but); + UI_but_funcN_set(but, file_filename_enter_handle, NULL, but); /* check if this overrides a file and if the operator option is used */ if (overwrite_alert) { - uiButSetFlag(but, UI_BUT_REDALERT); + UI_but_flag_enable(but, UI_BUT_REDALERT); } } /* clear func */ - uiBlockSetFunc(block, NULL, NULL, NULL); + UI_block_func_set(block, NULL, NULL, NULL); } /* Filename number increment / decrement buttons. */ if (fnumbuttons && (params->flag & FILE_DIRSEL_ONLY) == 0) { - uiBlockBeginAlign(block); - but = uiDefIconButO(block, BUT, "FILE_OT_filenum", 0, ICON_ZOOMOUT, + UI_block_align_begin(block); + but = uiDefIconButO(block, UI_BTYPE_BUT, "FILE_OT_filenum", 0, ICON_ZOOMOUT, min_x + line2_w + separator - chan_offs, line2_y, btn_fn_w, btn_h, TIP_("Decrement the filename number")); - RNA_int_set(uiButGetOperatorPtrRNA(but), "increment", -1); + RNA_int_set(UI_but_operator_ptr_get(but), "increment", -1); - but = uiDefIconButO(block, BUT, "FILE_OT_filenum", 0, ICON_ZOOMIN, + but = uiDefIconButO(block, UI_BTYPE_BUT, "FILE_OT_filenum", 0, ICON_ZOOMIN, min_x + line2_w + separator + btn_fn_w - chan_offs, line2_y, btn_fn_w, btn_h, TIP_("Increment the filename number")); - RNA_int_set(uiButGetOperatorPtrRNA(but), "increment", 1); - uiBlockEndAlign(block); + RNA_int_set(UI_but_operator_ptr_get(but), "increment", 1); + UI_block_align_end(block); } /* Execute / cancel buttons. */ if (loadbutton) { /* params->title is already translated! */ - uiDefButO(block, BUT, "FILE_OT_execute", WM_OP_EXEC_REGION_WIN, params->title, + uiDefButO(block, UI_BTYPE_BUT, "FILE_OT_execute", WM_OP_EXEC_REGION_WIN, params->title, max_x - loadbutton, line1_y, loadbutton, btn_h, ""); - uiDefButO(block, BUT, "FILE_OT_cancel", WM_OP_EXEC_REGION_WIN, IFACE_("Cancel"), + uiDefButO(block, UI_BTYPE_BUT, "FILE_OT_cancel", WM_OP_EXEC_REGION_WIN, IFACE_("Cancel"), max_x - loadbutton, line2_y, loadbutton, btn_h, ""); } - uiEndBlock(C, block); - uiDrawBlock(C, block); + UI_block_end(C, block); + UI_block_draw(C, block); } static void draw_tile(int sx, int sy, int width, int height, int colorid, int shade) { UI_ThemeColorShade(colorid, shade); - uiSetRoundBox(UI_CNR_ALL); - uiRoundBox((float)sx, (float)(sy - height), (float)(sx + width), (float)sy, 5.0f); + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox((float)sx, (float)(sy - height), (float)(sx + width), (float)sy, 5.0f); } @@ -281,16 +276,16 @@ static void file_draw_icon(uiBlock *block, char *path, int sx, int sy, int icon, /*if (icon == ICON_FILE_BLANK) alpha = 0.375f;*/ - but = uiDefIconBut(block, LABEL, 0, icon, x, y, width, height, NULL, 0.0f, 0.0f, 0.0f, 0.0f, ""); + but = uiDefIconBut(block, UI_BTYPE_LABEL, 0, icon, x, y, width, height, NULL, 0.0f, 0.0f, 0.0f, 0.0f, ""); if (drag) - uiButSetDragPath(but, path); + UI_but_drag_set_path(but, path); } static void file_draw_string(int sx, int sy, const char *string, float width, int height, short align) { - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_style_get(); uiFontStyle fs = style->widgetlabel; rcti rect; char fname[FILE_MAXFILE]; @@ -300,13 +295,13 @@ static void file_draw_string(int sx, int sy, const char *string, float width, in BLI_strncpy(fname, string, FILE_MAXFILE); file_shorten_string(fname, width + 1.0f, 0); - /* no text clipping needed, uiStyleFontDraw does it but is a bit too strict (for buttons it works) */ + /* no text clipping needed, UI_fontstyle_draw does it but is a bit too strict (for buttons it works) */ rect.xmin = sx; rect.xmax = (int)(sx + ceil(width + 4.0f)); rect.ymin = sy - height; rect.ymax = sy; - uiStyleFontDraw(&fs, &rect, fname); + UI_fontstyle_draw(&fs, &rect, fname); } void file_calc_previews(const bContext *C, ARegion *ar) @@ -362,7 +357,7 @@ static void file_draw_preview(uiBlock *block, struct direntry *file, int sx, int /* shadow */ if (dropshadow) - uiDrawBoxShadow(220, (float)xco, (float)yco, (float)(xco + ex), (float)(yco + ey)); + UI_draw_box_shadow(220, (float)xco, (float)yco, (float)(xco + ex), (float)(yco + ey)); glEnable(GL_BLEND); @@ -378,8 +373,8 @@ static void file_draw_preview(uiBlock *block, struct direntry *file, int sx, int /* dragregion */ if (drag) { - but = uiDefBut(block, LABEL, 0, "", xco, yco, ex, ey, NULL, 0.0, 0.0, 0, 0, ""); - uiButSetDragImage(but, file->path, get_file_icon(file), imb, scale); + but = uiDefBut(block, UI_BTYPE_LABEL, 0, "", xco, yco, ex, ey, NULL, 0.0, 0.0, 0, 0, ""); + UI_but_drag_set_image(but, file->path, get_file_icon(file), imb, scale); } glDisable(GL_BLEND); @@ -470,7 +465,7 @@ void file_draw_list(const bContext *C, ARegion *ar) struct FileList *files = sfile->files; struct direntry *file; ImBuf *imb; - uiBlock *block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); + uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS); int numfiles; int numfiles_layout; int sx, sy; @@ -526,7 +521,7 @@ void file_draw_list(const bContext *C, ARegion *ar) draw_tile(sx, sy - 1, layout->tile_w + 4, sfile->layout->tile_h + layout->tile_border_y, colorid, shade); } } - uiSetRoundBox(UI_CNR_NONE); + UI_draw_roundbox_corner_set(UI_CNR_NONE); /* don't drag parent or refresh items */ do_drag = !(STREQ(file->relname, "..") || STREQ(file->relname, ".")); @@ -549,12 +544,28 @@ void file_draw_list(const bContext *C, ARegion *ar) UI_ThemeColor4(TH_TEXT); if (file->selflag & EDITING_FILE) { - uiBut *but = uiDefBut(block, TEX, 1, "", sx, sy - layout->tile_h - 0.15f * UI_UNIT_X, - textwidth, textheight, sfile->params->renameedit, 1.0f, (float)sizeof(sfile->params->renameedit), 0, 0, ""); - uiButSetRenameFunc(but, renamebutton_cb, file); - uiButSetFlag(but, UI_BUT_NO_UTF8); /* allow non utf8 names */ - uiButClearFlag(but, UI_BUT_UNDO); - if (false == uiButActiveOnly(C, ar, block, but)) { + uiBut *but; + short width; + + if (params->display == FILE_SHORTDISPLAY) { + width = layout->tile_w - (ICON_DEFAULT_WIDTH_SCALE + 0.2f * UI_UNIT_X); + } + else if (params->display == FILE_LONGDISPLAY) { + width = layout->column_widths[COLUMN_NAME] + layout->column_widths[COLUMN_MODE1] + + layout->column_widths[COLUMN_MODE2] + layout->column_widths[COLUMN_MODE3] + + (column_space * 3.5f); + } + else { + BLI_assert(params->display == FILE_IMGDISPLAY); + width = textwidth; + } + + but = uiDefBut(block, UI_BTYPE_TEXT, 1, "", sx, sy - layout->tile_h - 0.15f * UI_UNIT_X, + width, textheight, sfile->params->renameedit, 1.0f, (float)sizeof(sfile->params->renameedit), 0, 0, ""); + UI_but_func_rename_set(but, renamebutton_cb, file); + UI_but_flag_enable(but, UI_BUT_NO_UTF8); /* allow non utf8 names */ + UI_but_flag_disable(but, UI_BUT_UNDO); + if (false == UI_but_active_only(C, ar, block, but)) { file->selflag &= ~EDITING_FILE; } } @@ -602,7 +613,7 @@ void file_draw_list(const bContext *C, ARegion *ar) } } - uiEndBlock(C, block); - uiDrawBlock(C, block); + UI_block_end(C, block); + UI_block_draw(C, block); } diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 27d6fabba4e..df3f989c3a2 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -34,6 +34,7 @@ #include "BLO_readfile.h" +#include "BKE_appdir.h" #include "BKE_context.h" #include "BKE_screen.h" #include "BKE_global.h" @@ -472,7 +473,7 @@ static int bookmark_add_exec(bContext *C, wmOperator *UNUSED(op)) char name[FILE_MAX]; fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir, FS_INSERT_SAVE); - BLI_make_file_string("/", name, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); + BLI_make_file_string("/", name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); fsmenu_write_file(fsmenu, name); } @@ -504,7 +505,7 @@ static int bookmark_delete_exec(bContext *C, wmOperator *op) char name[FILE_MAX]; fsmenu_remove_entry(fsmenu, FS_CATEGORY_BOOKMARKS, index); - BLI_make_file_string("/", name, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); + BLI_make_file_string("/", name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); fsmenu_write_file(fsmenu, name); ED_area_tag_redraw(sa); } @@ -540,7 +541,7 @@ static int reset_recent_exec(bContext *C, wmOperator *UNUSED(op)) while (fsmenu_get_entry(fsmenu, FS_CATEGORY_RECENT, 0) != NULL) { fsmenu_remove_entry(fsmenu, FS_CATEGORY_RECENT, 0); } - BLI_make_file_string("/", name, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); + BLI_make_file_string("/", name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); fsmenu_write_file(fsmenu, name); ED_area_tag_redraw(sa); @@ -821,7 +822,7 @@ int file_exec(bContext *C, wmOperator *exec_op) fsmenu_insert_entry(fsmenu_get(), FS_CATEGORY_RECENT, sfile->params->dir, FS_INSERT_SAVE | FS_INSERT_FIRST); } - BLI_make_file_string(G.main->name, filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); + BLI_make_file_string(G.main->name, filepath, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); fsmenu_write_file(fsmenu_get(), filepath); WM_event_fileselect_event(wm, op, EVT_FILESELECT_EXEC); @@ -1197,7 +1198,7 @@ static void file_expand_directory(bContext *C) else if (sfile->params->dir[0] == '~') { char tmpstr[sizeof(sfile->params->dir) - 1]; BLI_strncpy(tmpstr, sfile->params->dir + 1, sizeof(tmpstr)); - BLI_join_dirfile(sfile->params->dir, sizeof(sfile->params->dir), BLI_getDefaultDocumentFolder(), tmpstr); + BLI_join_dirfile(sfile->params->dir, sizeof(sfile->params->dir), BKE_appdir_folder_default(), tmpstr); } else if (sfile->params->dir[0] == '\0') @@ -1498,6 +1499,15 @@ static int file_rename_poll(bContext *C) SpaceFile *sfile = CTX_wm_space_file(C); if (sfile && sfile->params) { + int idx = sfile->params->active_file; + + if (idx >= 0) { + struct direntry *file = filelist_file(sfile->files, idx); + if (STREQ(file->relname, "..") || STREQ(file->relname, ".")) { + poll = 0; + } + } + if (sfile->params->active_file < 0) { poll = 0; } diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c index 8fad17e1210..c224da721fa 100644 --- a/source/blender/editors/space_file/file_panels.c +++ b/source/blender/editors/space_file/file_panels.c @@ -114,16 +114,16 @@ static void file_panel_category(const bContext *C, Panel *pa, FSMenuCategory cat BLI_strncpy(dir, entry, FILE_MAX); /* create list item */ - but = uiDefIconTextButS(block, LISTROW, 0, icon, dir, 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, nr, 0, i, 0, 0, entry); - uiButSetFunc(but, file_panel_cb, entry, NULL); - uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ - uiButSetDrawFlag(but, UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT); + but = uiDefIconTextButS(block, UI_BTYPE_LISTROW, 0, icon, dir, 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, nr, 0, i, 0, 0, entry); + UI_but_func_set(but, file_panel_cb, entry, NULL); + UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */ + UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT); /* create delete button */ if (allow_delete && fsmenu_can_save(fsmenu, category, i)) { - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); uiItemIntO(layout, "", ICON_X, "FILE_OT_bookmark_delete", "index", i); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); } } } @@ -218,11 +218,11 @@ static void file_panel_operator(const bContext *C, Panel *pa) wmOperator *op = sfile->op; // int empty = 1, flag; - uiBlockSetFunc(uiLayoutGetBlock(pa->layout), file_draw_check_cb, NULL, NULL); + UI_block_func_set(uiLayoutGetBlock(pa->layout), file_draw_check_cb, NULL, NULL); uiLayoutOperatorButs(C, pa->layout, op, file_panel_check_prop, '\0', UI_LAYOUT_OP_SHOW_EMPTY); - uiBlockSetFunc(uiLayoutGetBlock(pa->layout), NULL, NULL, NULL); + UI_block_func_set(uiLayoutGetBlock(pa->layout), NULL, NULL, NULL); } void file_panels_register(ARegionType *art) diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 871abbda48a..ec57d08c21e 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -298,21 +298,21 @@ static bool is_hidden_file(const char *filename, short hide_dot) if (hide_dot) { if (filename[0] == '.' && filename[1] != '.' && filename[1] != 0) { - is_hidden = 1; /* ignore .file */ + is_hidden = true; /* ignore .file */ } else if (((filename[0] == '.') && (filename[1] == 0))) { - is_hidden = 1; /* ignore . */ + is_hidden = true; /* ignore . */ } else { int len = strlen(filename); if ((len > 0) && (filename[len - 1] == '~')) { - is_hidden = 1; /* ignore file~ */ + is_hidden = true; /* ignore file~ */ } } } else { if (((filename[0] == '.') && (filename[1] == 0))) { - is_hidden = 1; /* ignore . */ + is_hidden = true; /* ignore . */ } } return is_hidden; @@ -323,16 +323,16 @@ static bool is_filtered_file(struct direntry *file, const char *UNUSED(dir), uns bool is_filtered = false; if (filter) { if (file->flags & filter) { - is_filtered = 1; + is_filtered = true; } else if (file->type & S_IFDIR) { if (filter & FOLDERFILE) { - is_filtered = 1; + is_filtered = true; } } } else { - is_filtered = 1; + is_filtered = true; } return is_filtered && !is_hidden_file(file->relname, hide_dot); } diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index afe3f29e9bc..bdeb6e337d2 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -58,6 +58,7 @@ #include "BLI_fileops_types.h" #include "BLI_fnmatch.h" +#include "BKE_appdir.h" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_main.h" @@ -253,7 +254,7 @@ short ED_fileselect_set_params(SpaceFile *sfile) BLI_split_dir_part(G.main->name, sfile->params->dir, sizeof(sfile->params->dir)); } else { - const char *doc_path = BLI_getDefaultDocumentFolder(); + const char *doc_path = BKE_appdir_folder_default(); if (doc_path) { BLI_strncpy(sfile->params->dir, doc_path, sizeof(sfile->params->dir)); } @@ -444,8 +445,8 @@ float file_shorten_string(char *string, float w, int front) float file_string_width(const char *str) { - uiStyle *style = UI_GetStyle(); - uiStyleFontSet(&style->widget); + uiStyle *style = UI_style_get(); + UI_fontstyle_set(&style->widget); return BLF_width(style->widget.uifont_id, str, BLF_DRAW_STR_DUMMY_MAX); } @@ -454,13 +455,13 @@ float file_font_pointsize(void) #if 0 float s; char tmp[2] = "X"; - uiStyle *style = UI_GetStyle(); - uiStyleFontSet(&style->widget); + uiStyle *style = UI_style_get(); + UI_fontstyle_set(&style->widget); s = BLF_height(style->widget.uifont_id, tmp); return style->widget.points; #else - uiStyle *style = UI_GetStyle(); - uiStyleFontSet(&style->widget); + uiStyle *style = UI_style_get(); + UI_fontstyle_set(&style->widget); return style->widget.points * UI_DPI_FAC; #endif } @@ -662,7 +663,7 @@ int autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v)) dir = opendir(dirname); if (dir) { - AutoComplete *autocpl = autocomplete_begin(str, FILE_MAX); + AutoComplete *autocpl = UI_autocomplete_begin(str, FILE_MAX); while ((de = readdir(dir)) != NULL) { if (strcmp(".", de->d_name) == 0 || strcmp("..", de->d_name) == 0) { @@ -676,14 +677,14 @@ int autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v)) if (BLI_stat(path, &status) == 0) { if (S_ISDIR(status.st_mode)) { /* is subdir */ - autocomplete_do_name(autocpl, path); + UI_autocomplete_update_name(autocpl, path); } } } } closedir(dir); - match = autocomplete_end(autocpl, str); + match = UI_autocomplete_end(autocpl, str); if (match) { if (match == AUTOCOMPLETE_FULL_MATCH) { BLI_add_slash(str); @@ -705,17 +706,17 @@ int autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v)) /* search if str matches the beginning of name */ if (str[0] && sfile->files) { - AutoComplete *autocpl = autocomplete_begin(str, FILE_MAX); + AutoComplete *autocpl = UI_autocomplete_begin(str, FILE_MAX); int nentries = filelist_numfiles(sfile->files); int i; for (i = 0; i < nentries; ++i) { struct direntry *file = filelist_file(sfile->files, i); if (file && (S_ISREG(file->type) || S_ISDIR(file->type))) { - autocomplete_do_name(autocpl, file->relname); + UI_autocomplete_update_name(autocpl, file->relname); } } - match = autocomplete_end(autocpl, str); + match = UI_autocomplete_end(autocpl, str); } return match; diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c index c117b8c2d3e..4ab9bc6a849 100644 --- a/source/blender/editors/space_file/fsmenu.c +++ b/source/blender/editors/space_file/fsmenu.c @@ -367,7 +367,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) /* As 10.4 doesn't provide proper API to retrieve the favorite places, * assume they are the standard ones - * TODO : replace hardcoded paths with proper BLI_get_folder calls */ + * TODO : replace hardcoded paths with proper BKE_appdir_folder_id calls */ home = getenv("HOME"); if (read_bookmarks && home) { BLI_snprintf(line, sizeof(line), "%s/", home); @@ -447,7 +447,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) /* Exclude "all my files" as it makes no sense in blender fileselector */ /* Exclude "airdrop" if wlan not active as it would show "" ) */ if (!strstr(line, "myDocuments.cannedSearch") && (*line != '\0')) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_APPEND_LAST); } CFRelease(pathString); diff --git a/source/blender/editors/space_file/fsmenu.h b/source/blender/editors/space_file/fsmenu.h index 01bd4e95afa..831ec138474 100644 --- a/source/blender/editors/space_file/fsmenu.h +++ b/source/blender/editors/space_file/fsmenu.h @@ -47,7 +47,8 @@ typedef enum FSMenuCategory { typedef enum FSMenuInsert { FS_INSERT_SORTED = (1 << 0), FS_INSERT_SAVE = (1 << 1), - FS_INSERT_FIRST = (1 << 2) /* moves the item to the front of the list when its not already there */ + FS_INSERT_FIRST = (1 << 2), /* moves the item to the front of the list when its not already there */ + FS_APPEND_LAST = (1 << 3) /* just append to preseve delivered order */ } FSMenuInsert; struct FSMenu; diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index d5be04cff20..fa65053ca8e 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -39,8 +39,8 @@ #include "BLI_utildefines.h" #include "BLI_fileops_types.h" -#include "BLO_readfile.h" +#include "BKE_appdir.h" #include "BKE_context.h" #include "BKE_screen.h" #include "BKE_global.h" @@ -656,7 +656,7 @@ void ED_file_exit(void) void ED_file_read_bookmarks(void) { - const char * const cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL); + const char * const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL); fsmenu_free(); diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index b59030d3c12..a2b64afdb15 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -159,7 +159,7 @@ static void graph_panel_properties(const bContext *C, Panel *pa) // UNUSED // block = uiLayoutGetBlock(layout); - // uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL); + // UI_block_func_handle_set(block, do_graph_region_buttons, NULL); /* F-Curve pointer */ RNA_pointer_create(ale->id, &RNA_FCurve, fcu, &fcu_ptr); @@ -315,7 +315,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa) return; block = uiLayoutGetBlock(layout); - /* uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL); */ + /* UI_block_func_handle_set(block, do_graph_region_buttons, NULL); */ /* only show this info if there are keyframes to edit */ if (get_active_fcurve_keyframe_edit(fcu, &bezt, &prevbezt)) { @@ -366,33 +366,33 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa) { uiItemL(col, IFACE_("Key:"), ICON_NONE); - but = uiDefButR(block, NUM, B_REDR, IFACE_("Frame:"), 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, IFACE_("Frame:"), 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "co", 0, 0, 0, -1, -1, NULL); - uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt); + UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt); - but = uiDefButR(block, NUM, B_REDR, IFACE_("Value:"), 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, IFACE_("Value:"), 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "co", 1, 0, 0, -1, -1, NULL); - uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt); - uiButSetUnitType(but, unit); + UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt); + UI_but_unit_type_set(but, unit); } /* previous handle - only if previous was Bezier interpolation */ if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) { uiItemL(col, IFACE_("Left Handle:"), ICON_NONE); - but = uiDefButR(block, NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_left", 0, 0, 0, -1, -1, NULL); - uiButSetFunc(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt); + UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt); - but = uiDefButR(block, NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_left", 1, 0, 0, -1, -1, NULL); - uiButSetFunc(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt); - uiButSetUnitType(but, unit); + UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt); + UI_but_unit_type_set(but, unit); /* XXX: with label? */ - but = uiDefButR(block, MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, UI_BTYPE_MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_left_type", 0, 0, 0, -1, -1, "Type of left handle"); - uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); + UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt); } /* next handle - only if current is Bezier interpolation */ @@ -400,19 +400,19 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa) /* NOTE: special update callbacks are needed on the coords here due to T39911 */ uiItemL(col, IFACE_("Right Handle:"), ICON_NONE); - but = uiDefButR(block, NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_right", 0, 0, 0, -1, -1, NULL); - uiButSetFunc(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt); + UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt); - but = uiDefButR(block, NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_right", 1, 0, 0, -1, -1, NULL); - uiButSetFunc(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt); - uiButSetUnitType(but, unit); + UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt); + UI_but_unit_type_set(but, unit); /* XXX: with label? */ - but = uiDefButR(block, MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, UI_BTYPE_MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_right_type", 0, 0, 0, -1, -1, "Type of right handle"); - uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); + UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt); } } else { @@ -671,22 +671,22 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) /* set event handler for panel */ block = uiLayoutGetBlock(pa->layout); // xxx? - uiBlockSetHandleFunc(block, do_graph_region_driver_buttons, NULL); + UI_block_func_handle_set(block, do_graph_region_driver_buttons, NULL); /* general actions - management */ col = uiLayoutColumn(pa->layout, false); block = uiLayoutGetBlock(col); - but = uiDefIconTextBut(block, BUT, B_IPO_DEPCHANGE, ICON_FILE_REFRESH, IFACE_("Update Dependencies"), + but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_FILE_REFRESH, IFACE_("Update Dependencies"), 0, 0, 10 * UI_UNIT_X, 22, NULL, 0.0, 0.0, 0, 0, TIP_("Force updates of dependencies")); - uiButSetFunc(but, driver_update_flags_cb, fcu, NULL); + UI_but_func_set(but, driver_update_flags_cb, fcu, NULL); - but = uiDefIconTextBut(block, BUT, B_IPO_DEPCHANGE, ICON_ZOOMOUT, IFACE_("Remove Driver"), + but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ZOOMOUT, IFACE_("Remove Driver"), 0, 0, 10 * UI_UNIT_X, 18, NULL, 0.0, 0.0, 0, 0, TIP_("Remove this driver")); - uiButSetNFunc(but, driver_remove_cb, MEM_dupallocN(ale), NULL); + UI_but_funcN_set(but, driver_remove_cb, MEM_dupallocN(ale), NULL); /* driver-level settings - type, expressions, and errors */ RNA_pointer_create(ale->id, &RNA_Driver, driver, &driver_ptr); @@ -763,11 +763,11 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) /* add driver variables */ col = uiLayoutColumn(pa->layout, false); block = uiLayoutGetBlock(col); - but = uiDefIconTextBut(block, BUT, B_IPO_DEPCHANGE, ICON_ZOOMIN, IFACE_("Add Variable"), + but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ZOOMIN, IFACE_("Add Variable"), 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, TIP_("Driver variables ensure that all dependencies will be accounted for and that drivers will update correctly")); - uiButSetFunc(but, driver_add_var_cb, driver, NULL); + UI_but_func_set(but, driver_add_var_cb, driver, NULL); /* loop over targets, drawing them */ for (dvar = driver->variables.first; dvar; dvar = dvar->next) { @@ -788,11 +788,11 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) uiItemR(row, &dvar_ptr, "name", 0, "", ICON_NONE); /* remove button */ - uiBlockSetEmboss(block, UI_EMBOSSN); - but = uiDefIconBut(block, BUT, B_IPO_DEPCHANGE, ICON_X, 290, 0, UI_UNIT_X, UI_UNIT_Y, + UI_block_emboss_set(block, UI_EMBOSS_NONE); + but = uiDefIconBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_X, 290, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, IFACE_("Delete target variable")); - uiButSetFunc(but, driver_delete_var_cb, driver, dvar); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_but_func_set(but, driver_delete_var_cb, driver, dvar); + UI_block_emboss_set(block, UI_EMBOSS); /* variable type */ row = uiLayoutRow(box, false); @@ -869,7 +869,7 @@ static void graph_panel_modifiers(const bContext *C, Panel *pa) return; block = uiLayoutGetBlock(pa->layout); - uiBlockSetHandleFunc(block, do_graph_region_modifier_buttons, NULL); + UI_block_func_handle_set(block, do_graph_region_modifier_buttons, NULL); /* 'add modifier' button at top of panel */ { @@ -879,7 +879,7 @@ static void graph_panel_modifiers(const bContext *C, Panel *pa) /* this is an operator button which calls a 'add modifier' operator... * a menu might be nicer but would be tricky as we need some custom filtering */ - uiDefButO(block, BUT, "GRAPH_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, IFACE_("Add Modifier"), + uiDefButO(block, UI_BTYPE_BUT, "GRAPH_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, IFACE_("Add Modifier"), 0.5 * UI_UNIT_X, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y, TIP_("Adds a new F-Curve Modifier for the active F-Curve")); /* copy/paste (as sub-row)*/ diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index ed7cfe7da99..9093734f25f 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -33,6 +33,7 @@ #include <float.h> #include "BLI_blenlib.h" +#include "BLI_math.h" #include "BLI_utildefines.h" #include "DNA_anim_types.h" @@ -42,6 +43,7 @@ #include "DNA_userdef_types.h" #include "BKE_context.h" +#include "BKE_curve.h" #include "BKE_fcurve.h" @@ -475,6 +477,7 @@ static void draw_fcurve_samples(SpaceIpo *sipo, ARegion *ar, FCurve *fcu) /* helper func - just draw the F-Curve by sampling the visible region (for drawing curves with modifiers) */ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, View2DGrid *grid) { + SpaceIpo *sipo = (SpaceIpo *)ac->sl; ChannelDriver *driver; float samplefreq; float stime, etime; @@ -502,7 +505,7 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d * which means that our curves can be as smooth as possible. However, * this does mean that curves may not be fully accurate (i.e. if they have * sudden spikes which happen at the sampling point, we may have problems). - * Also, this may introduce lower performance on less densely detailed curves,' + * Also, this may introduce lower performance on less densely detailed curves, * though it is impossible to predict this from the modifiers! * * If the automatically determined sampling frequency is likely to cause an infinite @@ -512,7 +515,25 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d /* grid->dx represents the number of 'frames' between gridlines, but we divide by U.v2d_min_gridsize to get pixels-steps */ /* TODO: perhaps we should have 1.0 frames as upper limit so that curves don't get too distorted? */ samplefreq = dx / (U.v2d_min_gridsize * U.pixelsize); - if (samplefreq < 0.00001f) samplefreq = 0.00001f; + + if (sipo->flag & SIPO_BEAUTYDRAW_OFF) { + /* Low Precision = coarse lower-bound clamping + * + * Although the "Beauty Draw" flag was originally for AA'd + * line drawing, the sampling rate here has a much greater + * impact on performance (e.g. for T40372)! + * + * This one still amounts to 10 sample-frames for each 1-frame interval + * which should be quite a decent approximation in many situations. + */ + if (samplefreq < 0.1f) + samplefreq = 0.1f; + } + else { + /* "Higher Precision" but slower - especially on larger windows (e.g. T40372) */ + if (samplefreq < 0.00001f) + samplefreq = 0.00001f; + } /* the start/end times are simply the horizontal extents of the 'cur' rect */ @@ -525,12 +546,13 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d * the displayed values appear correctly in the viewport */ glBegin(GL_LINE_STRIP); - - for (i = 0, n = (etime - stime) / samplefreq + 0.5f; i < n; ++i) { + + n = (etime - stime) / samplefreq + 0.5f; + for (i = 0; i <= n; i++) { float ctime = stime + i * samplefreq; glVertex2f(ctime, evaluate_fcurve(fcu, ctime) * unitFac); } - + glEnd(); /* restore driver */ @@ -616,8 +638,24 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie glPopMatrix(); } -#if 0 -/* helper func - draw one repeat of an F-Curve */ +/* helper func - check if the F-Curve only contains easily drawable segments + * (i.e. no easing equation interpolations) + */ +static bool fcurve_can_use_simple_bezt_drawing(FCurve *fcu) +{ + BezTriple *bezt; + int i; + + for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) { + if (ELEM(bezt->ipo, BEZT_IPO_CONST, BEZT_IPO_LIN, BEZT_IPO_BEZ) == false) { + return false; + } + } + + return true; +} + +/* helper func - draw one repeat of an F-Curve (using Bezier curve approximations) */ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d) { BezTriple *prevbezt = fcu->bezt; @@ -629,12 +667,12 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2 int resol; float unit_scale; short mapping_flag = ANIM_get_normalization_flags(ac); - + /* apply unit mapping */ glPushMatrix(); unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag); glScalef(1.0f, unit_scale, 1.0f); - + glBegin(GL_LINE_STRIP); /* extrapolate to left? */ @@ -689,17 +727,19 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2 v1[1] = prevbezt->vec[1][1]; glVertex2fv(v1); } - else { + else if (prevbezt->ipo == BEZT_IPO_BEZ) { /* Bezier-Interpolation: draw curve as series of segments between keyframes * - resol determines number of points to sample in between keyframes */ /* resol depends on distance between points (not just horizontal) OR is a fixed high res */ /* TODO: view scale should factor into this someday too... */ - if (fcu->driver) + if (fcu->driver) { resol = 32; - else + } + else { resol = (int)(5.0f * len_v2v2(bezt->vec[1], prevbezt->vec[1])); + } if (resol < 2) { /* only draw one */ @@ -773,7 +813,6 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2 glEnd(); glPopMatrix(); } -#endif /* Debugging -------------------------------- */ @@ -989,11 +1028,15 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid } else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) { /* just draw curve based on defined data (i.e. no modifiers) */ - if (fcu->bezt) - //draw_fcurve_curve_bezts(ac, ale->id, fcu, &ar->v2d); - draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid); // XXX: better to do an optimised integration here instead, but for now, this works - else if (fcu->fpt) + if (fcu->bezt) { + if (fcurve_can_use_simple_bezt_drawing(fcu)) + draw_fcurve_curve_bezts(ac, ale->id, fcu, &ar->v2d); + else + draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid); + } + else if (fcu->fpt) { draw_fcurve_curve_samples(ac, ale->id, fcu, &ar->v2d); + } } /* restore settings */ @@ -1109,7 +1152,7 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar) } } { /* second pass: widgets */ - uiBlock *block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); + uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS); size_t channel_index = 0; y = (float)ACHANNEL_FIRST; @@ -1135,8 +1178,8 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar) channel_index++; } - uiEndBlock(C, block); - uiDrawBlock(C, block); + UI_block_end(C, block); + UI_block_draw(C, block); glDisable(GL_BLEND); } diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index c8298927f7d..2ca659252d2 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -60,8 +60,6 @@ #include "BKE_context.h" #include "BKE_report.h" -#include "UI_interface.h" -#include "UI_resources.h" #include "UI_view2d.h" #include "ED_anim_api.h" @@ -1888,7 +1886,7 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op)) ked.f1 += current_ked.f1; ked.i1 += current_ked.i1; - ked.f2 += current_ked.f2 / unit_scale; + ked.f2 += current_ked.f2 * unit_scale; ked.i2 += current_ked.i2; } diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h index 408c78d194e..50412952139 100644 --- a/source/blender/editors/space_graph/graph_intern.h +++ b/source/blender/editors/space_graph/graph_intern.h @@ -62,6 +62,7 @@ void graph_draw_ghost_curves(struct bAnimContext *ac, struct SpaceIpo *sipo, str void GRAPH_OT_select_all_toggle(struct wmOperatorType *ot); void GRAPH_OT_select_border(struct wmOperatorType *ot); void GRAPH_OT_select_lasso(struct wmOperatorType *ot); +void GRAPH_OT_select_circle(struct wmOperatorType *ot); void GRAPH_OT_select_column(struct wmOperatorType *ot); void GRAPH_OT_select_linked(struct wmOperatorType *ot); void GRAPH_OT_select_more(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index 62b6b59df29..f06d738200a 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -34,6 +34,7 @@ #include "DNA_scene_types.h" +#include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BLI_math_base.h" @@ -200,6 +201,174 @@ static void GRAPH_OT_cursor_set(wmOperatorType *ot) RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Value", "", -100.0f, 100.0f); } +/* Hide/Reveal ------------------------------------------------------------ */ + +static int graphview_curves_hide_exec(bContext *C, wmOperator *op) +{ + bAnimContext ac; + ListBase anim_data = {NULL, NULL}; + ListBase all_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + const bool unselected = RNA_boolean_get(op->ptr, "unselected"); + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + + /* get list of all channels that selection may need to be flushed to + * - hierarchy must not affect what we have access to here... + */ + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS); + ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype); + + /* filter data + * - of the remaining visible curves, we want to hide the ones that are + * selected/unselected (depending on "unselected" prop) + */ + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); + if (unselected) + filter |= ANIMFILTER_UNSEL; + else + filter |= ANIMFILTER_SEL; + + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + for (ale = anim_data.first; ale; ale = ale->next) { + /* hack: skip object channels for now, since flushing those will always flush everything, but they are always included */ + /* TODO: find out why this is the case, and fix that */ + if (ale->type == ANIMTYPE_OBJECT) + continue; + + /* change the hide setting, and unselect it... */ + ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_CLEAR); + ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_SELECT, ACHANNEL_SETFLAG_CLEAR); + + /* now, also flush selection status up/down as appropriate */ + ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_CLEAR); + } + + /* cleanup */ + ANIM_animdata_freelist(&anim_data); + BLI_freelistN(&all_data); + + /* unhide selected */ + if (unselected) { + /* turn off requirement for visible */ + filter = ANIMFILTER_SEL | ANIMFILTER_NODUPLIS | ANIMFILTER_LIST_CHANNELS; + + /* flushing has been done */ + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + for (ale = anim_data.first; ale; ale = ale->next) { + /* hack: skip object channels for now, since flushing those will always flush everything, but they are always included */ + /* TODO: find out why this is the case, and fix that */ + if (ale->type == ANIMTYPE_OBJECT) + continue; + + /* change the hide setting, and unselect it... */ + ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD); + ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_SELECT, ACHANNEL_SETFLAG_ADD); + + /* now, also flush selection status up/down as appropriate */ + ANIM_flush_setting_anim_channels(&ac, &anim_data, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD); + } + ANIM_animdata_freelist(&anim_data); + } + + + /* send notifier that things have changed */ + WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +static void GRAPH_OT_hide(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Hide Curves"; + ot->idname = "GRAPH_OT_hide"; + ot->description = "Hide selected curves from Graph Editor view"; + + /* api callbacks */ + ot->exec = graphview_curves_hide_exec; + ot->poll = ED_operator_graphedit_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected curves"); +} + +/* ........ */ + +static int graphview_curves_reveal_exec(bContext *C, wmOperator *UNUSED(op)) +{ + bAnimContext ac; + ListBase anim_data = {NULL, NULL}; + ListBase all_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + + /* get list of all channels that selection may need to be flushed to + * - hierarchy must not affect what we have access to here... + */ + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS); + ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype); + + /* filter data + * - just go through all visible channels, ensuring that everything is set to be curve-visible + */ + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS); + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + for (ale = anim_data.first; ale; ale = ale->next) { + /* hack: skip object channels for now, since flushing those will always flush everything, but they are always included */ + /* TODO: find out why this is the case, and fix that */ + if (ale->type == ANIMTYPE_OBJECT) + continue; + + /* select if it is not visible */ + if (ANIM_channel_setting_get(&ac, ale, ACHANNEL_SETTING_VISIBLE) == 0) + ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_SELECT, ACHANNEL_SETFLAG_ADD); + + /* change the visibility setting */ + ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD); + + /* now, also flush selection status up/down as appropriate */ + ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, true); + } + + /* cleanup */ + ANIM_animdata_freelist(&anim_data); + BLI_freelistN(&all_data); + + /* send notifier that things have changed */ + WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +static void GRAPH_OT_reveal(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Reveal Curves"; + ot->idname = "GRAPH_OT_reveal"; + ot->description = "Make previously hidden curves visible again in Graph Editor view"; + + /* api callbacks */ + ot->exec = graphview_curves_reveal_exec; + ot->poll = ED_operator_graphedit_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /* ************************** registration - operator types **********************************/ void graphedit_operatortypes(void) @@ -215,12 +384,16 @@ void graphedit_operatortypes(void) WM_operatortype_append(GRAPH_OT_ghost_curves_create); WM_operatortype_append(GRAPH_OT_ghost_curves_clear); + WM_operatortype_append(GRAPH_OT_hide); + WM_operatortype_append(GRAPH_OT_reveal); + /* keyframes */ /* selection */ WM_operatortype_append(GRAPH_OT_clickselect); WM_operatortype_append(GRAPH_OT_select_all_toggle); WM_operatortype_append(GRAPH_OT_select_border); WM_operatortype_append(GRAPH_OT_select_lasso); + WM_operatortype_append(GRAPH_OT_select_circle); WM_operatortype_append(GRAPH_OT_select_column); WM_operatortype_append(GRAPH_OT_select_linked); WM_operatortype_append(GRAPH_OT_select_more); @@ -359,6 +532,8 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "deselect", true); + WM_keymap_add_item(keymap, "GRAPH_OT_select_circle", CKEY, KM_PRESS, 0, 0); + /* column select */ RNA_enum_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_column", KKEY, KM_PRESS, 0, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_KEYS); RNA_enum_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_column", KKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_CFRA); @@ -429,6 +604,19 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) /* transform system */ transform_keymap_for_space(keyconf, keymap, SPACE_IPO); + /* pivot point settings */ + kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", COMMAKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point"); + RNA_string_set(kmi->ptr, "value", "BOUNDING_BOX_CENTER"); + + kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", PERIODKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point"); + RNA_string_set(kmi->ptr, "value", "CURSOR"); + + kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", PERIODKEY, KM_PRESS, KM_CTRL, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point"); + RNA_string_set(kmi->ptr, "value", "INDIVIDUAL_ORIGINS"); + /* special markers hotkeys for anim editors: see note in definition of this function */ ED_marker_keymap_animedit_conflictfree(keymap); } @@ -438,6 +626,7 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) void graphedit_keymap(wmKeyConfig *keyconf) { wmKeyMap *keymap; + wmKeyMapItem *kmi; /* keymap for all regions */ keymap = WM_keymap_find(keyconf, "Graph Editor Generic", SPACE_IPO, 0); @@ -448,7 +637,17 @@ void graphedit_keymap(wmKeyConfig *keyconf) /* find (i.e. a shortcut for setting the name filter) */ WM_keymap_add_item(keymap, "ANIM_OT_channels_find", FKEY, KM_PRESS, KM_CTRL, 0); - + + /* hide/reveal selected curves */ + kmi = WM_keymap_add_item(keymap, "GRAPH_OT_hide", HKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "unselected", false); + + kmi = WM_keymap_add_item(keymap, "GRAPH_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "unselected", true); + + WM_keymap_add_item(keymap, "GRAPH_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0); + + /* channels */ /* Channels are not directly handled by the Graph Editor module, but are inherited from the Animation module. * All the relevant operations, keymaps, drawing, etc. can therefore all be found in that module instead, as these diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index 378139accbc..78dbae7618b 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -219,7 +219,7 @@ void GRAPH_OT_select_all_toggle(wmOperatorType *ot) */ static void borderselect_graphkeys( bAnimContext *ac, const rctf *rectf_view, short mode, short selectmode, bool incl_handles, - struct KeyframeEdit_LassoData *data_lasso) + void *data) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; @@ -244,10 +244,16 @@ static void borderselect_graphkeys( /* init editing data */ memset(&ked, 0, sizeof(KeyframeEditData)); - if (data_lasso) { + if (mode == BEZT_OK_REGION_LASSO) { + struct KeyframeEdit_LassoData *data_lasso = data; data_lasso->rectf_scaled = &scaled_rectf; ked.data = data_lasso; } + else if (mode == BEZT_OK_REGION_CIRCLE) { + struct KeyframeEdit_CircleData *data_circle = data; + data_circle->rectf_scaled = &scaled_rectf; + ked.data = data; + } else { ked.data = &scaled_rectf; } @@ -485,6 +491,81 @@ void GRAPH_OT_select_lasso(wmOperatorType *ot) RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend selection instead of deselecting everything first"); } +static int graph_circle_select_exec(bContext *C, wmOperator *op) +{ + bAnimContext ac; + const int gesture_mode = RNA_int_get(op->ptr, "gesture_mode"); + short selectmode; + bool incl_handles; + rctf rect_fl; + struct KeyframeEdit_CircleData data; + float x = RNA_int_get(op->ptr, "x"); + float y = RNA_int_get(op->ptr, "y"); + float radius = RNA_int_get(op->ptr, "radius"); + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + + data.mval[0] = x; + data.mval[1] = y; + data.radius_squared = radius * radius; + data.rectf_view = &rect_fl; + + if (gesture_mode == GESTURE_MODAL_SELECT) + selectmode = SELECT_ADD; + else + selectmode = SELECT_SUBTRACT; + + rect_fl.xmin = x - radius; + rect_fl.xmax = x + radius; + rect_fl.ymin = y - radius; + rect_fl.ymax = y + radius; + + if (ac.spacetype == SPACE_IPO) { + SpaceIpo *sipo = (SpaceIpo *)ac.sl; + if (selectmode == SELECT_ADD) { + incl_handles = ((sipo->flag & SIPO_SELVHANDLESONLY) || + (sipo->flag & SIPO_NOHANDLES)) == 0; + } + else { + incl_handles = (sipo->flag & SIPO_NOHANDLES) == 0; + } + } + else { + incl_handles = false; + } + + /* apply borderselect action */ + borderselect_graphkeys(&ac, &rect_fl, BEZT_OK_REGION_CIRCLE, selectmode, incl_handles, &data); + + /* send notifier that keyframe selection has changed */ + WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL); + + return OPERATOR_FINISHED; +} + +void GRAPH_OT_select_circle(wmOperatorType *ot) +{ + ot->name = "Circle Select"; + ot->description = "Select keyframe points using circle selection"; + ot->idname = "GRAPH_OT_select_circle"; + + ot->invoke = WM_gesture_circle_invoke; + ot->modal = WM_gesture_circle_modal; + ot->exec = graph_circle_select_exec; + ot->poll = graphop_visible_keyframes_poll; + ot->cancel = WM_gesture_circle_cancel; + + /* flags */ + ot->flag = OPTYPE_UNDO; + + RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "radius", 1, 1, INT_MAX, "Radius", "", 1, INT_MAX); + RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Event Type", "", INT_MIN, INT_MAX); +} + /* ******************** Column Select Operator **************************** */ /* This operator works in one of four ways: * - 1) select all keyframes in the same frame as a selected one (KKEY) diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c index e9c8ae95acd..eea360ced45 100644 --- a/source/blender/editors/space_graph/graph_utils.c +++ b/source/blender/editors/space_graph/graph_utils.c @@ -40,7 +40,6 @@ #include "MEM_guardedalloc.h" -#include "BLI_math.h" #include "BLI_blenlib.h" #include "BKE_context.h" diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index 6dba706b241..ad6f3ff5c7e 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -182,7 +182,7 @@ static void graph_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa) { SpaceIpo *sipo = (SpaceIpo *)sa->spacedata.first; - /* init dopesheet data if non-existant (i.e. for old files) */ + /* init dopesheet data if non-existent (i.e. for old files) */ if (sipo->ads == NULL) { sipo->ads = MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet"); sipo->ads->source = (ID *)(G.main->scene.first); // FIXME: this is a really nasty hack here for now... @@ -293,7 +293,7 @@ static void graph_main_area_draw(const bContext *C, ARegion *ar) /* markers */ UI_view2d_view_orthoSpecial(ar, v2d, 1); - draw_markers_time(C, 0); + ED_markers_draw(C, DRAW_MARKERS_MARGIN); /* preview range */ UI_view2d_view_ortho(v2d); diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 154437ab53a..05868283b2e 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -268,7 +268,7 @@ static void image_panel_preview(ScrArea *sa, short cntrl) // IMAGE_HANDLER_PRE return; } - block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); + block = UI_block_begin(C, ar, __func__, UI_EMBOSS); uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl); uiSetPanelHandler(IMAGE_HANDLER_PREVIEW); // for close and esc @@ -276,7 +276,7 @@ static void image_panel_preview(ScrArea *sa, short cntrl) // IMAGE_HANDLER_PRE ofsy = -100 + (sa->winy / 2) / sima->blockscale; if (uiNewPanel(C, ar, block, "Preview", "Image", ofsx, ofsy, 300, 200) == 0) return; - uiBlockSetDrawExtraFunc(block, preview_cb); + UI_but_func_drawextra_set(block, preview_cb); } #endif @@ -290,7 +290,7 @@ static void ui_imageuser_slot_menu(bContext *UNUSED(C), uiLayout *layout, void * Image *image = image_p; int slot; - uiDefBut(block, LABEL, 0, IFACE_("Slot"), + uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Slot"), 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); uiItemS(layout); @@ -303,7 +303,7 @@ static void ui_imageuser_slot_menu(bContext *UNUSED(C), uiLayout *layout, void * else { BLI_snprintf(str, sizeof(str), IFACE_("Slot %d"), slot + 1); } - uiDefButS(block, BUTM, B_NOP, str, 0, 0, + uiDefButS(block, UI_BTYPE_BUT_MENU, B_NOP, str, 0, 0, UI_UNIT_X * 5, UI_UNIT_X, &image->render_slot, (float) slot, 0.0, 0, -1, ""); } } @@ -340,14 +340,14 @@ static void ui_imageuser_layer_menu(bContext *UNUSED(C), uiLayout *layout, void return; } - uiBlockSetCurLayout(block, layout); + UI_block_layout_set_current(block, layout); uiLayoutColumn(layout, false); - uiDefBut(block, LABEL, 0, IFACE_("Layer"), + uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Layer"), 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); uiItemS(layout); - nr = BLI_countlist(&rr->layers) - 1; + nr = BLI_listbase_count(&rr->layers) - 1; fake_name = ui_imageuser_layer_fake_name(rr); if (fake_name) { @@ -357,7 +357,7 @@ static void ui_imageuser_layer_menu(bContext *UNUSED(C), uiLayout *layout, void for (rl = rr->layers.last; rl; rl = rl->prev, nr--) { final: - uiDefButS(block, BUTM, B_NOP, IFACE_(rl->name), 0, 0, + uiDefButS(block, UI_BTYPE_BUT_MENU, B_NOP, IFACE_(rl->name), 0, 0, UI_UNIT_X * 5, UI_UNIT_X, &iuser->layer, (float) nr, 0.0, 0, -1, ""); } @@ -406,15 +406,15 @@ static void ui_imageuser_pass_menu(bContext *UNUSED(C), uiLayout *layout, void * rl = BLI_findlink(&rr->layers, rpass_index); - uiBlockSetCurLayout(block, layout); + UI_block_layout_set_current(block, layout); uiLayoutColumn(layout, false); - uiDefBut(block, LABEL, 0, IFACE_("Pass"), + uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Pass"), 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); uiItemS(layout); - nr = (rl ? BLI_countlist(&rl->passes) : 0) - 1; + nr = (rl ? BLI_listbase_count(&rl->passes) : 0) - 1; fake_name = ui_imageuser_pass_fake_name(rl); if (fake_name) { @@ -425,7 +425,7 @@ static void ui_imageuser_pass_menu(bContext *UNUSED(C), uiLayout *layout, void * /* rendered results don't have a Combined pass */ for (rpass = rl ? rl->passes.last : NULL; rpass; rpass = rpass->prev, nr--) { final: - uiDefButS(block, BUTM, B_NOP, IFACE_(rpass->name), 0, 0, + uiDefButS(block, UI_BTYPE_BUT_MENU, B_NOP, IFACE_(rpass->name), 0, 0, UI_UNIT_X * 5, UI_UNIT_X, &iuser->pass, (float) nr, 0.0, 0, -1, ""); } @@ -452,7 +452,7 @@ static void image_multi_inclay_cb(bContext *C, void *rr_v, void *iuser_v) { RenderResult *rr = rr_v; ImageUser *iuser = iuser_v; - int tot = BLI_countlist(&rr->layers); + int tot = BLI_listbase_count(&rr->layers); if (rr->rectf || rr->rect32) tot++; /* fake compo/sequencer layer */ @@ -480,7 +480,7 @@ static void image_multi_incpass_cb(bContext *C, void *rr_v, void *iuser_v) RenderLayer *rl = BLI_findlink(&rr->layers, iuser->layer); if (rl) { - int tot = BLI_countlist(&rl->passes); + int tot = BLI_listbase_count(&rl->passes); if (rr->rectf || rr->rect32) tot++; /* fake compo/sequencer layer */ @@ -551,8 +551,8 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, Image *image, RenderRes BLI_snprintf(str, sizeof(str), IFACE_("Slot %d"), *render_slot + 1); } but = uiDefMenuBut(block, ui_imageuser_slot_menu, image, str, 0, 0, wmenu1, UI_UNIT_Y, TIP_("Select Slot")); - uiButSetFunc(but, image_multi_cb, rr, iuser); - uiButSetMenuFromPulldown(but); + UI_but_func_set(but, image_multi_cb, rr, iuser); + UI_but_type_set_menu_from_pulldown(but); } if (rr) { @@ -567,8 +567,8 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, Image *image, RenderRes display_name = rl ? rl->name : (fake_name ? fake_name : ""); but = uiDefMenuBut(block, ui_imageuser_layer_menu, rnd_pt, display_name, 0, 0, wmenu2, UI_UNIT_Y, TIP_("Select Layer")); - uiButSetFunc(but, image_multi_cb, rr, iuser); - uiButSetMenuFromPulldown(but); + UI_but_func_set(but, image_multi_cb, rr, iuser); + UI_but_type_set_menu_from_pulldown(but); /* pass */ @@ -577,8 +577,8 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, Image *image, RenderRes display_name = rpass ? rpass->name : (fake_name ? fake_name : ""); but = uiDefMenuBut(block, ui_imageuser_pass_menu, rnd_pt, display_name, 0, 0, wmenu3, UI_UNIT_Y, TIP_("Select Pass")); - uiButSetFunc(but, image_multi_cb, rr, iuser); - uiButSetMenuFromPulldown(but); + UI_but_func_set(but, image_multi_cb, rr, iuser); + UI_but_type_set_menu_from_pulldown(but); } } @@ -599,20 +599,20 @@ static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, Image *image, Ren } /* decrease, increase arrows */ - but = uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT, 0, 0, 0.85f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Previous Layer")); - uiButSetFunc(but, image_multi_declay_cb, rr, iuser); - but = uiDefIconBut(block, BUT, 0, ICON_TRIA_RIGHT, 0, 0, 0.90f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Next Layer")); - uiButSetFunc(but, image_multi_inclay_cb, rr, iuser); + but = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_TRIA_LEFT, 0, 0, 0.85f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Previous Layer")); + UI_but_func_set(but, image_multi_declay_cb, rr, iuser); + but = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_TRIA_RIGHT, 0, 0, 0.90f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Next Layer")); + UI_but_func_set(but, image_multi_inclay_cb, rr, iuser); uiblock_layer_pass_buttons(row, image, rr, iuser, 230 * dpi_fac, render_slot); /* decrease, increase arrows */ - but = uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT, 0, 0, 0.85f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Previous Pass")); - uiButSetFunc(but, image_multi_decpass_cb, rr, iuser); - but = uiDefIconBut(block, BUT, 0, ICON_TRIA_RIGHT, 0, 0, 0.90f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Next Pass")); - uiButSetFunc(but, image_multi_incpass_cb, rr, iuser); + but = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_TRIA_LEFT, 0, 0, 0.85f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Previous Pass")); + UI_but_func_set(but, image_multi_decpass_cb, rr, iuser); + but = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_TRIA_RIGHT, 0, 0, 0.90f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Next Pass")); + UI_but_func_set(but, image_multi_incpass_cb, rr, iuser); - uiBlockEndAlign(block); + UI_block_align_end(block); } // XXX HACK! @@ -690,7 +690,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char uiTemplateID(layout, C, ptr, propname, "IMAGE_OT_new", "IMAGE_OT_open", NULL); if (ima) { - uiBlockSetNFunc(block, rna_update_cb, MEM_dupallocN(cb), NULL); + UI_block_funcN_set(block, rna_update_cb, MEM_dupallocN(cb), NULL); if (ima->source == IMA_SRC_VIEWER) { ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock); @@ -705,18 +705,18 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char #if 0 iuser = ntree_get_active_iuser(scene->nodetree); if (iuser) { - uiBlockBeginAlign(block); - uiDefIconTextBut(block, BUT, B_SIMA_RECORD, ICON_REC, "Record", 10, 120, 100, 20, 0, 0, 0, 0, 0, ""); - uiDefIconTextBut(block, BUT, B_SIMA_PLAY, ICON_PLAY, "Play", 110, 120, 100, 20, 0, 0, 0, 0, 0, ""); - but = uiDefBut(block, BUT, B_NOP, "Free Cache", 210, 120, 100, 20, 0, 0, 0, 0, 0, ""); - uiButSetFunc(but, image_freecache_cb, ima, NULL); + UI_block_align_begin(block); + uiDefIconTextBut(block, UI_BTYPE_BUT, B_SIMA_RECORD, ICON_REC, "Record", 10, 120, 100, 20, 0, 0, 0, 0, 0, ""); + uiDefIconTextBut(block, UI_BTYPE_BUT, B_SIMA_PLAY, ICON_PLAY, "Play", 110, 120, 100, 20, 0, 0, 0, 0, 0, ""); + but = uiDefBut(block, UI_BTYPE_BUT, B_NOP, "Free Cache", 210, 120, 100, 20, 0, 0, 0, 0, 0, ""); + UI_but_func_set(but, image_freecache_cb, ima, NULL); if (iuser->frames) BLI_snprintf(str, sizeof(str), "(%d) Frames:", iuser->framenr); else strcpy(str, "Frames:"); - uiBlockBeginAlign(block); - uiDefButI(block, NUM, imagechanged, str, 10, 90, 150, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Number of images of a movie to use"); - uiDefButI(block, NUM, imagechanged, "StartFr:", 160, 90, 150, 20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Global starting frame of the movie"); + UI_block_align_begin(block); + uiDefButI(block, UI_BTYPE_NUM, imagechanged, str, 10, 90, 150, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Number of images of a movie to use"); + uiDefButI(block, UI_BTYPE_NUM, imagechanged, "StartFr:", 160, 90, 150, 20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Global starting frame of the movie"); } #endif } @@ -852,7 +852,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char } - uiBlockSetNFunc(block, NULL, NULL, NULL); + UI_block_funcN_set(block, NULL, NULL, NULL); } MEM_freeN(cb); @@ -977,19 +977,9 @@ void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser } } -void image_buttons_register(ARegionType *art) +void image_buttons_register(ARegionType *UNUSED(art)) { - PanelType *pt; - const char *category = "Grease Pencil"; - - pt = MEM_callocN(sizeof(PanelType), "spacetype image panel gpencil"); - strcpy(pt->idname, "IMAGE_PT_gpencil"); - strcpy(pt->label, N_("Grease Pencil")); - strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA); - pt->draw_header = ED_gpencil_panel_standard_header; - pt->draw = ED_gpencil_panel_standard; - BLI_strncpy(pt->category, category, BLI_strlen_utf8(category)); - BLI_addtail(&art->paneltypes, pt); + } static int image_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op)) diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index f41e237beb4..7c5aa349fa0 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -854,8 +854,13 @@ void draw_image_main(const bContext *C, ARegion *ar) draw_render_info(sima->iuser.scene, ima, ar, zoomx, zoomy); } -static bool show_image_cache(Image *image, Mask *mask) +bool ED_space_image_show_cache(SpaceImage *sima) { + Image *image = ED_space_image(sima); + Mask *mask = NULL; + if (sima->mode == SI_MODE_MASK) { + mask = ED_space_image_get_mask(sima); + } if (image == NULL && mask == NULL) { return false; } @@ -873,12 +878,12 @@ void draw_image_cache(const bContext *C, ARegion *ar) float x, cfra = CFRA, sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1); Mask *mask = NULL; - if (sima->mode == SI_MODE_MASK) { - mask = ED_space_image_get_mask(sima); + if (!ED_space_image_show_cache(sima)) { + return; } - if (!show_image_cache(image, mask)) { - return; + if (sima->mode == SI_MODE_MASK) { + mask = ED_space_image_get_mask(sima); } glEnable(GL_BLEND); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index df556f94f28..ec90217940c 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -92,6 +92,8 @@ #include "PIL_time.h" +#include "RE_engine.h" + #include "image_intern.h" /******************** view navigation utilities *********************/ @@ -947,7 +949,7 @@ static void image_open_init(bContext *C, wmOperator *op) op->customdata = iod = MEM_callocN(sizeof(ImageOpenData), __func__); iod->iuser = CTX_data_pointer_get_type(C, "image_user", &RNA_ImageUser).data; - uiIDContextProperty(C, &iod->pprop.ptr, &iod->pprop.prop); + UI_context_active_but_prop_get_templateID(C, &iod->pprop.ptr, &iod->pprop.prop); } static void image_open_cancel(bContext *UNUSED(C), wmOperator *op) @@ -1024,7 +1026,7 @@ static int image_sequence_get_len(ListBase *frames, int *ofs) { ImageFrame *frame; - BLI_sortlist(frames, image_cmp_frame); + BLI_listbase_sort(frames, image_cmp_frame); frame = frames->first; if (frame) { @@ -1052,6 +1054,7 @@ static int image_open_exec(bContext *C, wmOperator *op) char path[FILE_MAX]; int frame_seq_len = 0; int frame_ofs = 1; + bool exists = false; const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path"); @@ -1070,7 +1073,7 @@ static int image_open_exec(bContext *C, wmOperator *op) errno = 0; - ima = BKE_image_load_exists(path); + ima = BKE_image_load_exists_ex(path, &exists); if (!ima) { if (op->customdata) MEM_freeN(op->customdata); @@ -1084,8 +1087,9 @@ static int image_open_exec(bContext *C, wmOperator *op) /* only image path after save, never ibuf */ if (is_relative_path) { - const char *relbase = ID_BLEND_PATH(bmain, &ima->id); - BLI_path_rel(ima->name, relbase); + if (!exists) { + BLI_path_rel(ima->name, bmain->name); + } } /* hook into UI */ @@ -1127,7 +1131,7 @@ static int image_open_exec(bContext *C, wmOperator *op) } /* XXX unpackImage frees image buffers */ - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), bmain); BKE_image_signal(ima, iuser, IMA_SIGNAL_RELOAD); WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima); @@ -1158,7 +1162,7 @@ static int image_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED( PropertyRNA *prop; /* hook into UI */ - uiIDContextProperty(C, &ptr, &prop); + UI_context_active_but_prop_get_templateID(C, &ptr, &prop); if (prop) { PointerRNA oldptr; @@ -1279,7 +1283,7 @@ static int image_replace_exec(bContext *C, wmOperator *op) sima->image->source = IMA_SRC_FILE; /* XXX unpackImage frees image buffers */ - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); BKE_icon_changed(BKE_icon_getid(&sima->image->id)); BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_RELOAD); @@ -1880,7 +1884,7 @@ static int image_reload_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_CANCELLED; /* XXX unpackImage frees image buffers */ - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); // XXX other users? BKE_image_signal(ima, (sima) ? &sima->iuser : NULL, IMA_SIGNAL_RELOAD); @@ -1958,7 +1962,7 @@ static int image_new_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; /* hook into UI */ - uiIDContextProperty(C, &ptr, &prop); + UI_context_active_but_prop_get_templateID(C, &ptr, &prop); if (prop) { /* when creating new ID blocks, use is already 1, but RNA @@ -2024,7 +2028,7 @@ static int image_new_exec(bContext *C, wmOperator *op) } /* XXX, Ton is not a fan of OK buttons but using this function to avoid undo/redo bug while in mesh-editmode, - campbell */ -/* XXX Note: the WM_operator_props_dialog_popup() doesn't work for uiIDContextProperty(), image is not being that way */ +/* XXX Note: the WM_operator_props_dialog_popup() doesn't work for UI_context_active_but_prop_get_templateID(), image is not being that way */ static int image_new_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { /* Better for user feedback. */ @@ -2248,15 +2252,15 @@ static int image_pack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED( ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); if (!as_png && (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))) { - pup = uiPupMenuBegin(C, IFACE_("OK"), ICON_QUESTION); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, IFACE_("OK"), ICON_QUESTION); + layout = UI_popup_menu_layout(pup); uiItemBooleanO(layout, IFACE_("Can't pack edited image from disk, pack as internal PNG?"), ICON_NONE, op->idname, "as_png", 1); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); BKE_image_release_ibuf(ima, ibuf, NULL); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } BKE_image_release_ibuf(ima, ibuf, NULL); @@ -2309,7 +2313,7 @@ static int image_unpack_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save"); /* XXX unpackImage frees image buffers */ - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); unpackImage(op->reports, ima, method); @@ -2580,8 +2584,9 @@ static int image_sample_invoke(bContext *C, wmOperator *op, const wmEvent *event ImageSampleInfo *info; if (ar->regiontype == RGN_TYPE_WINDOW) { - if (event->mval[1] <= 16) + if (event->mval[1] <= 16 && ED_space_image_show_cache(sima)) { return OPERATOR_PASS_THROUGH; + } } if (!ED_space_image_has_buffer(sima)) @@ -3015,8 +3020,10 @@ static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event ARegion *ar = CTX_wm_region(C); if (ar->regiontype == RGN_TYPE_WINDOW) { - if (event->mval[1] > 16) + SpaceImage *sima = CTX_wm_space_image(C); + if (event->mval[1] > 16 || !ED_space_image_show_cache(sima)) { return OPERATOR_PASS_THROUGH; + } } RNA_int_set(op->ptr, "frame", frame_from_event(C, event)); @@ -3108,8 +3115,21 @@ static int render_border_exec(bContext *C, wmOperator *op) { ARegion *ar = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); + Render *re = RE_GetRender(scene->id.name); + RenderData *rd; rctf border; + if (re == NULL) { + /* Shouldn't happen, but better be safe close to the release. */ + return OPERATOR_CANCELLED; + } + + rd = RE_engine_get_render_data(re); + if ((rd->mode & (R_BORDER | R_CROP)) == (R_BORDER | R_CROP)) { + BKE_report(op->reports, RPT_INFO, "Can not set border from a cropped render"); + return OPERATOR_CANCELLED; + } + /* get rectangle from operator */ WM_operator_properties_border_to_rctf(op, &border); UI_view2d_region_to_view_rctf(&ar->v2d, &border, &border); diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 9cfd2e645f9..df78dfa4a14 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -33,6 +33,7 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_image_types.h" #include "MEM_guardedalloc.h" @@ -355,7 +356,7 @@ static void image_keymap(struct wmKeyConfig *keyconf) static int image_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) { if (drag->type == WM_DRAG_PATH) - if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_BLANK)) /* rule might not work? */ + if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE, ICON_FILE_BLANK)) /* rule might not work? */ return 1; return 0; } @@ -712,7 +713,7 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW); - draw_uvedit_main(sima, ar, scene, obedit, obact); + ED_uvedit_draw_main(sima, ar, scene, obedit, obact); /* check for mask (delay draw) */ if (ED_space_image_show_uvedit(sima, obedit)) { @@ -772,12 +773,12 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) NULL, C); UI_view2d_view_ortho(v2d); - draw_image_cursor(ar, sima->cursor); + ED_image_draw_cursor(ar, sima->cursor); UI_view2d_view_restore(C); } else if (curve) { UI_view2d_view_ortho(v2d); - draw_image_cursor(ar, sima->cursor); + ED_image_draw_cursor(ar, sima->cursor); UI_view2d_view_restore(C); } @@ -791,7 +792,7 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) #endif } -static void image_main_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn) +static void image_main_area_listener(bScreen *UNUSED(sc), ScrArea *sa, ARegion *ar, wmNotifier *wmn) { /* context changes */ switch (wmn->category) { @@ -803,6 +804,14 @@ static void image_main_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), A if (wmn->action == NA_PAINTING) ED_region_tag_redraw(ar); break; + case NC_MATERIAL: + if (wmn->data == ND_SHADING_LINKS) { + SpaceImage *sima = sa->spacedata.first; + + if (sima->iuser.scene && (sima->iuser.scene->toolsettings->uv_flag & UV_SHOW_SAME_IMAGE)) + ED_region_tag_redraw(ar); + } + break; } } diff --git a/source/blender/editors/space_info/info_draw.c b/source/blender/editors/space_info/info_draw.c index 86af89bd6a9..e2895109b48 100644 --- a/source/blender/editors/space_info/info_draw.c +++ b/source/blender/editors/space_info/info_draw.c @@ -33,7 +33,6 @@ #include <sys/stat.h> #include <limits.h> -#include "BLF_api.h" #include "BLI_utildefines.h" @@ -45,8 +44,6 @@ #include "BIF_gl.h" -#include "ED_datafiles.h" -#include "ED_types.h" #include "UI_resources.h" #include "UI_interface.h" diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c index 25fa31407ff..240d8baa6f2 100644 --- a/source/blender/editors/space_info/info_ops.c +++ b/source/blender/editors/space_info/info_ops.c @@ -253,15 +253,15 @@ static int unpack_all_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED( else BLI_snprintf(title, sizeof(title), IFACE_("Unpack %d Files"), count); - pup = uiPupMenuBegin(C, title, ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, title, ICON_NONE); + layout = UI_popup_menu_layout(pup); uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); uiItemsEnumO(layout, "FILE_OT_unpack_all", "method"); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } void FILE_OT_unpack_all(wmOperatorType *ot) @@ -322,15 +322,15 @@ static int unpack_item_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED uiPopupMenu *pup; uiLayout *layout; - pup = uiPupMenuBegin(C, IFACE_("Unpack"), ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, IFACE_("Unpack"), ICON_NONE); + layout = UI_popup_menu_layout(pup); uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); uiItemsFullEnumO(layout, op->type->idname, "method", op->ptr->data, WM_OP_EXEC_REGION_WIN, 0); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } void FILE_OT_unpack_item(wmOperatorType *ot) diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c index 33333e4c992..ebce13389c9 100644 --- a/source/blender/editors/space_info/textview.c +++ b/source/blender/editors/space_info/textview.c @@ -155,7 +155,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str MEM_freeN(offsets); return 1; } - else if (y_next - cdc->lheight < cdc->ymin) { + else if (y_next < cdc->ymin) { /* have not reached the drawable area so don't break */ cdc->xy[1] = y_next; diff --git a/source/blender/editors/space_logic/logic_buttons.c b/source/blender/editors/space_logic/logic_buttons.c index 2c521532484..e0cbc1c9539 100644 --- a/source/blender/editors/space_logic/logic_buttons.c +++ b/source/blender/editors/space_logic/logic_buttons.c @@ -34,7 +34,6 @@ #include "BLI_utildefines.h" #include "BKE_context.h" -#include "BKE_screen.h" #include "ED_screen.h" @@ -124,12 +123,12 @@ static int cut_links_exec(bContext *C, wmOperator *op) for (block = ar->uiblocks.first; block; block = block->next) { but = block->buttons.first; while (but) { - if (but->type==LINK && but->link) { + if (but->type==UI_BTYPE_LINK && but->link) { for (line = but->link->lines.first; line; line = nline) { nline = line->next; if (cut_links_intersect(line, mcoords, i)) { - ui_delete_linkline(line, but); + ui_linkline_remove(line, but); } } } diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index dd152022762..5464449a94e 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -126,10 +126,10 @@ void make_unique_prop_names(bContext *C, char *str) /* count total names */ for (a=0; a<obcount; a++) { ob= (Object *)idar[a]; - propcount+= BLI_countlist(&ob->prop); - propcount+= BLI_countlist(&ob->sensors); - propcount+= BLI_countlist(&ob->controllers); - propcount+= BLI_countlist(&ob->actuators); + propcount+= BLI_listbase_count(&ob->prop); + propcount+= BLI_listbase_count(&ob->sensors); + propcount+= BLI_listbase_count(&ob->controllers); + propcount+= BLI_listbase_count(&ob->actuators); } if (propcount==0) { if (idar) MEM_freeN(idar); @@ -761,17 +761,17 @@ static uiBlock *sensor_menu(bContext *C, ARegion *ar, void *UNUSED(arg)) uiBlock *block; int yco=0; - block= uiBeginBlock(C, ar, __func__, UI_EMBOSSP); - uiBlockSetButmFunc(block, do_sensor_menu, NULL); + block= UI_block_begin(C, ar, __func__, UI_EMBOSS_PULLDOWN); + UI_block_func_butmenu_set(block, do_sensor_menu, NULL); - uiDefBut(block, BUTM, 1, IFACE_("Show Objects"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, ""); - uiDefBut(block, BUTM, 1, IFACE_("Hide Objects"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, ""); - uiDefBut(block, SEPRLINE, 0, "", 0, (short)(yco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, ""); - uiDefBut(block, BUTM, 1, IFACE_("Show Sensors"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, ""); - uiDefBut(block, BUTM, 1, IFACE_("Hide Sensors"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 3, ""); + uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Show Objects"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, ""); + uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Hide Objects"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, ""); + uiDefBut(block, UI_BTYPE_SEPR_LINE, 0, "", 0, (short)(yco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Show Sensors"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, ""); + uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Hide Sensors"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 3, ""); - uiBlockSetDirection(block, UI_TOP); - uiEndBlock(C, block); + UI_block_direction_set(block, UI_DIR_UP); + UI_block_end(C, block); return block; } @@ -810,17 +810,17 @@ static uiBlock *controller_menu(bContext *C, ARegion *ar, void *UNUSED(arg)) uiBlock *block; int yco=0; - block= uiBeginBlock(C, ar, __func__, UI_EMBOSSP); - uiBlockSetButmFunc(block, do_controller_menu, NULL); + block= UI_block_begin(C, ar, __func__, UI_EMBOSS_PULLDOWN); + UI_block_func_butmenu_set(block, do_controller_menu, NULL); - uiDefBut(block, BUTM, 1, IFACE_("Show Objects"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, ""); - uiDefBut(block, BUTM, 1, IFACE_("Hide Objects"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, ""); - uiDefBut(block, SEPRLINE, 0, "", 0, (short)(yco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, ""); - uiDefBut(block, BUTM, 1, IFACE_("Show Controllers"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 2, 2, ""); - uiDefBut(block, BUTM, 1, IFACE_("Hide Controllers"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 3, 3, ""); + uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Show Objects"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, ""); + uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Hide Objects"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, ""); + uiDefBut(block, UI_BTYPE_SEPR_LINE, 0, "", 0, (short)(yco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Show Controllers"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 2, 2, ""); + uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Hide Controllers"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 3, 3, ""); - uiBlockSetDirection(block, UI_TOP); - uiEndBlock(C, block); + UI_block_direction_set(block, UI_DIR_UP); + UI_block_end(C, block); return block; } @@ -859,17 +859,17 @@ static uiBlock *actuator_menu(bContext *C, ARegion *ar, void *UNUSED(arg)) uiBlock *block; int xco=0; - block= uiBeginBlock(C, ar, __func__, UI_EMBOSSP); - uiBlockSetButmFunc(block, do_actuator_menu, NULL); + block= UI_block_begin(C, ar, __func__, UI_EMBOSS_PULLDOWN); + UI_block_func_butmenu_set(block, do_actuator_menu, NULL); - uiDefBut(block, BUTM, 1, IFACE_("Show Objects"), 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, ""); - uiDefBut(block, BUTM, 1, IFACE_("Hide Objects"), 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, ""); - uiDefBut(block, SEPRLINE, 0, "", 0, (short)(xco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, ""); - uiDefBut(block, BUTM, 1, IFACE_("Show Actuators"), 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, ""); - uiDefBut(block, BUTM, 1, IFACE_("Hide Actuators"), 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 3, ""); + uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Show Objects"), 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, ""); + uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Hide Objects"), 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, ""); + uiDefBut(block, UI_BTYPE_SEPR_LINE, 0, "", 0, (short)(xco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Show Actuators"), 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, ""); + uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Hide Actuators"), 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 3, ""); - uiBlockSetDirection(block, UI_TOP); - uiEndBlock(C, block); + UI_block_direction_set(block, UI_DIR_UP); + UI_block_end(C, block); return block; } @@ -892,26 +892,26 @@ static uiBlock *controller_state_mask_menu(bContext *C, ARegion *ar, void *arg_c short yco = 12, xco = 0, stbit, offset; - block= uiBeginBlock(C, ar, __func__, UI_EMBOSS); + block= UI_block_begin(C, ar, __func__, UI_EMBOSS); /* use this for a fake extra empy space around the buttons */ - uiDefBut(block, LABEL, 0, "", -5, -5, 200, 34, NULL, 0, 0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 0, "", -5, -5, 200, 34, NULL, 0, 0, 0, 0, ""); for (offset=0; offset<15; offset += 5) { - uiBlockBeginAlign(block); + UI_block_align_begin(block); for (stbit=0; stbit<5; stbit++) { - but = uiDefButBitI(block, TOG, (1<<(stbit+offset)), (stbit+offset), "", (short)(xco+12*stbit+13*offset), yco, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, ""); - uiButSetFunc(but, check_controller_state_mask, but, &(cont->state_mask)); + but = uiDefButBitI(block, UI_BTYPE_TOGGLE, (1<<(stbit+offset)), (stbit+offset), "", (short)(xco+12*stbit+13*offset), yco, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, ""); + UI_but_func_set(but, check_controller_state_mask, but, &(cont->state_mask)); } for (stbit=0; stbit<5; stbit++) { - but = uiDefButBitI(block, TOG, (1<<(stbit+offset+15)), (stbit+offset+15), "", (short)(xco+12*stbit+13*offset), yco-12, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, ""); - uiButSetFunc(but, check_controller_state_mask, but, &(cont->state_mask)); + but = uiDefButBitI(block, UI_BTYPE_TOGGLE, (1<<(stbit+offset+15)), (stbit+offset+15), "", (short)(xco+12*stbit+13*offset), yco-12, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, ""); + UI_but_func_set(but, check_controller_state_mask, but, &(cont->state_mask)); } } - uiBlockEndAlign(block); + UI_block_align_end(block); - uiBlockSetDirection(block, UI_TOP); - uiEndBlock(C, block); + UI_block_direction_set(block, UI_DIR_UP); + UI_block_end(C, block); return block; } @@ -923,7 +923,7 @@ static bool is_sensor_linked(uiBlock *block, bSensor *sens) for (i=0; i<sens->totlinks; i++) { cont = sens->links[i]; - if (uiFindInlink(block, cont) != NULL) + if (UI_block_links_find_inlink(block, cont) != NULL) return 1; } return 0; @@ -2353,9 +2353,9 @@ void logic_buttons(bContext *C, ARegion *ar) idar= get_selected_and_linked_obs(C, &count, slogic->scaflag); BLI_snprintf(uiblockstr, sizeof(uiblockstr), "buttonswin %p", (void *)ar); - block= uiBeginBlock(C, ar, uiblockstr, UI_EMBOSS); - uiBlockSetHandleFunc(block, do_logic_buts, NULL); - uiBoundsBlock(block, U.widget_unit/2); + block= UI_block_begin(C, ar, uiblockstr, UI_EMBOSS); + UI_block_func_handle_set(block, do_logic_buts, NULL); + UI_block_bounds_set_normal(block, U.widget_unit/2); /* loop over all objects and set visible/linked flags for the logic bricks */ for (a=0; a<count; a++) { @@ -2401,7 +2401,7 @@ void logic_buttons(bContext *C, ARegion *ar) /* ****************** Controllers ****************** */ xco= 21 * U.widget_unit; yco= - U.widget_unit / 2; width= 15 * U.widget_unit; - layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, 0, UI_GetStyle()); + layout= UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, 0, UI_style_get()); row = uiLayoutRow(layout, true); uiDefBlockBut(block, controller_menu, NULL, IFACE_("Controllers"), xco - U.widget_unit / 2, yco, width, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */ @@ -2431,7 +2431,7 @@ void logic_buttons(bContext *C, ARegion *ar) uiItemR(split, &settings_ptr, "show_state_panel", UI_ITEM_R_NO_BG, "", ICON_DISCLOSURE_TRI_RIGHT); row = uiLayoutRow(split, true); - uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name + 2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide controllers")); + uiDefButBitS(block, UI_BTYPE_TOGGLE, OB_SHOWCONT, B_REDR, ob->id.name + 2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide controllers")); RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr); uiLayoutSetContextPointer(row, "object", &object_ptr); @@ -2479,9 +2479,9 @@ void logic_buttons(bContext *C, ARegion *ar) col = uiLayoutColumn(split, false); uiLayoutSetActive(col, RNA_boolean_get(&ptr, "active")); uiLayoutSetAlignment(col, UI_LAYOUT_ALIGN_LEFT); - but = uiDefIconBut(block, INLINK, 0, ICON_INLINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, cont, LINK_CONTROLLER, 0, 0, 0, ""); + but = uiDefIconBut(block, UI_BTYPE_INLINK, 0, ICON_INLINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, cont, LINK_CONTROLLER, 0, 0, 0, ""); if (!RNA_boolean_get(&ptr, "active")) { - uiButSetFlag(but, UI_BUT_SCA_LINK_GREY); + UI_but_flag_enable(but, UI_BUT_SCA_LINK_GREY); } //col = uiLayoutColumn(split, true); @@ -2502,22 +2502,22 @@ void logic_buttons(bContext *C, ARegion *ar) col = uiLayoutColumn(subsplit, false); uiLayoutSetActive(col, RNA_boolean_get(&ptr, "active")); uiLayoutSetAlignment(col, UI_LAYOUT_ALIGN_LEFT); - but = uiDefIconBut(block, LINK, 0, ICON_LINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); + but = uiDefIconBut(block, UI_BTYPE_LINK, 0, ICON_LINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); if (!RNA_boolean_get(&ptr, "active")) { - uiButSetFlag(but, UI_BUT_SCA_LINK_GREY); + UI_but_flag_enable(but, UI_BUT_SCA_LINK_GREY); } - uiSetButLink(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR); + UI_but_link_set(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR); } } - uiBlockLayoutResolve(block, NULL, &yco); /* stores final height in yco */ + UI_block_layout_resolve(block, NULL, &yco); /* stores final height in yco */ height = yco; /* ****************** Sensors ****************** */ xco= U.widget_unit / 2; yco= -U.widget_unit / 2; width= 17 * U.widget_unit; - layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, 0, UI_GetStyle()); + layout= UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, 0, UI_style_get()); row = uiLayoutRow(layout, true); uiDefBlockBut(block, sensor_menu, NULL, IFACE_("Sensors"), xco - U.widget_unit / 2, yco, 15 * U.widget_unit, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */ @@ -2537,7 +2537,7 @@ void logic_buttons(bContext *C, ARegion *ar) if ((ob->scavisflag & OB_VIS_SENS) == 0) continue; row = uiLayoutRow(layout, true); - uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name + 2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide sensors")); + uiDefButBitS(block, UI_BTYPE_TOGGLE, OB_SHOWSENS, B_REDR, ob->id.name + 2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide sensors")); RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr); uiLayoutSetContextPointer(row, "object", &object_ptr); @@ -2575,23 +2575,23 @@ void logic_buttons(bContext *C, ARegion *ar) /* put link button to the right */ col = uiLayoutColumn(split, false); uiLayoutSetActive(col, RNA_boolean_get(&ptr, "active")); - but = uiDefIconBut(block, LINK, 0, ICON_LINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); + but = uiDefIconBut(block, UI_BTYPE_LINK, 0, ICON_LINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); if (!RNA_boolean_get(&ptr, "active")) { - uiButSetFlag(but, UI_BUT_SCA_LINK_GREY); + UI_but_flag_enable(but, UI_BUT_SCA_LINK_GREY); } /* use old-school uiButtons for links for now */ - uiSetButLink(but, NULL, (void ***)&sens->links, &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER); + UI_but_link_set(but, NULL, (void ***)&sens->links, &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER); } } } - uiBlockLayoutResolve(block, NULL, &yco); /* stores final height in yco */ + UI_block_layout_resolve(block, NULL, &yco); /* stores final height in yco */ height = MIN2(height, yco); /* ****************** Actuators ****************** */ xco= 40 * U.widget_unit; yco= -U.widget_unit / 2; width= 17 * U.widget_unit; - layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, 0, UI_GetStyle()); + layout= UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, 0, UI_style_get()); row = uiLayoutRow(layout, true); uiDefBlockBut(block, actuator_menu, NULL, IFACE_("Actuators"), xco - U.widget_unit / 2, yco, 15 * U.widget_unit, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */ @@ -2613,7 +2613,7 @@ void logic_buttons(bContext *C, ARegion *ar) } row = uiLayoutRow(layout, true); - uiDefButBitS(block, TOG, OB_SHOWACT, B_REDR, ob->id.name + 2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide actuators")); + uiDefButBitS(block, UI_BTYPE_TOGGLE, OB_SHOWACT, B_REDR, ob->id.name + 2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide actuators")); RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr); uiLayoutSetContextPointer(row, "object", &object_ptr); @@ -2644,9 +2644,9 @@ void logic_buttons(bContext *C, ARegion *ar) /* put inlink button to the left */ col = uiLayoutColumn(split, false); uiLayoutSetActive(col, RNA_boolean_get(&ptr, "active")); - but = uiDefIconBut(block, INLINK, 0, ICON_INLINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, act, LINK_ACTUATOR, 0, 0, 0, ""); + but = uiDefIconBut(block, UI_BTYPE_INLINK, 0, ICON_INLINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, act, LINK_ACTUATOR, 0, 0, 0, ""); if (!RNA_boolean_get(&ptr, "active")) { - uiButSetFlag(but, UI_BUT_SCA_LINK_GREY); + UI_but_flag_enable(but, UI_BUT_SCA_LINK_GREY); } col = uiLayoutColumn(split, true); @@ -2661,7 +2661,7 @@ void logic_buttons(bContext *C, ARegion *ar) } } } - uiBlockLayoutResolve(block, NULL, &yco); /* stores final height in yco */ + UI_block_layout_resolve(block, NULL, &yco); /* stores final height in yco */ height = MIN2(height, yco); UI_view2d_totRect_set(&ar->v2d, 57.5f * U.widget_unit, height - U.widget_unit); @@ -2669,10 +2669,10 @@ void logic_buttons(bContext *C, ARegion *ar) /* set the view */ UI_view2d_view_ortho(&ar->v2d); - uiComposeLinks(block); + UI_block_links_compose(block); - uiEndBlock(C, block); - uiDrawBlock(C, block); + UI_block_end(C, block); + UI_block_draw(C, block); /* restore view matrix */ UI_view2d_view_restore(C); diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index 1090106d79f..66023ce1243 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -143,6 +143,7 @@ bool nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_p case ANIMTYPE_DSLAT: case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: + case ANIMTYPE_DSGPENCIL: { /* for these channels, we only do AnimData */ if (ale->adt && adt_ptr) { @@ -254,7 +255,7 @@ static void nla_panel_animdata(const bContext *C, Panel *pa) /* adt = adt_ptr.data; */ block = uiLayoutGetBlock(layout); - uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL); + UI_block_func_handle_set(block, do_nla_region_buttons, NULL); /* AnimData Source Properties ----------------------------------- */ @@ -309,7 +310,7 @@ static void nla_panel_track(const bContext *C, Panel *pa) return; block = uiLayoutGetBlock(layout); - uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL); + UI_block_func_handle_set(block, do_nla_region_buttons, NULL); /* Info - Active NLA-Context:Track ---------------------- */ row = uiLayoutRow(layout, true); @@ -329,7 +330,7 @@ static void nla_panel_properties(const bContext *C, Panel *pa) return; block = uiLayoutGetBlock(layout); - uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL); + UI_block_func_handle_set(block, do_nla_region_buttons, NULL); /* Strip Properties ------------------------------------- */ /* strip type */ @@ -394,7 +395,7 @@ static void nla_panel_actclip(const bContext *C, Panel *pa) return; block = uiLayoutGetBlock(layout); - uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL); + UI_block_func_handle_set(block, do_nla_region_buttons, NULL); /* Strip Properties ------------------------------------- */ /* action pointer */ @@ -434,7 +435,7 @@ static void nla_panel_evaluation(const bContext *C, Panel *pa) return; block = uiLayoutGetBlock(layout); - uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL); + UI_block_func_handle_set(block, do_nla_region_buttons, NULL); col = uiLayoutColumn(layout, true); uiItemR(col, &strip_ptr, "use_animated_influence", 0, NULL, ICON_NONE); @@ -468,7 +469,7 @@ static void nla_panel_modifiers(const bContext *C, Panel *pa) strip = strip_ptr.data; block = uiLayoutGetBlock(pa->layout); - uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL); + UI_block_func_handle_set(block, do_nla_region_buttons, NULL); /* 'add modifier' button at top of panel */ { @@ -477,7 +478,7 @@ static void nla_panel_modifiers(const bContext *C, Panel *pa) // XXX for now, this will be a operator button which calls a temporary 'add modifier' operator // FIXME: we need to set the only-active property so that this will only add modifiers for the active strip (not all selected) - uiDefButO(block, BUT, "NLA_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, IFACE_("Add Modifier"), 10, 0, 150, 20, + uiDefButO(block, UI_BTYPE_BUT, "NLA_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, IFACE_("Add Modifier"), 10, 0, 150, 20, TIP_("Adds a new F-Modifier for the active NLA Strip")); /* copy/paste (as sub-row)*/ diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c index fbb4d273626..0abe5e42c3e 100644 --- a/source/blender/editors/space_nla/nla_channels.c +++ b/source/blender/editors/space_nla/nla_channels.c @@ -182,6 +182,7 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe case ANIMTYPE_DSLAT: case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: + case ANIMTYPE_DSGPENCIL: { /* sanity checking... */ if (ale->adt) { diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index ac8dca6e83a..c5105fd9724 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -59,7 +59,6 @@ #include "WM_types.h" #include "UI_interface.h" -#include "UI_interface_icons.h" #include "UI_resources.h" #include "UI_view2d.h" @@ -341,9 +340,9 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri if (nonSolo == 0) { /* strip is in normal track */ glColor3fv(color); - uiSetRoundBox(UI_CNR_ALL); /* all corners rounded */ + UI_draw_roundbox_corner_set(UI_CNR_ALL); /* all corners rounded */ - uiDrawBoxShade(GL_POLYGON, strip->start, yminc, strip->end, ymaxc, 0.0, 0.5, 0.1); + UI_draw_roundbox_shade_x(GL_POLYGON, strip->start, yminc, strip->end, ymaxc, 0.0, 0.5, 0.1); } else { /* strip is in disabled track - make less visible */ @@ -379,7 +378,7 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri setlinestyle(4); /* draw outline */ - uiDrawBoxShade(GL_LINE_LOOP, strip->start, yminc, strip->end, ymaxc, 0.0, 0.0, 0.1); + UI_draw_roundbox_shade_x(GL_LINE_LOOP, strip->start, yminc, strip->end, ymaxc, 0.0, 0.0, 0.1); /* if action-clip strip, draw lines delimiting repeats too (in the same color as outline) */ if ((strip->type == NLASTRIP_TYPE_CLIP) && IS_EQF(strip->repeat, 1.0f) == 0) { @@ -670,7 +669,7 @@ void draw_nla_channel_list(bContext *C, bAnimContext *ac, ARegion *ar) } } { /* second pass: UI widgets */ - uiBlock *block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); + uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS); size_t channel_index = 0; y = (float)(-NLACHANNEL_HEIGHT(snla)); @@ -697,8 +696,8 @@ void draw_nla_channel_list(bContext *C, bAnimContext *ac, ARegion *ar) channel_index++; } - uiEndBlock(C, block); - uiDrawBlock(C, block); + UI_block_end(C, block); + UI_block_draw(C, block); glDisable(GL_BLEND); } diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index c787177a62a..a883f350f1c 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -1372,11 +1372,15 @@ static int nlaedit_toggle_mute_exec(bContext *C, wmOperator *UNUSED(op)) /* just flip the mute flag for now */ // TODO: have a pre-pass to check if mute all or unmute all? strip->flag ^= NLASTRIP_FLAG_MUTED; + + /* tag AnimData to get recalculated */ + ale->update |= ANIM_UPDATE_DEPS; } } } - /* free temp data */ + /* cleanup */ + ANIM_animdata_update(&ac, &anim_data); ANIM_animdata_freelist(&anim_data); /* set notifier that things have changed */ @@ -1436,7 +1440,9 @@ static int nlaedit_swap_exec(bContext *C, wmOperator *op) if (BLI_listbase_is_empty(&nlt->strips) == false) { NlaStrip *mstrip = (NlaStrip *)nlt->strips.first; - if ((mstrip->flag & NLASTRIP_FLAG_TEMP_META) && (BLI_countlist(&mstrip->strips) == 2)) { + if ((mstrip->flag & NLASTRIP_FLAG_TEMP_META) && + (BLI_listbase_count_ex(&mstrip->strips, 3) == 2)) + { /* remove this temp meta, so that we can see the strips inside */ BKE_nlastrips_clear_metas(&nlt->strips, 0, 1); } @@ -2128,9 +2134,13 @@ static int nlaedit_snap_exec(bContext *C, wmOperator *op) /* remove the meta-strips now that we're done */ BKE_nlastrips_clear_metas(&nlt->strips, 0, 1); + + /* tag for recalculating the animation */ + ale->update |= ANIM_UPDATE_DEPS; } - /* free temp data */ + /* cleanup */ + ANIM_animdata_update(&ac, &anim_data); ANIM_animdata_freelist(&anim_data); /* refresh auto strip properties */ @@ -2174,8 +2184,8 @@ static int nla_fmodifier_add_invoke(bContext *C, wmOperator *UNUSED(op), const w uiLayout *layout; int i; - pup = uiPupMenuBegin(C, IFACE_("Add F-Modifier"), ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, IFACE_("Add F-Modifier"), ICON_NONE); + layout = UI_popup_menu_layout(pup); /* start from 1 to skip the 'Invalid' modifier type */ for (i = 1; i < FMODIFIER_NUM_TYPES; i++) { @@ -2192,9 +2202,9 @@ static int nla_fmodifier_add_invoke(bContext *C, wmOperator *UNUSED(op), const w } uiItemS(layout); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } static int nla_fmodifier_add_exec(bContext *C, wmOperator *op) @@ -2244,6 +2254,7 @@ static int nla_fmodifier_add_exec(bContext *C, wmOperator *op) if (fcm) { set_active_fmodifier(&strip->modifiers, fcm); + ale->update |= ANIM_UPDATE_DEPS; } else { BKE_reportf(op->reports, RPT_ERROR, @@ -2254,6 +2265,7 @@ static int nla_fmodifier_add_exec(bContext *C, wmOperator *op) } /* free temp data */ + ANIM_animdata_update(&ac, &anim_data); ANIM_animdata_freelist(&anim_data); /* set notifier that things have changed */ @@ -2319,6 +2331,9 @@ static int nla_fmodifier_copy_exec(bContext *C, wmOperator *op) } } + /* free temp data */ + ANIM_animdata_freelist(&anim_data); + /* successful or not? */ if (ok == 0) { BKE_report(op->reports, RPT_ERROR, "No F-Modifiers available to be copied"); @@ -2373,10 +2388,12 @@ static int nla_fmodifier_paste_exec(bContext *C, wmOperator *op) for (strip = nlt->strips.first; strip; strip = strip->next) { // TODO: do we want to replace existing modifiers? add user pref for that! ok += ANIM_fmodifiers_paste_from_buf(&strip->modifiers, 0); + ale->update |= ANIM_UPDATE_DEPS; } } /* clean up */ + ANIM_animdata_update(&ac, &anim_data); ANIM_animdata_freelist(&anim_data); /* successful or not? */ diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c index 5e1381db696..b3a875047db 100644 --- a/source/blender/editors/space_nla/nla_ops.c +++ b/source/blender/editors/space_nla/nla_ops.c @@ -28,15 +28,11 @@ * \ingroup spnla */ - #include <string.h> #include <stdio.h> #include "DNA_scene_types.h" - -#include "BLI_blenlib.h" - #include "BKE_context.h" #include "BKE_screen.h" diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c index 134e5dd80a2..cc1d6002134 100644 --- a/source/blender/editors/space_nla/space_nla.c +++ b/source/blender/editors/space_nla/space_nla.c @@ -180,7 +180,7 @@ static void nla_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa) { SpaceNla *snla = (SpaceNla *)sa->spacedata.first; - /* init dopesheet data if non-existant (i.e. for old files) */ + /* init dopesheet data if non-existent (i.e. for old files) */ if (snla->ads == NULL) { snla->ads = MEM_callocN(sizeof(bDopeSheet), "NlaEdit DopeSheet"); snla->ads->source = (ID *)G.main->scene.first; // XXX this is bad, but we need this to be set correct @@ -305,7 +305,7 @@ static void nla_main_area_draw(const bContext *C, ARegion *ar) /* markers */ UI_view2d_view_orthoSpecial(ar, v2d, 1); - draw_markers_time(C, 0); + ED_markers_draw(C, DRAW_MARKERS_MARGIN); /* preview range */ UI_view2d_view_ortho(v2d); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 5a3d4d6312a..d03f980e204 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -54,7 +54,6 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "RNA_enum_types.h" #include "ED_node.h" @@ -64,7 +63,6 @@ #include "UI_resources.h" #include "IMB_colormanagement.h" -#include "IMB_imbuf.h" #include "IMB_imbuf_types.h" #include "node_intern.h" /* own include */ @@ -382,7 +380,7 @@ static void node_draw_frame_prepare(const bContext *UNUSED(C), bNodeTree *ntree, static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float aspect) { /* XXX font id is crap design */ - const int fontid = UI_GetStyle()->widgetlabel.uifont_id; + const int fontid = UI_style_get()->widgetlabel.uifont_id; NodeFrame *data = (NodeFrame *)node->storage; rctf *rct = &node->totr; int color_id = node_get_colorid(node); @@ -424,7 +422,7 @@ static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode, /* skip if out of view */ if (BLI_rctf_isect(&node->totr, &ar->v2d.cur, NULL) == false) { - uiEndBlock(C, node->block); + UI_block_end(C, node->block); node->block = NULL; return; } @@ -441,8 +439,8 @@ static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode, else UI_ThemeColor4(TH_NODE_FRAME); glEnable(GL_BLEND); - uiSetRoundBox(UI_CNR_ALL); - uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD); + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD); glDisable(GL_BLEND); /* outline active and selected emphasis */ @@ -454,8 +452,8 @@ static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode, UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -40); else UI_ThemeColorShadeAlpha(TH_SELECT, 0, -40); - uiSetRoundBox(UI_CNR_ALL); - uiDrawBox(GL_LINE_LOOP, + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD); @@ -468,8 +466,8 @@ static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode, UI_ThemeClearColor(color_id); - uiEndBlock(C, node->block); - uiDrawBlock(C, node->block); + UI_block_end(C, node->block); + UI_block_draw(C, node->block); node->block = NULL; } @@ -546,7 +544,7 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED( if (node->totr.xmax < ar->v2d.cur.xmin || node->totr.xmin > ar->v2d.cur.xmax || node->totr.ymax < ar->v2d.cur.ymin || node->totr.ymin > ar->v2d.cur.ymax) { - uiEndBlock(C, node->block); + UI_block_end(C, node->block); node->block = NULL; return; } @@ -556,10 +554,10 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED( */ #if 0 /* body */ - uiSetRoundBox(UI_CNR_ALL); + UI_draw_roundbox_corner_set(UI_CNR_ALL); UI_ThemeColor4(TH_NODE); glEnable(GL_BLEND); - uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, size); + UI_draw_roundbox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, size); glDisable(GL_BLEND); /* outline active and selected emphasis */ @@ -571,7 +569,7 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED( UI_ThemeColorShadeAlpha(TH_TEXT_HI, 0, -40); else UI_ThemeColorShadeAlpha(TH_TEXT_HI, -20, -120); - uiDrawBox(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, size); + UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, size); glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); @@ -581,7 +579,7 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED( if (node->label[0] != '\0') { /* draw title (node label) */ BLI_strncpy(showname, node->label, sizeof(showname)); - uiDefBut(node->block, LABEL, 0, showname, + uiDefBut(node->block, UI_BTYPE_LABEL, 0, showname, (int)(rct->xmin - NODE_DYS), (int)(rct->ymax), (short)512, (short)NODE_DY, NULL, 0, 0, 0, 0, NULL); @@ -594,8 +592,8 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED( node_socket_circle_draw(C, ntree, node, sock, socket_size, (sock->flag & SELECT) || (node->flag & SELECT)); } - uiEndBlock(C, node->block); - uiDrawBlock(C, node->block); + UI_block_end(C, node->block); + UI_block_draw(C, node->block); node->block = NULL; } @@ -2899,9 +2897,9 @@ static void node_file_output_socket_draw(bContext *C, uiLayout *layout, PointerR RNA_property_enum_name((bContext *)C, &imfptr, imtype_prop, RNA_property_enum_get(&imfptr, imtype_prop), &imtype_name); block = uiLayoutGetBlock(row); - uiBlockSetEmboss(block, UI_EMBOSSP); + UI_block_emboss_set(block, UI_EMBOSS_PULLDOWN); uiItemL(row, imtype_name, ICON_NONE); - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); } } @@ -3444,7 +3442,7 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link) { bool do_shaded = false; bool do_triple = false; - int th_col1 = TH_SYNTAX_R, th_col2 = TH_SYNTAX_R, th_col3 = TH_WIRE; + int th_col1 = TH_WIRE_INNER, th_col2 = TH_WIRE_INNER, th_col3 = TH_WIRE; if (link->fromsock == NULL && link->tosock == NULL) return; diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c index 02e6f9b69f3..c3064432131 100644 --- a/source/blender/editors/space_node/node_add.c +++ b/source/blender/editors/space_node/node_add.c @@ -29,8 +29,6 @@ * \ingroup spnode */ -#include <errno.h> - #include "MEM_guardedalloc.h" #include "DNA_node_types.h" @@ -227,7 +225,7 @@ static int add_reroute_exec(bContext *C, wmOperator *op) float insert_point[2]; /* always first */ - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); node_deselect_all(snode); @@ -304,33 +302,12 @@ static int node_add_file_exec(bContext *C, wmOperator *op) { SpaceNode *snode = CTX_wm_space_node(C); bNode *node; - Image *ima = NULL; + Image *ima; int type = 0; - /* check input variables */ - if (RNA_struct_property_is_set(op->ptr, "filepath")) { - char path[FILE_MAX]; - RNA_string_get(op->ptr, "filepath", path); - - errno = 0; - - ima = BKE_image_load_exists(path); - - if (!ima) { - BKE_reportf(op->reports, RPT_ERROR, "Cannot read image '%s': %s", - path, errno ? strerror(errno) : TIP_("unsupported format")); - return OPERATOR_CANCELLED; - } - } - else if (RNA_struct_property_is_set(op->ptr, "name")) { - char name[MAX_ID_NAME - 2]; - RNA_string_get(op->ptr, "name", name); - ima = (Image *)BKE_libblock_find_name(ID_IM, name); - - if (!ima) { - BKE_reportf(op->reports, RPT_ERROR, "Image '%s' not found", name); - return OPERATOR_CANCELLED; - } + ima = (Image *)WM_operator_drop_load_path(C, op, ID_IM); + if (!ima) { + return OPERATOR_CANCELLED; } switch (snode->nodetree->type) { @@ -347,7 +324,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); node = node_add_node(C, NULL, type, snode->cursor[0], snode->cursor[1]); @@ -397,8 +374,8 @@ void NODE_OT_add_file(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE, - WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); //XXX TODO, relative_path + WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, + WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Datablock name to assign"); } @@ -426,7 +403,7 @@ static int node_add_mask_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); node = node_add_node(C, NULL, CMP_NODE_MASK, snode->cursor[0], snode->cursor[1]); @@ -498,7 +475,7 @@ static int new_node_tree_exec(bContext *C, wmOperator *op) ntree = ntreeAddTree(bmain, treename, idname); /* hook into UI */ - uiIDContextProperty(C, &ptr, &prop); + UI_context_active_but_prop_get_templateID(C, &ptr, &prop); if (prop) { /* RNA_property_pointer_set increases the user count, diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c index 58d94a28226..76a096b8471 100644 --- a/source/blender/editors/space_node/node_buttons.c +++ b/source/blender/editors/space_node/node_buttons.c @@ -57,6 +57,7 @@ /* ******************* node space & buttons ************** */ +#if 0 /* poll for active nodetree */ static int active_nodetree_poll(const bContext *C, PanelType *UNUSED(pt)) { @@ -64,6 +65,7 @@ static int active_nodetree_poll(const bContext *C, PanelType *UNUSED(pt)) return (snode && snode->nodetree); } +#endif static int node_sockets_poll(const bContext *C, PanelType *UNUSED(pt)) { @@ -197,15 +199,6 @@ void node_buttons_register(ARegionType *art) pt->draw = node_tree_interface_panel; pt->poll = node_tree_interface_poll; BLI_addtail(&art->paneltypes, pt); - - pt = MEM_callocN(sizeof(PanelType), "spacetype node panel gpencil"); - strcpy(pt->idname, "NODE_PT_gpencil"); - strcpy(pt->label, N_("Grease Pencil")); - strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA); - pt->draw_header = ED_gpencil_panel_standard_header; - pt->draw = ED_gpencil_panel_standard; - pt->poll = active_nodetree_poll; - BLI_addtail(&art->paneltypes, pt); } static int node_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op)) diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 7b5ec38f4c6..127e2d3a48e 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -66,10 +66,13 @@ #include "RNA_access.h" #include "node_intern.h" /* own include */ -#include "COM_compositor.h" + +#ifdef WITH_COMPOSITOR +# include "COM_compositor.h" +#endif /* XXX interface.h */ -extern void ui_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int select); +extern void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int select); float ED_node_grid_size(void) { @@ -214,7 +217,7 @@ void ED_node_sort(bNodeTree *ntree) { /* merge sort is the algorithm of choice here */ bNode *first_a, *first_b, *node_a, *node_b, *tmp; - int totnodes = BLI_countlist(&ntree->nodes); + int totnodes = BLI_listbase_count(&ntree->nodes); int k, a, b; k = 1; @@ -283,11 +286,11 @@ static void node_uiblocks_init(const bContext *C, bNodeTree *ntree) for (node = ntree->nodes.first; node; node = node->next) { /* ui block */ BLI_snprintf(uiblockstr, sizeof(uiblockstr), "node buttons %p", (void *)node); - node->block = uiBeginBlock(C, CTX_wm_region(C), uiblockstr, UI_EMBOSS); - uiBlockSetHandleFunc(node->block, do_node_internal_buttons, node); + node->block = UI_block_begin(C, CTX_wm_region(C), uiblockstr, UI_EMBOSS); + UI_block_func_handle_set(node->block, do_node_internal_buttons, node); /* this cancels events for background nodes */ - uiBlockSetFlag(node->block, UI_BLOCK_CLIP_EVENTS); + UI_block_flag_enable(node->block, UI_BLOCK_CLIP_EVENTS); } } @@ -336,8 +339,9 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) RNA_pointer_create(&ntree->id, &RNA_NodeSocket, nsock, &sockptr); - layout = uiBlockLayout(node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, - locx + NODE_DYS, dy, NODE_WIDTH(node) - NODE_DY, NODE_DY, 0, UI_GetStyle()); + layout = UI_block_layout( + node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, + locx + NODE_DYS, dy, NODE_WIDTH(node) - NODE_DY, NODE_DY, 0, UI_style_get()); /* context pointers for current node and socket */ uiLayoutSetContextPointer(layout, "node", &nodeptr); uiLayoutSetContextPointer(layout, "socket", &sockptr); @@ -348,8 +352,8 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) nsock->typeinfo->draw((bContext *)C, row, &sockptr, &nodeptr, IFACE_(nsock->name)); - uiBlockEndAlign(node->block); - uiBlockLayoutResolve(node->block, NULL, &buty); + UI_block_align_end(node->block); + UI_block_layout_resolve(node->block, NULL, &buty); /* ensure minimum socket height in case layout is empty */ buty = min_ii(buty, dy - NODE_DY); @@ -407,14 +411,15 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) node->butr.ymax = 0; - layout = uiBlockLayout(node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, - locx + NODE_DYS, dy, node->butr.xmax, 0, 0, UI_GetStyle()); + layout = UI_block_layout( + node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, + locx + NODE_DYS, dy, node->butr.xmax, 0, 0, UI_style_get()); uiLayoutSetContextPointer(layout, "node", &nodeptr); node->typeinfo->draw_buttons(layout, (bContext *)C, &nodeptr); - uiBlockEndAlign(node->block); - uiBlockLayoutResolve(node->block, NULL, &buty); + UI_block_align_end(node->block); + UI_block_layout_resolve(node->block, NULL, &buty); dy = buty - NODE_DYS / 2; } @@ -426,8 +431,9 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) RNA_pointer_create(&ntree->id, &RNA_NodeSocket, nsock, &sockptr); - layout = uiBlockLayout(node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, - locx + NODE_DYS, dy, NODE_WIDTH(node) - NODE_DY, NODE_DY, 0, UI_GetStyle()); + layout = UI_block_layout( + node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, + locx + NODE_DYS, dy, NODE_WIDTH(node) - NODE_DY, NODE_DY, 0, UI_style_get()); /* context pointers for current node and socket */ uiLayoutSetContextPointer(layout, "node", &nodeptr); uiLayoutSetContextPointer(layout, "socket", &sockptr); @@ -436,8 +442,8 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) nsock->typeinfo->draw((bContext *)C, row, &sockptr, &nodeptr, IFACE_(nsock->name)); - uiBlockEndAlign(node->block); - uiBlockLayoutResolve(node->block, NULL, &buty); + UI_block_align_end(node->block); + UI_block_layout_resolve(node->block, NULL, &buty); /* ensure minimum socket height in case layout is empty */ buty = min_ii(buty, dy - NODE_DY); @@ -463,11 +469,12 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) /* Set the block bounds to clip mouse events from underlying nodes. * Add a margin for sockets on each side. */ - uiExplicitBoundsBlock(node->block, - node->totr.xmin - NODE_SOCKSIZE, - node->totr.ymin, - node->totr.xmax + NODE_SOCKSIZE, - node->totr.ymax); + UI_block_bounds_set_explicit( + node->block, + node->totr.xmin - NODE_SOCKSIZE, + node->totr.ymin, + node->totr.xmax + NODE_SOCKSIZE, + node->totr.ymax); } /* based on settings in node, sets drawing rect info. each redraw! */ @@ -524,11 +531,12 @@ static void node_update_hidden(bNode *node) /* Set the block bounds to clip mouse events from underlying nodes. * Add a margin for sockets on each side. */ - uiExplicitBoundsBlock(node->block, - node->totr.xmin - NODE_SOCKSIZE, - node->totr.ymin, - node->totr.xmax + NODE_SOCKSIZE, - node->totr.ymax); + UI_block_bounds_set_explicit( + node->block, + node->totr.xmin - NODE_SOCKSIZE, + node->totr.ymin, + node->totr.xmax + NODE_SOCKSIZE, + node->totr.ymax); } void node_update_default(const bContext *C, bNodeTree *ntree, bNode *node) @@ -739,16 +747,16 @@ void node_draw_shadow(SpaceNode *snode, bNode *node, float radius, float alpha) { rctf *rct = &node->totr; - uiSetRoundBox(UI_CNR_ALL); + UI_draw_roundbox_corner_set(UI_CNR_ALL); if (node->parent == NULL) - ui_dropshadow(rct, radius, snode->aspect, alpha, node->flag & SELECT); + ui_draw_dropshadow(rct, radius, snode->aspect, alpha, node->flag & SELECT); else { const float margin = 3.0f; glColor4f(0.0f, 0.0f, 0.0f, 0.33f); glEnable(GL_BLEND); - uiRoundBox(rct->xmin - margin, rct->ymin - margin, - rct->xmax + margin, rct->ymax + margin, radius + margin); + UI_draw_roundbox(rct->xmin - margin, rct->ymin - margin, + rct->xmax + margin, rct->ymax + margin, radius + margin); glDisable(GL_BLEND); } } @@ -771,7 +779,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN /* skip if out of view */ if (BLI_rctf_isect(&node->totr, &ar->v2d.cur, NULL) == false) { - uiEndBlock(C, node->block); + UI_block_end(C, node->block); node->block = NULL; return; } @@ -800,8 +808,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN } #endif - uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT); - uiRoundBox(rct->xmin, rct->ymax - NODE_DY, rct->xmax, rct->ymax, BASIS_RAD); + UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT); + UI_draw_roundbox(rct->xmin, rct->ymax - NODE_DY, rct->xmax, rct->ymax, BASIS_RAD); /* show/hide icons */ iconofs = rct->xmax - 0.35f * U.widget_unit; @@ -810,27 +818,27 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN if (node->typeinfo->flag & NODE_PREVIEW) { uiBut *but; iconofs -= iconbutw; - uiBlockSetEmboss(node->block, UI_EMBOSSN); - but = uiDefIconBut(node->block, TOGBUT, B_REDR, ICON_MATERIAL, + UI_block_emboss_set(node->block, UI_EMBOSS_NONE); + but = uiDefIconBut(node->block, UI_BTYPE_BUT_TOGGLE, B_REDR, ICON_MATERIAL, iconofs, rct->ymax - NODE_DY, iconbutw, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); - uiButSetFunc(but, node_toggle_button_cb, node, (void *)"NODE_OT_preview_toggle"); + UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_preview_toggle"); /* XXX this does not work when node is activated and the operator called right afterwards, * since active ID is not updated yet (needs to process the notifier). * This can only work as visual indicator! */ // if (!(node->flag & (NODE_ACTIVE_ID|NODE_DO_OUTPUT))) -// uiButSetFlag(but, UI_BUT_DISABLED); - uiBlockSetEmboss(node->block, UI_EMBOSS); +// UI_but_flag_enable(but, UI_BUT_DISABLED); + UI_block_emboss_set(node->block, UI_EMBOSS); } /* group edit */ if (node->type == NODE_GROUP) { uiBut *but; iconofs -= iconbutw; - uiBlockSetEmboss(node->block, UI_EMBOSSN); - but = uiDefIconBut(node->block, TOGBUT, B_REDR, ICON_NODETREE, + UI_block_emboss_set(node->block, UI_EMBOSS_NONE); + but = uiDefIconBut(node->block, UI_BTYPE_BUT_TOGGLE, B_REDR, ICON_NODETREE, iconofs, rct->ymax - NODE_DY, iconbutw, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); - uiButSetFunc(but, node_toggle_button_cb, node, (void *)"NODE_OT_group_edit"); - uiBlockSetEmboss(node->block, UI_EMBOSS); + UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_group_edit"); + UI_block_emboss_set(node->block, UI_EMBOSS); } /* title */ @@ -844,15 +852,15 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN uiBut *but; int but_size = UI_UNIT_X * 0.6f; /* XXX button uses a custom triangle draw below, so make it invisible without icon */ - uiBlockSetEmboss(node->block, UI_EMBOSSN); - but = uiDefBut(node->block, TOGBUT, B_REDR, "", + UI_block_emboss_set(node->block, UI_EMBOSS_NONE); + but = uiDefBut(node->block, UI_BTYPE_BUT_TOGGLE, B_REDR, "", rct->xmin + 0.5f * U.widget_unit - but_size / 2, rct->ymax - NODE_DY / 2.0f - but_size / 2, but_size, but_size, NULL, 0, 0, 0, 0, ""); - uiButSetFunc(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle"); - uiBlockSetEmboss(node->block, UI_EMBOSS); + UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle"); + UI_block_emboss_set(node->block, UI_EMBOSS); /* custom draw function for this button */ - UI_DrawTriIcon(rct->xmin + 0.5f * U.widget_unit, rct->ymax - NODE_DY / 2.0f, 'v'); + UI_draw_icon_tri(rct->xmin + 0.5f * U.widget_unit, rct->ymax - NODE_DY / 2.0f, 'v'); } /* this isn't doing anything for the label, so commenting out */ @@ -868,7 +876,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN //if (node->flag & NODE_MUTED) // BLI_snprintf(showname, sizeof(showname), "[%s]", showname); /* XXX - don't print into self! */ - uiDefBut(node->block, LABEL, 0, showname, + uiDefBut(node->block, UI_BTYPE_LABEL, 0, showname, (int)(rct->xmin + (NODE_MARGIN_X)), (int)(rct->ymax - NODE_DY), (short)(iconofs - rct->xmin - 18.0f), (short)NODE_DY, NULL, 0, 0, 0, 0, ""); @@ -881,8 +889,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN else UI_ThemeColor4(TH_NODE); glEnable(GL_BLEND); - uiSetRoundBox(UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT); - uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax - NODE_DY, BASIS_RAD); + UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT); + UI_draw_roundbox(rct->xmin, rct->ymin, rct->xmax, rct->ymax - NODE_DY, BASIS_RAD); glDisable(GL_BLEND); /* outline active and selected emphasis */ @@ -896,8 +904,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN else UI_ThemeColorShadeAlpha(TH_SELECT, 0, -40); - uiSetRoundBox(UI_CNR_ALL); - uiDrawBox(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD); + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD); glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); @@ -936,8 +944,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN UI_ThemeClearColor(color_id); - uiEndBlock(C, node->block); - uiDrawBlock(C, node->block); + UI_block_end(C, node->block); + UI_block_draw(C, node->block); node->block = NULL; } @@ -969,7 +977,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b (void)ntree; #endif - uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad); + UI_draw_roundbox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad); /* outline active and selected emphasis */ if (node->flag & SELECT) { @@ -980,7 +988,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -40); else UI_ThemeColorShadeAlpha(TH_SELECT, 0, -40); - uiDrawBox(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad); + UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad); glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); @@ -992,7 +1000,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b glEnable(GL_LINE_SMOOTH); glColor3fv(node->color); - uiDrawBox(GL_LINE_LOOP, rct->xmin + 1, rct->ymin + 1, rct->xmax -1, rct->ymax - 1, hiddenrad); + UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin + 1, rct->ymin + 1, rct->xmax -1, rct->ymax - 1, hiddenrad); glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); @@ -1009,15 +1017,15 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b uiBut *but; int but_size = UI_UNIT_X * 0.6f; /* XXX button uses a custom triangle draw below, so make it invisible without icon */ - uiBlockSetEmboss(node->block, UI_EMBOSSN); - but = uiDefBut(node->block, TOGBUT, B_REDR, "", + UI_block_emboss_set(node->block, UI_EMBOSS_NONE); + but = uiDefBut(node->block, UI_BTYPE_BUT_TOGGLE, B_REDR, "", rct->xmin + 10.0f - but_size / 2, centy - but_size / 2, but_size, but_size, NULL, 0, 0, 0, 0, ""); - uiButSetFunc(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle"); - uiBlockSetEmboss(node->block, UI_EMBOSS); + UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle"); + UI_block_emboss_set(node->block, UI_EMBOSS); /* custom draw function for this button */ - UI_DrawTriIcon(rct->xmin + 10.0f, centy, 'h'); + UI_draw_icon_tri(rct->xmin + 10.0f, centy, 'h'); } /* disable lines */ @@ -1035,7 +1043,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b //if (node->flag & NODE_MUTED) // BLI_snprintf(showname, sizeof(showname), "[%s]", showname); /* XXX - don't print into self! */ - uiDefBut(node->block, LABEL, 0, showname, + uiDefBut(node->block, UI_BTYPE_LABEL, 0, showname, (int)(rct->xmin + (NODE_MARGIN_X)), (int)(centy - 10), (short)(BLI_rctf_size_x(rct) - 18.0f - 12.0f), (short)NODE_DY, NULL, 0, 0, 0, 0, ""); @@ -1063,8 +1071,8 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b node_socket_circle_draw(C, ntree, node, sock, socket_size, sock->flag & SELECT); } - uiEndBlock(C, node->block); - uiDrawBlock(C, node->block); + UI_block_end(C, node->block); + UI_block_draw(C, node->block); node->block = NULL; } @@ -1243,15 +1251,15 @@ static void draw_group_overlay(const bContext *C, ARegion *ar) /* shade node groups to separate them visually */ UI_ThemeColorShadeAlpha(TH_NODE_GROUP, 0, -70); glEnable(GL_BLEND); - uiSetRoundBox(UI_CNR_NONE); - uiDrawBox(GL_POLYGON, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 0); + UI_draw_roundbox_corner_set(UI_CNR_NONE); + UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 0); glDisable(GL_BLEND); /* set the block bounds to clip mouse events from underlying nodes */ - block = uiBeginBlock(C, ar, "node tree bounds block", UI_EMBOSS); - uiExplicitBoundsBlock(block, rect.xmin, rect.ymin, rect.xmax, rect.ymax); - uiBlockSetFlag(block, UI_BLOCK_CLIP_EVENTS); - uiEndBlock(C, block); + block = UI_block_begin(C, ar, "node tree bounds block", UI_EMBOSS); + UI_block_bounds_set_explicit(block, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + UI_block_flag_enable(block, UI_BLOCK_CLIP_EVENTS); + UI_block_end(C, block); } void drawnodespace(const bContext *C, ARegion *ar) diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index ca13d87d632..1e258368b8b 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -31,7 +31,6 @@ #include "MEM_guardedalloc.h" -#include "DNA_action_types.h" #include "DNA_lamp_types.h" #include "DNA_material_types.h" #include "DNA_node_types.h" @@ -73,8 +72,6 @@ #include "IMB_imbuf_types.h" #include "node_intern.h" /* own include */ -#include "NOD_common.h" -#include "NOD_socket.h" #include "NOD_composite.h" #include "NOD_shader.h" #include "NOD_texture.h" @@ -342,14 +339,22 @@ void snode_dag_update(bContext *C, SpaceNode *snode) void snode_notify(bContext *C, SpaceNode *snode) { + ID *id = snode->id; + WM_event_add_notifier(C, NC_NODE | NA_EDITED, NULL); - if (ED_node_is_shader(snode)) - WM_event_add_notifier(C, NC_MATERIAL | ND_NODES, snode->id); + if (ED_node_is_shader(snode)) { + if (GS(id->name) == ID_MA) + WM_main_add_notifier(NC_MATERIAL | ND_SHADING, id); + else if (GS(id->name) == ID_LA) + WM_main_add_notifier(NC_LAMP | ND_LIGHTING, id); + else if (GS(id->name) == ID_WO) + WM_main_add_notifier(NC_WORLD | ND_WORLD, id); + } else if (ED_node_is_compositor(snode)) - WM_event_add_notifier(C, NC_SCENE | ND_NODES, snode->id); + WM_event_add_notifier(C, NC_SCENE | ND_NODES, id); else if (ED_node_is_texture(snode)) - WM_event_add_notifier(C, NC_TEXTURE | ND_NODES, snode->id); + WM_event_add_notifier(C, NC_TEXTURE | ND_NODES, id); } void ED_node_set_tree_type(SpaceNode *snode, bNodeTreeType *typeinfo) @@ -662,11 +667,16 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node) /* if active texture changed, free glsl materials */ if ((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) { Material *ma; + World *wo; for (ma = bmain->mat.first; ma; ma = ma->id.next) if (ma->nodetree && ma->use_nodes && ntreeHasTree(ma->nodetree, ntree)) - GPU_material_free(ma); + GPU_material_free(&ma->gpumaterial); + for (wo = bmain->world.first; wo; wo = wo->id.next) + if (wo->nodetree && wo->use_nodes && ntreeHasTree(wo->nodetree, ntree)) + GPU_material_free(&wo->gpumaterial); + WM_main_add_notifier(NC_IMAGE, NULL); } @@ -695,7 +705,7 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node) for (scene = bmain->scene.first; scene; scene = scene->id.next) { if (scene->nodetree && scene->use_nodes && ntreeHasTree(scene->nodetree, ntree)) { if (node->id == NULL || node->id == (ID *)scene) { - int num_layers = BLI_countlist(&scene->r.layers); + int num_layers = BLI_listbase_count(&scene->r.layers); scene->r.actlay = node->custom1; /* Clamp the value, because it might have come from a different * scene which could have more render layers than new one. @@ -1142,7 +1152,7 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) bNodeLink *link, *newlink, *lastlink; const bool keep_inputs = RNA_boolean_get(op->ptr, "keep_inputs"); - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); lastnode = ntree->nodes.last; for (node = ntree->nodes.first; node; node = node->next) { @@ -1277,7 +1287,7 @@ static int node_read_renderlayers_exec(bContext *C, wmOperator *UNUSED(op)) Scene *curscene = CTX_data_scene(C), *scene; bNode *node; - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), bmain); /* first tag scenes unread */ for (scene = bmain->scene.first; scene; scene = scene->id.next) @@ -1476,7 +1486,7 @@ static int node_preview_toggle_exec(bContext *C, wmOperator *UNUSED(op)) if ((snode == NULL) || (snode->edittree == NULL)) return OPERATOR_CANCELLED; - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); node_flag_toggle_exec(snode, NODE_PREVIEW); @@ -1540,7 +1550,7 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op)) if ((snode == NULL) || (snode->edittree == NULL)) return OPERATOR_CANCELLED; - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); /* Toggle for all selected nodes */ hidden = 0; @@ -1588,7 +1598,7 @@ static int node_mute_exec(bContext *C, wmOperator *UNUSED(op)) SpaceNode *snode = CTX_wm_space_node(C); bNode *node; - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); for (node = snode->edittree->nodes.first; node; node = node->next) { /* Only allow muting of nodes having a mute func! */ @@ -1626,7 +1636,7 @@ static int node_delete_exec(bContext *C, wmOperator *UNUSED(op)) SpaceNode *snode = CTX_wm_space_node(C); bNode *node, *next; - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); for (node = snode->edittree->nodes.first; node; node = next) { next = node->next; @@ -1667,7 +1677,7 @@ static int node_delete_reconnect_exec(bContext *C, wmOperator *UNUSED(op)) SpaceNode *snode = CTX_wm_space_node(C); bNode *node, *next; - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); for (node = snode->edittree->nodes.first; node; node = next) { next = node->next; @@ -1924,7 +1934,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op)) bNode *node; bNodeLink *link, *newlink; - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); /* clear current clipboard */ BKE_node_clipboard_clear(); @@ -2037,7 +2047,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op) if (!all_nodes_valid) return OPERATOR_CANCELLED; - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); /* deselect old nodes */ node_deselect_all(snode); @@ -2445,7 +2455,7 @@ static int viewer_border_exec(bContext *C, wmOperator *op) void *lock; ImBuf *ibuf; - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c index 96cc7fb4407..b69808d4e81 100644 --- a/source/blender/editors/space_node/node_group.c +++ b/source/blender/editors/space_node/node_group.c @@ -55,7 +55,6 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "RNA_enum_types.h" #include "WM_api.h" #include "WM_types.h" @@ -64,7 +63,6 @@ #include "node_intern.h" /* own include */ #include "NOD_common.h" -#include "NOD_socket.h" static int node_group_operator_active(bContext *C) { @@ -144,7 +142,7 @@ static int node_group_edit_exec(bContext *C, wmOperator *op) bNode *gnode; const bool exit = RNA_boolean_get(op->ptr, "exit"); - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); gnode = node_group_get_active(C, node_idname); @@ -352,7 +350,7 @@ static int node_group_ungroup_exec(bContext *C, wmOperator *op) const char *node_idname = group_node_idname(C); bNode *gnode; - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); gnode = node_group_get_active(C, node_idname); if (!gnode) @@ -522,7 +520,7 @@ static int node_group_separate_exec(bContext *C, wmOperator *op) int type = RNA_enum_get(op->ptr, "type"); float offx, offy; - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); /* are we inside of a group? */ ngroup = snode->edittree; @@ -562,16 +560,16 @@ static int node_group_separate_exec(bContext *C, wmOperator *op) static int node_group_separate_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event)) { - uiPopupMenu *pup = uiPupMenuBegin(C, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Separate"), ICON_NONE); - uiLayout *layout = uiPupMenuLayout(pup); + uiPopupMenu *pup = UI_popup_menu_begin(C, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Separate"), ICON_NONE); + uiLayout *layout = UI_popup_menu_layout(pup); uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_COPY); uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_MOVE); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } void NODE_OT_group_separate(wmOperatorType *ot) @@ -915,7 +913,7 @@ static int node_group_make_exec(bContext *C, wmOperator *op) bNode *gnode; Main *bmain = CTX_data_main(C); - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); if (!node_group_make_test_selected(ntree, NULL, ntree_idname, op->reports)) return OPERATOR_CANCELLED; @@ -966,7 +964,7 @@ static int node_group_insert_exec(bContext *C, wmOperator *op) bNode *gnode; Main *bmain = CTX_data_main(C); - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); gnode = node_group_get_active(C, node_idname); diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 9598ff190c0..27c3ab813ae 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -163,7 +163,6 @@ void NODE_OT_links_cut(struct wmOperatorType *ot); void NODE_OT_links_detach(struct wmOperatorType *ot); void NODE_OT_parent_set(struct wmOperatorType *ot); -void NODE_OT_parent_clear(struct wmOperatorType *ot); void NODE_OT_join(struct wmOperatorType *ot); void NODE_OT_attach(struct wmOperatorType *ot); void NODE_OT_detach(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index 7dcbeae4627..a7799e79312 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -111,7 +111,6 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_output_file_move_active_socket); WM_operatortype_append(NODE_OT_parent_set); - WM_operatortype_append(NODE_OT_parent_clear); WM_operatortype_append(NODE_OT_join); WM_operatortype_append(NODE_OT_attach); WM_operatortype_append(NODE_OT_detach); @@ -147,6 +146,10 @@ void ED_operatormacros_node(void) RNA_boolean_set(mot->ptr, "release_confirm", true); WM_operatortype_macro_define(ot, "NODE_OT_attach"); + /* Note: Currently not in a default keymap or menu due to messy keymaps + * and tricky invoke functionality. + * Kept around in case users want to make own shortcuts. + */ ot = WM_operatortype_append_macro("NODE_OT_detach_translate_attach", "Detach and Move", "Detach nodes, move and attach to frame", OPTYPE_UNDO | OPTYPE_REGISTER); @@ -267,7 +270,7 @@ void node_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "NODE_OT_duplicate_move_keep_inputs", DKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0); WM_keymap_add_item(keymap, "NODE_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "NODE_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "NODE_OT_detach", PKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "NODE_OT_join", JKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "NODE_OT_hide_toggle", HKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c index 973ce56857c..c8951a1172e 100644 --- a/source/blender/editors/space_node/node_relationships.c +++ b/source/blender/editors/space_node/node_relationships.c @@ -57,7 +57,6 @@ #include "BLF_translation.h" #include "node_intern.h" /* own include */ -#include "NOD_common.h" /* ****************** Add *********************** */ @@ -203,7 +202,7 @@ static void snode_autoconnect(SpaceNode *snode, const bool allow_multiple, const } /* sort nodes left to right */ - BLI_sortlist(nodelist, sort_nodes_locx); + BLI_listbase_sort(nodelist, sort_nodes_locx); for (nli = nodelist->first; nli; nli = nli->next) { bNode *node_fr, *node_to; @@ -236,7 +235,7 @@ static void snode_autoconnect(SpaceNode *snode, const bool allow_multiple, const if (!has_selected_inputs) { /* no selected inputs, connect by finding suitable match */ - int num_inputs = BLI_countlist(&node_to->inputs); + int num_inputs = BLI_listbase_count(&node_to->inputs); for (i = 0; i < num_inputs; i++) { @@ -368,7 +367,7 @@ static int node_active_link_viewer_exec(bContext *C, wmOperator *UNUSED(op)) if (!node) return OPERATOR_CANCELLED; - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); if (node_link_viewer(C, node) == OPERATOR_CANCELLED) return OPERATOR_CANCELLED; @@ -747,7 +746,7 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event) UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &cursor[0], &cursor[1]); - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); nldrag = node_link_init(snode, cursor, detach); @@ -803,7 +802,7 @@ static int node_make_link_exec(bContext *C, wmOperator *op) SpaceNode *snode = CTX_wm_space_node(C); const bool replace = RNA_boolean_get(op->ptr, "replace"); - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); snode_autoconnect(snode, 1, replace); @@ -874,7 +873,7 @@ static int cut_links_exec(bContext *C, wmOperator *op) bool found = false; bNodeLink *link, *next; - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); for (link = snode->edittree->links.first; link; link = next) { next = link->next; @@ -884,7 +883,8 @@ static int cut_links_exec(bContext *C, wmOperator *op) if (cut_links_intersect(link, mcoords, i)) { if (found == false) { - ED_preview_kill_jobs(C); + /* TODO(sergey): Why did we kill jobs twice? */ + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); found = true; } @@ -941,7 +941,7 @@ static int detach_links_exec(bContext *C, wmOperator *UNUSED(op)) bNodeTree *ntree = snode->edittree; bNode *node; - ED_preview_kill_jobs(C); + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); for (node = ntree->nodes.first; node; node = node->next) { if (node->flag & SELECT) { @@ -1011,40 +1011,6 @@ void NODE_OT_parent_set(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ****************** Clear Parent ******************* */ - -static int node_parent_clear_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceNode *snode = CTX_wm_space_node(C); - bNodeTree *ntree = snode->edittree; - bNode *node; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->flag & NODE_SELECT) { - nodeDetachNode(node); - } - } - - WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL); - - return OPERATOR_FINISHED; -} - -void NODE_OT_parent_clear(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Clear Parent"; - ot->description = "Detach selected nodes"; - ot->idname = "NODE_OT_parent_clear"; - - /* api callbacks */ - ot->exec = node_parent_clear_exec; - ot->poll = ED_operator_node_editable; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - /* ****************** Join Nodes ******************* */ /* tags for depth-first search */ diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index de580f612a0..25f9d56c8f0 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -972,7 +972,7 @@ static void node_find_cb(const struct bContext *C, void *UNUSED(arg), const char BLI_snprintf(name, 256, "%s (%s)", node->name, node->label); else BLI_strncpy(name, node->name, 256); - if (false == uiSearchItemAdd(items, name, node, 0)) + if (false == UI_search_item_add(items, name, node, 0)) break; } } @@ -1006,18 +1006,18 @@ static uiBlock *node_find_menu(bContext *C, ARegion *ar, void *arg_op) uiBut *but; wmOperator *op = (wmOperator *)arg_op; - block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS); - uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU); + block = UI_block_begin(C, ar, "_popup", UI_EMBOSS); + UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU); but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 10, 9 * UI_UNIT_X, UI_UNIT_Y, 0, 0, ""); - uiButSetSearchFunc(but, node_find_cb, op->type, node_find_call_cb, NULL); + UI_but_func_search_set(but, node_find_cb, op->type, node_find_call_cb, NULL); /* fake button, it holds space for search items */ - uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 10 - UI_searchbox_size_y(), UI_searchbox_size_x(), UI_searchbox_size_y(), NULL, 0, 0, 0, 0, NULL); - uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */ + UI_block_bounds_set_popup(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */ - // uiButActiveOnly(C, ar, block, but); XXX using this here makes Blender hang - investigate + // UI_but_active_only(C, ar, block, but); XXX using this here makes Blender hang - investigate wm_event_init_from_window(win, &event); event.type = EVT_BUT_OPEN; event.val = KM_PRESS; @@ -1031,7 +1031,7 @@ static uiBlock *node_find_menu(bContext *C, ARegion *ar, void *arg_op) static int node_find_node_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - uiPupBlock(C, node_find_menu, op); + UI_popup_block_invoke(C, node_find_menu, op); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index 99a481e5d82..8b68ac013c2 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -30,7 +30,6 @@ #include "DNA_node_types.h" #include "DNA_screen_types.h" -#include "DNA_space_types.h" #include "BLI_listbase.h" #include "BLI_string.h" @@ -54,7 +53,6 @@ #include "ED_util.h" -#include "node_intern.h" /************************* Node Socket Manipulation **************************/ @@ -300,7 +298,7 @@ static void ui_node_link_items(NodeLinkArg *arg, int in_out, NodeLinkItem **r_it for (ngroup = arg->bmain->nodetree.first; ngroup; ngroup = ngroup->id.next) { ListBase *lb = ((in_out == SOCK_IN) ? &ngroup->inputs : &ngroup->outputs); - totitems += BLI_countlist(lb); + totitems += BLI_listbase_count(lb); } if (totitems > 0) { @@ -454,7 +452,7 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname) if (first) { column = uiLayoutColumn(layout, 0); - uiBlockSetCurLayout(block, column); + UI_block_layout_set_current(block, column); uiItemL(column, IFACE_(cname), ICON_NODE); but = block->buttons.last; @@ -466,7 +464,7 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname) if (!cur_node_name || !STREQ(cur_node_name, items[i].node_name)) { cur_node_name = items[i].node_name; /* XXX Do not use uiItemL here, it would add an empty icon as we are in a menu! */ - uiDefBut(block, LABEL, 0, IFACE_(cur_node_name), 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, + uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_(cur_node_name), 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, ""); } @@ -478,12 +476,12 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname) icon = ICON_NONE; } - but = uiDefIconTextBut(block, BUT, 0, icon, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, + but = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, icon, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Add node to input")); argN = MEM_dupallocN(arg); argN->item = items[i]; - uiButSetNFunc(but, ui_node_link, argN, NULL); + UI_but_funcN_set(but, ui_node_link, argN, NULL); } if (items) @@ -511,8 +509,8 @@ static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_ bNodeSocket *sock = arg->sock; bNodeTreeType *ntreetype = arg->ntree->typeinfo; - uiBlockSetFlag(block, UI_BLOCK_NO_FLIP); - uiBlockSetCurLayout(block, layout); + UI_block_flag_enable(block, UI_BLOCK_NO_FLIP); + UI_block_layout_set_current(block, layout); split = uiLayoutSplit(layout, 0.0f, false); arg->bmain = bmain; @@ -523,20 +521,20 @@ static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_ ntreetype->foreach_nodeclass(scene, arg, node_menu_column_foreach_cb); column = uiLayoutColumn(split, false); - uiBlockSetCurLayout(block, column); + UI_block_layout_set_current(block, column); if (sock->link) { uiItemL(column, IFACE_("Link"), ICON_NONE); but = block->buttons.last; but->drawflag = UI_BUT_TEXT_LEFT; - but = uiDefBut(block, BUT, 0, IFACE_("Remove"), 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, + but = uiDefBut(block, UI_BTYPE_BUT, 0, IFACE_("Remove"), 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Remove nodes connected to the input")); - uiButSetNFunc(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_REMOVE)); + UI_but_funcN_set(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_REMOVE)); - but = uiDefBut(block, BUT, 0, IFACE_("Disconnect"), 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, + but = uiDefBut(block, UI_BTYPE_BUT, 0, IFACE_("Disconnect"), 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Disconnect nodes connected to the input")); - uiButSetNFunc(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_DISCONNECT)); + UI_but_funcN_set(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_DISCONNECT)); } ui_node_menu_column(arg, NODE_CLASS_GROUP, N_("Group")); @@ -553,7 +551,7 @@ void uiTemplateNodeLink(uiLayout *layout, bNodeTree *ntree, bNode *node, bNodeSo arg->node = node; arg->sock = sock; - uiBlockSetCurLayout(block, layout); + UI_block_layout_set_current(block, layout); if (sock->link || sock->type == SOCK_SHADER || (sock->flag & SOCK_HIDE_VALUE)) { char name[UI_MAX_NAME_STR]; @@ -563,7 +561,7 @@ void uiTemplateNodeLink(uiLayout *layout, bNodeTree *ntree, bNode *node, bNodeSo else but = uiDefIconMenuBut(block, ui_template_node_link_menu, NULL, ICON_NONE, 0, 0, UI_UNIT_X, UI_UNIT_Y, ""); - uiButSetMenuFromPulldown(but); + UI_but_type_set_menu_from_pulldown(but); but->flag |= UI_BUT_NODE_LINK; but->poin = (char *)but; @@ -638,7 +636,7 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree, row = uiLayoutRow(split, true); if (depth > 0) { - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); if (lnode && (lnode->inputs.first || (lnode->typeinfo->draw_buttons && lnode->type != NODE_GROUP))) { int icon = (input->flag & SOCK_COLLAPSED) ? ICON_DISCLOSURE_TRI_RIGHT : ICON_DISCLOSURE_TRI_DOWN; @@ -650,7 +648,7 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree, bt = block->buttons.last; bt->rect.xmax = UI_UNIT_X / 2; - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); } uiItemL(row, label, ICON_NONE); diff --git a/source/blender/editors/space_node/node_toolbar.c b/source/blender/editors/space_node/node_toolbar.c index dd5bad3f8ad..e3e263f2e44 100644 --- a/source/blender/editors/space_node/node_toolbar.c +++ b/source/blender/editors/space_node/node_toolbar.c @@ -28,27 +28,18 @@ * \ingroup nodes */ - -#include "MEM_guardedalloc.h" - #include "BLI_utildefines.h" #include "DNA_node_types.h" #include "BKE_context.h" -#include "BKE_node.h" #include "BKE_screen.h" #include "WM_api.h" #include "WM_types.h" -#include "RNA_access.h" - #include "ED_screen.h" -#include "UI_interface.h" -#include "UI_resources.h" - #include "node_intern.h" /* own include */ diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index ccaeae34927..e3baddef158 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -28,8 +28,6 @@ * \ingroup spnode */ - - #include "DNA_lamp_types.h" #include "DNA_material_types.h" #include "DNA_node_types.h" @@ -152,7 +150,7 @@ void ED_node_tree_pop(SpaceNode *snode) int ED_node_tree_depth(SpaceNode *snode) { - return BLI_countlist(&snode->treepath); + return BLI_listbase_count(&snode->treepath); } bNodeTree *ED_node_tree_get(SpaceNode *snode, int level) @@ -515,6 +513,11 @@ static void node_area_listener(bScreen *sc, ScrArea *sa, wmNotifier *wmn) ED_area_tag_refresh(sa); } break; + case NC_GPENCIL: + if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) { + ED_area_tag_redraw(sa); + } + break; } } @@ -670,7 +673,7 @@ static int node_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent * return 1; } else if (drag->type == WM_DRAG_PATH) { - if (ELEM(drag->icon, 0, ICON_FILE_IMAGE)) /* rule might not work? */ + if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE)) /* rule might not work? */ return 1; } return 0; @@ -699,9 +702,11 @@ static void node_id_path_drop_copy(wmDrag *drag, wmDropBox *drop) if (id) { RNA_string_set(drop->ptr, "name", id->name + 2); + RNA_struct_property_unset(drop->ptr, "filepath"); } - if (drag->path[0]) { + else if (drag->path[0]) { RNA_string_set(drop->ptr, "filepath", drag->path); + RNA_struct_property_unset(drop->ptr, "name"); } } @@ -768,6 +773,8 @@ static void node_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegi case NC_GPENCIL: if (wmn->action == NA_EDITED) ED_region_tag_redraw(ar); + else if (wmn->data & ND_GPENCIL_EDITMODE) + ED_region_tag_redraw(ar); break; } } diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index e033f781f62..3df6bd51f37 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -197,7 +197,7 @@ static void restrictbutton_recursive_child(bContext *C, Scene *scene, Object *ob RNA_id_pointer_create(&ob->id, &ptr); prop = RNA_struct_find_property(&ptr, rnapropname); - fcu = rna_get_fcurve_context_ui(C, &ptr, prop, 0, &action, &driven); + fcu = rna_get_fcurve_context_ui(C, &ptr, prop, 0, NULL, &action, &driven); if (fcu && !driven) { id = ptr.id.data; @@ -584,29 +584,29 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar ob = (Object *)tselem->id; RNA_pointer_create((ID *)ob, &RNA_Object, ob, &ptr); - uiBlockSetEmboss(block, UI_EMBOSSN); - bt = uiDefIconButR_prop(block, ICONTOG, 0, ICON_RESTRICT_VIEW_OFF, + UI_block_emboss_set(block, UI_EMBOSS_NONE); + bt = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, ICON_RESTRICT_VIEW_OFF, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, &ptr, object_prop_hide, -1, 0, 0, -1, -1, TIP_("Restrict viewport visibility (Ctrl - Recursive)")); - uiButSetFunc(bt, restrictbutton_view_cb, scene, ob); - uiButSetFlag(bt, UI_BUT_DRAG_LOCK); + UI_but_func_set(bt, restrictbutton_view_cb, scene, ob); + UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); - bt = uiDefIconButR_prop(block, ICONTOG, 0, ICON_RESTRICT_SELECT_OFF, + bt = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, ICON_RESTRICT_SELECT_OFF, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y, &ptr, object_prop_hide_select, -1, 0, 0, -1, -1, TIP_("Restrict viewport selection (Ctrl - Recursive)")); - uiButSetFunc(bt, restrictbutton_sel_cb, scene, ob); - uiButSetFlag(bt, UI_BUT_DRAG_LOCK); + UI_but_func_set(bt, restrictbutton_sel_cb, scene, ob); + UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); - bt = uiDefIconButR_prop(block, ICONTOG, 0, ICON_RESTRICT_RENDER_OFF, + bt = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, ICON_RESTRICT_RENDER_OFF, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y, &ptr, object_prop_hide_render, -1, 0, 0, -1, -1, TIP_("Restrict rendering (Ctrl - Recursive)")); - uiButSetFunc(bt, restrictbutton_rend_cb, scene, ob); - uiButSetFlag(bt, UI_BUT_DRAG_LOCK); + UI_but_func_set(bt, restrictbutton_rend_cb, scene, ob); + UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); } if (tselem->type == 0 && te->idcode == ID_GR) { @@ -617,130 +617,130 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar if (gr->id.lib) but_flag |= UI_BUT_DISABLED; - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); restrict_bool = group_restrict_flag(gr, OB_RESTRICT_VIEW); - bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF, + bt = uiDefIconBut(block, UI_BTYPE_ICON_TOGGLE, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Restrict/Allow visibility in the 3D View")); - uiButSetFunc(bt, restrictbutton_gr_restrict_view, scene, gr); - uiButSetFlag(bt, but_flag); + UI_but_func_set(bt, restrictbutton_gr_restrict_view, scene, gr); + UI_but_flag_enable(bt, but_flag); restrict_bool = group_restrict_flag(gr, OB_RESTRICT_SELECT); - bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF, + bt = uiDefIconBut(block, UI_BTYPE_ICON_TOGGLE, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Restrict/Allow selection in the 3D View")); - uiButSetFunc(bt, restrictbutton_gr_restrict_select, scene, gr); - uiButSetFlag(bt, but_flag); + UI_but_func_set(bt, restrictbutton_gr_restrict_select, scene, gr); + UI_but_flag_enable(bt, but_flag); restrict_bool = group_restrict_flag(gr, OB_RESTRICT_RENDER); - bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF, + bt = uiDefIconBut(block, UI_BTYPE_ICON_TOGGLE, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Restrict/Allow renderability")); - uiButSetFunc(bt, restrictbutton_gr_restrict_render, scene, gr); - uiButSetFlag(bt, but_flag); + UI_but_func_set(bt, restrictbutton_gr_restrict_render, scene, gr); + UI_but_flag_enable(bt, but_flag); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); } /* scene render layers and passes have toggle-able flags too! */ else if (tselem->type == TSE_R_LAYER) { - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); - bt = uiDefIconButBitI(block, ICONTOGN, SCE_LAY_DISABLE, 0, ICON_CHECKBOX_HLT - 1, + bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE_N, SCE_LAY_DISABLE, 0, ICON_CHECKBOX_HLT - 1, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, te->directdata, 0, 0, 0, 0, TIP_("Render this RenderLayer")); - uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL); - uiButSetFlag(bt, UI_BUT_DRAG_LOCK); + UI_but_func_set(bt, restrictbutton_r_lay_cb, tselem->id, NULL); + UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); } else if (tselem->type == TSE_R_PASS) { int *layflag = te->directdata; int passflag = 1 << tselem->nr; - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); - bt = uiDefIconButBitI(block, ICONTOG, passflag, 0, ICON_CHECKBOX_HLT - 1, + bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE, passflag, 0, ICON_CHECKBOX_HLT - 1, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, layflag, 0, 0, 0, 0, TIP_("Render this Pass")); - uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL); - uiButSetFlag(bt, UI_BUT_DRAG_LOCK); + UI_but_func_set(bt, restrictbutton_r_lay_cb, tselem->id, NULL); + UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); layflag++; /* is lay_xor */ if (ELEM(passflag, SCE_PASS_SPEC, SCE_PASS_SHADOW, SCE_PASS_AO, SCE_PASS_REFLECT, SCE_PASS_REFRACT, SCE_PASS_INDIRECT, SCE_PASS_EMIT, SCE_PASS_ENVIRONMENT)) { - bt = uiDefIconButBitI(block, TOG, passflag, 0, (*layflag & passflag) ? ICON_DOT : ICON_BLANK1, + bt = uiDefIconButBitI(block, UI_BTYPE_TOGGLE, passflag, 0, (*layflag & passflag) ? ICON_DOT : ICON_BLANK1, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y, layflag, 0, 0, 0, 0, TIP_("Exclude this Pass from Combined")); - uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL); - uiButSetFlag(bt, UI_BUT_DRAG_LOCK); + UI_but_func_set(bt, restrictbutton_r_lay_cb, tselem->id, NULL); + UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); } - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); } else if (tselem->type == TSE_MODIFIER) { ModifierData *md = (ModifierData *)te->directdata; ob = (Object *)tselem->id; - uiBlockSetEmboss(block, UI_EMBOSSN); - bt = uiDefIconButBitI(block, ICONTOGN, eModifierMode_Realtime, 0, ICON_RESTRICT_VIEW_OFF, + UI_block_emboss_set(block, UI_EMBOSS_NONE); + bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE_N, eModifierMode_Realtime, 0, ICON_RESTRICT_VIEW_OFF, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, &(md->mode), 0, 0, 0, 0, TIP_("Restrict/Allow visibility in the 3D View")); - uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob); - uiButSetFlag(bt, UI_BUT_DRAG_LOCK); + UI_but_func_set(bt, restrictbutton_modifier_cb, scene, ob); + UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); - bt = uiDefIconButBitI(block, ICONTOGN, eModifierMode_Render, 0, ICON_RESTRICT_RENDER_OFF, + bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE_N, eModifierMode_Render, 0, ICON_RESTRICT_RENDER_OFF, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y, &(md->mode), 0, 0, 0, 0, TIP_("Restrict/Allow renderability")); - uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob); - uiButSetFlag(bt, UI_BUT_DRAG_LOCK); + UI_but_func_set(bt, restrictbutton_modifier_cb, scene, ob); + UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); } else if (tselem->type == TSE_POSE_CHANNEL) { bPoseChannel *pchan = (bPoseChannel *)te->directdata; Bone *bone = pchan->bone; ob = (Object *)tselem->id; - uiBlockSetEmboss(block, UI_EMBOSSN); - bt = uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_P, 0, ICON_RESTRICT_VIEW_OFF, + UI_block_emboss_set(block, UI_EMBOSS_NONE); + bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE, BONE_HIDDEN_P, 0, ICON_RESTRICT_VIEW_OFF, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, &(bone->flag), 0, 0, 0, 0, TIP_("Restrict/Allow visibility in the 3D View")); - uiButSetFunc(bt, restrictbutton_bone_visibility_cb, ob->data, bone); - uiButSetFlag(bt, UI_BUT_DRAG_LOCK); + UI_but_func_set(bt, restrictbutton_bone_visibility_cb, ob->data, bone); + UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); - bt = uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF, + bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y, &(bone->flag), 0, 0, 0, 0, TIP_("Restrict/Allow selection in the 3D View")); - uiButSetFunc(bt, restrictbutton_bone_select_cb, ob->data, bone); - uiButSetFlag(bt, UI_BUT_DRAG_LOCK); + UI_but_func_set(bt, restrictbutton_bone_select_cb, ob->data, bone); + UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); } else if (tselem->type == TSE_EBONE) { EditBone *ebone = (EditBone *)te->directdata; - uiBlockSetEmboss(block, UI_EMBOSSN); - bt = uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_A, 0, ICON_RESTRICT_VIEW_OFF, + UI_block_emboss_set(block, UI_EMBOSS_NONE); + bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE, BONE_HIDDEN_A, 0, ICON_RESTRICT_VIEW_OFF, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, &(ebone->flag), 0, 0, 0, 0, TIP_("Restrict/Allow visibility in the 3D View")); - uiButSetFunc(bt, restrictbutton_ebone_visibility_cb, NULL, ebone); - uiButSetFlag(bt, UI_BUT_DRAG_LOCK); + UI_but_func_set(bt, restrictbutton_ebone_visibility_cb, NULL, ebone); + UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); - bt = uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF, + bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y, &(ebone->flag), 0, 0, 0, 0, TIP_("Restrict/Allow selection in the 3D View")); - uiButSetFunc(bt, restrictbutton_ebone_select_cb, NULL, ebone); - uiButSetFlag(bt, UI_BUT_DRAG_LOCK); + UI_but_func_set(bt, restrictbutton_ebone_select_cb, NULL, ebone); + UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); } } @@ -775,8 +775,6 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa TreeStoreElem *tselem; PointerRNA *ptr; PropertyRNA *prop; - - uiBlockSetEmboss(block, UI_EMBOSST); for (te = lb->first; te; te = te->next) { tselem = TREESTORE(te); @@ -789,7 +787,7 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa if (RNA_property_type(prop) == PROP_POINTER) { uiBut *but = uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y - 1); - uiButSetFlag(but, UI_BUT_DISABLED); + UI_but_flag_enable(but, UI_BUT_DISABLED); } else if (RNA_property_type(prop) == PROP_ENUM) { uiDefAutoButR(block, ptr, prop, -1, NULL, ICON_NONE, sizex, te->ys, OL_RNA_COL_SIZEX, @@ -813,7 +811,7 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa if (TSELEM_OPEN(tselem, soops)) outliner_draw_rnabuts(block, scene, ar, soops, sizex, &te->subtree); } - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); } static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, TreeElement *te) @@ -837,12 +835,12 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Tre spx = te->xs + 1.8f * UI_UNIT_X; dx = ar->v2d.cur.xmax - (spx + 3.2f * UI_UNIT_X); - bt = uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, te->ys, dx, UI_UNIT_Y - 1, (void *)te->name, + bt = uiDefBut(block, UI_BTYPE_TEXT, OL_NAMEBUTTON, "", spx, te->ys, dx, UI_UNIT_Y - 1, (void *)te->name, 1.0, (float)len, 0, 0, ""); - uiButSetRenameFunc(bt, namebutton_cb, tselem); + UI_but_func_rename_set(bt, namebutton_cb, tselem); /* returns false if button got removed */ - if (false == uiButActiveOnly(C, ar, block, bt)) { + if (false == UI_but_active_only(C, ar, block, bt)) { tselem->flag &= ~TSE_TEXTBUT; /* bad! (notifier within draw) without this, we don't get a refesh */ @@ -870,11 +868,11 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon) glDisable(GL_BLEND); } else { - uiBut *but = uiDefIconBut(arg->block, LABEL, 0, icon, arg->xb, arg->yb, UI_UNIT_X, UI_UNIT_Y, NULL, + uiBut *but = uiDefIconBut(arg->block, UI_BTYPE_LABEL, 0, icon, arg->xb, arg->yb, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, arg->alpha, (arg->id && arg->id->lib) ? arg->id->lib->name : ""); if (arg->id) - uiButSetDragID(but, arg->id); + UI_but_drag_set_id(but, arg->id); } } @@ -1206,13 +1204,14 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa if (active != OL_DRAWSEL_NONE) { float ufac = UI_UNIT_X / 20.0f; - uiSetRoundBox(UI_CNR_ALL); + UI_draw_roundbox_corner_set(UI_CNR_ALL); glColor4ub(255, 255, 255, 100); - uiRoundBox((float) *offsx - 1.0f * ufac, - (float)ys + 1.0f * ufac, - (float)*offsx + UI_UNIT_X - 2.0f * ufac, - (float)ys + UI_UNIT_Y - ufac, - (float)UI_UNIT_Y / 2.0f - ufac); + UI_draw_roundbox( + (float) *offsx - 1.0f * ufac, + (float)ys + 1.0f * ufac, + (float)*offsx + UI_UNIT_X - 2.0f * ufac, + (float)ys + UI_UNIT_Y - ufac, + (float)UI_UNIT_Y / 2.0f - ufac); glEnable(GL_BLEND); /* roundbox disables */ } @@ -1352,12 +1351,13 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene /* active circle */ if (active != OL_DRAWSEL_NONE) { - uiSetRoundBox(UI_CNR_ALL); - uiRoundBox((float)startx + UI_UNIT_X, - (float)*starty + 1.0f * ufac, - (float)startx + 2.0f * UI_UNIT_X - 2.0f * ufac, - (float)*starty + UI_UNIT_Y - 1.0f * ufac, - UI_UNIT_Y / 2.0f - 1.0f * ufac); + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox( + (float)startx + UI_UNIT_X, + (float)*starty + 1.0f * ufac, + (float)startx + 2.0f * UI_UNIT_X - 2.0f * ufac, + (float)*starty + UI_UNIT_Y - 1.0f * ufac, + UI_UNIT_Y / 2.0f - 1.0f * ufac); glEnable(GL_BLEND); /* roundbox disables it */ te->flag |= TE_ACTIVE; // for lookup in display hierarchies @@ -1406,9 +1406,9 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene else if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) UI_ThemeColorBlend(TH_BACK, TH_TEXT, 0.75f); else UI_ThemeColor(TH_TEXT); - UI_DrawString(startx + offsx, *starty + 5 * ufac, te->name); + UI_draw_string(startx + offsx, *starty + 5 * ufac, te->name); - offsx += (int)(UI_UNIT_X + UI_GetStringWidth(te->name)); + offsx += (int)(UI_UNIT_X + UI_fontstyle_string_width(te->name)); /* closed item, we draw the icons, not when it's a scene, or master-server list though */ if (!TSELEM_OPEN(tselem, soops)) { @@ -1684,7 +1684,7 @@ void draw_outliner(const bContext *C) /* draw outliner stuff (background, hierarchy lines and names) */ outliner_back(ar); - block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); + block = UI_block_begin(C, ar, __func__, UI_EMBOSS); outliner_draw_tree((bContext *)C, block, scene, ar, soops, &te_edit); if (ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF)) { @@ -1703,8 +1703,8 @@ void draw_outliner(const bContext *C) outliner_buttons(C, block, ar, te_edit); } - uiEndBlock(C, block); - uiDrawBlock(C, block); + UI_block_end(C, block); + UI_block_draw(C, block); /* clear flag that allows quick redraws */ soops->storeflag &= ~SO_TREESTORE_REDRAW; diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index ef621407abd..ab7b1583275 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -1305,7 +1305,7 @@ static KeyingSet *verify_active_keyingset(Scene *scene, short add) // XXX the default settings have yet to evolve if ((add) && (ks == NULL)) { ks = BKE_keyingset_add(&scene->keyingsets, NULL, NULL, KEYINGSET_ABSOLUTE, 0); - scene->active_keyingset = BLI_countlist(&scene->keyingsets); + scene->active_keyingset = BLI_listbase_count(&scene->keyingsets); } return ks; @@ -1347,7 +1347,7 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa /* TODO: what do we do with group name? * for now, we don't supply one, and just let this use the KeyingSet name */ BKE_keyingset_add_path(ks, id, NULL, path, array_index, flag, groupmode); - ks->active_path = BLI_countlist(&ks->paths); + ks->active_path = BLI_listbase_count(&ks->paths); break; } case KEYINGSET_EDITMODE_REMOVE: @@ -1543,8 +1543,8 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) else { /* Menu creation */ wmOperatorType *ot = WM_operatortype_find("OUTLINER_OT_parent_drop", false); - uiPopupMenu *pup = uiPupMenuBegin(C, IFACE_("Set Parent To"), ICON_NONE); - uiLayout *layout = uiPupMenuLayout(pup); + uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Set Parent To"), ICON_NONE); + uiLayout *layout = UI_popup_menu_layout(pup); PointerRNA ptr; @@ -1615,9 +1615,9 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) uiItemFullO_ptr(layout, ot, IFACE_("Lattice Deform"), 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); } - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } } else { diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c index d735b5e75cf..4f13454ef34 100644 --- a/source/blender/editors/space_outliner/outliner_ops.c +++ b/source/blender/editors/space_outliner/outliner_ops.c @@ -30,7 +30,6 @@ #include "DNA_space_types.h" -#include "BLI_utildefines.h" #include "RNA_access.h" diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 6f5bf712d55..23586a6a509 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -290,6 +290,10 @@ static eOLDrawState tree_element_active_material( } } if (set != OL_SETSEL_NONE) { + /* Tagging object for update seems a bit stupid here, but looks like we have to do it + * for render views to update. See T42973. + * Note that RNA material update does it too, see e.g. rna_MaterialSlot_update(). */ + DAG_id_tag_update((ID *)ob, OB_RECALC_OB); WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, NULL); } return OL_DRAWSEL_NONE; diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 5801dd126e3..f8a90c942bc 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -434,7 +434,7 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s outliner_add_element(soops, lb, sce->world, te, 0, 0); #ifdef WITH_FREESTYLE - if (STREQ(sce->r.engine, "BLENDER_RENDER") && (sce->r.mode & R_EDGE_FRS)) + if (STREQ(sce->r.engine, RE_engine_id_BLENDER_RENDER) && (sce->r.mode & R_EDGE_FRS)) outliner_add_line_styles(soops, lb, sce, te); #endif } diff --git a/source/blender/editors/space_script/script_edit.c b/source/blender/editors/space_script/script_edit.c index 9077d0cf8ed..d265ae62db6 100644 --- a/source/blender/editors/space_script/script_edit.c +++ b/source/blender/editors/space_script/script_edit.c @@ -32,7 +32,6 @@ #include <string.h> #include <stdio.h> -#include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BKE_context.h" @@ -131,7 +130,7 @@ static int script_reload_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_WINDOW, NULL); return OPERATOR_FINISHED; #else - (void)C, (void)op; /* unused */ + UNUSED_VARS(C, op); return OPERATOR_CANCELLED; #endif } diff --git a/source/blender/editors/space_script/script_ops.c b/source/blender/editors/space_script/script_ops.c index 045df87d8db..41c07596a3b 100644 --- a/source/blender/editors/space_script/script_ops.c +++ b/source/blender/editors/space_script/script_ops.c @@ -32,19 +32,7 @@ #include <stdlib.h> #include <math.h> - -#include "DNA_screen_types.h" -#include "DNA_space_types.h" - -#include "BLI_math.h" -#include "BLI_blenlib.h" - -#include "BKE_context.h" - -#include "RNA_access.h" - #include "WM_api.h" -#include "WM_types.h" #include "script_intern.h" @@ -63,4 +51,3 @@ void script_keymap(wmKeyConfig *UNUSED(keyconf)) { /* Script space is deprecated, and doesn't need a keymap */ } - diff --git a/source/blender/editors/space_script/space_script.c b/source/blender/editors/space_script/space_script.c index fd2cd268a27..759dcd3d0a4 100644 --- a/source/blender/editors/space_script/space_script.c +++ b/source/blender/editors/space_script/space_script.c @@ -35,7 +35,6 @@ #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" -#include "BLI_math.h" #include "BLI_utildefines.h" #include "BKE_context.h" @@ -53,7 +52,6 @@ #include "UI_view2d.h" #ifdef WITH_PYTHON -#include "BPY_extern.h" #endif #include "script_intern.h" // own include diff --git a/source/blender/editors/space_sequencer/CMakeLists.txt b/source/blender/editors/space_sequencer/CMakeLists.txt index 4cf9c0c95c2..d9aff2781f0 100644 --- a/source/blender/editors/space_sequencer/CMakeLists.txt +++ b/source/blender/editors/space_sequencer/CMakeLists.txt @@ -43,6 +43,7 @@ set(SRC sequencer_edit.c sequencer_modifier.c sequencer_ops.c + sequencer_preview.c sequencer_scopes.c sequencer_select.c sequencer_view.c diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 345988c1d5c..0ab4dcbeae2 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -40,7 +40,6 @@ #include "DNA_scene_types.h" #include "DNA_mask_types.h" -#include "BLF_translation.h" #include "BKE_context.h" #include "BKE_global.h" @@ -61,7 +60,6 @@ #include "ED_screen.h" #include "ED_sequencer.h" -#include "UI_view2d.h" #include "BKE_sound.h" @@ -923,5 +921,6 @@ void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot) WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME | SEQPROP_ENDFRAME); RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_TYPE_CROSS, "Type", "Sequencer effect type"); - RNA_def_float_vector(ot->srna, "color", 3, NULL, 0.0f, 1.0f, "Color", "Initialize the strip with this color (only used when type='COLOR')", 0.0f, 1.0f); + RNA_def_float_vector(ot->srna, "color", 3, NULL, 0.0f, 1.0f, "Color", + "Initialize the strip with this color (only used when type='COLOR')", 0.0f, 1.0f); } diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c index d75eeca2c67..70c6da0bfb3 100644 --- a/source/blender/editors/space_sequencer/sequencer_buttons.c +++ b/source/blender/editors/space_sequencer/sequencer_buttons.c @@ -46,12 +46,12 @@ #include "WM_api.h" #include "WM_types.h" -#include "UI_interface.h" #include "sequencer_intern.h" /* **************************** buttons ********************************* */ +#if 0 static int sequencer_grease_pencil_panel_poll(const bContext *C, PanelType *UNUSED(pt)) { SpaceSeq *sseq = CTX_wm_space_seq(C); @@ -59,9 +59,11 @@ static int sequencer_grease_pencil_panel_poll(const bContext *C, PanelType *UNUS /* don't show the gpencil if we are not showing the image */ return ED_space_sequencer_check_show_imbuf(sseq); } +#endif -void sequencer_buttons_register(ARegionType *art) +void sequencer_buttons_register(ARegionType *UNUSED(art)) { +#if 0 PanelType *pt; pt = MEM_callocN(sizeof(PanelType), "spacetype sequencer panel gpencil"); @@ -72,6 +74,7 @@ void sequencer_buttons_register(ARegionType *art) pt->draw = ED_gpencil_panel_standard; pt->poll = sequencer_grease_pencil_panel_poll; BLI_addtail(&art->paneltypes, pt); +#endif } /* **************** operator to open/close properties view ************* */ diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index dab51f752b4..144f7876b5e 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -34,6 +34,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_threads.h" #include "IMB_imbuf_types.h" @@ -69,6 +70,7 @@ #include "WM_api.h" + /* own include */ #include "sequencer_intern.h" @@ -82,9 +84,11 @@ /* Note, Don't use SEQ_BEGIN/SEQ_END while drawing! * it messes up transform, - Campbell */ -static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2); +#undef SEQ_BEGIN +#undef SEQP_BEGIN +#undef SEQ_END -static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[3]) +void color3ubv_from_seq(Scene *curscene, Sequence *seq, unsigned char col[3]) { unsigned char blendcol[3]; SolidColorVars *colvars = (SolidColorVars *)seq->effectdata; @@ -175,14 +179,14 @@ static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[ } } -static void drawseqwave(Scene *scene, Sequence *seq, float x1, float y1, float x2, float y2, float stepsize) +static void drawseqwave(const bContext *C, SpaceSeq *sseq, Scene *scene, Sequence *seq, float x1, float y1, float x2, float y2, float stepsize) { /* * x1 is the starting x value to draw the wave, * x2 the end x value, same for y1 and y2 * stepsize is width of a pixel. */ - if (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM) { + if ((sseq->flag & SEQ_ALL_WAVEFORMS) || (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM)) { int i, j, pos; int length = floor((x2 - x1) / stepsize) + 1; float ymid = (y1 + y2) / 2; @@ -190,20 +194,30 @@ static void drawseqwave(Scene *scene, Sequence *seq, float x1, float y1, float x float samplestep; float startsample, endsample; float value; - + bSound *sound = seq->sound; + SoundWaveform *waveform; - - if (!seq->sound->waveform) - sound_read_waveform(seq->sound); - - if (!seq->sound->waveform) - return; /* zero length sound */ - + + if (!sound->mutex) + sound->mutex = BLI_mutex_alloc(); + + BLI_mutex_lock(sound->mutex); + if (!seq->sound->waveform) { + if (!(sound->flags & SOUND_FLAGS_WAVEFORM_LOADING)) { + /* prevent sounds from reloading */ + seq->sound->flags |= SOUND_FLAGS_WAVEFORM_LOADING; + BLI_mutex_unlock(sound->mutex); + sequencer_preview_add_sound(C, seq); + } + else { + BLI_mutex_unlock(sound->mutex); + } + return; /* nothing to draw */ + } + BLI_mutex_unlock(sound->mutex); + waveform = seq->sound->waveform; - - if (!waveform) - return; - + startsample = floor((seq->startofs + seq->anim_startofs) / FPS * SOUND_WAVE_SAMPLES_PER_SECOND); endsample = ceil((seq->startofs + seq->anim_startofs + seq->enddisp - seq->startdisp) / FPS * SOUND_WAVE_SAMPLES_PER_SECOND); samplestep = (endsample - startsample) * stepsize / (x2 - x1); @@ -299,7 +313,7 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, if ((seqm->flag & SEQ_MUTE) == 0 && (seq->flag & SEQ_MUTE)) drawmeta_stipple(1); - get_seq_color3ubv(scene, seq, col); + color3ubv_from_seq(scene, seq, col); glColor4ubv(col); @@ -332,7 +346,10 @@ static float draw_seq_handle_size_get_clamped(Sequence *seq, const float pixelx) { const float minhandle = pixelx * SEQ_HANDLE_SIZE_MIN; const float maxhandle = pixelx * SEQ_HANDLE_SIZE_MAX; - return CLAMPIS(seq->handsize, minhandle, maxhandle); + float size = CLAMPIS(seq->handsize, minhandle, maxhandle); + + /* ensure we're not greater than half width */ + return min_ff(size, ((float)(seq->enddisp - seq->startdisp) / 2.0f) / pixelx); } /* draw a handle, for each end of a sequence strip */ @@ -415,112 +432,6 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_cla } } -static void draw_seq_extensions(Scene *scene, ARegion *ar, Sequence *seq) -{ - float x1, x2, y1, y2, pixely, a; - unsigned char col[3], blendcol[3]; - View2D *v2d = &ar->v2d; - - if (seq->type >= SEQ_TYPE_EFFECT) return; - - x1 = seq->startdisp; - x2 = seq->enddisp; - - y1 = seq->machine + SEQ_STRIP_OFSBOTTOM; - y2 = seq->machine + SEQ_STRIP_OFSTOP; - - pixely = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask); - - if (pixely <= 0) return; /* can happen when the view is split/resized */ - - blendcol[0] = blendcol[1] = blendcol[2] = 120; - - if (seq->startofs) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - get_seq_color3ubv(scene, seq, col); - - if (seq->flag & SELECT) { - UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40); - glColor4ub(col[0], col[1], col[2], 170); - } - else { - UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0); - glColor4ub(col[0], col[1], col[2], 110); - } - - glRectf((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1); - - if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255); - else glColor4ub(col[0], col[1], col[2], 160); - - fdrawbox((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1); //outline - - glDisable(GL_BLEND); - } - if (seq->endofs) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - get_seq_color3ubv(scene, seq, col); - - if (seq->flag & SELECT) { - UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40); - glColor4ub(col[0], col[1], col[2], 170); - } - else { - UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0); - glColor4ub(col[0], col[1], col[2], 110); - } - - glRectf(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); - - if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255); - else glColor4ub(col[0], col[1], col[2], 160); - - fdrawbox(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); //outline - - glDisable(GL_BLEND); - } - if (seq->startstill) { - get_seq_color3ubv(scene, seq, col); - UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40); - glColor3ubv((GLubyte *)col); - - draw_shadedstrip(seq, col, x1, y1, (float)(seq->start), y2); - - /* feint pinstripes, helps see exactly which is extended and which isn't, - * especially when the extension is very small */ - if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24); - else UI_GetColorPtrShade3ubv(col, col, -16); - - glColor3ubv((GLubyte *)col); - - for (a = y1; a < y2; a += pixely * 2.0f) { - fdrawline(x1, a, (float)(seq->start), a); - } - } - if (seq->endstill) { - get_seq_color3ubv(scene, seq, col); - UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40); - glColor3ubv((GLubyte *)col); - - draw_shadedstrip(seq, col, (float)(seq->start + seq->len), y1, x2, y2); - - /* feint pinstripes, helps see exactly which is extended and which isn't, - * especially when the extension is very small */ - if (seq->flag & SELECT) UI_GetColorPtrShade3ubv(col, col, 24); - else UI_GetColorPtrShade3ubv(col, col, -16); - - glColor3ubv((GLubyte *)col); - - for (a = y1; a < y2; a += pixely * 2.0f) { - fdrawline((float)(seq->start + seq->len), a, x2, a); - } - } -} - /* draw info text on a sequence strip */ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float y1, float y2, const unsigned char background_col[3]) { @@ -627,7 +538,7 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float } /* draws a shaded strip, made from gradient + flat color + gradient */ -static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2) +void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2) { float ymid1, ymid2; @@ -684,12 +595,117 @@ static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, floa } } +void draw_sequence_extensions(Scene *scene, ARegion *ar, Sequence *seq) +{ + float x1, x2, y1, y2, pixely, a; + unsigned char col[3], blendcol[3]; + View2D *v2d = &ar->v2d; + + x1 = seq->startdisp; + x2 = seq->enddisp; + + y1 = seq->machine + SEQ_STRIP_OFSBOTTOM; + y2 = seq->machine + SEQ_STRIP_OFSTOP; + + pixely = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask); + + if (pixely <= 0) return; /* can happen when the view is split/resized */ + + blendcol[0] = blendcol[1] = blendcol[2] = 120; + + if (seq->startofs) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + color3ubv_from_seq(scene, seq, col); + + if (seq->flag & SELECT) { + UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40); + glColor4ub(col[0], col[1], col[2], 170); + } + else { + UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0); + glColor4ub(col[0], col[1], col[2], 110); + } + + glRectf((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1); + + if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255); + else glColor4ub(col[0], col[1], col[2], 160); + + fdrawbox((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1); //outline + + glDisable(GL_BLEND); + } + if (seq->endofs) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + color3ubv_from_seq(scene, seq, col); + + if (seq->flag & SELECT) { + UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40); + glColor4ub(col[0], col[1], col[2], 170); + } + else { + UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0); + glColor4ub(col[0], col[1], col[2], 110); + } + + glRectf(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); + + if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255); + else glColor4ub(col[0], col[1], col[2], 160); + + fdrawbox(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); //outline + + glDisable(GL_BLEND); + } + if (seq->startstill) { + color3ubv_from_seq(scene, seq, col); + UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40); + glColor3ubv((GLubyte *)col); + + draw_shadedstrip(seq, col, x1, y1, (float)(seq->start), y2); + + /* feint pinstripes, helps see exactly which is extended and which isn't, + * especially when the extension is very small */ + if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24); + else UI_GetColorPtrShade3ubv(col, col, -16); + + glColor3ubv((GLubyte *)col); + + for (a = y1; a < y2; a += pixely * 2.0f) { + fdrawline(x1, a, (float)(seq->start), a); + } + } + if (seq->endstill) { + color3ubv_from_seq(scene, seq, col); + UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40); + glColor3ubv((GLubyte *)col); + + draw_shadedstrip(seq, col, (float)(seq->start + seq->len), y1, x2, y2); + + /* feint pinstripes, helps see exactly which is extended and which isn't, + * especially when the extension is very small */ + if (seq->flag & SELECT) UI_GetColorPtrShade3ubv(col, col, 24); + else UI_GetColorPtrShade3ubv(col, col, -16); + + glColor3ubv((GLubyte *)col); + + for (a = y1; a < y2; a += pixely * 2.0f) { + fdrawline((float)(seq->start + seq->len), a, x2, a); + } + } +} + + /* * Draw a sequence strip, bounds check already made * ARegion is currently only used to get the windows width in pixels * so wave file sample drawing precision is zoom adjusted */ -static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline_tint, float pixelx) +static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, ARegion *ar, Sequence *seq, int outline_tint, float pixelx) { View2D *v2d = &ar->v2d; float x1, x2, y1, y2; @@ -707,8 +723,8 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline /* get the correct color per strip type*/ - //get_seq_color3ubv(scene, seq, col); - get_seq_color3ubv(scene, seq, background_col); + //color3ubv_from_seq(scene, seq, col); + color3ubv_from_seq(scene, seq, background_col); /* draw the main strip body */ if (is_single_image) { /* single image */ @@ -720,10 +736,10 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline draw_shadedstrip(seq, background_col, x1, y1, x2, y2); } - /* draw additional info and controls */ - if (!is_single_image) - draw_seq_extensions(scene, ar, seq); - + if ((sseq->draw_flag & SEQ_DRAW_OFFSET_EXT) && !is_single_image) { + draw_sequence_extensions(scene, ar, seq); + } + draw_seq_handle(v2d, seq, handsize_clamped, SEQ_LEFTHANDLE); draw_seq_handle(v2d, seq, handsize_clamped, SEQ_RIGHTHANDLE); @@ -733,7 +749,9 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline /* draw sound wave */ if (seq->type == SEQ_TYPE_SOUND_RAM) { - drawseqwave(scene, seq, x1, y1, x2, y2, BLI_rctf_size_x(&ar->v2d.cur) / ar->winx); + if (!(sseq->flag & SEQ_NO_WAVEFORMS)) { + drawseqwave(C, sseq, scene, seq, x1, y1, x2, y2, BLI_rctf_size_x(&ar->v2d.cur) / ar->winx); + } } /* draw lock */ @@ -766,7 +784,7 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline glDisable(GL_POLYGON_STIPPLE); } - get_seq_color3ubv(scene, seq, col); + color3ubv_from_seq(scene, seq, col); if ((G.moving & G_TRANSFORM_SEQ) && (seq->flag & SELECT)) { if (seq->flag & SEQ_OVERLAP) { col[0] = 255; col[1] = col[2] = 40; @@ -784,7 +802,7 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline glLineStipple(1, 0x8888); } - uiDrawBoxShade(GL_LINE_LOOP, x1, y1, x2, y2, 0.0, 0.1, 0.0); + UI_draw_roundbox_shade_x(GL_LINE_LOOP, x1, y1, x2, y2, 0.0, 0.1, 0.0); if (seq->flag & SEQ_MUTE) { glDisable(GL_LINE_STIPPLE); @@ -917,7 +935,7 @@ static ImBuf *sequencer_make_scope(Scene *scene, ImBuf *ibuf, ImBuf *(*make_scop return scope; } -void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq, int cfra, int frame_ofs, bool draw_overlay) +void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq, int cfra, int frame_ofs, bool draw_overlay, bool draw_backdrop) { struct Main *bmain = CTX_data_main(C); struct ImBuf *ibuf = NULL; @@ -973,7 +991,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq viewrecty /= proxy_size / 100.0f; } - if (!draw_overlay || sseq->overlay_type == SEQ_DRAW_OVERLAY_REFERENCE) { + if ((!draw_overlay || sseq->overlay_type == SEQ_DRAW_OVERLAY_REFERENCE) && !draw_backdrop) { UI_GetThemeColor3fv(TH_SEQ_PREVIEW, col); glClearColor(col[0], col[1], col[2], 0.0); glClear(GL_COLOR_BUFFER_BIT); @@ -1048,23 +1066,25 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq /* without this colors can flicker from previous opengl state */ glColor4ub(255, 255, 255, 255); - UI_view2d_totRect_set(v2d, viewrectx + 0.5f, viewrecty + 0.5f); - UI_view2d_curRect_validate(v2d); - - /* setting up the view - actual drawing starts here */ - UI_view2d_view_ortho(v2d); - - /* only draw alpha for main buffer */ - if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { - if (sseq->flag & SEQ_USE_ALPHA) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - fdrawcheckerboard(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax); - glColor4f(1.0, 1.0, 1.0, 1.0); + if (!draw_backdrop) { + UI_view2d_totRect_set(v2d, viewrectx + 0.5f, viewrecty + 0.5f); + UI_view2d_curRect_validate(v2d); + + /* setting up the view - actual drawing starts here */ + UI_view2d_view_ortho(v2d); + + /* only draw alpha for main buffer */ + if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { + if (sseq->flag & SEQ_USE_ALPHA) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + fdrawcheckerboard(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax); + glColor4f(1.0, 1.0, 1.0, 1.0); + } } } - + if (scope) { IMB_freeImBuf(ibuf); ibuf = scope; @@ -1154,6 +1174,14 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq else glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, format, type, display_buffer); + if (draw_backdrop) { + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + } glBegin(GL_QUADS); if (draw_overlay) { @@ -1176,6 +1204,25 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq glTexCoord2f(1.0f, 0.0f); glVertex2f(v2d->tot.xmax, v2d->tot.ymin); } } + else if (draw_backdrop) { + float aspect = BLI_rcti_size_x(&ar->winrct) / (float)BLI_rcti_size_y(&ar->winrct); + float image_aspect = viewrectx / viewrecty; + float imagex, imagey; + + if (aspect >= image_aspect) { + imagex = image_aspect / aspect; + imagey = 1.0f; + } + else { + imagex = 1.0f; + imagey = aspect / image_aspect; + } + + glTexCoord2f(0.0f, 0.0f); glVertex2f(-imagex, -imagey); + glTexCoord2f(0.0f, 1.0f); glVertex2f(-imagex, imagey); + glTexCoord2f(1.0f, 1.0f); glVertex2f(imagex, imagey); + glTexCoord2f(1.0f, 0.0f); glVertex2f(imagex, -imagey); + } else { glTexCoord2f(0.0f, 0.0f); glVertex2f(v2d->tot.xmin, v2d->tot.ymin); glTexCoord2f(0.0f, 1.0f); glVertex2f(v2d->tot.xmin, v2d->tot.ymax); @@ -1183,6 +1230,15 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq glTexCoord2f(1.0f, 0.0f); glVertex2f(v2d->tot.xmax, v2d->tot.ymin); } glEnd(); + + if (draw_backdrop) { + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + } + glBindTexture(GL_TEXTURE_2D, last_texid); glDisable(GL_TEXTURE_2D); if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) @@ -1192,6 +1248,16 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq if (glsl_used) IMB_colormanagement_finish_glsl_draw(); + if (cache_handle) + IMB_display_buffer_release(cache_handle); + + if (!scope) + IMB_freeImBuf(ibuf); + + if (draw_backdrop) { + return; + } + if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { float x1 = v2d->tot.xmin; @@ -1225,8 +1291,8 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - uiSetRoundBox(UI_CNR_ALL); - uiDrawBox(GL_LINE_LOOP, x1, y1, x2, y2, 12.0); + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox_gl_mode(GL_LINE_LOOP, x1, y1, x2, y2, 12.0); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); @@ -1241,9 +1307,6 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq ED_gpencil_draw_2dimage(C); } } - - if (!scope) - IMB_freeImBuf(ibuf); /* ortho at pixel level */ UI_view2d_view_restore(C); @@ -1280,9 +1343,6 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq NULL, C); } } - - if (cache_handle) - IMB_display_buffer_release(cache_handle); } #if 0 @@ -1359,6 +1419,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar) { Scene *scene = CTX_data_scene(C); View2D *v2d = &ar->v2d; + SpaceSeq *sseq = CTX_wm_space_seq(C); Sequence *last_seq = BKE_sequencer_active_get(scene); int sel = 0, j; float pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask); @@ -1379,7 +1440,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar) else if (seq->machine > v2d->cur.ymax) continue; /* strip passed all tests unscathed... so draw it now */ - draw_seq_strip(scene, ar, seq, outline_tint, pixelx); + draw_seq_strip(C, sseq, scene, ar, seq, outline_tint, pixelx); } /* draw selected next time round */ @@ -1388,20 +1449,24 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar) /* draw the last selected last (i.e. 'active' in other parts of Blender), removes some overlapping error */ if (last_seq) - draw_seq_strip(scene, ar, last_seq, 120, pixelx); + draw_seq_strip(C, sseq, scene, ar, last_seq, 120, pixelx); } static void seq_draw_sfra_efra(Scene *scene, View2D *v2d) -{ +{ + const Editing *ed = BKE_sequencer_editing_get(scene, false); + const int frame_sta = PSFRA; + const int frame_end = PEFRA + 1; + glEnable(GL_BLEND); /* draw darkened area outside of active timeline * frame range used is preview range or scene range */ UI_ThemeColorShadeAlpha(TH_BACK, -25, -100); - if (PSFRA < PEFRA + 1) { - glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax); - glRectf((float)(PEFRA + 1), v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); + if (frame_sta < frame_end) { + glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)frame_sta, v2d->cur.ymax); + glRectf((float)frame_end, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); } else { glRectf(v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); @@ -1409,9 +1474,21 @@ static void seq_draw_sfra_efra(Scene *scene, View2D *v2d) UI_ThemeColorShade(TH_BACK, -60); /* thin lines where the actual frames are */ - fdrawline((float)PSFRA, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax); - fdrawline((float)(PEFRA + 1), v2d->cur.ymin, (float)(PEFRA + 1), v2d->cur.ymax); - + fdrawline(frame_sta, v2d->cur.ymin, frame_sta, v2d->cur.ymax); + fdrawline(frame_end, v2d->cur.ymin, frame_end, v2d->cur.ymax); + + if (ed && !BLI_listbase_is_empty(&ed->metastack)) { + MetaStack *ms = ed->metastack.last; + + glColor4ub(255, 255, 255, 8); + glRectf(ms->disp_range[0], v2d->cur.ymin, ms->disp_range[1], v2d->cur.ymax); + + UI_ThemeColorShade(TH_BACK, -40); + + fdrawline(ms->disp_range[0], v2d->cur.ymin, ms->disp_range[0], v2d->cur.ymax); + fdrawline(ms->disp_range[1], v2d->cur.ymin, ms->disp_range[1], v2d->cur.ymax); + } + glDisable(GL_BLEND); } @@ -1450,6 +1527,12 @@ void draw_timeline_seq(const bContext *C, ARegion *ar) // NOTE: the gridlines are currently spaced every 25 frames, which is only fine for 25 fps, but maybe not for 30... UI_view2d_constant_grid_draw(v2d); + if (sseq->draw_flag & SEQ_DRAW_BACKDROP) { + draw_image_seq(C, scene, ar, sseq, scene->r.cfra, 0, false, true); + UI_SetTheme(SPACE_SEQ, RGN_TYPE_WINDOW); + UI_view2d_view_ortho(v2d); + } + ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW); seq_draw_sfra_efra(scene, v2d); @@ -1471,7 +1554,7 @@ void draw_timeline_seq(const bContext *C, ARegion *ar) /* markers */ UI_view2d_view_orthoSpecial(ar, v2d, 1); - draw_markers_time(C, DRAW_MARKERS_LINES); + ED_markers_draw(C, DRAW_MARKERS_LINES | DRAW_MARKERS_MARGIN); /* preview range */ UI_view2d_view_ortho(v2d); diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 9c43d22ae2f..c48171826a9 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -49,7 +49,6 @@ #include "BKE_report.h" #include "BKE_sound.h" -#include "IMB_imbuf.h" #include "WM_api.h" #include "WM_types.h" @@ -62,9 +61,11 @@ #include "ED_screen.h" #include "ED_transform.h" #include "ED_sequencer.h" +#include "ED_space_api.h" #include "UI_view2d.h" + /* own include */ #include "sequencer_intern.h" @@ -385,7 +386,7 @@ Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[ displen = (float)abs(seq->startdisp - seq->enddisp); if (displen / pixelx > 16) { /* don't even try to grab the handles of small strips */ - /* Set the max value to handle to 1/3 of the total len when its less then 28. + /* Set the max value to handle to 1/3 of the total len when its less than 28. * This is important because otherwise selecting handles happens even when you click in the middle */ if ((displen / 3) < 30 * pixelx) { @@ -1231,6 +1232,387 @@ void SEQUENCER_OT_snap(struct wmOperatorType *ot) RNA_def_int(ot->srna, "frame", 0, INT_MIN, INT_MAX, "Frame", "Frame where selected strips will be snapped", INT_MIN, INT_MAX); } +typedef struct SlipData { + int init_mouse[2]; + float init_mouseloc[2]; + TransSeq *ts; + Sequence **seq_array; + bool *trim; + int num_seq; + bool slow; + int slow_offset; /* offset at the point where offset was turned on */ + void *draw_handle; +} SlipData; + +static void transseq_backup(TransSeq *ts, Sequence *seq) +{ + ts->start = seq->start; + ts->machine = seq->machine; + ts->startstill = seq->startstill; + ts->endstill = seq->endstill; + ts->startdisp = seq->startdisp; + ts->enddisp = seq->enddisp; + ts->startofs = seq->startofs; + ts->endofs = seq->endofs; + ts->anim_startofs = seq->anim_startofs; + ts->anim_endofs = seq->anim_endofs; + ts->len = seq->len; +} + + +static void transseq_restore(TransSeq *ts, Sequence *seq) +{ + seq->start = ts->start; + seq->machine = ts->machine; + seq->startstill = ts->startstill; + seq->endstill = ts->endstill; + seq->startdisp = ts->startdisp; + seq->enddisp = ts->enddisp; + seq->startofs = ts->startofs; + seq->endofs = ts->endofs; + seq->anim_startofs = ts->anim_startofs; + seq->anim_endofs = ts->anim_endofs; + seq->len = ts->len; +} + +static void draw_slip_extensions(const bContext *C, ARegion *ar, void *data) +{ + Scene *scene = CTX_data_scene(C); + SlipData *td = data; + int i; + + for (i = 0; i < td->num_seq; i++) { + Sequence *seq = td->seq_array[i]; + + if ((seq->type != SEQ_TYPE_META) && td->trim[i]) { + draw_sequence_extensions(scene, ar, seq); + } + } +} + +static int slip_add_sequences_rec(ListBase *seqbasep, Sequence **seq_array, bool *trim, int offset, bool do_trim) +{ + Sequence *seq; + int num_items = 0; + + for (seq = seqbasep->first; seq; seq = seq->next) { + if (!do_trim || (!(seq->type & SEQ_TYPE_EFFECT) && (seq->flag & SELECT))) { + seq_array[offset + num_items] = seq; + trim[offset + num_items] = do_trim; + num_items++; + + if (seq->type == SEQ_TYPE_META) { + /* trim the sub-sequences */ + num_items += slip_add_sequences_rec(&seq->seqbase, seq_array, trim, num_items + offset, false); + } + else if (seq->type & SEQ_TYPE_EFFECT) { + trim[offset + num_items] = false; + } + } + } + + return num_items; +} + +static int slip_count_sequences_rec(ListBase *seqbasep, bool first_level) +{ + Sequence *seq; + int trimmed_sequences = 0; + + for (seq = seqbasep->first; seq; seq = seq->next) { + if (!first_level || (!(seq->type & SEQ_TYPE_EFFECT) && (seq->flag & SELECT))) { + trimmed_sequences++; + + if (seq->type == SEQ_TYPE_META) { + /* trim the sub-sequences */ + trimmed_sequences += slip_count_sequences_rec(&seq->seqbase, false); + } + } + } + + return trimmed_sequences; +} + +static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + SlipData *data; + Scene *scene = CTX_data_scene(C); + Editing *ed = BKE_sequencer_editing_get(scene, false); + ARegion *ar = CTX_wm_region(C); + float mouseloc[2]; + int num_seq, i; + View2D *v2d = UI_view2d_fromcontext(C); + + /* first recursively cound the trimmed elements */ + num_seq = slip_count_sequences_rec(ed->seqbasep, true); + + if (num_seq == 0) + return OPERATOR_CANCELLED; + + data = op->customdata = MEM_mallocN(sizeof(SlipData), "trimdata"); + data->ts = MEM_mallocN(num_seq * sizeof(TransSeq), "trimdata_transform"); + data->seq_array = MEM_mallocN(num_seq * sizeof(Sequence *), "trimdata_sequences"); + data->trim = MEM_mallocN(num_seq * sizeof(bool), "trimdata_trim"); + data->num_seq = num_seq; + + slip_add_sequences_rec(ed->seqbasep, data->seq_array, data->trim, 0, true); + + for (i = 0; i < num_seq; i++) { + transseq_backup(data->ts + i, data->seq_array[i]); + } + + data->draw_handle = ED_region_draw_cb_activate(ar->type, draw_slip_extensions, data, REGION_DRAW_POST_VIEW); + + UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &mouseloc[0], &mouseloc[1]); + + copy_v2_v2_int(data->init_mouse, event->mval); + copy_v2_v2(data->init_mouseloc, mouseloc); + + data->slow = false; + + WM_event_add_modal_handler(C, op); + + /* notify so we draw extensions immediately */ + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + + return OPERATOR_RUNNING_MODAL; +} + +static bool sequencer_slip_recursively(Scene *scene, SlipData *data, int offset) +{ + + /* only data types supported for now */ + if (offset != 0) { + Editing *ed = BKE_sequencer_editing_get(scene, false); + int i; + + /* we iterate in reverse so metastrips are iterated after their children */ + for (i = data->num_seq - 1; i >= 0; i--) { + Sequence *seq = data->seq_array[i]; + int endframe; + /* we have the offset, do the terrible math */ + + /* first, do the offset */ + seq->start = data->ts[i].start + offset; + + if (data->trim[i]) { + /* find the endframe */ + endframe = seq->start + seq->len; + + /* now compute the terrible offsets */ + if (endframe > seq->enddisp) { + seq->endstill = 0; + seq->endofs = endframe - seq->enddisp; + } + else if (endframe <= seq->enddisp) { + seq->endstill = seq->enddisp - endframe; + seq->endofs = 0; + } + + if (seq->start > seq->startdisp) { + seq->startstill = seq->start - seq->startdisp; + seq->startofs = 0; + } + else if (seq->start <= seq->startdisp) { + seq->startstill = 0; + seq->startofs = seq->startdisp - seq->start; + } + } + else { + /* if no real trim, don't change the data, rather transform the strips themselves */ + seq->startdisp = data->ts[i].startdisp + offset; + seq->enddisp = data->ts[i].enddisp + offset; + } + + /* effects are only added if we they are in a metastrip. In this case, dependent strips will just be transformed and we can skip calculating for effects + * This way we can avoid an extra loop just for effects*/ + if (!(seq->type & SEQ_TYPE_EFFECT)) + BKE_sequence_calc(scene, seq); + } + BKE_sequencer_free_imbuf(scene, &ed->seqbase, false); + + return true; + } + + return false; +} + +static int sequencer_slip_exec(bContext *C, wmOperator *op) +{ + SlipData *data; + Scene *scene = CTX_data_scene(C); + Editing *ed = BKE_sequencer_editing_get(scene, false); + int num_seq, i; + int offset = RNA_int_get(op->ptr, "offset"); + bool success = false; + + /* first recursively cound the trimmed elements */ + num_seq = slip_count_sequences_rec(ed->seqbasep, true); + + if (num_seq == 0) + return OPERATOR_CANCELLED; + + data = op->customdata = MEM_mallocN(sizeof(SlipData), "trimdata"); + data->ts = MEM_mallocN(num_seq * sizeof(TransSeq), "trimdata_transform"); + data->seq_array = MEM_mallocN(num_seq * sizeof(Sequence *), "trimdata_sequences"); + data->trim = MEM_mallocN(num_seq * sizeof(bool), "trimdata_trim"); + data->num_seq = num_seq; + + slip_add_sequences_rec(ed->seqbasep, data->seq_array, data->trim, 0, true); + + for (i = 0; i < num_seq; i++) { + transseq_backup(data->ts + i, data->seq_array[i]); + } + + success = sequencer_slip_recursively(scene, data, offset); + + MEM_freeN(data->seq_array); + MEM_freeN(data->trim); + MEM_freeN(data->ts); + MEM_freeN(data); + + if (success) { + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + Scene *scene = CTX_data_scene(C); + SlipData *data = (SlipData *)op->customdata; + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + + switch (event->type) { + case MOUSEMOVE: + { + float mouseloc[2]; + int offset; + int mouse_x; + View2D *v2d = UI_view2d_fromcontext(C); + + if (data->slow) { + mouse_x = event->mval[0] - data->slow_offset; + mouse_x *= 0.1f; + mouse_x += data->slow_offset; + } + else { + mouse_x = event->mval[0]; + } + + + /* choose the side based on which side of the playhead the mouse is on */ + UI_view2d_region_to_view(v2d, mouse_x, 0, &mouseloc[0], &mouseloc[1]); + offset = mouseloc[0] - data->init_mouseloc[0]; + + RNA_int_set(op->ptr, "offset", offset); + + if (sa) { +#define HEADER_LENGTH 40 + char msg[HEADER_LENGTH]; + BLI_snprintf(msg, HEADER_LENGTH, "Trim offset: %d", offset); +#undef HEADER_LENGTH + ED_area_headerprint(sa, msg); + } + + if (sequencer_slip_recursively(scene, data, offset)) { + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + } + break; + } + + case LEFTMOUSE: + { + ED_region_draw_cb_exit(ar->type, data->draw_handle); + MEM_freeN(data->seq_array); + MEM_freeN(data->trim); + MEM_freeN(data->ts); + MEM_freeN(data); + op->customdata = NULL; + if (sa) { + ED_area_headerprint(sa, NULL); + } + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + return OPERATOR_FINISHED; + } + + case ESCKEY: + case RIGHTMOUSE: + { + int i; + Editing *ed = BKE_sequencer_editing_get(scene, false); + + for (i = 0; i < data->num_seq; i++) { + transseq_restore(data->ts + i, data->seq_array[i]); + } + + for (i = 0; i < data->num_seq; i++) { + Sequence *seq = data->seq_array[i]; + BKE_sequence_reload_new_file(scene, seq, false); + BKE_sequence_calc(scene, seq); + } + + ED_region_draw_cb_exit(ar->type, data->draw_handle); + + MEM_freeN(data->seq_array); + MEM_freeN(data->ts); + MEM_freeN(data->trim); + MEM_freeN(data); + op->customdata = NULL; + + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + + BKE_sequencer_free_imbuf(scene, &ed->seqbase, false); + + if (sa) { + ED_area_headerprint(sa, NULL); + } + + return OPERATOR_CANCELLED; + } + + case RIGHTSHIFTKEY: + case LEFTSHIFTKEY: + if (event->val == KM_PRESS) { + data->slow = true; + data->slow_offset = event->mval[0]; + } + else if (event->val == KM_RELEASE) { + data->slow = false; + } + break; + + default: + break; + } + + return OPERATOR_RUNNING_MODAL; +} + +void SEQUENCER_OT_slip(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Trim Strips"; + ot->idname = "SEQUENCER_OT_slip"; + ot->description = "Trim the contents of the active strip"; + + /* api callbacks */ + ot->invoke = sequencer_slip_invoke; + ot->modal = sequencer_slip_modal; + ot->exec = sequencer_slip_exec; + ot->poll = sequencer_edit_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_int(ot->srna, "offset", 0, INT32_MIN, INT32_MAX, "Offset", "Offset to the data of the strip", + INT32_MIN, INT32_MAX); +} + /* mute operator */ static int sequencer_mute_exec(bContext *C, wmOperator *op) { @@ -1993,6 +2375,7 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op)) BLI_addtail(&ed->metastack, ms); ms->parseq = last_seq; ms->oldbasep = ed->seqbasep; + copy_v2_v2_int(ms->disp_range, &ms->parseq->startdisp); ed->seqbasep = &last_seq->seqbase; @@ -2012,12 +2395,25 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op)) ed->seqbasep = ms->oldbasep; + /* for old files, update from meta */ + if (ms->disp_range[0] == ms->disp_range[1]) { + copy_v2_v2_int(ms->disp_range, &ms->parseq->startdisp); + } + /* recalc all: the meta can have effects connected to it */ for (seq = ed->seqbasep->first; seq; seq = seq->next) BKE_sequence_calc(scene, seq); + /* 2.73+, keeping endpoings is important! + * moving them around means you can't usefully use metas in a complex edit */ +#if 1 + BKE_sequence_tx_set_final_left(ms->parseq, ms->disp_range[0]); + BKE_sequence_tx_set_final_right(ms->parseq, ms->disp_range[1]); + BKE_sequence_calc(scene, ms->parseq); +#else if (BKE_sequence_test_overlap(ed->seqbasep, ms->parseq)) BKE_sequence_base_shuffle(ed->seqbasep, ms->parseq, scene); +#endif BKE_sequencer_active_set(scene, ms->parseq); @@ -2059,8 +2455,8 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op) Sequence *seq, *seqm, *next, *last_seq = BKE_sequencer_active_get(scene); int channel_max = 1; - if (BKE_sequence_base_isolated_sel_check(ed->seqbasep, false) == false) { - BKE_report(op->reports, RPT_ERROR, "Please select more than one or all related strips"); + if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == false) { + BKE_report(op->reports, RPT_ERROR, "Please select all related strips"); return OPERATOR_CANCELLED; } @@ -2439,88 +2835,13 @@ void SEQUENCER_OT_view_selected(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER; } - -static int find_next_prev_edit(Scene *scene, int cfra, - const short side, - const bool do_skip_mute, const bool do_center) -{ - Editing *ed = BKE_sequencer_editing_get(scene, false); - Sequence *seq, *best_seq = NULL, *frame_seq = NULL; - - int dist, best_dist; - best_dist = MAXFRAME * 2; - - if (ed == NULL) return cfra; - - for (seq = ed->seqbasep->first; seq; seq = seq->next) { - int seq_frame; - - if (do_skip_mute && (seq->flag & SEQ_MUTE)) { - continue; - } - - if (do_center) { - seq_frame = (seq->startdisp + seq->enddisp) / 2; - } - else { - seq_frame = seq->startdisp; - } - - dist = MAXFRAME * 2; - - switch (side) { - case SEQ_SIDE_LEFT: - if (seq_frame < cfra) { - dist = cfra - seq_frame; - } - break; - case SEQ_SIDE_RIGHT: - if (seq_frame > cfra) { - dist = seq_frame - cfra; - } - else if (seq_frame == cfra) { - frame_seq = seq; - } - break; - } - - if (dist < best_dist) { - best_dist = dist; - best_seq = seq; - } - } - - /* if no sequence to the right is found and the - * frame is on the start of the last sequence, - * move to the end of the last sequence */ - if (frame_seq) { - if (do_center) { - cfra = (frame_seq->startdisp + frame_seq->enddisp) / 2; - } - else { - cfra = frame_seq->enddisp; - } - } - - if (best_seq) { - if (do_center) { - cfra = (best_seq->startdisp + best_seq->enddisp) / 2; - } - else { - cfra = best_seq->startdisp; - } - } - - return cfra; -} - static bool strip_jump_internal(Scene *scene, const short side, const bool do_skip_mute, const bool do_center) { bool changed = false; int cfra = CFRA; - int nfra = find_next_prev_edit(scene, cfra, side, do_skip_mute, do_center); + int nfra = BKE_sequencer_find_next_prev_edit(scene, cfra, side, do_skip_mute, do_center, false); if (nfra != cfra) { CFRA = nfra; @@ -2767,7 +3088,7 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) BKE_sequencer_free_clipboard(); - if (BKE_sequence_base_isolated_sel_check(ed->seqbasep, true) == false) { + if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == false) { BKE_report(op->reports, RPT_ERROR, "Please select all related strips"); return OPERATOR_CANCELLED; } @@ -2804,9 +3125,7 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) } /* duplicate pointers */ - for (seq = seqbase_clipboard.first; seq; seq = seq->next) { - BKE_sequence_clipboard_pointers_store(seq); - } + BKE_sequencer_base_clipboard_pointers_store(&seqbase_clipboard); } return OPERATOR_FINISHED; @@ -2850,9 +3169,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op)) } } - for (iseq = nseqbase.first; iseq; iseq = iseq->next) { - BKE_sequence_clipboard_pointers_restore(iseq, bmain); - } + BKE_sequencer_base_clipboard_pointers_restore(&nseqbase, bmain); for (iseq = nseqbase.first; iseq; iseq = iseq->next) { BKE_sequence_sound_init(scene, iseq); @@ -3270,4 +3587,3 @@ void SEQUENCER_OT_change_path(struct wmOperatorType *ot) WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILEPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY); } - diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h index df266b0f546..4e11b4da235 100644 --- a/source/blender/editors/space_sequencer/sequencer_intern.h +++ b/source/blender/editors/space_sequencer/sequencer_intern.h @@ -45,6 +45,7 @@ struct ARegion; struct ARegionType; struct Scene; struct Main; +struct SequencePreview; /* space_sequencer.c */ struct ARegion *sequencer_has_buttons_region(struct ScrArea *sa); @@ -52,7 +53,10 @@ struct ARegion *sequencer_has_buttons_region(struct ScrArea *sa); /* sequencer_draw.c */ void draw_timeline_seq(const struct bContext *C, struct ARegion *ar); -void draw_image_seq(const struct bContext *C, struct Scene *scene, struct ARegion *ar, struct SpaceSeq *sseq, int cfra, int offset, bool draw_overlay); +void draw_image_seq(const struct bContext *C, struct Scene *scene, struct ARegion *ar, struct SpaceSeq *sseq, int cfra, int offset, bool draw_overlay, bool draw_backdrop); +void color3ubv_from_seq(struct Scene *curscene, struct Sequence *seq, unsigned char col[3]); +void draw_shadedstrip(struct Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2); +void draw_sequence_extensions(struct Scene *scene, struct ARegion *ar, struct Sequence *seq); /* UNUSED */ // void seq_reset_imageofs(struct SpaceSeq *sseq); @@ -84,6 +88,7 @@ struct wmOperatorType; struct wmKeyConfig; void SEQUENCER_OT_cut(struct wmOperatorType *ot); +void SEQUENCER_OT_slip(struct wmOperatorType *ot); void SEQUENCER_OT_mute(struct wmOperatorType *ot); void SEQUENCER_OT_unmute(struct wmOperatorType *ot); void SEQUENCER_OT_lock(struct wmOperatorType *ot); @@ -149,13 +154,6 @@ void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot); void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot); void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot); -/* RNA enums, just to be more readable */ -enum { - SEQ_SIDE_NONE = 0, - SEQ_SIDE_LEFT, - SEQ_SIDE_RIGHT, - SEQ_SIDE_BOTH -}; enum { SEQ_CUT_SOFT, SEQ_CUT_HARD @@ -198,5 +196,8 @@ void SEQUENCER_OT_strip_modifier_move(struct wmOperatorType *ot); /* sequencer_view.c */ void SEQUENCER_OT_sample(struct wmOperatorType *ot); +/* sequencer_preview.c */ +void sequencer_preview_add_sound(const struct bContext *C, struct Sequence *seq); + #endif /* __SEQUENCER_INTERN_H__ */ diff --git a/source/blender/editors/space_sequencer/sequencer_modifier.c b/source/blender/editors/space_sequencer/sequencer_modifier.c index ff40bf1e638..83f3f9bc961 100644 --- a/source/blender/editors/space_sequencer/sequencer_modifier.c +++ b/source/blender/editors/space_sequencer/sequencer_modifier.c @@ -29,24 +29,14 @@ * \ingroup spseq */ -#include "MEM_guardedalloc.h" #include "BLI_blenlib.h" -#include "BLI_math.h" #include "BLI_utildefines.h" #include "DNA_scene_types.h" -#include "DNA_mask_types.h" -#include "DNA_userdef_types.h" #include "BKE_context.h" -#include "BKE_global.h" -#include "BKE_library.h" -#include "BKE_main.h" #include "BKE_sequencer.h" -#include "BKE_movieclip.h" -#include "BKE_mask.h" -#include "BKE_report.h" #include "WM_api.h" #include "WM_types.h" @@ -54,8 +44,6 @@ #include "RNA_define.h" #include "RNA_enum_types.h" -#include "UI_interface.h" -#include "UI_resources.h" /* own include */ #include "sequencer_intern.h" diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c index c5e47c3aa3e..9b5ef18f7cd 100644 --- a/source/blender/editors/space_sequencer/sequencer_ops.c +++ b/source/blender/editors/space_sequencer/sequencer_ops.c @@ -40,6 +40,8 @@ #include "ED_markers.h" #include "ED_transform.h" /* transform keymap */ +#include "BKE_sequencer.h" + #include "sequencer_intern.h" @@ -50,6 +52,7 @@ void sequencer_operatortypes(void) { /* sequencer_edit.c */ WM_operatortype_append(SEQUENCER_OT_cut); + WM_operatortype_append(SEQUENCER_OT_slip); WM_operatortype_append(SEQUENCER_OT_mute); WM_operatortype_append(SEQUENCER_OT_unmute); WM_operatortype_append(SEQUENCER_OT_lock); @@ -316,6 +319,8 @@ void sequencer_keymap(wmKeyConfig *keyconf) WM_keymap_add_menu(keymap, "SEQUENCER_MT_change", CKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "SEQUENCER_OT_slip", SKEY, KM_PRESS, 0, 0); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_int", OKEY, KM_PRESS, 0, 0); RNA_string_set(kmi->ptr, "data_path", "scene.sequence_editor.overlay_frame"); RNA_int_set(kmi->ptr, "value", 0); diff --git a/source/blender/editors/space_sequencer/sequencer_preview.c b/source/blender/editors/space_sequencer/sequencer_preview.c new file mode 100644 index 00000000000..dd6349efb8f --- /dev/null +++ b/source/blender/editors/space_sequencer/sequencer_preview.c @@ -0,0 +1,172 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * Contributor(s): Blender Foundation, 2003-2009, Antony Riakiotakis + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_sequencer/sequencer_preview.c + * \ingroup spseq + */ + +#include "DNA_sequence_types.h" +#include "DNA_sound_types.h" + +#include "BLI_listbase.h" +#include "BLI_threads.h" + +#include "BKE_sound.h" +#include "BKE_context.h" +#include "BKE_global.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" + +#include "MEM_guardedalloc.h" + +#include "sequencer_intern.h" + +typedef struct PreviewJob { + ListBase previews; + ThreadMutex *mutex; + Scene *scene; + int total; + int processed; +} PreviewJob; + +typedef struct PreviewJobAudio { + struct PreviewJobAudio *next, *prev; + bSound *sound; + int lr; /* sample left or right */ + int startframe; + bool waveform; /* reload sound or waveform */ +} PreviewJobAudio; + +static void free_preview_job(void *data) +{ + PreviewJob *pj = (PreviewJob *)data; + + BLI_mutex_free(pj->mutex); + BLI_freelistN(&pj->previews); + MEM_freeN(pj); +} + +/* only this runs inside thread */ +static void preview_startjob(void *data, short *stop, short *do_update, float *progress) +{ + PreviewJob *pj = data; + PreviewJobAudio *previewjb; + + BLI_mutex_lock(pj->mutex); + previewjb = pj->previews.first; + BLI_mutex_unlock(pj->mutex); + + while (previewjb) { + PreviewJobAudio *preview_next; + bSound *sound = previewjb->sound; + + sound_read_waveform(sound, true, stop); + + if (*stop || G.is_break) { + BLI_mutex_lock(pj->mutex); + previewjb = previewjb->next; + BLI_mutex_unlock(pj->mutex); + while (previewjb) { + sound = previewjb->sound; + + /* make sure we cleanup the loading flag! */ + BLI_mutex_lock(sound->mutex); + sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING; + BLI_mutex_unlock(sound->mutex); + + BLI_mutex_lock(pj->mutex); + previewjb = previewjb->next; + BLI_mutex_unlock(pj->mutex); + } + + BLI_mutex_lock(pj->mutex); + BLI_freelistN(&pj->previews); + pj->total = 0; + pj->processed = 0; + BLI_mutex_unlock(pj->mutex); + break; + } + + BLI_mutex_lock(pj->mutex); + preview_next = previewjb->next; + BLI_freelinkN(&pj->previews, previewjb); + previewjb = preview_next; + pj->processed++; + *progress = (pj->total > 0) ? (float)pj->processed / (float)pj->total : 1.0; + *do_update = true; + BLI_mutex_unlock(pj->mutex); + } +} + +static void preview_endjob(void *data) +{ + PreviewJob *pj = data; + + WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, pj->scene); +} + + +void sequencer_preview_add_sound(const bContext *C, Sequence *seq) +{ + /* first, get the preview job, if it exists */ + wmJob *wm_job; + PreviewJob *pj; + ScrArea *sa = CTX_wm_area(C); + PreviewJobAudio *audiojob = MEM_callocN(sizeof(PreviewJobAudio), "preview_audio"); + wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, "Strip Previews", + WM_JOB_PROGRESS, WM_JOB_TYPE_SEQ_BUILD_PREVIEW); + + pj = WM_jobs_customdata_get(wm_job); + + if (!pj) { + pj = MEM_callocN(sizeof(PreviewJob), "preview rebuild job"); + + pj->mutex = BLI_mutex_alloc(); + pj->scene = CTX_data_scene(C); + + WM_jobs_customdata_set(wm_job, pj, free_preview_job); + WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_SEQUENCER, NC_SCENE | ND_SEQUENCER); + WM_jobs_callbacks(wm_job, preview_startjob, NULL, NULL, preview_endjob); + } + + /* attempt to lock mutex of job here */ + + audiojob->sound = seq->sound; + + BLI_mutex_lock(pj->mutex); + BLI_addtail(&pj->previews, audiojob); + pj->total++; + BLI_mutex_unlock(pj->mutex); + + if (!WM_jobs_is_running(wm_job)) { + G.is_break = false; + WM_jobs_start(CTX_wm_manager(C), wm_job); + } + + ED_area_tag_redraw(sa); +} diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 933daf4adee..6792bbe0577 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -357,25 +357,22 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *e case SEQ_SELECT_LR_MOUSE: x = UI_view2d_region_to_view_x(v2d, event->mval[0]); break; - case SEQ_SELECT_LR_LEFT: - x = CFRA - 1; - break; case SEQ_SELECT_LR_RIGHT: - x = CFRA + 1; + x = CFRA; break; } SEQP_BEGIN (ed, seq) { if (x < CFRA) { - if (seq->enddisp < CFRA) { + if (seq->enddisp <= CFRA) { seq->flag |= SELECT; recurs_sel_seq(seq); } } else { - if (seq->startdisp > CFRA) { + if (seq->startdisp >= CFRA) { seq->flag |= SELECT; recurs_sel_seq(seq); } diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index c0cfaed7867..6231f02907a 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -328,7 +328,7 @@ static SpaceLink *sequencer_duplicate(SpaceLink *sl) SpaceSeq *sseqn = MEM_dupallocN(sl); /* clear or remove stuff from old */ -// XXX sseq->gpd = gpencil_data_duplicate(sseq->gpd); +// XXX sseq->gpd = gpencil_data_duplicate(sseq->gpd, false); memset(&sseqn->scopes, 0, sizeof(sseqn->scopes)); @@ -352,6 +352,10 @@ static void sequencer_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn if (wmn->data == ND_SPACE_SEQUENCER) sequencer_scopes_tag_refresh(sa); break; + case NC_GPENCIL: + if (wmn->data & ND_GPENCIL_EDITMODE) + ED_area_tag_redraw(sa); + break; } } @@ -559,7 +563,7 @@ static void sequencer_preview_area_draw(const bContext *C, ARegion *ar) if (sseq->mainb == SEQ_DRAW_SEQUENCE) sseq->mainb = SEQ_DRAW_IMG_IMBUF; if (!show_split || sseq->overlay_type != SEQ_DRAW_OVERLAY_REFERENCE) - draw_image_seq(C, scene, ar, sseq, scene->r.cfra, 0, false); + draw_image_seq(C, scene, ar, sseq, scene->r.cfra, 0, false, false); if (show_split && sseq->overlay_type != SEQ_DRAW_OVERLAY_CURRENT) { int over_cfra; @@ -570,7 +574,7 @@ static void sequencer_preview_area_draw(const bContext *C, ARegion *ar) over_cfra = scene->r.cfra + scene->ed->over_ofs; if (over_cfra != scene->r.cfra || sseq->overlay_type != SEQ_DRAW_OVERLAY_RECT) - draw_image_seq(C, scene, ar, sseq, scene->r.cfra, over_cfra - scene->r.cfra, true); + draw_image_seq(C, scene, ar, sseq, scene->r.cfra, over_cfra - scene->r.cfra, true, false); } if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_playing(wm)) { @@ -585,7 +589,7 @@ static void sequencer_preview_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED /* context changes */ switch (wmn->category) { case NC_GPENCIL: - if (wmn->action == NA_EDITED) { + if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) { ED_region_tag_redraw(ar); } break; @@ -641,7 +645,7 @@ static void sequencer_buttons_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED /* context changes */ switch (wmn->category) { case NC_GPENCIL: - if (wmn->data == ND_DATA) { + if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) { ED_region_tag_redraw(ar); } break; diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index 1e710b88cad..d890b9f9b4d 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -135,7 +135,7 @@ static void text_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn) break; case ND_CURSOR: if (st->text && st->text == wmn->reference) - text_scroll_to_cursor(st, sa); + text_scroll_to_cursor__area(st, sa, true); ED_area_tag_redraw(sa); break; @@ -156,7 +156,7 @@ static void text_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn) break; case NA_SELECTED: if (st->text && st->text == wmn->reference) - text_scroll_to_cursor(st, sa); + text_scroll_to_cursor__area(st, sa, true); break; } diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index af827d6dc5a..a43d430045e 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -28,8 +28,6 @@ * \ingroup sptext */ - - #include "MEM_guardedalloc.h" #include "BLF_api.h" @@ -44,6 +42,7 @@ #include "BKE_context.h" #include "BKE_suggestions.h" #include "BKE_text.h" +#include "BKE_screen.h" #include "BIF_gl.h" @@ -381,7 +380,9 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w int a, fstart, fpos; /* utf8 chars */ int mi, ma, mstart, mend; /* mem */ char fmt_prev = 0xff; - + /* don't draw lines below this */ + const int clip_min_y = -(int)(st->lheight_dpi - 1); + flatten_string(st, &fs, str); str = fs.buf; max = w / st->cwidth; @@ -424,7 +425,8 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w mend = txt_utf8_forward_columns(str + mend, max, &padding) - str; end = (wrap += max - padding); - if (y <= 0) break; + if (y <= clip_min_y) + break; } else if (str[mi] == ' ' || str[mi] == '-') { wrap = i + 1; mend = mi + 1; @@ -432,7 +434,7 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w } /* Draw the remaining text */ - for (a = fstart, ma = mstart; str[ma] && y > 0; a++, ma += BLI_str_utf8_size_safe(str + ma)) { + for (a = fstart, ma = mstart; str[ma] && y > clip_min_y; a++, ma += BLI_str_utf8_size_safe(str + ma)) { if (use_syntax) { if (fmt_prev != format[a]) format_draw_color(fmt_prev = format[a]); } @@ -519,7 +521,7 @@ static void text_drawcache_init(SpaceText *st) DrawCache *drawcache = MEM_callocN(sizeof(DrawCache), "text draw cache"); drawcache->winx = -1; - drawcache->nlines = BLI_countlist(&st->text->lines); + drawcache->nlines = BLI_listbase_count(&st->text->lines); drawcache->text_id[0] = '\0'; st->drawcache = drawcache; @@ -560,7 +562,7 @@ static void text_update_drawcache(SpaceText *st, ARegion *ar) int lineno = 0, size, lines_count; int *fp = drawcache->line_height, *new_tail, *old_tail; - nlines = BLI_countlist(&txt->lines); + nlines = BLI_listbase_count(&txt->lines); size = sizeof(int) * nlines; if (fp) fp = MEM_reallocN(fp, size); @@ -605,7 +607,7 @@ static void text_update_drawcache(SpaceText *st, ARegion *ar) } if (full_update || drawcache->update_flag) { - nlines = BLI_countlist(&txt->lines); + nlines = BLI_listbase_count(&txt->lines); if (st->showlinenrs) st->linenrs_tot = (int)floor(log10((float)nlines)) + 1; @@ -892,15 +894,15 @@ static void draw_textscroll(SpaceText *st, rcti *scroll, rcti *back) UI_ThemeColor(TH_BACK); glRecti(back->xmin, back->ymin, back->xmax, back->ymax); - uiWidgetScrollDraw(&wcol, scroll, &st->txtbar, (st->flags & ST_SCROLL_SELECT) ? UI_SCROLL_PRESSED : 0); + UI_draw_widget_scroll(&wcol, scroll, &st->txtbar, (st->flags & ST_SCROLL_SELECT) ? UI_SCROLL_PRESSED : 0); - uiSetRoundBox(UI_CNR_ALL); + UI_draw_roundbox_corner_set(UI_CNR_ALL); rad = 0.4f * min_ii(BLI_rcti_size_x(&st->txtscroll), BLI_rcti_size_y(&st->txtscroll)); UI_GetThemeColor3ubv(TH_HILITE, col); col[3] = 48; glColor4ubv(col); glEnable(GL_BLEND); - uiRoundBox(st->txtscroll.xmin + 1, st->txtscroll.ymin, st->txtscroll.xmax - 1, st->txtscroll.ymax, rad); + UI_draw_roundbox(st->txtscroll.xmin + 1, st->txtscroll.ymin, st->txtscroll.xmax - 1, st->txtscroll.ymax, rad); glDisable(GL_BLEND); } @@ -1034,7 +1036,7 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar) x = MAX2(0, ar->winx - boxw); /* not needed but stands out nicer */ - uiDrawBoxShadow(220, x, y - boxh, x + boxw, y); + UI_draw_box_shadow(220, x, y - boxh, x + boxw, y); UI_ThemeColor(TH_SHADE1); glRecti(x - 1, y + 1, x + boxw + 1, y - boxh - 1); @@ -1323,6 +1325,8 @@ void draw_text_main(SpaceText *st, ARegion *ar) int i, x, y, winx, linecount = 0, lineno = 0; int wraplinecount = 0, wrap_skip = 0; int margin_column_x; + /* don't draw lines below this */ + const int clip_min_y = -(int)(st->lheight_dpi - 1); /* if no text, nothing to do */ if (!text) @@ -1330,7 +1334,7 @@ void draw_text_main(SpaceText *st, ARegion *ar) /* dpi controlled line height and font size */ st->lheight_dpi = (U.widget_unit * st->lheight) / 20; - st->viewlines = (st->lheight_dpi) ? (int)ar->winy / (st->lheight_dpi + TXT_LINE_SPACING) : 0; + st->viewlines = (st->lheight_dpi) ? (int)(ar->winy - clip_min_y) / (st->lheight_dpi + TXT_LINE_SPACING) : 0; text_update_drawcache(st, ar); @@ -1394,7 +1398,7 @@ void draw_text_main(SpaceText *st, ARegion *ar) /* draw the text */ UI_ThemeColor(TH_TEXT); - for (i = 0; y > 0 && i < st->viewlines && tmp; i++, tmp = tmp->next) { + for (i = 0; y > clip_min_y && i < st->viewlines && tmp; i++, tmp = tmp->next) { if (st->showsyntax && !tmp->format) tft->format_line(st, tmp, false); @@ -1461,22 +1465,15 @@ void text_update_character_width(SpaceText *st) /* Moves the view to the cursor location, * also used to make sure the view isn't outside the file */ -void text_scroll_to_cursor(SpaceText *st, ScrArea *sa) +void text_scroll_to_cursor(SpaceText *st, ARegion *ar, const bool center) { Text *text; - ARegion *ar = NULL; - int i, x, winx = 0; + int i, x, winx = ar->winx; if (ELEM(NULL, st, st->text, st->text->curl)) return; text = st->text; - for (ar = sa->regionbase.first; ar; ar = ar->next) - if (ar->regiontype == RGN_TYPE_WINDOW) { - winx = ar->winx; - break; - } - text_update_character_width(st); i = txt_get_span(text->lines.first, text->sell); @@ -1486,8 +1483,19 @@ void text_scroll_to_cursor(SpaceText *st, ScrArea *sa) i += offl; } - if (st->top + st->viewlines <= i || st->top > i) - st->top = i - st->viewlines / 2; + if (center) { + if (st->top + st->viewlines <= i || st->top > i) { + st->top = i - st->viewlines / 2; + } + } + else { + if (st->top + st->viewlines <= i) { + st->top = i - (st->viewlines - 1); + } + else if (st->top > i) { + st->top = i; + } + } if (st->wordwrap) { st->left = 0; @@ -1496,8 +1504,19 @@ void text_scroll_to_cursor(SpaceText *st, ScrArea *sa) x = st->cwidth * (text_get_char_pos(st, text->sell->line, text->selc) - st->left); winx -= TXT_OFFSET + (st->showlinenrs ? TEXTXLOC : 0) + TXT_SCROLL_WIDTH; - if (x <= 0 || x > winx) - st->left += (x - winx / 2) / st->cwidth; + if (center) { + if (x <= 0 || x > winx) { + st->left += (x - winx / 2) / st->cwidth; + } + } + else { + if (x <= 0) { + st->left += ((x + 1) / st->cwidth) - 1; + } + else if (x > winx) { + st->left += ((x - (winx + 1)) / st->cwidth) + 1; + } + } } if (st->top < 0) st->top = 0; @@ -1507,10 +1526,24 @@ void text_scroll_to_cursor(SpaceText *st, ScrArea *sa) st->scroll_accum[1] = 0.0f; } +/* takes an area instead of a region, use for listeners */ +void text_scroll_to_cursor__area(SpaceText *st, ScrArea *sa, const bool center) +{ + ARegion *ar; + + if (ELEM(NULL, st, st->text, st->text->curl)) return; + + ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); + + if (ar) { + text_scroll_to_cursor(st, ar, center); + } +} + void text_update_cursor_moved(bContext *C) { ScrArea *sa = CTX_wm_area(C); SpaceText *st = CTX_wm_space_text(C); - text_scroll_to_cursor(st, sa); + text_scroll_to_cursor__area(st, sa, true); } diff --git a/source/blender/editors/space_text/text_header.c b/source/blender/editors/space_text/text_header.c index b1d57f5a75e..92a3cce12e6 100644 --- a/source/blender/editors/space_text/text_header.c +++ b/source/blender/editors/space_text/text_header.c @@ -34,7 +34,6 @@ #include "BLI_blenlib.h" -#include "BLF_translation.h" #include "BKE_context.h" #include "BKE_screen.h" @@ -142,7 +141,7 @@ void TEXT_OT_start_find(wmOperatorType *ot) uiPopupMenu *pup; if (text) { - pup = uiPupMenuBegin(C, IFACE_("Text"), ICON_NONE); + pup = UI_popup_menu_begin(C, IFACE_("Text"), ICON_NONE); if (txt_has_sel(text)) { uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_cut"); uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_copy"); @@ -153,13 +152,13 @@ void TEXT_OT_start_find(wmOperatorType *ot) uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_save"); uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_save_as"); uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_run_script"); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); } else { - pup = uiPupMenuBegin(C, IFACE_("File"), ICON_NONE); + pup = UI_popup_menu_begin(C, IFACE_("File"), ICON_NONE); uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_new"); uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_open"); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); } } @@ -168,11 +167,11 @@ void TEXT_OT_start_find(wmOperatorType *ot) uiPopupMenu *pup; - pup = uiPupMenuBegin(C, IFACE_("Edit"), ICON_NONE); + pup = UI_popup_menu_begin(C, IFACE_("Edit"), ICON_NONE); uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_cut"); uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_copy"); uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_paste"); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); } { @@ -181,19 +180,19 @@ void TEXT_OT_start_find(wmOperatorType *ot) uiPopupMenu *pup; if (text) { - pup = uiPupMenuBegin(C, IFACE_("Text"), ICON_NONE); + pup = UI_popup_menu_begin(C, IFACE_("Text"), ICON_NONE); uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_new"); uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_open"); uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_save"); uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_save_as"); uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_run_script"); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); } else { - pup = uiPupMenuBegin(C, IFACE_("File"), ICON_NONE); + pup = UI_popup_menu_begin(C, IFACE_("File"), ICON_NONE); uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_new"); uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_open"); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); } } @@ -202,7 +201,7 @@ void TEXT_OT_start_find(wmOperatorType *ot) uiPopupMenu *pup; - pup = uiPupMenuBegin(C, IFACE_("Text"), ICON_NONE); + pup = UI_popup_menu_begin(C, IFACE_("Text"), ICON_NONE); uiItemEnumO(layout, "TEXT_OT_move", CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Top of File"), 0, "type", FILE_TOP); uiItemEnumO(layout, "TEXT_OT_move", CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Bottom of File"), @@ -210,7 +209,7 @@ void TEXT_OT_start_find(wmOperatorType *ot) uiItemEnumO(layout, "TEXT_OT_move", CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Page Up"), 0, "type", PREV_PAGE); uiItemEnumO(layout, "TEXT_OT_move", CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Page Down"), 0, "type", NEXT_PAGE); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); } #endif diff --git a/source/blender/editors/space_text/text_intern.h b/source/blender/editors/space_text/text_intern.h index d4cd029dac0..5483cf04db7 100644 --- a/source/blender/editors/space_text/text_intern.h +++ b/source/blender/editors/space_text/text_intern.h @@ -50,7 +50,8 @@ void draw_text_main(struct SpaceText *st, struct ARegion *ar); void text_update_line_edited(struct TextLine *line); void text_update_edited(struct Text *text); void text_update_character_width(struct SpaceText *st); -void text_scroll_to_cursor(struct SpaceText *st, struct ScrArea *sa); +void text_scroll_to_cursor(struct SpaceText *st, struct ARegion *ar, bool center); +void text_scroll_to_cursor__area(struct SpaceText *st, struct ScrArea *sa, bool center); void text_update_cursor_moved(struct bContext *C); #define TXT_OFFSET ((int)(0.5f * U.widget_unit)) diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 852edaac7dc..ffabefdfb29 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -171,7 +171,7 @@ static int text_new_exec(bContext *C, wmOperator *UNUSED(op)) text = BKE_text_add(bmain, "Text"); /* hook into UI */ - uiIDContextProperty(C, &ptr, &prop); + UI_context_active_but_prop_get_templateID(C, &ptr, &prop); if (prop) { RNA_id_pointer_create(&text->id, &idptr); @@ -214,7 +214,7 @@ static void text_open_init(bContext *C, wmOperator *op) PropertyPointerRNA *pprop; op->customdata = pprop = MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA"); - uiIDContextProperty(C, &pprop->ptr, &pprop->prop); + UI_context_active_but_prop_get_templateID(C, &pprop->ptr, &pprop->prop); } static void text_open_cancel(bContext *UNUSED(C), wmOperator *op) @@ -2415,6 +2415,7 @@ typedef struct SetSelection { int selecting; int selc, sell; short old[2]; + wmTimer *timer; /* needed for scrolling when mouse at region bounds */ } SetSelection; static int flatten_width(SpaceText *st, const char *str) @@ -2629,6 +2630,29 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, con if (!sel) txt_pop_sel(text); } +static void text_cursor_timer_ensure(bContext *C, SetSelection *ssel) +{ + if (ssel->timer == NULL) { + wmWindowManager *wm = CTX_wm_manager(C); + wmWindow *win = CTX_wm_window(C); + + ssel->timer = WM_event_add_timer(wm, win, TIMER, 0.02f); + } +} + +static void text_cursor_timer_remove(bContext *C, SetSelection *ssel) +{ + if (ssel->timer) { + wmWindowManager *wm = CTX_wm_manager(C); + wmWindow *win = CTX_wm_window(C); + + WM_event_remove_timer(wm, win, ssel->timer); + } + ssel->timer = NULL; +} + + + static void text_cursor_set_apply(bContext *C, wmOperator *op, const wmEvent *event) { SpaceText *st = CTX_wm_space_text(C); @@ -2636,32 +2660,34 @@ static void text_cursor_set_apply(bContext *C, wmOperator *op, const wmEvent *ev SetSelection *ssel = op->customdata; if (event->mval[1] < 0 || event->mval[1] > ar->winy) { - int d = (ssel->old[1] - event->mval[1]) * st->pix_per_line; - if (d) txt_screen_skip(st, ar, d); + text_cursor_timer_ensure(C, ssel); - text_cursor_set_to_pos(st, ar, event->mval[0], event->mval[1] < 0 ? 0 : ar->winy, 1); - - text_update_cursor_moved(C); - WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text); + if (event->type == TIMER) { + text_cursor_set_to_pos(st, ar, event->mval[0], event->mval[1], 1); + text_scroll_to_cursor(st, ar, false); + WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text); + } } else if (!st->wordwrap && (event->mval[0] < 0 || event->mval[0] > ar->winx)) { - if (event->mval[0] > ar->winx) st->left++; - else if (event->mval[0] < 0 && st->left > 0) st->left--; - - text_cursor_set_to_pos(st, ar, event->mval[0], event->mval[1], 1); + text_cursor_timer_ensure(C, ssel); - text_update_cursor_moved(C); - WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text); - // XXX PIL_sleep_ms(10); + if (event->type == TIMER) { + text_cursor_set_to_pos(st, ar, CLAMPIS(event->mval[0], 0, ar->winx), event->mval[1], 1); + text_scroll_to_cursor(st, ar, false); + WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text); + } } else { - text_cursor_set_to_pos(st, ar, event->mval[0], event->mval[1], 1); + text_cursor_timer_remove(C, ssel); - text_update_cursor_moved(C); - WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text); + if (event->type != TIMER) { + text_cursor_set_to_pos(st, ar, event->mval[0], event->mval[1], 1); + text_scroll_to_cursor(st, ar, false); + WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text); - ssel->old[0] = event->mval[0]; - ssel->old[1] = event->mval[1]; + ssel->old[0] = event->mval[0]; + ssel->old[1] = event->mval[1]; + } } } @@ -2681,6 +2707,7 @@ static void text_cursor_set_exit(bContext *C, wmOperator *op) text_update_cursor_moved(C); WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text); + text_cursor_timer_remove(C, ssel); MEM_freeN(ssel); } @@ -2717,6 +2744,7 @@ static int text_set_selection_modal(bContext *C, wmOperator *op, const wmEvent * case RIGHTMOUSE: text_cursor_set_exit(C, op); return OPERATOR_FINISHED; + case TIMER: case MOUSEMOVE: text_cursor_set_apply(C, op, event); break; @@ -3144,36 +3172,36 @@ static int text_resolve_conflict_invoke(bContext *C, wmOperator *op, const wmEve case 1: if (text->flags & TXT_ISDIRTY) { /* modified locally and externally, ahhh. offer more possibilites. */ - pup = uiPupMenuBegin(C, IFACE_("File Modified Outside and Inside Blender"), ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, IFACE_("File Modified Outside and Inside Blender"), ICON_NONE); + layout = UI_popup_menu_layout(pup); uiItemEnumO_ptr(layout, op->type, IFACE_("Reload from disk (ignore local changes)"), 0, "resolution", RESOLVE_RELOAD); uiItemEnumO_ptr(layout, op->type, IFACE_("Save to disk (ignore outside changes)"), 0, "resolution", RESOLVE_SAVE); uiItemEnumO_ptr(layout, op->type, IFACE_("Make text internal (separate copy)"), 0, "resolution", RESOLVE_MAKE_INTERNAL); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); } else { - pup = uiPupMenuBegin(C, IFACE_("File Modified Outside Blender"), ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, IFACE_("File Modified Outside Blender"), ICON_NONE); + layout = UI_popup_menu_layout(pup); uiItemEnumO_ptr(layout, op->type, IFACE_("Reload from disk"), 0, "resolution", RESOLVE_RELOAD); uiItemEnumO_ptr(layout, op->type, IFACE_("Make text internal (separate copy)"), 0, "resolution", RESOLVE_MAKE_INTERNAL); uiItemEnumO_ptr(layout, op->type, IFACE_("Ignore"), 0, "resolution", RESOLVE_IGNORE); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); } break; case 2: - pup = uiPupMenuBegin(C, IFACE_("File Deleted Outside Blender"), ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, IFACE_("File Deleted Outside Blender"), ICON_NONE); + layout = UI_popup_menu_layout(pup); uiItemEnumO_ptr(layout, op->type, IFACE_("Make text internal"), 0, "resolution", RESOLVE_MAKE_INTERNAL); uiItemEnumO_ptr(layout, op->type, IFACE_("Recreate file"), 0, "resolution", RESOLVE_SAVE); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); break; } - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } void TEXT_OT_resolve_conflict(wmOperatorType *ot) diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c index 88c57d45b79..69a1853b7f1 100644 --- a/source/blender/editors/space_time/space_time.c +++ b/source/blender/editors/space_time/space_time.c @@ -32,6 +32,7 @@ #include <string.h> #include <stdio.h> +#include "DNA_gpencil_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -310,6 +311,9 @@ static void time_draw_idblock_keyframes(View2D *v2d, ID *id, short onlysel) case ID_OB: ob_to_keylist(&ads, (Object *)id, &keys, NULL); break; + case ID_GD: + gpencil_to_keylist(&ads, (bGPdata *)id, &keys); + break; } /* build linked-list for searching */ @@ -339,9 +343,16 @@ static void time_draw_keyframes(const bContext *C, ARegion *ar) { Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); + bGPdata *gpd = CTX_data_gpencil_data(C); View2D *v2d = &ar->v2d; bool onlysel = ((scene->flag & SCE_KEYS_NO_SELONLY) == 0); + /* draw grease pencil keyframes (if available) */ + if (gpd) { + glColor3ub(0xB5, 0xE6, 0x1D); + time_draw_idblock_keyframes(v2d, (ID *)gpd, onlysel); + } + /* draw scene keyframes first * - don't try to do this when only drawing active/selected data keyframes, * since this can become quite slow @@ -520,7 +531,7 @@ static void time_main_area_draw(const bContext *C, ARegion *ar) /* markers */ UI_view2d_view_orthoSpecial(ar, v2d, 1); - draw_markers_time(C, 0); + ED_markers_draw(C, 0); /* caches */ time_draw_cache(stime, obact, scene); diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c index 0bd094b6a33..f986e909c7f 100644 --- a/source/blender/editors/space_userpref/space_userpref.c +++ b/source/blender/editors/space_userpref/space_userpref.c @@ -47,9 +47,7 @@ #include "WM_api.h" #include "WM_types.h" -#include "UI_view2d.h" -#include "userpref_intern.h" // own include /* ******************** default callbacks for userpref space ***************** */ diff --git a/source/blender/editors/space_userpref/userpref_ops.c b/source/blender/editors/space_userpref/userpref_ops.c index 8dd6c3c0271..0783eacc65c 100644 --- a/source/blender/editors/space_userpref/userpref_ops.c +++ b/source/blender/editors/space_userpref/userpref_ops.c @@ -32,5 +32,4 @@ #include <string.h> #include <stdio.h> -#include "userpref_intern.h" diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c index 17f90fc54e3..d8b18140cde 100644 --- a/source/blender/editors/space_view3d/drawanimviz.c +++ b/source/blender/editors/space_view3d/drawanimviz.c @@ -54,7 +54,6 @@ #include "ED_armature.h" #include "ED_keyframes_draw.h" -#include "BLF_api.h" #include "UI_resources.h" diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index dfa373f111f..691da78f26b 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -61,7 +61,6 @@ #include "ED_armature.h" #include "ED_keyframes_draw.h" -#include "BLF_api.h" #include "UI_resources.h" @@ -2088,6 +2087,10 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, if (v3d->zbuf) glEnable(GL_DEPTH_TEST); } } + + if (index != -1) { + GPU_select_load_id(-1); + } } /* in editmode, we don't store the bone matrix... */ @@ -2392,7 +2395,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base if (v3d->zbuf) glDisable(GL_DEPTH_TEST); /* draw from first frame of range to last */ - for (CFRA = (int)start; CFRA < end; CFRA += (int)stepsize) { + for (CFRA = (int)start; CFRA <= end; CFRA += (int)stepsize) { colfac = (end - (float)CFRA) / range; UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac))); diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index fa9ba23e454..755c633531d 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -60,7 +60,6 @@ #include "UI_resources.h" -#include "GPU_buffers.h" #include "GPU_extensions.h" #include "GPU_draw.h" #include "GPU_material.h" @@ -97,7 +96,7 @@ typedef struct drawTFace_userData { BLI_INLINE int edge_vis_index(const int index) { return index * 2; } BLI_INLINE int edge_sel_index(const int index) { return index * 2 + 1; } -static BLI_bitmap *get_tface_mesh_marked_edge_info(Mesh *me) +static BLI_bitmap *get_tface_mesh_marked_edge_info(Mesh *me, bool draw_select_edges) { BLI_bitmap *bitmap_edge_flags = BLI_BITMAP_NEW(me->totedge * 2, __func__); MPoly *mp; @@ -113,8 +112,17 @@ static BLI_bitmap *get_tface_mesh_marked_edge_info(Mesh *me) ml = me->mloop + mp->loopstart; for (j = 0; j < mp->totloop; j++, ml++) { - BLI_BITMAP_ENABLE(bitmap_edge_flags, edge_vis_index(ml->e)); - if (select_set) BLI_BITMAP_ENABLE(bitmap_edge_flags, edge_sel_index(ml->e)); + if ((draw_select_edges == false) && + (select_set && BLI_BITMAP_TEST(bitmap_edge_flags, edge_sel_index(ml->e)))) + { + BLI_BITMAP_DISABLE(bitmap_edge_flags, edge_vis_index(ml->e)); + } + else { + BLI_BITMAP_ENABLE(bitmap_edge_flags, edge_vis_index(ml->e)); + if (select_set) { + BLI_BITMAP_ENABLE(bitmap_edge_flags, edge_sel_index(ml->e)); + } + } } } } @@ -129,21 +137,26 @@ static DMDrawOption draw_mesh_face_select__setHiddenOpts(void *userData, int ind Mesh *me = data->me; if (me->drawflag & ME_DRAWEDGES) { - if ((me->drawflag & ME_HIDDENEDGES) || (BLI_BITMAP_TEST(data->edge_flags, edge_vis_index(index)))) + if ((BLI_BITMAP_TEST(data->edge_flags, edge_vis_index(index)))) return DM_DRAW_OPTION_NORMAL; else return DM_DRAW_OPTION_SKIP; } - else if (BLI_BITMAP_TEST(data->edge_flags, edge_sel_index(index))) + else if (BLI_BITMAP_TEST(data->edge_flags, edge_sel_index(index)) && + BLI_BITMAP_TEST(data->edge_flags, edge_vis_index(index))) + { return DM_DRAW_OPTION_NORMAL; - else + } + else { return DM_DRAW_OPTION_SKIP; + } } static DMDrawOption draw_mesh_face_select__setSelectOpts(void *userData, int index) { drawMeshFaceSelect_userData *data = userData; - return (BLI_BITMAP_TEST(data->edge_flags, edge_sel_index(index))) ? DM_DRAW_OPTION_NORMAL : DM_DRAW_OPTION_SKIP; + return (BLI_BITMAP_TEST(data->edge_flags, edge_sel_index(index)) && + BLI_BITMAP_TEST(data->edge_flags, edge_vis_index(index))) ? DM_DRAW_OPTION_NORMAL : DM_DRAW_OPTION_SKIP; } /* draws unselected */ @@ -158,12 +171,12 @@ static DMDrawOption draw_mesh_face_select__drawFaceOptsInv(void *userData, int i return DM_DRAW_OPTION_SKIP; } -void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm) +void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm, bool draw_select_edges) { drawMeshFaceSelect_userData data; data.me = me; - data.edge_flags = get_tface_mesh_marked_edge_info(me); + data.edge_flags = get_tface_mesh_marked_edge_info(me, draw_select_edges); glEnable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); @@ -562,14 +575,6 @@ static DMDrawOption draw_tface__set_draw_legacy(MTFace *tface, const bool has_mc } } -static DMDrawOption draw_mcol__set_draw_legacy(MTFace *UNUSED(tface), const bool has_mcol, int UNUSED(matnr)) -{ - if (has_mcol) - return DM_DRAW_OPTION_NORMAL; - else - return DM_DRAW_OPTION_NO_MCOL; -} - static DMDrawOption draw_tface__set_draw(MTFace *tface, const bool UNUSED(has_mcol), int matnr) { Material *ma = give_current_material(Gtexdraw.ob, matnr + 1); @@ -668,48 +673,48 @@ static void update_tface_color_layer(DerivedMesh *dm) } } -static DMDrawOption draw_tface_mapped__set_draw(void *userData, int index) +static DMDrawOption draw_tface_mapped__set_draw(void *userData, int origindex, int UNUSED(mat_nr)) { Mesh *me = ((drawTFace_userData *)userData)->me; /* array checked for NULL before calling */ - MPoly *mpoly = &me->mpoly[index]; + MPoly *mpoly = &me->mpoly[origindex]; - BLI_assert(index >= 0 && index < me->totpoly); + BLI_assert(origindex >= 0 && origindex < me->totpoly); if (mpoly->flag & ME_HIDE) { return DM_DRAW_OPTION_SKIP; } else { - MTexPoly *tpoly = (me->mtpoly) ? &me->mtpoly[index] : NULL; + MTexPoly *tpoly = (me->mtpoly) ? &me->mtpoly[origindex] : NULL; MTFace mtf = {{{0}}}; int matnr = mpoly->mat_nr; if (tpoly) { ME_MTEXFACE_CPY(&mtf, tpoly); } - + return draw_tface__set_draw(&mtf, (me->mloopcol != NULL), matnr); } } -static DMDrawOption draw_em_tf_mapped__set_draw(void *userData, int index) +static DMDrawOption draw_em_tf_mapped__set_draw(void *userData, int origindex, int mat_nr) { drawEMTFMapped_userData *data = userData; BMEditMesh *em = data->em; BMFace *efa; - if (UNLIKELY(index >= em->bm->totface)) + if (UNLIKELY(origindex >= em->bm->totface)) return DM_DRAW_OPTION_NORMAL; - efa = BM_face_at_index(em->bm, index); + efa = BM_face_at_index(em->bm, origindex); if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { return DM_DRAW_OPTION_SKIP; } else { MTFace mtf = {{{0}}}; - int matnr = efa->mat_nr; + int matnr = (mat_nr != -1) ? mat_nr : efa->mat_nr; if (data->has_mtface) { MTexPoly *tpoly = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); @@ -929,24 +934,16 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d dm->drawMappedFacesTex(dm, me->mpoly ? draw_tface_mapped__set_draw : NULL, compareDrawOptions, &userData, uvflag); } } - else { - if (GPU_buffer_legacy(dm)) { - if (draw_flags & DRAW_MODIFIERS_PREVIEW) - dm->drawFacesTex(dm, draw_mcol__set_draw_legacy, NULL, NULL, uvflag); - else - dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL, uvflag); - } - else { - drawTFace_userData userData; - - update_tface_color_layer(dm); - - userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE); - userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE); - userData.me = NULL; - - dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData, uvflag); - } + else { + drawTFace_userData userData; + + update_tface_color_layer(dm); + + userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE); + userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE); + userData.me = NULL; + + dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData, uvflag); } /* draw game engine text hack */ @@ -956,8 +953,10 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d draw_textured_end(); /* draw edges and selected faces over textured mesh */ - if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT)) - draw_mesh_face_select(rv3d, me, dm); + if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT)) { + bool draw_select_edges = (ob->mode & OB_MODE_TEXTURE_PAINT) == 0; + draw_mesh_face_select(rv3d, me, dm, draw_select_edges); + } /* reset from negative scale correction */ glFrontFace(GL_CCW); @@ -1153,8 +1152,10 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, glMatrixMode(GL_MODELVIEW); /* faceselect mode drawing over textured mesh */ - if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT)) - draw_mesh_face_select(rv3d, ob->data, dm); + if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT)) { + bool draw_select_edges = (ob->mode & OB_MODE_TEXTURE_PAINT) == 0; + draw_mesh_face_select(rv3d, ob->data, dm, draw_select_edges); + } } /* Vertex Paint and Weight Paint */ @@ -1189,7 +1190,7 @@ void draw_mesh_paint_weight_faces(DerivedMesh *dm, const bool use_light, } dm->drawMappedFaces(dm, (DMSetDrawOptions)facemask_cb, GPU_enable_material, NULL, user_data, - DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH); + DM_DRAW_USE_COLORS); if (use_light) { draw_mesh_paint_light_end(); @@ -1206,12 +1207,11 @@ void draw_mesh_paint_vcolor_faces(DerivedMesh *dm, const bool use_light, if (me->mloopcol) { dm->drawMappedFaces(dm, facemask_cb, GPU_enable_material, NULL, user_data, - DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH); + DM_DRAW_USE_COLORS); } else { glColor3f(1.0f, 1.0f, 1.0f); - dm->drawMappedFaces(dm, facemask_cb, GPU_enable_material, NULL, user_data, - DM_DRAW_ALWAYS_SMOOTH); + dm->drawMappedFaces(dm, facemask_cb, GPU_enable_material, NULL, user_data, 0); } if (use_light) { @@ -1279,7 +1279,8 @@ void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d, /* draw face selection on top */ if (draw_flags & DRAW_FACE_SELECT) { - draw_mesh_face_select(rv3d, me, dm); + bool draw_select_edges = (ob->mode & OB_MODE_TEXTURE_PAINT) == 0; + draw_mesh_face_select(rv3d, me, dm, draw_select_edges); } else if ((use_light == false) || (ob->dtx & OB_DRAWWIRE)) { const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) || !(ob->mode & OB_MODE_WEIGHT_PAINT); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index db04d3ccd66..a63b166969e 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -1331,7 +1331,7 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base, /* draw the circle/square representing spotbl */ if (la->type == LA_SPOT) { - float spotblcirc = fabsf(z) * (1.0f - powf(la->spotblend, 2)); + float spotblcirc = fabsf(z) * (1.0f - pow2f(la->spotblend)); /* hide line if it is zero size or overlaps with outer border, * previously it adjusted to always to show it but that seems * confusing because it doesn't show the actual blend size */ @@ -2153,8 +2153,7 @@ static void calcDrawDMNormalScale(Object *ob, drawDMNormal_userData *data) invert_m3_m3(data->imat, obmat); /* transposed inverted matrix */ - copy_m3_m3(data->tmat, data->imat); - transpose_m3(data->tmat); + transpose_m3_m3(data->tmat, data->imat); } } @@ -2497,7 +2496,7 @@ static void draw_dm_edges_weight_interp(BMEditMesh *em, DerivedMesh *dm, const c data.bm = em->bm; data.cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); - data.defgroup_tot = BLI_countlist(&ob->defbase); + data.defgroup_tot = BLI_listbase_count(&ob->defbase); data.vgroup_index = ob->actdef - 1; data.weight_user = weight_user; UI_GetThemeColor3fv(TH_VERTEX_UNREFERENCED, data.alert_color); @@ -3375,7 +3374,6 @@ static DMDrawOption draw_em_fancy__setFaceOpts(void *userData, int index) efa = BM_face_at_index(em->bm, index); if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - GPU_enable_material(efa->mat_nr + 1, NULL); return DM_DRAW_OPTION_NORMAL; } else { @@ -3773,7 +3771,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D glFrontFace(GL_CCW); if (draw_flags & DRAW_FACE_SELECT) - draw_mesh_face_select(rv3d, me, dm); + draw_mesh_face_select(rv3d, me, dm, false); } else { draw_mesh_textured(scene, v3d, rv3d, ob, dm, draw_flags); @@ -6859,15 +6857,18 @@ static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base, glDepthMask(0); if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) { - DerivedMesh *dm = ob->derivedFinal; + DerivedMesh *dm; bool has_faces = false; - if (dm) - DM_update_materials(dm, ob); #ifdef SEQUENCER_DAG_WORKAROUND ensure_curve_cache(scene, ob); #endif + dm = ob->derivedFinal; + if (dm) { + DM_update_materials(dm, ob); + } + if (dm) { has_faces = dm->getNumTessFaces(dm) > 0; } diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index 59798f97d93..a220e1e39b0 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -27,8 +27,6 @@ * \ingroup spview3d */ - - #include <string.h> #include <math.h> @@ -38,7 +36,6 @@ #include "DNA_screen_types.h" #include "DNA_smoke_types.h" #include "DNA_view3d_types.h" -#include "DNA_property_types.h" #include "BLI_utildefines.h" #include "BLI_math.h" @@ -53,8 +50,6 @@ #include "ED_mesh.h" -#include "BLF_api.h" - #include "view3d_intern.h" // own include struct GPUTexture; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index b3accb431ee..55d5273b198 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -414,7 +414,7 @@ static void view3d_free(SpaceLink *sl) /* matcap material, its preview rect gets freed via icons */ if (vd->defmaterial) { if (vd->defmaterial->gpumaterial.first) - GPU_material_free(vd->defmaterial); + GPU_material_free(&vd->defmaterial->gpumaterial); BKE_previewimg_free(&vd->defmaterial->preview); MEM_freeN(vd->defmaterial); } @@ -599,7 +599,7 @@ static int view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent return 1; } else if (drag->type == WM_DRAG_PATH) { - if (ELEM(drag->icon, 0, ICON_FILE_IMAGE)) /* rule might not work? */ + if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE)) /* rule might not work? */ return 1; } return 0; @@ -665,10 +665,14 @@ static void view3d_id_path_drop_copy(wmDrag *drag, wmDropBox *drop) { ID *id = (ID *)drag->poin; - if (id) + if (id) { RNA_string_set(drop->ptr, "name", id->name + 2); - if (drag->path[0]) + RNA_struct_property_unset(drop->ptr, "filepath"); + } + else if (drag->path[0]) { RNA_string_set(drop->ptr, "filepath", drag->path); + RNA_struct_property_unset(drop->ptr, "image"); + } } @@ -950,8 +954,9 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN break; case NC_GPENCIL: - if (wmn->action == NA_EDITED) + if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) { ED_region_tag_redraw(ar); + } break; } } @@ -1007,6 +1012,10 @@ static void view3d_header_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa) if (wmn->data == ND_SPACE_VIEW3D) ED_region_tag_redraw(ar); break; + case NC_GPENCIL: + if (wmn->data & ND_GPENCIL_EDITMODE) + ED_region_tag_redraw(ar); + break; } } @@ -1104,7 +1113,7 @@ static void view3d_buttons_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa ED_region_tag_redraw(ar); break; case NC_GPENCIL: - if (wmn->data == ND_DATA || wmn->action == NA_EDITED) + if ((wmn->data & (ND_DATA | ND_GPENCIL_EDITMODE)) || (wmn->action == NA_EDITED)) ED_region_tag_redraw(ar); break; case NC_IMAGE: @@ -1168,7 +1177,8 @@ static void space_view3d_listener(bScreen *UNUSED(sc), ScrArea *sa, struct wmNot case NC_WORLD: switch (wmn->data) { case ND_WORLD_DRAW: - if (v3d->flag2 & V3D_RENDER_OVERRIDE) + case ND_WORLD: + if (v3d->flag3 & V3D_SHOW_WORLD) ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW); break; } diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index cf589cdd946..42b7f62c8d1 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -60,6 +60,7 @@ #include "BKE_editmesh.h" #include "BKE_deform.h" #include "BKE_object.h" +#include "BKE_object_deform.h" #include "WM_api.h" #include "WM_types.h" @@ -68,7 +69,6 @@ #include "ED_armature.h" #include "ED_gpencil.h" -#include "ED_object.h" #include "ED_mesh.h" #include "ED_screen.h" @@ -82,7 +82,7 @@ #define B_REDR 2 #define B_OBJECTPANELMEDIAN 1008 -#define NBR_TRANSFORM_PROPERTIES 7 +#define NBR_TRANSFORM_PROPERTIES 8 /* temporary struct for storing transform properties */ typedef struct { @@ -124,38 +124,84 @@ static float compute_scale_factor(const float ve_median, const float median) } } +/* Apply helpers. + * Note: In case we only have one element, copy directly the value instead of applying the diff or scale factor. + * Avoids some glitches when going e.g. from 3 to 0.0001 (see T37327). + */ +static void apply_raw_diff(float *val, const int tot, const float ve_median, const float median) +{ + *val = (tot == 1) ? ve_median : (*val + median); +} + +static void apply_raw_diff_v3(float val[3], const int tot, const float ve_median[3], const float median[3]) +{ + if (tot == 1) { + copy_v3_v3(val, ve_median); + } + else { + add_v3_v3(val, median); + } +} + +static void apply_scale_factor(float *val, const int tot, const float ve_median, const float median, const float sca) +{ + if (tot == 1 || ve_median == median) { + *val = ve_median; + } + else { + *val *= sca; + } +} + +static void apply_scale_factor_clamp(float *val, const int tot, const float ve_median, const float sca) +{ + if (tot == 1) { + *val = ve_median; + CLAMP(*val, 0.0f, 1.0f); + } + else if (ELEM(sca, 0.0f, 1.0f)) { + *val = sca; + } + else { + *val = (sca > 0.0f) ? (*val * sca) : (1.0f + ((1.0f - *val) * sca)); + CLAMP(*val, 0.0f, 1.0f); + } +} + /* is used for both read and write... */ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim) { /* Get rid of those ugly magic numbers, even in a single func they become confusing! */ /* Location, common to all. */ -/* XXX Those two *must* remain contiguous (used as array)! */ -#define LOC_X 0 -#define LOC_Y 1 -#define LOC_Z 2 +/* Next three *must* remain contiguous (used as array)! */ +#define LOC_X 0 +#define LOC_Y 1 +#define LOC_Z 2 /* Meshes... */ -#define M_CREASE 3 -#define M_WEIGHT 4 -/* XXX Those two *must* remain contiguous (used as array)! */ -#define M_SKIN_X 5 -#define M_SKIN_Y 6 +#define M_BV_WEIGHT 3 +/* Next two *must* remain contiguous (used as array)! */ +#define M_SKIN_X 4 +#define M_SKIN_Y 5 +#define M_BE_WEIGHT 6 +#define M_CREASE 7 /* Curves... */ -#define C_BWEIGHT 3 -#define C_WEIGHT 4 -#define C_RADIUS 5 -#define C_TILT 6 +#define C_BWEIGHT 3 +#define C_WEIGHT 4 +#define C_RADIUS 5 +#define C_TILT 6 /*Lattice... */ -#define L_WEIGHT 4 +#define L_WEIGHT 4 uiBlock *block = (layout) ? uiLayoutAbsoluteBlock(layout) : NULL; TransformProperties *tfp; float median[NBR_TRANSFORM_PROPERTIES], ve_median[NBR_TRANSFORM_PROPERTIES]; - int tot, totedgedata, totcurvedata, totlattdata, totskinradius, totcurvebweight; + int tot, totedgedata, totcurvedata, totlattdata, totcurvebweight; bool has_meshdata = false; + bool has_skinradius = false; PointerRNA data_ptr; fill_vn_fl(median, NBR_TRANSFORM_PROPERTIES, 0.0f); - tot = totedgedata = totcurvedata = totlattdata = totskinradius = totcurvebweight = 0; + tot = totedgedata = totcurvedata = totlattdata = totcurvebweight = 0; /* make sure we got storage */ if (v3d->properties_storage == NULL) @@ -170,37 +216,37 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float BMEdge *eed; BMIter iter; - const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN); const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); + const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN); const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + has_skinradius = (cd_vert_skin_offset != -1); + if (bm->totvertsel) { BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { tot++; add_v3_v3(&median[LOC_X], eve->co); - /* TODO cd_vert_bweight_offset */ - (void)cd_vert_bweight_offset; + if (cd_vert_bweight_offset != -1) { + median[M_BV_WEIGHT] += BM_ELEM_CD_GET_FLOAT(eve, cd_vert_bweight_offset); + } - if (cd_vert_skin_offset != -1) { + if (has_skinradius) { MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset); add_v2_v2(&median[M_SKIN_X], vs->radius); /* Third val not used currently. */ - totskinradius++; } } } } - if ((cd_edge_bweight_offset != -1) || - (cd_edge_crease_offset != -1)) - { + if ((cd_edge_bweight_offset != -1) || (cd_edge_crease_offset != -1)) { if (bm->totedgesel) { BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { if (cd_edge_bweight_offset != -1) { - median[M_WEIGHT] += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_bweight_offset); + median[M_BE_WEIGHT] += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_bweight_offset); } if (cd_edge_crease_offset != -1) { @@ -216,7 +262,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float totedgedata = bm->totedgesel; } - has_meshdata = (totedgedata || totskinradius); + has_meshdata = (tot || totedgedata); } else if (ob->type == OB_CURVE || ob->type == OB_SURF) { Curve *cu = ob->data; @@ -314,7 +360,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } if (tot == 0) { - uiDefBut(block, LABEL, 0, IFACE_("Nothing selected"), 0, 130, 200, 20, NULL, 0, 0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Nothing selected"), 0, 130, 200, 20, NULL, 0, 0, 0, 0, ""); return; } @@ -326,22 +372,27 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float if (has_meshdata) { if (totedgedata) { median[M_CREASE] /= (float)totedgedata; - median[M_WEIGHT] /= (float)totedgedata; + median[M_BE_WEIGHT] /= (float)totedgedata; } - if (totskinradius) { - median[M_SKIN_X] /= (float)totskinradius; - median[M_SKIN_Y] /= (float)totskinradius; + if (tot) { + median[M_BV_WEIGHT] /= (float)tot; + if (has_skinradius) { + median[M_SKIN_X] /= (float)tot; + median[M_SKIN_Y] /= (float)tot; + } } } else if (totcurvedata) { + if (totcurvebweight) { + median[C_BWEIGHT] /= (float)totcurvebweight; + } median[C_WEIGHT] /= (float)totcurvedata; median[C_RADIUS] /= (float)totcurvedata; median[C_TILT] /= (float)totcurvedata; - if (totcurvebweight) - median[C_BWEIGHT] /= (float)totcurvebweight; } - else if (totlattdata) + else if (totlattdata) { median[L_WEIGHT] /= (float)totlattdata; + } if (block) { /* buttons */ uiBut *but; @@ -353,7 +404,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float memcpy(tfp->ve_median, median, sizeof(tfp->ve_median)); - uiBlockBeginAlign(block); + UI_block_align_begin(block); if (tot == 1) { if (totcurvedata) /* Curve */ c = IFACE_("Control Point:"); @@ -362,98 +413,111 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } else c = IFACE_("Median:"); - uiDefBut(block, LABEL, 0, c, 0, yi -= buth, 200, buth, NULL, 0, 0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 0, c, 0, yi -= buth, 200, buth, NULL, 0, 0, 0, 0, ""); - uiBlockBeginAlign(block); + UI_block_align_begin(block); /* Should be no need to translate these. */ - but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("X:"), 0, yi -= buth, 200, buth, + but = uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, IFACE_("X:"), 0, yi -= buth, 200, buth, &(tfp->ve_median[LOC_X]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); - uiButSetUnitType(but, PROP_UNIT_LENGTH); - but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Y:"), 0, yi -= buth, 200, buth, + UI_but_unit_type_set(but, PROP_UNIT_LENGTH); + but = uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, IFACE_("Y:"), 0, yi -= buth, 200, buth, &(tfp->ve_median[LOC_Y]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); - uiButSetUnitType(but, PROP_UNIT_LENGTH); - but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Z:"), 0, yi -= buth, 200, buth, + UI_but_unit_type_set(but, PROP_UNIT_LENGTH); + but = uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, IFACE_("Z:"), 0, yi -= buth, 200, buth, &(tfp->ve_median[LOC_Z]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); - uiButSetUnitType(but, PROP_UNIT_LENGTH); + UI_but_unit_type_set(but, PROP_UNIT_LENGTH); if (totcurvebweight == tot) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("W:"), 0, yi -= buth, 200, buth, + uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, IFACE_("W:"), 0, yi -= buth, 200, buth, &(tfp->ve_median[C_BWEIGHT]), 0.01, 100.0, 1, 3, ""); } - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, IFACE_("Global"), + UI_block_align_begin(block); + uiDefButBitS(block, UI_BTYPE_TOGGLE, V3D_GLOBAL_STATS, B_REDR, IFACE_("Global"), 0, yi -= buth + but_margin, 100, buth, &v3d->flag, 0, 0, 0, 0, TIP_("Displays global values")); - uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, IFACE_("Local"), + uiDefButBitS(block, UI_BTYPE_TOGGLE_N, V3D_GLOBAL_STATS, B_REDR, IFACE_("Local"), 100, yi, 100, buth, &v3d->flag, 0, 0, 0, 0, TIP_("Displays local values")); - uiBlockEndAlign(block); + UI_block_align_end(block); /* Meshes... */ if (has_meshdata) { - if (totedgedata) { + if (tot) { + uiDefBut(block, UI_BTYPE_LABEL, 0, tot == 1 ? IFACE_("Vertex Data:") : IFACE_("Vertices Data:"), + 0, yi -= buth + but_margin, 200, buth, NULL, 0.0, 0.0, 0, 0, ""); /* customdata layer added on demand */ - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, - totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"), + uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, + tot == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"), 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 2, TIP_("Weight used by SubSurf modifier")); - /* customdata layer added on demand */ - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, - totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[M_WEIGHT]), 0.0, 1.0, 1, 2, TIP_("Weight used by Bevel modifier")); + &(tfp->ve_median[M_BV_WEIGHT]), 0.0, 1.0, 1, 2, TIP_("Vertex weight used by Bevel modifier")); } - if (totskinradius) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, - totskinradius == 1 ? IFACE_("Radius X:") : IFACE_("Mean Radius X:"), + if (has_skinradius) { + UI_block_align_begin(block); + uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, + tot == 1 ? IFACE_("Radius X:") : IFACE_("Mean Radius X:"), 0, yi -= buth + but_margin, 200, buth, &(tfp->ve_median[M_SKIN_X]), 0.0, 100.0, 1, 3, TIP_("X radius used by Skin modifier")); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, - totskinradius == 1 ? IFACE_("Radius Y:") : IFACE_("Mean Radius Y:"), + uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, + tot == 1 ? IFACE_("Radius Y:") : IFACE_("Mean Radius Y:"), 0, yi -= buth + but_margin, 200, buth, &(tfp->ve_median[M_SKIN_Y]), 0.0, 100.0, 1, 3, TIP_("Y radius used by Skin modifier")); + UI_block_align_end(block); + } + if (totedgedata) { + uiDefBut(block, UI_BTYPE_LABEL, 0, totedgedata == 1 ? IFACE_("Edge Data:") : IFACE_("Edges Data:"), + 0, yi -= buth + but_margin, 200, buth, NULL, 0.0, 0.0, 0, 0, ""); + /* customdata layer added on demand */ + uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, + totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[M_BE_WEIGHT]), 0.0, 1.0, 1, 2, TIP_("Edge weight used by Bevel modifier")); + /* customdata layer added on demand */ + uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, + totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 2, TIP_("Weight used by SubSurf modifier")); } } /* Curve... */ else if (totcurvedata == 1) { - uiDefButR(block, NUM, 0, IFACE_("Weight:"), 0, yi -= buth + but_margin, 200, buth, + uiDefButR(block, UI_BTYPE_NUM, 0, IFACE_("Weight:"), 0, yi -= buth + but_margin, 200, buth, &data_ptr, "weight_softbody", 0, 0.0, 1.0, 1, 3, NULL); - uiDefButR(block, NUM, 0, IFACE_("Radius:"), 0, yi -= buth + but_margin, 200, buth, + uiDefButR(block, UI_BTYPE_NUM, 0, IFACE_("Radius:"), 0, yi -= buth + but_margin, 200, buth, &data_ptr, "radius", 0, 0.0, 100.0, 1, 3, NULL); - uiDefButR(block, NUM, 0, IFACE_("Tilt:"), 0, yi -= buth + but_margin, 200, buth, + uiDefButR(block, UI_BTYPE_NUM, 0, IFACE_("Tilt:"), 0, yi -= buth + but_margin, 200, buth, &data_ptr, "tilt", 0, -tilt_limit, tilt_limit, 1, 3, NULL); } else if (totcurvedata > 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"), + uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"), 0, yi -= buth + but_margin, 200, buth, &(tfp->ve_median[C_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal")); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius:"), + uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius:"), 0, yi -= buth + but_margin, 200, buth, &(tfp->ve_median[C_RADIUS]), 0.0, 100.0, 1, 3, TIP_("Radius of curve control points")); - but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Tilt:"), + but = uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Tilt:"), 0, yi -= buth + but_margin, 200, buth, &(tfp->ve_median[C_TILT]), -tilt_limit, tilt_limit, 1, 3, TIP_("Tilt of curve control points")); - uiButSetUnitType(but, PROP_UNIT_ROTATION); + UI_but_unit_type_set(but, PROP_UNIT_ROTATION); } /* Lattice... */ else if (totlattdata == 1) { - uiDefButR(block, NUM, 0, IFACE_("Weight:"), 0, yi -= buth + but_margin, 200, buth, + uiDefButR(block, UI_BTYPE_NUM, 0, IFACE_("Weight:"), 0, yi -= buth + but_margin, 200, buth, &data_ptr, "weight_softbody", 0, 0.0, 1.0, 1, 3, NULL); } else if (totlattdata > 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"), + uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"), 0, yi -= buth + but_margin, 200, buth, &(tfp->ve_median[L_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal")); } - uiBlockEndAlign(block); - + UI_block_align_end(block); } else { /* apply */ int i; + bool apply_vcos; memcpy(ve_median, tfp->ve_median, sizeof(tfp->ve_median)); @@ -466,155 +530,130 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float while (i--) median[i] = ve_median[i] - median[i]; - if (ob->type == OB_MESH) { + /* Note with a single element selected, we always do. */ + apply_vcos = (tot == 1) || (len_squared_v3(&median[LOC_X]) != 0.0f); + + if ((ob->type == OB_MESH) && + (apply_vcos || median[M_BV_WEIGHT] || median[M_SKIN_X] || median[M_SKIN_Y] || + median[M_BE_WEIGHT] || median[M_CREASE])) + { Mesh *me = ob->data; BMEditMesh *em = me->edit_btmesh; BMesh *bm = em->bm; BMIter iter; + BMVert *eve; + BMEdge *eed; - if (tot == 1 || len_v3(&median[LOC_X]) != 0.0f) { - BMVert *eve; + int cd_vert_bweight_offset = -1; + int cd_vert_skin_offset = -1; + int cd_edge_bweight_offset = -1; + int cd_edge_crease_offset = -1; - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - if (tot == 1) { - /* In case we only have one element selected, copy directly the value instead of applying - * the diff. Avoids some glitches when going e.g. from 3 to 0.0001 (see [#37327]). - */ - copy_v3_v3(eve->co, &ve_median[LOC_X]); - } - else { - add_v3_v3(eve->co, &median[LOC_X]); - } - } - } + float scale_bv_weight = 1.0f; + float scale_skin_x = 1.0f; + float scale_skin_y = 1.0f; + float scale_be_weight = 1.0f; + float scale_crease = 1.0f; - EDBM_mesh_normals_update(em); - } + /* Vertices */ - if (median[M_CREASE] != 0.0f) { - const int cd_edge_crease_offset = (BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_CREASE), - CustomData_get_offset(&bm->edata, CD_CREASE)); - const float sca = compute_scale_factor(ve_median[M_CREASE], median[M_CREASE]); - BMEdge *eed; + if (apply_vcos || median[M_BV_WEIGHT] || median[M_SKIN_X] || median[M_SKIN_Y]) { + if (median[M_BV_WEIGHT]) { + BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_VERT_BWEIGHT); + cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); + BLI_assert(cd_vert_bweight_offset != -1); - if (ELEM(sca, 0.0f, 1.0f)) { - BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { - BM_ELEM_CD_SET_FLOAT(eed, cd_edge_crease_offset, sca); - } - } - } - else if (sca > 0.0f) { - BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - float *crease = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_crease_offset); - *crease *= sca; - CLAMP(*crease, 0.0f, 1.0f); - } - } + scale_bv_weight = compute_scale_factor(ve_median[M_BV_WEIGHT], median[M_BV_WEIGHT]); } - else { - BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - float *crease = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_crease_offset); - *crease = 1.0f + ((1.0f - *crease) * sca); - CLAMP(*crease, 0.0f, 1.0f); - } - } - } - } - if (median[M_WEIGHT] != 0.0f) { - const int cd_edge_bweight_offset = (BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_BWEIGHT), - CustomData_get_offset(&bm->edata, CD_BWEIGHT)); - const float sca = compute_scale_factor(ve_median[M_WEIGHT], median[M_WEIGHT]); - BMEdge *eed; + if (median[M_SKIN_X]) { + cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN); + BLI_assert(cd_vert_skin_offset != -1); - BLI_assert(cd_edge_bweight_offset != -1); - - if (ELEM(sca, 0.0f, 1.0f)) { - BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { - float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset); - *bweight = sca; - } + if (ve_median[M_SKIN_X] != median[M_SKIN_X]) { + scale_skin_x = ve_median[M_SKIN_X] / (ve_median[M_SKIN_X] - median[M_SKIN_X]); } } - else if (sca > 0.0f) { - BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset); - *bweight *= sca; - CLAMP(*bweight, 0.0f, 1.0f); - } + if (median[M_SKIN_Y]) { + if (cd_vert_skin_offset == -1) { + cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN); + BLI_assert(cd_vert_skin_offset != -1); } - } - else { - BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset); - *bweight = 1.0f + ((1.0f - *bweight) * sca); - CLAMP(*bweight, 0.0f, 1.0f); - } + + if (ve_median[M_SKIN_Y] != median[M_SKIN_Y]) { + scale_skin_y = ve_median[M_SKIN_Y] / (ve_median[M_SKIN_Y] - median[M_SKIN_Y]); } } - } - - if (median[M_SKIN_X] != 0.0f) { - const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN); - /* That one is not clamped to [0.0, 1.0]. */ - float sca = ve_median[M_SKIN_X]; - BMVert *eve; - BLI_assert(cd_vert_skin_offset != -1); + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + if (apply_vcos) { + apply_raw_diff_v3(eve->co, tot, &ve_median[LOC_X], &median[LOC_X]); + } - if (ve_median[M_SKIN_X] - median[M_SKIN_X] == 0.0f) { - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset); - vs->radius[0] = sca; + if (cd_vert_bweight_offset != -1) { + float *bweight = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset); + apply_scale_factor_clamp(bweight, tot, ve_median[M_BV_WEIGHT], scale_bv_weight); } - } - } - else { - sca /= (ve_median[M_SKIN_X] - median[M_SKIN_X]); - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + + if (cd_vert_skin_offset != -1) { MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset); - vs->radius[0] *= sca; + + /* That one is not clamped to [0.0, 1.0]. */ + if (median[M_SKIN_X] != 0.0f) { + apply_scale_factor(&vs->radius[0], tot, ve_median[M_SKIN_X], median[M_SKIN_X], + scale_skin_x); + } + if (median[M_SKIN_Y] != 0.0f) { + apply_scale_factor(&vs->radius[1], tot, ve_median[M_SKIN_Y], median[M_SKIN_Y], + scale_skin_y); + } } } } } - if (median[M_SKIN_Y] != 0.0f) { - const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN); - /* That one is not clamped to [0.0, 1.0]. */ - float sca = ve_median[M_SKIN_Y]; - BMVert *eve; - BLI_assert(cd_vert_skin_offset != -1); + if (apply_vcos) { + EDBM_mesh_normals_update(em); + } - if (ve_median[M_SKIN_Y] - median[M_SKIN_Y] == 0.0f) { - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset); - vs->radius[1] = sca; - } - } + /* Edges */ + + if (median[M_BE_WEIGHT] || median[M_CREASE]) { + if (median[M_BE_WEIGHT]) { + BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_BWEIGHT); + cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + BLI_assert(cd_edge_bweight_offset != -1); + + scale_be_weight = compute_scale_factor(ve_median[M_BE_WEIGHT], median[M_BE_WEIGHT]); } - else { - sca /= (ve_median[M_SKIN_Y] - median[M_SKIN_Y]); - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset); - vs->radius[1] *= sca; + + if (median[M_CREASE]) { + BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_CREASE); + cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + BLI_assert(cd_edge_crease_offset != -1); + + scale_crease = compute_scale_factor(ve_median[M_CREASE], median[M_CREASE]); + } + + BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { + if (median[M_BE_WEIGHT] != 0.0f) { + float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset); + apply_scale_factor_clamp(bweight, tot, ve_median[M_BE_WEIGHT], scale_be_weight); + } + + if (median[M_CREASE] != 0.0f) { + float *crease = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_crease_offset); + apply_scale_factor_clamp(crease, tot, ve_median[M_CREASE], scale_crease); } } } } } - else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { + else if (ELEM(ob->type, OB_CURVE, OB_SURF) && + (apply_vcos || median[C_BWEIGHT] || median[C_WEIGHT] || median[C_RADIUS] || median[C_TILT])) + { Curve *cu = ob->data; Nurb *nu; BPoint *bp; @@ -628,44 +667,31 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float if (nu->type == CU_BEZIER) { for (a = nu->pntsu, bezt = nu->bezt; a--; bezt++) { if (bezt->f2 & SELECT) { - /* Here we always have to use the diff... :/ - * Cannot avoid some glitches when going e.g. from 3 to 0.0001 (see [#37327]), - * unless we use doubles. - */ - add_v3_v3(bezt->vec[0], &median[LOC_X]); - add_v3_v3(bezt->vec[1], &median[LOC_X]); - add_v3_v3(bezt->vec[2], &median[LOC_X]); - - if (median[C_WEIGHT] != 0.0f) { - if (ELEM(scale_w, 0.0f, 1.0f)) { - bezt->weight = scale_w; - } - else { - bezt->weight = scale_w > 0.0f ? bezt->weight * scale_w : - 1.0f + ((1.0f - bezt->weight) * scale_w); - CLAMP(bezt->weight, 0.0f, 1.0f); - } + if (apply_vcos) { + /* Here we always have to use the diff... :/ + * Cannot avoid some glitches when going e.g. from 3 to 0.0001 (see T37327), + * unless we use doubles. + */ + add_v3_v3(bezt->vec[0], &median[LOC_X]); + add_v3_v3(bezt->vec[1], &median[LOC_X]); + add_v3_v3(bezt->vec[2], &median[LOC_X]); + } + if (median[C_WEIGHT]) { + apply_scale_factor_clamp(&bezt->weight, tot, ve_median[C_WEIGHT], scale_w); + } + if (median[C_RADIUS]) { + apply_raw_diff(&bezt->radius, tot, ve_median[C_RADIUS], median[C_RADIUS]); + } + if (median[C_TILT]) { + apply_raw_diff(&bezt->alfa, tot, ve_median[C_TILT], median[C_TILT]); } - - bezt->radius += median[C_RADIUS]; - bezt->alfa += median[C_TILT]; } - else { + else if (apply_vcos) { /* Handles can only have their coordinates changed here. */ if (bezt->f1 & SELECT) { - if (tot == 1) { - copy_v3_v3(bezt->vec[0], &ve_median[LOC_X]); - } - else { - add_v3_v3(bezt->vec[0], &median[LOC_X]); - } + apply_raw_diff_v3(bezt->vec[0], tot, &ve_median[LOC_X], &median[LOC_X]); } if (bezt->f3 & SELECT) { - if (tot == 1) { - copy_v3_v3(bezt->vec[2], &ve_median[LOC_X]); - } - else { - add_v3_v3(bezt->vec[2], &median[LOC_X]); - } + apply_raw_diff_v3(bezt->vec[2], tot, &ve_median[LOC_X], &median[LOC_X]); } } } @@ -673,28 +699,20 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float else { for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a--; bp++) { if (bp->f1 & SELECT) { - if (tot == 1) { - copy_v3_v3(bp->vec, &ve_median[LOC_X]); - bp->vec[3] = ve_median[C_BWEIGHT]; - bp->radius = ve_median[C_RADIUS]; - bp->alfa = ve_median[C_TILT]; + if (apply_vcos) { + apply_raw_diff_v3(bp->vec, tot, &ve_median[LOC_X], &median[LOC_X]); } - else { - add_v3_v3(bp->vec, &median[LOC_X]); - bp->vec[3] += median[C_BWEIGHT]; - bp->radius += median[C_RADIUS]; - bp->alfa += median[C_TILT]; + if (median[C_BWEIGHT]) { + apply_raw_diff(&bp->vec[3], tot, ve_median[C_BWEIGHT], median[C_BWEIGHT]); } - - if (median[C_WEIGHT] != 0.0f) { - if (ELEM(scale_w, 0.0f, 1.0f)) { - bp->weight = scale_w; - } - else { - bp->weight = scale_w > 0.0f ? bp->weight * scale_w : - 1.0f + ((1.0f - bp->weight) * scale_w); - CLAMP(bp->weight, 0.0f, 1.0f); - } + if (median[C_WEIGHT]) { + apply_scale_factor_clamp(&bp->weight, tot, ve_median[C_WEIGHT], scale_w); + } + if (median[C_RADIUS]) { + apply_raw_diff(&bp->radius, tot, ve_median[C_RADIUS], median[C_RADIUS]); + } + if (median[C_TILT]) { + apply_raw_diff(&bp->alfa, tot, ve_median[C_TILT], median[C_TILT]); } } } @@ -705,7 +723,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float nu = nu->next; } } - else if (ob->type == OB_LATTICE) { + else if ((ob->type == OB_LATTICE) && (apply_vcos || median[L_WEIGHT])) { Lattice *lt = ob->data; BPoint *bp; int a; @@ -715,22 +733,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float bp = lt->editlatt->latt->def; while (a--) { if (bp->f1 & SELECT) { - if (tot == 1) { - copy_v3_v3(bp->vec, &ve_median[LOC_X]); - } - else { - add_v3_v3(bp->vec, &median[LOC_X]); + if (apply_vcos) { + apply_raw_diff_v3(bp->vec, tot, &ve_median[LOC_X], &median[LOC_X]); } - - if (median[L_WEIGHT] != 0.0f) { - if (ELEM(scale_w, 0.0f, 1.0f)) { - bp->weight = scale_w; - } - else { - bp->weight = scale_w > 0.0f ? bp->weight * scale_w : - 1.0f + ((1.0f - bp->weight) * scale_w); - CLAMP(bp->weight, 0.0f, 1.0f); - } + if (median[L_WEIGHT]) { + apply_scale_factor_clamp(&bp->weight, tot, ve_median[L_WEIGHT], scale_w); } } bp++; @@ -746,10 +753,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float #undef LOC_Y #undef LOC_Z /* Meshes (and lattice)... */ -#undef M_CREASE -#undef M_WEIGHT +#undef M_BV_WEIGHT #undef M_SKIN_X #undef M_SKIN_Y +#undef M_BE_WEIGHT +#undef M_CREASE /* Curves... */ #undef C_BWEIGHT #undef C_WEIGHT @@ -826,7 +834,7 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) int yco = 0; int lock_count = 0; - uiBlockSetHandleFunc(block, do_view3d_vgroup_buttons, NULL); + UI_block_func_handle_set(block, do_view3d_vgroup_buttons, NULL); bcol = uiLayoutColumn(pa->layout, true); row = uiLayoutRow(bcol, true); /* The filter button row */ @@ -836,7 +844,7 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) col = uiLayoutColumn(bcol, true); - vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); for (i = 0, dg = ob->defbase.first; dg; i++, dg = dg->next) { bool locked = dg->flag & DG_LOCK_WEIGHT; if (vgroup_validmap[i]) { @@ -850,13 +858,13 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) /* The Weight Group Name */ ot = ot_weight_set_active; - but = uiDefButO_ptr(block, BUT, ot, WM_OP_EXEC_DEFAULT, dg->name, + but = uiDefButO_ptr(block, UI_BTYPE_BUT, ot, WM_OP_EXEC_DEFAULT, dg->name, xco, yco, (x = UI_UNIT_X * 5), UI_UNIT_Y, ""); - but_ptr = uiButGetOperatorPtrRNA(but); + but_ptr = UI_but_operator_ptr_get(but); RNA_int_set(but_ptr, "weight_group", i); - uiButSetDrawFlag(but, UI_BUT_TEXT_RIGHT); + UI_but_drawflag_enable(but, UI_BUT_TEXT_RIGHT); if (ob->actdef != i + 1) { - uiButSetFlag(but, UI_BUT_INACTIVE); + UI_but_flag_enable(but, UI_BUT_INACTIVE); } xco += x; @@ -865,10 +873,10 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) /* The weight group value */ /* To be reworked still */ - but = uiDefButF(block, NUM, B_VGRP_PNL_EDIT_SINGLE + i, "", + but = uiDefButF(block, UI_BTYPE_NUM, B_VGRP_PNL_EDIT_SINGLE + i, "", xco, yco, (x = UI_UNIT_X * 4), UI_UNIT_Y, &dw->weight, 0.0, 1.0, 1, 3, ""); - uiButSetDrawFlag(but, UI_BUT_TEXT_LEFT); + UI_but_drawflag_enable(but, UI_BUT_TEXT_LEFT); if (locked) { lock_count++; } @@ -903,19 +911,19 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) row = uiLayoutRow(col, true); ot = WM_operatortype_find("OBJECT_OT_vertex_weight_normalize_active_vertex", 1); - but = uiDefButO_ptr(block, BUT, ot, WM_OP_EXEC_DEFAULT, "Normalize", + but = uiDefButO_ptr(block, UI_BTYPE_BUT, ot, WM_OP_EXEC_DEFAULT, "Normalize", 0, yco, UI_UNIT_X * 5, UI_UNIT_Y, TIP_("Normalize weights of active vertex (if affected groups are unlocked)")); if (lock_count) { - uiButSetFlag(but, UI_BUT_DISABLED); + UI_but_flag_enable(but, UI_BUT_DISABLED); } ot = WM_operatortype_find("OBJECT_OT_vertex_weight_copy", 1); - but = uiDefButO_ptr(block, BUT, ot, WM_OP_EXEC_DEFAULT, "Copy", + but = uiDefButO_ptr(block, UI_BTYPE_BUT, ot, WM_OP_EXEC_DEFAULT, "Copy", UI_UNIT_X * 5, yco, UI_UNIT_X * 5, UI_UNIT_Y, TIP_("Copy active vertex to other selected vertices (if affected groups are unlocked)")); if (lock_count) { - uiButSetFlag(but, UI_BUT_DISABLED); + UI_but_flag_enable(but, UI_BUT_DISABLED); } } @@ -1137,7 +1145,7 @@ static void view3d_panel_transform(const bContext *C, Panel *pa) uiLayout *col; block = uiLayoutGetBlock(pa->layout); - uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL); + UI_block_func_handle_set(block, do_view3d_region_buttons, NULL); col = uiLayoutColumn(pa->layout, false); @@ -1177,14 +1185,6 @@ void view3d_buttons_register(ARegionType *art) pt->poll = view3d_panel_transform_poll; BLI_addtail(&art->paneltypes, pt); - pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil"); - strcpy(pt->idname, "VIEW3D_PT_gpencil"); - strcpy(pt->label, N_("Grease Pencil")); /* XXX C panels are not available through RNA (bpy.types)! */ - strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA); - pt->draw_header = ED_gpencil_panel_standard_header; - pt->draw = ED_gpencil_panel_standard; - BLI_addtail(&art->paneltypes, pt); - pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel vgroup"); strcpy(pt->idname, "VIEW3D_PT_vgroup"); strcpy(pt->label, N_("Vertex Weights")); /* XXX C panels are not available through RNA (bpy.types)! */ diff --git a/source/blender/editors/space_view3d/view3d_camera_control.c b/source/blender/editors/space_view3d/view3d_camera_control.c index ee0f3da18b4..95e918abdcf 100644 --- a/source/blender/editors/space_view3d/view3d_camera_control.c +++ b/source/blender/editors/space_view3d/view3d_camera_control.c @@ -51,14 +51,12 @@ #include "MEM_guardedalloc.h" #include "BLI_math.h" -#include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BKE_object.h" #include "BKE_depsgraph.h" /* for object updating */ -#include "ED_keyframing.h" #include "ED_screen.h" #include "view3d_intern.h" /* own include */ @@ -266,6 +264,8 @@ void ED_view3d_cameracontrol_update( BKE_object_apply_mat4(v3d->camera, view_mat, true, true); + DAG_id_tag_update(&v3d->camera->id, OB_RECALC_OB); + copy_v3_v3(v3d->camera->size, size_back); id_key = &v3d->camera->id; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 61bfb0176ef..b3884cb2b72 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1146,10 +1146,10 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) if (scene->r.mode & R_BORDER) { float x3, y3, x4, y4; - x3 = x1 + scene->r.border.xmin * (x2 - x1); - y3 = y1 + scene->r.border.ymin * (y2 - y1); - x4 = x1 + scene->r.border.xmax * (x2 - x1); - y4 = y1 + scene->r.border.ymax * (y2 - y1); + x3 = x1i + 1 + roundf(scene->r.border.xmin * (x2 - x1)); + y3 = y1i + 1 + roundf(scene->r.border.ymin * (y2 - y1)); + x4 = x1i + 1 + roundf(scene->r.border.xmax * (x2 - x1)); + y4 = y1i + 1 + roundf(scene->r.border.ymax * (y2 - y1)); cpack(0x4040FF); glRecti(x3, y3, x4, y4); @@ -1221,11 +1221,11 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) hmargin = 0.1f * (x2 - x1); vmargin = 0.05f * (y2 - y1); - uiDrawBox(GL_LINE_LOOP, x1 + hmargin, y1 + vmargin, x2 - hmargin, y2 - vmargin, 2.0f); + UI_draw_roundbox_gl_mode(GL_LINE_LOOP, x1 + hmargin, y1 + vmargin, x2 - hmargin, y2 - vmargin, 2.0f); hmargin = 0.035f * (x2 - x1); vmargin = 0.035f * (y2 - y1); - uiDrawBox(GL_LINE_LOOP, x1 + hmargin, y1 + vmargin, x2 - hmargin, y2 - vmargin, 2.0f); + UI_draw_roundbox_gl_mode(GL_LINE_LOOP, x1 + hmargin, y1 + vmargin, x2 - hmargin, y2 - vmargin, 2.0f); } if (ca->flag & CAM_SHOWSENSOR) { /* determine sensor fit, and get sensor x/y, for auto fit we @@ -1260,7 +1260,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) /* draw */ UI_ThemeColorShade(TH_VIEW_OVERLAY, 100); - uiDrawBox(GL_LINE_LOOP, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 2.0f); + UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 2.0f); } } @@ -1362,7 +1362,7 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) else glScissor(ar->winrct.xmin, ar->winrct.ymin, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct)); - glClearColor(0.0, 0.0, 0.0, 0.0); + glClearColor(0.0, 0.0, 0.0, 0.0); if (v3d->zbuf) { glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -2003,7 +2003,7 @@ static void draw_dupli_objects_color( tbase.flag = OB_FROMDUPLI | base->flag; lb = object_duplilist(G.main->eval_ctx, scene, base->object); - // BLI_sortlist(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */ + // BLI_listbase_sort(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */ apply_data = duplilist_apply(base->object, lb); @@ -2646,10 +2646,7 @@ static void view3d_draw_objects( if (!draw_offscreen) { /* needs to be done always, gridview is adjusted in drawgrid() now, but only for ortho views. */ - rv3d->gridview = v3d->grid; - if (scene->unit.system) { - rv3d->gridview /= scene->unit.scale_length; - } + rv3d->gridview = ED_view3d_grid_scale(scene, v3d, grid_unit); if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) { if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { @@ -2801,6 +2798,203 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d) gpu_update_lamps_shadows(scene, v3d); } +/* + * Function to clear the view + */ +static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar, bool force) +{ + /* clear background */ + if (scene->world && ((v3d->flag3 & V3D_SHOW_WORLD) || force)) { + float alpha = (force) ? 1.0f : 0.0; + bool glsl = GPU_glsl_support() && BKE_scene_use_new_shading_nodes(scene) && scene->world->nodetree && scene->world->use_nodes; + + if (glsl) { + RegionView3D *rv3d = ar->regiondata; + GPUMaterial *gpumat = GPU_material_world(scene, scene->world); + + /* calculate full shader for background */ + GPU_material_bind(gpumat, 1, 1, 1.0, false, rv3d->viewmat, rv3d->viewinv, (v3d->scenelock != 0)); + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_ALWAYS); + glShadeModel(GL_SMOOTH); + glBegin(GL_QUADS); + glVertex3f(-1.0, -1.0, 1.0); + glVertex3f(1.0, -1.0, 1.0); + glVertex3f(1.0, 1.0, 1.0); + glVertex3f(-1.0, 1.0, 1.0); + glEnd(); + glShadeModel(GL_FLAT); + + GPU_material_unbind(gpumat); + + glDepthFunc(GL_LEQUAL); + glDisable(GL_DEPTH_TEST); + } + else if (scene->world->skytype & WO_SKYBLEND) { /* blend sky */ + int x, y; + float col_hor[3]; + float col_zen[3]; + +#define VIEWGRAD_RES_X 16 +#define VIEWGRAD_RES_Y 16 + + GLubyte grid_col[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][4]; + static float grid_pos[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][3]; + static GLushort indices[VIEWGRAD_RES_X - 1][VIEWGRAD_RES_X - 1][4]; + static bool buf_calculated = false; + + IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings, + &scene->display_settings); + IMB_colormanagement_pixel_to_display_space_v3(col_zen, &scene->world->zenr, &scene->view_settings, + &scene->display_settings); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glShadeModel(GL_SMOOTH); + + /* calculate buffers the first time only */ + if (!buf_calculated) { + for (x = 0; x < VIEWGRAD_RES_X; x++) { + for (y = 0; y < VIEWGRAD_RES_Y; y++) { + const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1); + const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1); + + /* -1..1 range */ + grid_pos[x][y][0] = (xf - 0.5f) * 2.0f; + grid_pos[x][y][1] = (yf - 0.5f) * 2.0f; + grid_pos[x][y][2] = 1.0; + } + } + + for (x = 0; x < VIEWGRAD_RES_X - 1; x++) { + for (y = 0; y < VIEWGRAD_RES_Y - 1; y++) { + indices[x][y][0] = x * VIEWGRAD_RES_X + y; + indices[x][y][1] = x * VIEWGRAD_RES_X + y + 1; + indices[x][y][2] = (x + 1) * VIEWGRAD_RES_X + y + 1; + indices[x][y][3] = (x + 1) * VIEWGRAD_RES_X + y; + } + } + + buf_calculated = true; + } + + for (x = 0; x < VIEWGRAD_RES_X; x++) { + for (y = 0; y < VIEWGRAD_RES_Y; y++) { + const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1); + const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1); + const float mval[2] = {xf * (float)ar->winx, yf * ar->winy}; + const float z_up[3] = {0.0f, 0.0f, 1.0f}; + float out[3]; + GLubyte *col_ub = grid_col[x][y]; + + float col_fac; + float col_fl[3]; + + ED_view3d_win_to_vector(ar, mval, out); + + if (scene->world->skytype & WO_SKYPAPER) { + if (scene->world->skytype & WO_SKYREAL) { + col_fac = fabsf(((float)y / (float)VIEWGRAD_RES_Y) - 0.5f) * 2.0f; + } + else { + col_fac = (float)y / (float)VIEWGRAD_RES_Y; + } + } + else { + if (scene->world->skytype & WO_SKYREAL) { + col_fac = fabsf((angle_normalized_v3v3(z_up, out) / (float)M_PI) - 0.5f) * 2.0f; + } + else { + col_fac = 1.0f - (angle_normalized_v3v3(z_up, out) / (float)M_PI); + } + } + + interp_v3_v3v3(col_fl, col_hor, col_zen, col_fac); + + rgb_float_to_uchar(col_ub, col_fl); + col_ub[3] = alpha * 255; + } + } + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_ALWAYS); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, grid_pos); + glColorPointer(4, GL_UNSIGNED_BYTE, 0, grid_col); + + glDrawElements(GL_QUADS, (VIEWGRAD_RES_X - 1) * (VIEWGRAD_RES_Y - 1) * 4, GL_UNSIGNED_SHORT, indices); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + glDepthFunc(GL_LEQUAL); + glDisable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glShadeModel(GL_FLAT); + +#undef VIEWGRAD_RES_X +#undef VIEWGRAD_RES_Y + } + else { /* solid sky */ + float col_hor[3]; + IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings, + &scene->display_settings); + + glClearColor(col_hor[0], col_hor[1], col_hor[2], alpha); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + } + else { + if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) { + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_ALWAYS); + glShadeModel(GL_SMOOTH); + glBegin(GL_QUADS); + UI_ThemeColor(TH_LOW_GRAD); + glVertex3f(-1.0, -1.0, 1.0); + glVertex3f(1.0, -1.0, 1.0); + UI_ThemeColor(TH_HIGH_GRAD); + glVertex3f(1.0, 1.0, 1.0); + glVertex3f(-1.0, 1.0, 1.0); + glEnd(); + glShadeModel(GL_FLAT); + + glDepthFunc(GL_LEQUAL); + glDisable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + } + else { + UI_ThemeClearColor(TH_HIGH_GRAD); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + } +} + /* ED_view3d_draw_offscreen_init should be called before this to initialize * stuff like shadow buffers */ @@ -2836,25 +3030,18 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, * warning! can be slow so only free animated images - campbell */ GPU_free_images_anim(); } - + /* setup view matrices */ + view3d_main_area_setup_view(scene, v3d, ar, viewmat, winmat); + /* clear opengl buffers */ if (do_sky) { - float sky_color[3]; - - ED_view3d_offscreen_sky_color_get(scene, sky_color); - glClearColor(sky_color[0], sky_color[1], sky_color[2], 1.0f); + view3d_main_area_clear(scene, v3d, ar, true); } else { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - - /* setup view matrices */ - view3d_main_area_setup_view(scene, v3d, ar, viewmat, winmat); - - /* main drawing call */ view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true); @@ -2957,7 +3144,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in /* creates own 3d views, used by the sequencer */ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height, unsigned int flag, int drawtype, - bool use_solid_tex, bool draw_background, int alpha_mode, char err_out[256]) + bool use_solid_tex, bool use_gpencil, bool draw_background, int alpha_mode, char err_out[256]) { View3D v3d = {NULL}; ARegion ar = {NULL}; @@ -2972,6 +3159,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w v3d.lay = scene->lay; v3d.drawtype = drawtype; v3d.flag2 = V3D_RENDER_OVERRIDE; + + if (use_gpencil) + v3d.flag2 |= V3D_SHOW_GPENCIL; if (use_solid_tex) v3d.flag2 |= V3D_SOLID_TEX; @@ -3205,178 +3395,6 @@ static void view3d_main_area_draw_engine_info(View3D *v3d, RegionView3D *rv3d, A ED_region_info_draw(ar, rv3d->render_engine->text, 1, fill_color); } -/* - * Function to clear the view - */ -static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar) -{ - /* clear background */ - if (scene->world && (v3d->flag2 & V3D_RENDER_OVERRIDE)) { /* clear with solid color */ - if (scene->world->skytype & WO_SKYBLEND) { /* blend sky */ - int x, y; - float col_hor[3]; - float col_zen[3]; - -#define VIEWGRAD_RES_X 16 -#define VIEWGRAD_RES_Y 16 - - GLubyte grid_col[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][4]; - static float grid_pos[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][3]; - static GLushort indices[VIEWGRAD_RES_X - 1][VIEWGRAD_RES_X - 1][4]; - static bool buf_calculated = false; - - IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings, - &scene->display_settings); - IMB_colormanagement_pixel_to_display_space_v3(col_zen, &scene->world->zenr, &scene->view_settings, - &scene->display_settings); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - glShadeModel(GL_SMOOTH); - - /* calculate buffers the first time only */ - if (!buf_calculated) { - for (x = 0; x < VIEWGRAD_RES_X; x++) { - for (y = 0; y < VIEWGRAD_RES_Y; y++) { - const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1); - const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1); - - /* -1..1 range */ - grid_pos[x][y][0] = (xf - 0.5f) * 2.0f; - grid_pos[x][y][1] = (yf - 0.5f) * 2.0f; - grid_pos[x][y][2] = 1.0; - } - } - - for (x = 0; x < VIEWGRAD_RES_X - 1; x++) { - for (y = 0; y < VIEWGRAD_RES_Y - 1; y++) { - indices[x][y][0] = x * VIEWGRAD_RES_X + y; - indices[x][y][1] = x * VIEWGRAD_RES_X + y + 1; - indices[x][y][2] = (x + 1) * VIEWGRAD_RES_X + y + 1; - indices[x][y][3] = (x + 1) * VIEWGRAD_RES_X + y; - } - } - - buf_calculated = true; - } - - for (x = 0; x < VIEWGRAD_RES_X; x++) { - for (y = 0; y < VIEWGRAD_RES_Y; y++) { - const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1); - const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1); - const float mval[2] = {xf * (float)ar->winx, yf * ar->winy}; - const float z_up[3] = {0.0f, 0.0f, 1.0f}; - float out[3]; - GLubyte *col_ub = grid_col[x][y]; - - float col_fac; - float col_fl[3]; - - ED_view3d_win_to_vector(ar, mval, out); - - if (scene->world->skytype & WO_SKYPAPER) { - if (scene->world->skytype & WO_SKYREAL) { - col_fac = fabsf(((float)y / (float)VIEWGRAD_RES_Y) - 0.5f) * 2.0f; - } - else { - col_fac = (float)y / (float)VIEWGRAD_RES_Y; - } - } - else { - if (scene->world->skytype & WO_SKYREAL) { - col_fac = fabsf((angle_normalized_v3v3(z_up, out) / (float)M_PI) - 0.5f) * 2.0f; - } - else { - col_fac = 1.0f - (angle_normalized_v3v3(z_up, out) / (float)M_PI); - } - } - - interp_v3_v3v3(col_fl, col_hor, col_zen, col_fac); - - rgb_float_to_uchar(col_ub, col_fl); - col_ub[3] = 0; - } - } - - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_ALWAYS); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, grid_pos); - glColorPointer(4, GL_UNSIGNED_BYTE, 0, grid_col); - - glDrawElements(GL_QUADS, (VIEWGRAD_RES_X - 1) * (VIEWGRAD_RES_Y - 1) * 4, GL_UNSIGNED_SHORT, indices); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - - glDepthFunc(GL_LEQUAL); - glDisable(GL_DEPTH_TEST); - - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - - glShadeModel(GL_FLAT); - -#undef VIEWGRAD_RES_X -#undef VIEWGRAD_RES_Y - } - else { /* solid sky */ - float col_hor[3]; - IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings, - &scene->display_settings); - - glClearColor(col_hor[0], col_hor[1], col_hor[2], 0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - } - } - else { - if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) { - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_ALWAYS); - glShadeModel(GL_SMOOTH); - glBegin(GL_QUADS); - UI_ThemeColor(TH_LOW_GRAD); - glVertex3f(-1.0, -1.0, 1.0); - glVertex3f(1.0, -1.0, 1.0); - UI_ThemeColor(TH_HIGH_GRAD); - glVertex3f(1.0, 1.0, 1.0); - glVertex3f(-1.0, 1.0, 1.0); - glEnd(); - glShadeModel(GL_FLAT); - - glDepthFunc(GL_LEQUAL); - glDisable(GL_DEPTH_TEST); - - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - } - else { - UI_ThemeClearColor(TH_HIGH_GRAD); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - } - } -} - - #ifdef WITH_GAMEENGINE static void update_lods(Scene *scene, float camera_pos[3]) { @@ -3413,7 +3431,7 @@ static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3 rv3d->rflag &= ~RV3D_IS_GAME_ENGINE; #ifdef WITH_GAMEENGINE - if (STREQ(scene->r.engine, "BLENDER_GAME")) { + if (STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME)) { rv3d->rflag |= RV3D_IS_GAME_ENGINE; /* Make sure LoDs are up to date */ @@ -3422,7 +3440,7 @@ static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3 #endif /* clear the background */ - view3d_main_area_clear(scene, v3d, ar); + view3d_main_area_clear(scene, v3d, ar, false); /* enables anti-aliasing for 3D view drawing */ if (U.ogl_multisamples != USER_MULTISAMPLE_NONE) { diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index f54e7ae06f6..8ee6c7d8df4 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -49,7 +49,6 @@ #include "BKE_camera.h" #include "BKE_context.h" #include "BKE_font.h" -#include "BKE_image.h" #include "BKE_library.h" #include "BKE_object.h" #include "BKE_paint.h" @@ -1119,6 +1118,8 @@ static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event) { ViewOpsData *vod = op->customdata; short event_code = VIEW_PASS; + bool use_autokey = false; + int ret = OPERATOR_RUNNING_MODAL; /* execute the events */ if (event->type == MOUSEMOVE) { @@ -1153,17 +1154,25 @@ static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event) if (event_code == VIEW_APPLY) { viewrotate_apply(vod, event->x, event->y); + if (ED_screen_animation_playing(CTX_wm_manager(C))) { + use_autokey = true; + } } else if (event_code == VIEW_CONFIRM) { - ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, true, true); ED_view3d_depth_tag_update(vod->rv3d); + use_autokey = true; + ret = OPERATOR_FINISHED; + } - viewops_data_free(C, op); + if (use_autokey) { + ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, true, true); + } - return OPERATOR_FINISHED; + if (ret & OPERATOR_FINISHED) { + viewops_data_free(C, op); } - return OPERATOR_RUNNING_MODAL; + return ret; } /** @@ -1221,26 +1230,31 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event) ED_region_tag_redraw(vod->ar); } - if (event->type == MOUSEPAN) { + if (ELEM(event->type, MOUSEPAN, MOUSEROTATE)) { /* Rotate direction we keep always same */ - if (U.uiflag2 & USER_TRACKPAD_NATURAL) - viewrotate_apply(vod, 2 * event->x - event->prevx, 2 * event->y - event->prevy); - else - viewrotate_apply(vod, event->prevx, event->prevy); - - ED_view3d_depth_tag_update(vod->rv3d); - - viewops_data_free(C, op); - - return OPERATOR_FINISHED; - } - else if (event->type == MOUSEROTATE) { - /* MOUSEROTATE performs orbital rotation, so y axis delta is set to 0 */ - viewrotate_apply(vod, event->prevx, event->y); + int x, y; + + if (event->type == MOUSEPAN) { + if (U.uiflag2 & USER_TRACKPAD_NATURAL) { + x = 2 * event->x - event->prevx; + y = 2 * event->y - event->prevy; + } + else { + x = event->prevx; + y = event->prevy; + } + } + else { + /* MOUSEROTATE performs orbital rotation, so y axis delta is set to 0 */ + x = event->prevx; + y = event->y; + } + + viewrotate_apply(vod, x, y); ED_view3d_depth_tag_update(vod->rv3d); - + viewops_data_free(C, op); - + return OPERATOR_FINISHED; } else { @@ -1946,6 +1960,8 @@ static int viewmove_modal(bContext *C, wmOperator *op, const wmEvent *event) ViewOpsData *vod = op->customdata; short event_code = VIEW_PASS; + bool use_autokey = false; + int ret = OPERATOR_RUNNING_MODAL; /* execute the events */ if (event->type == MOUSEMOVE) { @@ -1972,17 +1988,25 @@ static int viewmove_modal(bContext *C, wmOperator *op, const wmEvent *event) if (event_code == VIEW_APPLY) { viewmove_apply(vod, event->x, event->y); + if (ED_screen_animation_playing(CTX_wm_manager(C))) { + use_autokey = true; + } } else if (event_code == VIEW_CONFIRM) { - ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true); ED_view3d_depth_tag_update(vod->rv3d); + use_autokey = true; + ret = OPERATOR_FINISHED; + } - viewops_data_free(C, op); + if (use_autokey) { + ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true); + } - return OPERATOR_FINISHED; + if (ret & OPERATOR_FINISHED) { + viewops_data_free(C, op); } - return OPERATOR_RUNNING_MODAL; + return ret; } static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event) @@ -2214,6 +2238,8 @@ static int viewzoom_modal(bContext *C, wmOperator *op, const wmEvent *event) { ViewOpsData *vod = op->customdata; short event_code = VIEW_PASS; + bool use_autokey = false; + int ret = OPERATOR_RUNNING_MODAL; /* execute the events */ if (event->type == TIMER && event->customdata == vod->timer) { @@ -2244,16 +2270,25 @@ static int viewzoom_modal(bContext *C, wmOperator *op, const wmEvent *event) if (event_code == VIEW_APPLY) { viewzoom_apply(vod, &event->x, U.viewzoom, (U.uiflag & USER_ZOOM_INVERT) != 0); + if (ED_screen_animation_playing(CTX_wm_manager(C))) { + use_autokey = true; + } } else if (event_code == VIEW_CONFIRM) { - ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true); ED_view3d_depth_tag_update(vod->rv3d); - viewops_data_free(C, op); + use_autokey = true; + ret = OPERATOR_FINISHED; + } - return OPERATOR_FINISHED; + if (use_autokey) { + ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true); + } + + if (ret & OPERATOR_FINISHED) { + viewops_data_free(C, op); } - return OPERATOR_RUNNING_MODAL; + return ret; } static int viewzoom_exec(bContext *C, wmOperator *op) @@ -2315,6 +2350,7 @@ static int viewzoom_exec(bContext *C, wmOperator *op) ED_view3d_depth_tag_update(rv3d); ED_view3d_camera_lock_sync(v3d, rv3d); + ED_view3d_camera_lock_autokey(v3d, rv3d, C, false, true); ED_region_tag_redraw(ar); @@ -2389,8 +2425,10 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event) vod->origy = vod->oldy = vod->origy + event->x - event->prevx; viewzoom_apply(vod, &event->prevx, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) != 0); } + ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true); + ED_view3d_depth_tag_update(vod->rv3d); - + viewops_data_free(C, op); return OPERATOR_FINISHED; } @@ -2486,6 +2524,8 @@ static int viewdolly_modal(bContext *C, wmOperator *op, const wmEvent *event) { ViewOpsData *vod = op->customdata; short event_code = VIEW_PASS; + bool use_autokey = false; + int ret = OPERATOR_RUNNING_MODAL; /* execute the events */ if (event->type == MOUSEMOVE) { @@ -2512,16 +2552,25 @@ static int viewdolly_modal(bContext *C, wmOperator *op, const wmEvent *event) if (event_code == VIEW_APPLY) { viewdolly_apply(vod, event->x, event->y, (U.uiflag & USER_ZOOM_INVERT) != 0); + if (ED_screen_animation_playing(CTX_wm_manager(C))) { + use_autokey = true; + } } else if (event_code == VIEW_CONFIRM) { - ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true); ED_view3d_depth_tag_update(vod->rv3d); - viewops_data_free(C, op); + use_autokey = true; + ret = OPERATOR_FINISHED; + } - return OPERATOR_FINISHED; + if (use_autokey) { + ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true); + } + + if (ret & OPERATOR_FINISHED) { + viewops_data_free(C, op); } - return OPERATOR_RUNNING_MODAL; + return ret; } static int viewdolly_exec(bContext *C, wmOperator *op) @@ -3970,6 +4019,8 @@ static int viewroll_modal(bContext *C, wmOperator *op, const wmEvent *event) { ViewOpsData *vod = op->customdata; short event_code = VIEW_PASS; + bool use_autokey = false; + int ret = OPERATOR_RUNNING_MODAL; /* execute the events */ if (event->type == MOUSEMOVE) { @@ -3996,18 +4047,35 @@ static int viewroll_modal(bContext *C, wmOperator *op, const wmEvent *event) if (event_code == VIEW_APPLY) { viewroll_apply(vod, event->x, event->y); + if (ED_screen_animation_playing(CTX_wm_manager(C))) { + use_autokey = true; + } } else if (event_code == VIEW_CONFIRM) { - ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, true, false); ED_view3d_depth_tag_update(vod->rv3d); - viewops_data_free(C, op); + use_autokey = true; + ret = OPERATOR_FINISHED; + } - return OPERATOR_FINISHED; + if (use_autokey) { + ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, true, false); } - return OPERATOR_RUNNING_MODAL; + if (ret & OPERATOR_FINISHED) { + viewops_data_free(C, op); + } + + return ret; } +static EnumPropertyItem prop_view_roll_items[] = { + {0, "ROLLANGLE", 0, "Roll Angle", "Roll the view using an angle value"}, + {V3D_VIEW_STEPLEFT, "ROLLLEFT", 0, "Roll Left", "Roll the view around to the Left"}, + {V3D_VIEW_STEPRIGHT, "ROLLTRIGHT", 0, "Roll Right", "Roll the view around to the Right"}, + {0, NULL, 0, NULL, NULL} +}; + + static int viewroll_exec(bContext *C, wmOperator *op) { View3D *v3d; @@ -4025,12 +4093,17 @@ static int viewroll_exec(bContext *C, wmOperator *op) rv3d = ar->regiondata; if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) { - const float angle = RNA_float_get(op->ptr, "angle"); + int type = RNA_enum_get(op->ptr, "type"); + float angle = (type == 0) ? RNA_float_get(op->ptr, "angle") : DEG2RADF((float)U.pad_rot_angle); float mousevec[3]; float quat_new[4]; const int smooth_viewtx = WM_operator_smooth_viewtx_get(op); + if (type == V3D_VIEW_STEPLEFT) { + angle = -angle; + } + normalize_v3_v3(mousevec, rv3d->viewinv[2]); negate_v3(mousevec); view_roll_angle(ar, quat_new, rv3d->viewquat, mousevec, angle); @@ -4052,7 +4125,9 @@ static int viewroll_invoke(bContext *C, wmOperator *op, const wmEvent *event) { ViewOpsData *vod; - if (RNA_struct_property_is_set(op->ptr, "angle")) { + bool use_angle = RNA_enum_get(op->ptr, "type") != 0; + + if (use_angle || RNA_struct_property_is_set(op->ptr, "angle")) { viewroll_exec(C, op); } else { @@ -4090,6 +4165,8 @@ static void viewroll_cancel(bContext *C, wmOperator *op) void VIEW3D_OT_view_roll(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "View Roll"; ot->description = "Roll the view"; @@ -4106,7 +4183,10 @@ void VIEW3D_OT_view_roll(wmOperatorType *ot) ot->flag = 0; /* properties */ - ot->prop = RNA_def_float(ot->srna, "angle", 0, -FLT_MAX, FLT_MAX, "Roll", "", -FLT_MAX, FLT_MAX); + ot->prop = prop = RNA_def_float(ot->srna, "angle", 0, -FLT_MAX, FLT_MAX, "Roll", "", -FLT_MAX, FLT_MAX); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_enum(ot->srna, "type", prop_view_roll_items, 0, "Roll Angle Source", "How roll angle is calculated"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } static EnumPropertyItem prop_view_pan_items[] = { @@ -4259,32 +4339,16 @@ static int background_image_add_exec(bContext *C, wmOperator *UNUSED(op)) static int background_image_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { View3D *v3d = CTX_wm_view3d(C); - Image *ima = NULL; + Image *ima; BGpic *bgpic; - char name[MAX_ID_NAME - 2]; - - /* check input variables */ - if (RNA_struct_property_is_set(op->ptr, "filepath")) { - char path[FILE_MAX]; - - RNA_string_get(op->ptr, "filepath", path); - ima = BKE_image_load_exists(path); - } - else if (RNA_struct_property_is_set(op->ptr, "name")) { - RNA_string_get(op->ptr, "name", name); - ima = (Image *)BKE_libblock_find_name(ID_IM, name); - } + ima = (Image *)WM_operator_drop_load_path(C, op, ID_IM); + /* may be NULL, continue anyway */ + bgpic = background_image_add(C); - - if (ima) { - bgpic->ima = ima; - - id_us_plus(&ima->id); - - if (!(v3d->flag & V3D_DISPBGPICS)) - v3d->flag |= V3D_DISPBGPICS; - } + bgpic->ima = ima; + + v3d->flag |= V3D_DISPBGPICS; WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); @@ -4310,7 +4374,8 @@ void VIEW3D_OT_background_image_add(wmOperatorType *ot) /* properties */ RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Image name to assign"); - RNA_def_string(ot->srna, "filepath", "Path", FILE_MAX, "Filepath", "Path to image file"); + WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, + WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); } @@ -4360,12 +4425,16 @@ void VIEW3D_OT_background_image_remove(wmOperatorType *ot) /* ********************* set clipping operator ****************** */ -static void calc_clipping_plane(float clip[6][4], const BoundBox *clipbb) +static void calc_clipping_plane(float clip[6][4], const BoundBox *clipbb, const bool is_flip) { int val; for (val = 0; val < 4; val++) { normal_tri_v3(clip[val], clipbb->vec[val], clipbb->vec[val == 3 ? 0 : val + 1], clipbb->vec[val + 4]); + if (UNLIKELY(is_flip)) { + negate_v3(clip[val]); + } + clip[val][3] = -dot_v3v3(clip[val], clipbb->vec[val]); } } @@ -4382,7 +4451,7 @@ static void calc_local_clipping(float clip_local[6][4], BoundBox *clipbb, float mul_v3_m4v3(clipbb_local.vec[i], imat, clipbb->vec[i]); } - calc_clipping_plane(clip_local, &clipbb_local); + calc_clipping_plane(clip_local, &clipbb_local, is_negative_m4(mat)); } void ED_view3d_clipping_local(RegionView3D *rv3d, float mat[4][4]) diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index a88724a1cdd..11ed9867e2f 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -32,12 +32,9 @@ #include <stdio.h> #include <stdlib.h> -#include "DNA_brush_types.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" -#include "BLI_math.h" -#include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BLF_translation.h" @@ -45,8 +42,6 @@ #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_main.h" -#include "BKE_modifier.h" -#include "BKE_paint.h" #include "BKE_screen.h" #include "BKE_editmesh.h" @@ -262,7 +257,7 @@ void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C) Object *obedit = CTX_data_edit_object(C); uiBlock *block = uiLayoutGetBlock(layout); - uiBlockSetHandleFunc(block, do_view3d_header_buttons, NULL); + UI_block_func_handle_set(block, do_view3d_header_buttons, NULL); if (obedit && (obedit->type == OB_MESH)) { BMEditMesh *em = BKE_editmesh_from_object(obedit); @@ -270,13 +265,13 @@ void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C) row = uiLayoutRow(layout, true); block = uiLayoutGetBlock(row); - uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, + uiDefIconButBitS(block, UI_BTYPE_TOGGLE, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, TIP_("Vertex select - Shift-Click for multiple modes, Ctrl-Click contracts selection")); - uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL, + uiDefIconButBitS(block, UI_BTYPE_TOGGLE, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, TIP_("Edge select - Shift-Click for multiple modes, Ctrl-Click expands/contracts selection")); - uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, + uiDefIconButBitS(block, UI_BTYPE_TOGGLE, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, TIP_("Face select - Shift-Click for multiple modes, Ctrl-Click expands selection")); } @@ -302,10 +297,10 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) RNA_pointer_create(&scene->id, &RNA_Scene, scene, &sceneptr); block = uiLayoutGetBlock(layout); - uiBlockSetHandleFunc(block, do_view3d_header_buttons, NULL); + UI_block_func_handle_set(block, do_view3d_header_buttons, NULL); /* other buttons: */ - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); /* mode */ if (ob) { diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 84ac4f7d02d..d3a9f5ca967 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -163,7 +163,9 @@ bool draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, /* drawmesh.c */ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob, struct DerivedMesh *dm, const int draw_flags); -void draw_mesh_face_select(struct RegionView3D *rv3d, struct Mesh *me, struct DerivedMesh *dm); +void draw_mesh_face_select( + struct RegionView3D *rv3d, struct Mesh *me, struct DerivedMesh *dm, + bool draw_select_edges); void draw_mesh_paint_weight_faces(struct DerivedMesh *dm, const bool do_light, void *facemask_cb, void *user_data); void draw_mesh_paint_vcolor_faces(struct DerivedMesh *dm, const bool use_light, diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 7e101fea138..5df348408df 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -42,6 +42,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BKE_appdir.h" #include "BKE_blender.h" #include "BKE_context.h" #include "BKE_main.h" @@ -77,7 +78,7 @@ static int view3d_copybuffer_exec(bContext *C, wmOperator *op) } CTX_DATA_END; - BLI_make_file_string("/", str, BLI_temp_dir_base(), "copybuffer.blend"); + BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend"); BKE_copybuffer_save(str, op->reports); BKE_report(op->reports, RPT_INFO, "Copied selected objects to buffer"); @@ -102,7 +103,7 @@ static int view3d_pastebuffer_exec(bContext *C, wmOperator *op) { char str[FILE_MAX]; - BLI_make_file_string("/", str, BLI_temp_dir_base(), "copybuffer.blend"); + BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend"); if (BKE_copybuffer_paste(C, str, op->reports)) { WM_event_add_notifier(C, NC_WINDOW, NULL); @@ -296,8 +297,8 @@ void view3d_keymap(wmKeyConfig *keyconf) RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", PAD4, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANLEFT); RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", PAD6, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANRIGHT); RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", PAD8, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANUP); - RNA_float_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "angle", M_PI / -12); - RNA_float_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", PAD6, KM_PRESS, KM_SHIFT, 0)->ptr, "angle", M_PI / 12); + RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "type", V3D_VIEW_STEPLEFT); + RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", PAD6, KM_PRESS, KM_SHIFT, 0)->ptr, "type", V3D_VIEW_STEPRIGHT); RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANRIGHT); RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANLEFT); @@ -309,8 +310,8 @@ void view3d_keymap(wmKeyConfig *keyconf) RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", WHEELUPMOUSE, KM_PRESS, KM_SHIFT | KM_ALT, 0)->ptr, "type", V3D_VIEW_STEPUP); RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", WHEELDOWNMOUSE, KM_PRESS, KM_SHIFT | KM_ALT, 0)->ptr, "type", V3D_VIEW_STEPDOWN); - RNA_float_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", WHEELUPMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "angle", M_PI / -12); - RNA_float_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "angle", M_PI / 12); + RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", WHEELUPMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "type", V3D_VIEW_STEPLEFT); + RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "type", V3D_VIEW_STEPRIGHT); /* active aligned, replaces '*' key in 2.4x */ kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD1, KM_PRESS, KM_SHIFT, 0); diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c index 9d0a70ea9d0..eba31866f54 100644 --- a/source/blender/editors/space_view3d/view3d_ruler.c +++ b/source/blender/editors/space_view3d/view3d_ruler.c @@ -70,7 +70,7 @@ * \param r_co hit location. * \param r_no hit normal (optional). * \param co_ss Screenspace coordinate. - * \param use_depth Snap to the closest element, use when using more then one snap type. + * \param use_depth Snap to the closest element, use when using more than one snap type. * \param use_obedit Use editmode cage. * \param use_vert Snap to verts. * \param use_edge Snap to edges. @@ -122,12 +122,10 @@ static bool ED_view3d_snap_ray(bContext *C, float r_co[3], bool ret; Scene *scene = CTX_data_scene(C); - View3D *v3d = CTX_wm_view3d(C); - ARegion *ar = CTX_wm_region(C); struct Object *obedit = CTX_data_edit_object(C); /* try snap edge, then face if it fails */ - ret = snapObjectsRayEx(scene, NULL, v3d, ar, obedit, SCE_SNAP_MODE_FACE, + ret = snapObjectsRayEx(scene, NULL, NULL, NULL, obedit, SCE_SNAP_MODE_FACE, NULL, NULL, ray_start, ray_normal, &ray_dist, NULL, &dist_px, r_co, r_no_dummy, SNAP_ALL); @@ -189,7 +187,6 @@ typedef struct RulerInfo { /* wm state */ wmWindow *win; - ScrArea *sa; ARegion *ar; void *draw_handle_pixel; } RulerInfo; @@ -552,10 +549,11 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a /* draw text (bg) */ glColor4ubv(color_back); - uiSetRoundBox(UI_CNR_ALL); - uiRoundBox(pos[0] - bg_margin, pos[1] - bg_margin, - pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1], - bg_radius); + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox( + pos[0] - bg_margin, pos[1] - bg_margin, + pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1], + bg_radius); /* draw text */ glColor3ubv(color_text); BLF_position(blf_mono_font, pos[0], pos[1], 0.0f); @@ -641,8 +639,8 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a /* draw text (bg) */ glColor4ubv(color_back); - uiSetRoundBox(UI_CNR_ALL); - uiRoundBox(pos[0] - bg_margin, pos[1] - bg_margin, + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox(pos[0] - bg_margin, pos[1] - bg_margin, pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1], bg_radius); /* draw text */ @@ -800,7 +798,6 @@ static int view3d_ruler_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE op->customdata = ruler_info; ruler_info->win = win; - ruler_info->sa = sa; ruler_info->ar = ar; ruler_info->draw_handle_pixel = ED_region_draw_cb_activate(ar->type, ruler_info_draw_pixel, ruler_info, REGION_DRAW_POST_PIXEL); @@ -827,11 +824,11 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event) bool do_draw = false; int exit_code = OPERATOR_RUNNING_MODAL; RulerInfo *ruler_info = op->customdata; - ScrArea *sa = ruler_info->sa; + ScrArea *sa = CTX_wm_area(C); ARegion *ar = ruler_info->ar; RegionView3D *rv3d = ar->regiondata; - /* its possible to change spaces while running the operator [#34894] */ + /* its possible to change spaces while running the operator [#34894] */ if (UNLIKELY(ar != CTX_wm_region(C))) { exit_code = OPERATOR_FINISHED; goto exit; diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index ae429289ffd..38ecbed3b5f 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -93,7 +93,6 @@ #include "ED_mball.h" #include "UI_interface.h" -#include "UI_resources.h" #include "view3d_intern.h" /* own include */ @@ -1143,7 +1142,7 @@ static Base *object_mouse_select_menu(bContext *C, ViewContext *vc, unsigned int const char *name = ob->id.name + 2; BLI_strncpy(object_mouse_select_menu_data[i].idname, name, MAX_ID_NAME - 2); - object_mouse_select_menu_data[i].icon = uiIconFromID(&ob->id); + object_mouse_select_menu_data[i].icon = UI_icon_from_id(&ob->id); } { @@ -1181,14 +1180,14 @@ static short selectbuffer_ret_hits_15(unsigned int *UNUSED(buffer), const short static short selectbuffer_ret_hits_9(unsigned int *buffer, const short hits15, const short hits9) { const int offs = 4 * hits15; - memcpy(buffer, buffer + offs, 4 * hits9); + memcpy(buffer, buffer + offs, 4 * hits9 * sizeof(unsigned int)); return hits9; } static short selectbuffer_ret_hits_5(unsigned int *buffer, const short hits15, const short hits9, const short hits5) { const int offs = 4 * hits15 + 4 * hits9; - memcpy(buffer, buffer + offs, 4 * hits5); + memcpy(buffer, buffer + offs, 4 * hits5 * sizeof(unsigned int)); return hits5; } diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c index 3f7f12d2020..f127f375a9f 100644 --- a/source/blender/editors/space_view3d/view3d_toolbar.c +++ b/source/blender/editors/space_view3d/view3d_toolbar.c @@ -39,7 +39,6 @@ #include "MEM_guardedalloc.h" -#include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BLI_ghash.h" @@ -118,7 +117,7 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa) uiLayoutSetEnabled(pa->layout, false); /* note, blockfunc is a default but->func, use Handle func to allow button callbacks too */ - uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, op); + UI_block_func_handle_set(block, ED_undo_operator_repeat_cb_evt, op); view3d_panel_operator_redo_operator(C, pa, op); } @@ -151,20 +150,19 @@ static void operator_call_cb(struct bContext *C, void *arg_listbase, void *arg2) static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items) { - GHashIterator *iter = WM_operatortype_iter(); + GHashIterator iter; - for (; !BLI_ghashIterator_done(iter); BLI_ghashIterator_step(iter)) { - wmOperatorType *ot = BLI_ghashIterator_getValue(iter); + for (WM_operatortype_iter(&iter); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) { + wmOperatorType *ot = BLI_ghashIterator_getValue(&iter); if (BLI_strcasestr(ot->name, str)) { if (WM_operator_poll((bContext *)C, ot)) { - if (false == uiSearchItemAdd(items, ot->name, ot, 0)) + if (false == UI_search_item_add(items, ot->name, ot, 0)) break; } } } - BLI_ghashIterator_free(iter); } @@ -180,18 +178,18 @@ static uiBlock *tool_search_menu(bContext *C, ARegion *ar, void *arg_listbase) /* clear initial search string, then all items show */ search[0] = 0; - block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS); - uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_SEARCH_MENU); + block = UI_block_begin(C, ar, "_popup", UI_EMBOSS); + UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_SEARCH_MENU); /* fake button, it holds space for search items */ - uiDefBut(block, LABEL, 0, "", 10, 15, uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 15, UI_searchbox_size_x(), UI_searchbox_size_y(), NULL, 0, 0, 0, 0, NULL); but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, 150, 19, 0, 0, ""); - uiButSetSearchFunc(but, operator_search_cb, arg_listbase, operator_call_cb, NULL); + UI_but_func_search_set(but, operator_search_cb, arg_listbase, operator_call_cb, NULL); - uiBoundsBlock(block, 6); - uiBlockSetDirection(block, UI_DOWN); - uiEndBlock(C, block); + UI_block_bounds_set_normal(block, 6); + UI_block_direction_set(block, UI_DIR_DOWN); + UI_block_end(C, block); wm_event_init_from_window(win, &event); event.type = EVT_BUT_OPEN; diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 7d3f7ce282e..c0e26498af6 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -37,9 +37,7 @@ #include "BLI_math.h" #include "BLI_rect.h" -#include "BLI_listbase.h" #include "BLI_utildefines.h" -#include "BLI_callbacks.h" #include "BKE_anim.h" #include "BKE_action.h" @@ -55,7 +53,6 @@ #include "BIF_gl.h" #include "BIF_glutil.h" -#include "GPU_draw.h" #include "GPU_select.h" #include "WM_api.h" @@ -64,14 +61,16 @@ #include "ED_screen.h" #include "ED_armature.h" -#include "RE_engine.h" #ifdef WITH_GAMEENGINE -#include "BL_System.h" +# include "BLI_listbase.h" +# include "BLI_callbacks.h" + +# include "GPU_draw.h" + +# include "BL_System.h" #endif -#include "RNA_access.h" -#include "RNA_define.h" #include "view3d_intern.h" /* own include */ @@ -356,6 +355,7 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const w view3d_smooth_view_state_restore(&sms->dst, v3d, rv3d); ED_view3d_camera_lock_sync(v3d, rv3d); + ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true); } if ((rv3d->viewlock & RV3D_LOCKED) == 0) { @@ -382,6 +382,10 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const w v3d->lens = sms->dst.lens * step + sms->src.lens * step_inv; ED_view3d_camera_lock_sync(v3d, rv3d); + if (ED_screen_animation_playing(CTX_wm_manager(C))) { + ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true); + } + } if (rv3d->viewlock & RV3D_BOXVIEW) @@ -1047,7 +1051,7 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b Scene *scene = vc->scene; View3D *v3d = vc->v3d; ARegion *ar = vc->ar; - rctf rect, selrect; + rctf rect; short hits; const bool use_obedit_skip = (scene->obedit != NULL) && (vc->obedit == NULL); const bool do_passes = do_nearest && GPU_select_query_check_active(); @@ -1064,8 +1068,6 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b else { BLI_rctf_rcti_copy(&rect, input); } - - selrect = rect; view3d_winmatrix_set(ar, v3d, &rect); mul_m4_m4m4(vc->rv3d->persmat, vc->rv3d->winmat, vc->rv3d->viewmat); @@ -1079,9 +1081,9 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b ED_view3d_clipping_set(vc->rv3d); if (do_passes) - GPU_select_begin(buffer, bufsize, &selrect, GPU_SELECT_NEAREST_FIRST_PASS, 0); + GPU_select_begin(buffer, bufsize, &rect, GPU_SELECT_NEAREST_FIRST_PASS, 0); else - GPU_select_begin(buffer, bufsize, &selrect, GPU_SELECT_ALL, 0); + GPU_select_begin(buffer, bufsize, &rect, GPU_SELECT_ALL, 0); view3d_select_loop(vc, scene, v3d, ar, use_obedit_skip); @@ -1089,7 +1091,7 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b /* second pass, to get the closest object to camera */ if (do_passes) { - GPU_select_begin(buffer, bufsize, &selrect, GPU_SELECT_NEAREST_SECOND_PASS, hits); + GPU_select_begin(buffer, bufsize, &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits); view3d_select_loop(vc, scene, v3d, ar, use_obedit_skip); @@ -1545,18 +1547,22 @@ static void game_set_commmandline_options(GameData *gm) static int game_engine_poll(bContext *C) { + bScreen *screen; /* we need a context and area to launch BGE * it's a temporary solution to avoid crash at load time * if we try to auto run the BGE. Ideally we want the * context to be set as soon as we load the file. */ if (CTX_wm_window(C) == NULL) return 0; - if (CTX_wm_screen(C) == NULL) return 0; + if ((screen = CTX_wm_screen(C)) == NULL) return 0; if (CTX_wm_area(C) == NULL) return 0; if (CTX_data_mode_enum(C) != CTX_MODE_OBJECT) return 0; + if (!BKE_scene_uses_blender_game(screen->scene)) + return 0; + return 1; } diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c index c54948b23c6..191eeb05c71 100644 --- a/source/blender/editors/space_view3d/view3d_walk.c +++ b/source/blender/editors/space_view3d/view3d_walk.c @@ -42,8 +42,6 @@ #include "BLF_translation.h" -#include "RNA_define.h" -#include "RNA_enum_types.h" #include "BIF_gl.h" @@ -152,6 +150,8 @@ void walk_modal_keymap(wmKeyConfig *keyconf) {WALK_MODAL_JUMP, "JUMP", 0, "Jump", "Jump when in walk mode"}, {WALK_MODAL_JUMP_STOP, "JUMP_STOP", 0, "Jump Stop", "Stop pushing jump"}, + {WALK_MODAL_TOGGLE, "GRAVITY_TOGGLE", 0, "Toggle Gravity", "Toggle gravity effect"}, + {0, NULL, 0, NULL, NULL}}; wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Walk Modal"); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 24499688835..b87a823ce92 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -200,6 +200,12 @@ static bool transdata_check_local_center(TransInfo *t, short around) ); } +bool transdata_check_local_islands(TransInfo *t, short around) +{ + return ((around == V3D_LOCAL) && ( + (t->obedit && ELEM(t->obedit->type, OB_MESH)))); +} + /* ************************** SPACE DEPENDANT CODE **************************** */ void setTransformViewMatrices(TransInfo *t) @@ -1125,47 +1131,22 @@ int transformEvent(TransInfo *t, const wmEvent *event) handled = true; break; case TFM_MODAL_AXIS_X: - if ((t->flag & T_NO_CONSTRAINT) == 0) { - if (cmode == 'X') { - stopConstraint(t); - } - else { - if (t->flag & T_2D_EDIT) { - setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS0), IFACE_("along X")); - } - else { - setUserConstraint(t, t->current_orientation, (CON_AXIS0), IFACE_("along %s X")); - } - } + if (!(t->flag & T_NO_CONSTRAINT)) { + transform_event_xyz_constraint(t, XKEY, cmode); t->redraw |= TREDRAW_HARD; handled = true; } break; case TFM_MODAL_AXIS_Y: if ((t->flag & T_NO_CONSTRAINT) == 0) { - if (cmode == 'Y') { - stopConstraint(t); - } - else { - if (t->flag & T_2D_EDIT) { - setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS1), IFACE_("along Y")); - } - else { - setUserConstraint(t, t->current_orientation, (CON_AXIS1), IFACE_("along %s Y")); - } - } + transform_event_xyz_constraint(t, YKEY, cmode); t->redraw |= TREDRAW_HARD; handled = true; } break; case TFM_MODAL_AXIS_Z: - if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) { - if (cmode == 'Z') { - stopConstraint(t); - } - else { - setUserConstraint(t, t->current_orientation, (CON_AXIS2), IFACE_("along %s Z")); - } + if ((t->flag & (T_NO_CONSTRAINT)) == 0) { + transform_event_xyz_constraint(t, ZKEY, cmode); t->redraw |= TREDRAW_HARD; handled = true; } @@ -2032,6 +2013,12 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve options |= CTX_TEXTURE; } } + + if ((prop = RNA_struct_find_property(op->ptr, "gpencil_strokes")) && RNA_property_is_set(op->ptr, prop)) { + if (RNA_property_boolean_get(op->ptr, prop)) { + options |= CTX_GPENCIL_STROKES; + } + } t->options = options; @@ -3184,38 +3171,23 @@ static void headerResize(TransInfo *t, float vec[3], char str[MAX_INFO_LEN]) } } -/* FLT_EPSILON is too small [#29633], 0.0000001f starts to flip */ -#define TX_FLIP_EPS 0.00001f -BLI_INLINE int tx_sign(const float a) -{ - return (a < -TX_FLIP_EPS ? 1 : a > TX_FLIP_EPS ? 2 : 3); -} -BLI_INLINE int tx_vec_sign_flip(const float a[3], const float b[3]) -{ - return ((tx_sign(a[0]) & tx_sign(b[0])) == 0 || - (tx_sign(a[1]) & tx_sign(b[1])) == 0 || - (tx_sign(a[2]) & tx_sign(b[2])) == 0); -} - -/* smat is reference matrix, only scaled */ +/** + * \a smat is reference matrix only. + * + * \note this is a tricky area, before making changes see: T29633, T42444 + */ static void TransMat3ToSize(float mat[3][3], float smat[3][3], float size[3]) { - float vec[3]; - - copy_v3_v3(vec, mat[0]); - size[0] = normalize_v3(vec); - copy_v3_v3(vec, mat[1]); - size[1] = normalize_v3(vec); - copy_v3_v3(vec, mat[2]); - size[2] = normalize_v3(vec); - + float rmat[3][3]; + + mat3_to_rot_size(rmat, size, mat); + /* first tried with dotproduct... but the sign flip is crucial */ - if (tx_vec_sign_flip(mat[0], smat[0]) ) size[0] = -size[0]; - if (tx_vec_sign_flip(mat[1], smat[1]) ) size[1] = -size[1]; - if (tx_vec_sign_flip(mat[2], smat[2]) ) size[2] = -size[2]; + if (dot_v3v3(rmat[0], smat[0]) < 0.0f) size[0] = -size[0]; + if (dot_v3v3(rmat[1], smat[1]) < 0.0f) size[1] = -size[1]; + if (dot_v3v3(rmat[2], smat[2]) < 0.0f) size[2] = -size[2]; } - static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { float tmat[3][3], smat[3][3], center[3]; @@ -4101,6 +4073,11 @@ static void initTranslation(TransInfo *t) t->snap[1] = ED_node_grid_size() * NODE_GRID_STEPS; t->snap[2] = ED_node_grid_size(); } + else if (t->spacetype == SPACE_IPO) { + t->snap[0] = 0.0f; + t->snap[1] = 1.0; + t->snap[2] = 0.1f; + } else { t->snap[0] = 0.0f; t->snap[1] = t->snap[2] = 1.0f; @@ -4227,29 +4204,21 @@ static void applyTranslationValue(TransInfo *t, float vec[3]) if (td->flag & TD_SKIP) continue; - + /* handle snapping rotation before doing the translation */ if (usingSnappingNormal(t)) { if (validSnappingNormal(t)) { const float *original_normal; - float axis[3]; - float quat[4]; float mat[3][3]; - float angle; /* In pose mode, we want to align normals with Y axis of bones... */ if (t->flag & T_POSE) original_normal = td->axismtx[1]; else original_normal = td->axismtx[2]; - - cross_v3_v3v3(axis, original_normal, t->tsnap.snapNormal); - angle = saacos(dot_v3v3(original_normal, t->tsnap.snapNormal)); - - axis_angle_to_quat(quat, axis, angle); - - quat_to_mat3(mat, quat); - + + rotation_between_vecs_to_mat3(mat, original_normal, t->tsnap.snapNormal); + ElementRotation(t, td, mat, V3D_LOCAL); } else { @@ -7169,10 +7138,11 @@ static void headerSeqSlide(TransInfo *t, float val[2], char str[MAX_INFO_LEN]) WM_bool_as_string((t->flag & T_ALT_TRANSFORM) != 0)); } -static void applySeqSlideValue(TransInfo *t, const float val[2]) +static void applySeqSlideValue(TransInfo *t, const float val[2], int frame) { TransData *td = t->data; int i; + TransSeq *ts = t->customData; for (i = 0; i < t->total; i++, td++) { float tvec[2]; @@ -7187,15 +7157,21 @@ static void applySeqSlideValue(TransInfo *t, const float val[2]) mul_v2_fl(tvec, td->factor); - td->loc[0] = td->iloc[0] + tvec[0]; + if (t->modifiers & MOD_SNAP_INVERT) { + td->loc[0] = frame + td->factor * (td->iloc[0] - ts->min); + } + else { + td->loc[0] = td->iloc[0] + tvec[0]; + } + td->loc[1] = td->iloc[1] + tvec[1]; } } -static void applySeqSlide(TransInfo *t, const int UNUSED(mval[2])) +static void applySeqSlide(TransInfo *t, const int mval[2]) { char str[MAX_INFO_LEN]; - + int snap_frame = 0; if (t->con.mode & CON_APPLY) { float pvec[3] = {0.0f, 0.0f, 0.0f}; float tvec[3]; @@ -7203,7 +7179,8 @@ static void applySeqSlide(TransInfo *t, const int UNUSED(mval[2])) copy_v3_v3(t->values, tvec); } else { - snapGridIncrement(t, t->values); + snap_frame = snapSequenceBounds(t, mval); + // snapGridIncrement(t, t->values); applyNumInput(&t->num, t->values); } @@ -7211,7 +7188,7 @@ static void applySeqSlide(TransInfo *t, const int UNUSED(mval[2])) t->values[1] = floor(t->values[1] + 0.5f); headerSeqSlide(t, t->values, str); - applySeqSlideValue(t, t->values); + applySeqSlideValue(t, t->values, snap_frame); recalcData(t); diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 67d55639528..0d824be862e 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -173,6 +173,13 @@ typedef struct TransDataSeq { } TransDataSeq; +typedef struct TransSeq { + TransDataSeq *tdseq; + int min; + int max; + bool snap_left; +} TransSeq; + /* for NLA transform (stored in td->extra pointer) */ typedef struct TransDataNla { ID *id; /* ID-block NLA-data is attached to */ @@ -545,6 +552,7 @@ void special_aftertrans_update(struct bContext *C, TransInfo *t); int special_transform_moving(TransInfo *t); void transform_autoik_update(TransInfo *t, short mode); +bool transdata_check_local_islands(TransInfo *t, short around); int count_set_pose_transflags(int *out_mode, short around, struct Object *ob); @@ -588,6 +596,8 @@ typedef enum { void snapGridIncrement(TransInfo *t, float *val); void snapGridIncrementAction(TransInfo *t, float *val, GearsType action); +int snapSequenceBounds(TransInfo *t, const int mval[2]); + bool activeSnap(TransInfo *t); bool validSnap(TransInfo *t); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index e27dafca9af..6e06f2e9d43 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -54,7 +54,6 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_smallhash.h" #include "BLI_listbase.h" #include "BLI_linklist_stack.h" #include "BLI_string.h" @@ -90,7 +89,6 @@ #include "BKE_editmesh.h" #include "BKE_tracking.h" #include "BKE_mask.h" -#include "BKE_lattice.h" #include "BIK_api.h" @@ -107,6 +105,7 @@ #include "ED_uvedit.h" #include "ED_clip.h" #include "ED_mask.h" +#include "ED_gpencil.h" #include "WM_api.h" /* for WM_event_add_notifier to deal with stabilization nodes */ #include "WM_types.h" @@ -218,6 +217,9 @@ static void set_prop_dist(TransInfo *t, const bool with_dist) float _proj_vec[3]; const float *proj_vec = NULL; + /* support for face-islands */ + const bool use_island = transdata_check_local_islands(t, t->around); + if (t->flag & T_PROP_PROJECTED) { if (t->spacetype == SPACE_VIEW3D && t->ar && t->ar->regiontype == RGN_TYPE_WINDOW) { RegionView3D *rv3d = t->ar->regiondata; @@ -239,7 +241,12 @@ static void set_prop_dist(TransInfo *t, const bool with_dist) for (i = 0, td = t->data; i < t->total; i++, td++) { if (td->flag & TD_SELECTED) { - sub_v3_v3v3(vec, tob->center, td->center); + if (use_island) { + sub_v3_v3v3(vec, tob->iloc, td->iloc); + } + else { + sub_v3_v3v3(vec, tob->center, td->center); + } mul_m3_v3(tob->mtx, vec); if (proj_vec) { @@ -251,6 +258,10 @@ static void set_prop_dist(TransInfo *t, const bool with_dist) dist_sq = len_squared_v3(vec); if ((tob->rdist == -1.0f) || (dist_sq < SQUARE(tob->rdist))) { tob->rdist = sqrtf(dist_sq); + if (use_island) { + copy_v3_v3(tob->center, td->center); + copy_m3_m3(tob->axismtx, td->axismtx); + } } } else { @@ -1056,11 +1067,13 @@ static void createTransPose(TransInfo *t, Object *ob) void restoreBones(TransInfo *t) { + bArmature *arm = t->obedit->data; BoneInitData *bid = t->customData; EditBone *ebo; while (bid->bone) { ebo = bid->bone; + ebo->dist = bid->dist; ebo->rad_tail = bid->rad_tail; ebo->roll = bid->roll; @@ -1068,7 +1081,26 @@ void restoreBones(TransInfo *t) ebo->zwidth = bid->zwidth; copy_v3_v3(ebo->head, bid->head); copy_v3_v3(ebo->tail, bid->tail); + + if (arm->flag & ARM_MIRROR_EDIT) { + EditBone *ebo_child; + + /* Also move connected ebo_child, in case ebo_child's name aren't mirrored properly */ + for (ebo_child = arm->edbo->first; ebo_child; ebo_child = ebo_child->next) { + if ((ebo_child->flag & BONE_CONNECTED) && (ebo_child->parent == ebo)) { + copy_v3_v3(ebo_child->head, ebo->tail); + ebo_child->rad_head = ebo->rad_tail; + } + } + /* Also move connected parent, in case parent's name isn't mirrored properly */ + if ((ebo->flag & BONE_CONNECTED) && ebo->parent) { + EditBone *parent = ebo->parent; + copy_v3_v3(parent->tail, ebo->head); + parent->rad_tail = ebo->rad_head; + } + } + bid++; } } @@ -2146,6 +2178,7 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx BMEditMesh *em, BMVert *eve, float *bweight, struct TransIslandData *v_island) { + float *no, _no[3]; BLI_assert(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) == 0); td->flag = 0; @@ -2155,19 +2188,30 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx td->loc = eve->co; copy_v3_v3(td->iloc, td->loc); + if ((t->mode == TFM_SHRINKFATTEN) && + (em->selectmode & SCE_SELECT_FACE) && + BM_elem_flag_test(eve, BM_ELEM_SELECT) && + (BM_vert_normal_update_ex(eve, BM_ELEM_SELECT, _no))) + { + no = _no; + } + else { + no = eve->no; + } + if (v_island) { copy_v3_v3(td->center, v_island->co); copy_m3_m3(td->axismtx, v_island->axismtx); } else if (t->around == V3D_LOCAL) { copy_v3_v3(td->center, td->loc); - createSpaceNormal(td->axismtx, eve->no); + createSpaceNormal(td->axismtx, no); } else { copy_v3_v3(td->center, td->loc); /* Setting normals */ - copy_v3_v3(td->axismtx[2], eve->no); + copy_v3_v3(td->axismtx[2], no); td->axismtx[0][0] = td->axismtx[0][1] = td->axismtx[0][2] = @@ -2196,7 +2240,7 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx } else if (t->mode == TFM_SHRINKFATTEN) { td->ext = tx; - tx->isize[0] = BM_vert_calc_shell_factor_ex(eve, BM_ELEM_SELECT); + tx->isize[0] = BM_vert_calc_shell_factor_ex(eve, no, BM_ELEM_SELECT); } } @@ -2615,7 +2659,7 @@ static void UVsToTransData(SpaceImage *sima, TransData *td, TransData2D *td2d, f /* uv coords are scaled by aspects. this is needed for rotations and * proportional editing to be consistent with the stretched uv coords * that are displayed. this also means that for display and numinput, - * and when the the uv coords are flushed, these are converted each time */ + * and when the uv coords are flushed, these are converted each time */ td2d->loc[0] = uv[0] * aspx; td2d->loc[1] = uv[1] * aspy; td2d->loc[2] = 0.0f; @@ -2773,8 +2817,8 @@ void flushTransUVs(TransInfo *t) td->loc2d[1] = td->loc[1] * invy; if ((sima->flag & SI_PIXELSNAP) && (t->state != TRANS_CANCEL)) { - td->loc2d[0] = floorf(width * td->loc2d[0] + 0.5f) / width; - td->loc2d[1] = floorf(height * td->loc2d[1] + 0.5f) / height; + td->loc2d[0] = roundf(width * td->loc2d[0]) / width; + td->loc2d[1] = roundf(height * td->loc2d[1]) / height; } } } @@ -3117,7 +3161,7 @@ static void posttrans_gpd_clean(bGPdata *gpd) bGPDframe *gpf, *gpfn; bool is_double = false; - BLI_sortlist_r(&gpl->frames, &is_double, gpf_cmp_frame); + BLI_listbase_sort_r(&gpl->frames, &is_double, gpf_cmp_frame); if (is_double) { for (gpf = gpl->frames.first; gpf; gpf = gpfn) { @@ -3144,7 +3188,7 @@ static void posttrans_mask_clean(Mask *mask) MaskLayerShape *masklay_shape, *masklay_shape_next; bool is_double = false; - BLI_sortlist_r(&masklay->splines_shapes, &is_double, masklay_shape_cmp_frame); + BLI_listbase_sort_r(&masklay->splines_shapes, &is_double, masklay_shape_cmp_frame); if (is_double) { for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape_next) { @@ -3736,7 +3780,6 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) BezTriple *bezt; int count = 0, i; - float cfra; float mtx[3][3], smtx[3][3]; const bool is_translation_mode = graph_edit_is_translation_mode(t); const bool use_handle = !(sipo->flag & SIPO_NOHANDLES); @@ -3771,7 +3814,12 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) for (ale = anim_data.first; ale; ale = ale->next) { AnimData *adt = ANIM_nla_mapping_get(&ac, ale); FCurve *fcu = (FCurve *)ale->key_data; - + float cfra; + + /* F-Curve may not have any keyframes */ + if (fcu->bezt == NULL) + continue; + /* convert current-frame to action-time (slightly less accurate, especially under * higher scaling ratios, but is faster than converting all points) */ @@ -3779,11 +3827,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP); else cfra = (float)CFRA; - - /* F-Curve may not have any keyframes */ - if (fcu->bezt == NULL) - continue; - + /* only include BezTriples whose 'keyframe' occurs on the same side of the current frame as mouse */ for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) { if (FrameOnMouseSide(t->frame_side, bezt->vec[1][0], cfra)) { @@ -3791,33 +3835,19 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) const bool sel1 = use_handle ? bezt->f1 & SELECT : sel2; const bool sel3 = use_handle ? bezt->f3 & SELECT : sel2; - if (is_translation_mode) { - /* for 'normal' pivots - just include anything that is selected. - * this works a bit differently in translation modes */ - if (sel2) { + if (!is_translation_mode || !(sel2)) { + if (sel1) { count++; } - else { - if (sel1) count++; - if (sel3) count++; - } - } - else if (use_local_center) { - /* for local-pivot we only need to count the number of selected handles only, - * so that centerpoints don't get moved wrong - */ - if (bezt->ipo == BEZT_IPO_BEZ) { - if (sel1) count++; - if (sel3) count++; + + if (sel3) { + count++; } - /* else if (sel2) count++; // TODO: could this cause problems? */ - /* - yes this causes problems, because no td is created for the center point */ } - else { - /* for 'normal' pivots - just include anything that is selected */ - if (sel1) count++; - if (sel2) count++; - if (sel3) count++; + + /* only include main vert if selected */ + if (sel2 && !use_local_center) { + count++; } } } @@ -3866,8 +3896,13 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) for (ale = anim_data.first; ale; ale = ale->next) { AnimData *adt = ANIM_nla_mapping_get(&ac, ale); FCurve *fcu = (FCurve *)ale->key_data; - bool intvals = (fcu->flag & FCURVE_INT_VALUES); + bool intvals = (fcu->flag & FCURVE_INT_VALUES) != 0; float unit_scale; + float cfra; + + /* F-Curve may not have any keyframes */ + if (fcu->bezt == NULL) + continue; /* convert current-frame to action-time (slightly less accurate, especially under * higher scaling ratios, but is faster than converting all points) @@ -3876,11 +3911,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP); else cfra = (float)CFRA; - - /* F-Curve may not have any keyframes */ - if (fcu->bezt == NULL) - continue; - + unit_scale = ANIM_unit_mapping_get_factor(ac.scene, ale->id, ale->key_data, anim_map_flag); /* only include BezTriples whose 'keyframe' occurs on the same side of the current frame as mouse (if applicable) */ @@ -4495,10 +4526,47 @@ static int SeqToTransData_Recursive(TransInfo *t, ListBase *seqbase, TransData * } } } - return tot; } + +static void SeqTransDataBounds(TransInfo *t, ListBase *seqbase, TransSeq *ts) +{ + Sequence *seq; + int recursive, count, flag; + int max = INT32_MIN, min = INT32_MAX; + + for (seq = seqbase->first; seq; seq = seq->next) { + + /* just to get the flag since there are corner cases where this isn't totally obvious */ + SeqTransInfo(t, seq, &recursive, &count, &flag); + + /* use 'flag' which is derived from seq->flag but modified for special cases */ + if (flag & SELECT) { + if (flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) { + if (flag & SEQ_LEFTSEL) { + min = min_ii(seq->startdisp, min); + max = max_ii(seq->startdisp, max); + } + if (flag & SEQ_RIGHTSEL) { + min = min_ii(seq->enddisp, min); + max = max_ii(seq->enddisp, max); + } + } + else { + min = min_ii(seq->startdisp, min); + max = max_ii(seq->enddisp, max); + } + } + } + + if (ts) { + ts->max = max; + ts->min = min; + } +} + + static void freeSeqData(TransInfo *t) { Editing *ed = BKE_sequencer_editing_get(t->scene, false); @@ -4661,6 +4729,8 @@ static void freeSeqData(TransInfo *t) } if ((t->customData != NULL) && (t->flag & T_FREE_CUSTOMDATA)) { + TransSeq *ts = t->customData; + MEM_freeN(ts->tdseq); MEM_freeN(t->customData); t->customData = NULL; } @@ -4680,6 +4750,8 @@ static void createTransSeqData(bContext *C, TransInfo *t) TransData *td = NULL; TransData2D *td2d = NULL; TransDataSeq *tdsq = NULL; + TransSeq *ts = NULL; + float xmouse, ymouse; int count = 0; @@ -4690,12 +4762,11 @@ static void createTransSeqData(bContext *C, TransInfo *t) t->customFree = freeSeqData; + UI_view2d_region_to_view(v2d, t->imval[0], t->imval[1], &xmouse, &ymouse); + /* which side of the current frame should be allowed */ if (t->mode == TFM_TIME_EXTEND) { /* only side on which mouse is gets transformed */ - float xmouse, ymouse; - - UI_view2d_region_to_view(v2d, t->imval[0], t->imval[1], &xmouse, &ymouse); t->frame_side = (xmouse > CFRA) ? 'R' : 'L'; } else { @@ -4735,15 +4806,19 @@ static void createTransSeqData(bContext *C, TransInfo *t) return; } + t->customData = ts = MEM_mallocN(sizeof(TransSeq), "transseq"); td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransSeq TransData"); td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransSeq TransData2D"); - tdsq = t->customData = MEM_callocN(t->total * sizeof(TransDataSeq), "TransSeq TransDataSeq"); + ts->tdseq = tdsq = MEM_callocN(t->total * sizeof(TransDataSeq), "TransSeq TransDataSeq"); t->flag |= T_FREE_CUSTOMDATA; - - /* loop 2: build transdata array */ SeqToTransData_Recursive(t, ed->seqbasep, td, td2d, tdsq); + SeqTransDataBounds(t, ed->seqbasep, ts); + + /* set the snap mode based on how close the mouse is at the end/start points */ + if (abs(xmouse - ts->max) > abs(xmouse - ts->min)) + ts->snap_left = true; #undef XXX_DURIAN_ANIM_TX_HACK } @@ -4771,7 +4846,6 @@ static bool constraints_list_needinv(TransInfo *t, ListBase *list) /* (affirmative) returns for specific constraints here... */ /* constraints that require this regardless */ if (ELEM(con->type, - CONSTRAINT_TYPE_CHILDOF, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO, CONSTRAINT_TYPE_OBJECTSOLVER, @@ -4781,7 +4855,14 @@ static bool constraints_list_needinv(TransInfo *t, ListBase *list) } /* constraints that require this only under special conditions */ - if (con->type == CONSTRAINT_TYPE_ROTLIKE) { + if (con->type == CONSTRAINT_TYPE_CHILDOF) { + /* ChildOf constraint only works when using all location components, see T42256. */ + bChildOfConstraint *data = (bChildOfConstraint *)con->data; + + if ((data->flag & CHILDOF_LOCX) && (data->flag & CHILDOF_LOCY) && (data->flag & CHILDOF_LOCZ)) + return true; + } + else if (con->type == CONSTRAINT_TYPE_ROTLIKE) { /* CopyRot constraint only does this when rotating, and offset is on */ bRotateLikeConstraint *data = (bRotateLikeConstraint *)con->data; @@ -5533,7 +5614,10 @@ void special_aftertrans_update(bContext *C, TransInfo *t) } - if (t->spacetype == SPACE_SEQ) { + if (t->options & CTX_GPENCIL_STROKES) { + /* pass */ + } + else if (t->spacetype == SPACE_SEQ) { /* freeSeqData in transform_conversions.c does this * keep here so the else at the end wont run... */ @@ -6771,7 +6855,7 @@ static void MaskPointToTransData(Scene *scene, MaskSplinePoint *point, /* CV coords are scaled by aspects. this is needed for rotations and * proportional editing to be consistent with the stretched CV coords * that are displayed. this also means that for display and numinput, - * and when the the CV coords are flushed, these are converted each time */ + * and when the CV coords are flushed, these are converted each time */ mul_v2_m3v2(td2d->loc, parent_matrix, bezt->vec[i]); td2d->loc[0] *= asp[0]; td2d->loc[1] *= asp[1]; @@ -7200,6 +7284,230 @@ void flushTransPaintCurve(TransInfo *t) } +static void createTransGPencil(bContext *C, TransInfo *t) +{ + bGPdata *gpd = ED_gpencil_data_get_active(C); + bGPDlayer *gpl; + TransData *td = NULL; + float mtx[3][3], smtx[3][3]; + + const Scene *scene = CTX_data_scene(C); + const int cfra = CFRA; + + const int propedit = (t->flag & T_PROP_EDIT); + const int propedit_connected = (t->flag & T_PROP_CONNECTED); + + + /* == Grease Pencil Strokes to Transform Data == + * Grease Pencil stroke points can be a mixture of 2D (screen-space), + * or 3D coordinates. However, they're always saved as 3D points. + * For now, we just do these without creating TransData2D for the 2D + * strokes. This may cause issues in future though. + */ + t->total = 0; + + if (gpd == NULL) + return; + + /* First Pass: Count the number of datapoints required for the strokes, + * (and additional info about the configuration - e.g. 2D/3D?) + */ + for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { + /* only editable and visible layers are considered */ + if ((gpl->flag & (GP_LAYER_HIDE | GP_LAYER_LOCKED)) == 0 && + (gpl->actframe != NULL)) + { + bGPDframe *gpf = gpl->actframe; + bGPDstroke *gps; + + for (gps = gpf->strokes.first; gps; gps = gps->next) { + if (propedit) { + /* Proportional Editing... */ + if (propedit_connected) { + /* connected only - so only if selected */ + if (gps->flag & GP_STROKE_SELECT) + t->total += gps->totpoints; + } + else { + /* everything goes - connection status doesn't matter */ + t->total += gps->totpoints; + } + } + else { + /* only selected stroke points are considered */ + if (gps->flag & GP_STROKE_SELECT) { + bGPDspoint *pt; + int i; + + // TODO: 2D vs 3D? + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) + t->total++; + } + } + } + } + } + } + + /* Stop trying if nothing selected */ + if (t->total == 0) { + return; + } + + /* Allocate memory for data */ + t->data = MEM_callocN(t->total * sizeof(TransData), "TransData(GPencil)"); + td = t->data; + + unit_m3(smtx); + unit_m3(mtx); + + /* Second Pass: Build transdata array */ + for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { + /* only editable and visible layers are considered */ + if ((gpl->flag & (GP_LAYER_HIDE | GP_LAYER_LOCKED)) == 0 && + (gpl->actframe != NULL)) + { + bGPDframe *gpf = gpl->actframe; + bGPDstroke *gps; + + /* Make a new frame to work on if the layer's frame and the current scene frame don't match up + * - This is useful when animating as it saves that "uh-oh" moment when you realize you've + * spent too much time editing the wrong frame... + */ + // XXX: should this be allowed when framelock is enabled? + if (gpf->framenum != cfra) { + bGPDframe *new_frame = gpencil_frame_duplicate(gpf); + bGPDframe *gf; + bool found = false; + + /* Find frame to insert it before */ + for (gf = gpf->next; gf; gf = gf->next) { + if (gf->framenum > cfra) { + /* Add it here */ + BLI_insertlinkbefore(&gpl->frames, gf, new_frame); + + found = true; + break; + } + else if (gf->framenum == cfra) { + /* This only happens when we're editing with framelock on... + * - Delete the new frame and don't do anything else here... + */ + //printf("GP Frame convert to TransData - Copy aborted for frame %d -> %d\n", gpf->framenum, gf->framenum); + free_gpencil_strokes(new_frame); + MEM_freeN(new_frame); + new_frame = NULL; + + found = true; + break; + } + } + + if (found == false) { + /* Add new frame to the end */ + BLI_addtail(&gpl->frames, new_frame); + } + + /* Edit the new frame instead, if it did get created + added */ + if (new_frame) { + // TODO: tag this one as being "newly created" so that we can remove it if the edit is cancelled + new_frame->framenum = cfra; + + gpf = new_frame; + } + } + + /* Loop over strokes, adding TransData for points as needed... */ + for (gps = gpf->strokes.first; gps; gps = gps->next) { + TransData *head = td; + TransData *tail = td; + bool stroke_ok; + + /* What we need to include depends on proportional editing settings... */ + if (propedit) { + if (propedit_connected) { + /* A) "Connected" - Only those in selected strokes */ + stroke_ok = (gps->flag & GP_STROKE_SELECT) != 0; + } + else { + /* B) All points, always */ + stroke_ok = true; + } + } + else { + /* C) Only selected points in selected strokes */ + stroke_ok = (gps->flag & GP_STROKE_SELECT) != 0; + } + + /* Do stroke... */ + if (stroke_ok && gps->totpoints) { + bGPDspoint *pt; + int i; + +#if 0 /* XXX: this isn't needed anymore; cannot calculate center this way or propedit breaks */ + const float ninv = 1.0f / gps->totpoints; + float center[3] = {0.0f}; + + /* compute midpoint of stroke */ + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + madd_v3_v3v3fl(center, center, &pt->x, ninv); + } +#endif + + /* add all necessary points... */ + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + bool point_ok; + + /* include point? */ + if (propedit) { + /* Always all points in strokes that get included */ + point_ok = true; + } + else { + /* Only selected points in selected strokes */ + point_ok = (pt->flag & GP_SPOINT_SELECT) != 0; + } + + /* do point... */ + if (point_ok) { + copy_v3_v3(td->iloc, &pt->x); + copy_v3_v3(td->center, &pt->x); // XXX: what about t->around == local? + + td->loc = &pt->x; + + td->flag = 0; + + if (pt->flag & GP_SPOINT_SELECT) + td->flag |= TD_SELECTED; + + /* configure 2D points so that they don't play up... */ + if (gps->flag & (GP_STROKE_2DSPACE | GP_STROKE_2DIMAGE)) { + td->protectflag = OB_LOCK_LOCZ | OB_LOCK_ROTZ | OB_LOCK_SCALEZ; + // XXX: matrices may need to be different? + } + + copy_m3_m3(td->smtx, smtx); + copy_m3_m3(td->mtx, mtx); + unit_m3(td->axismtx); // XXX? + + td++; + tail++; + } + } + + /* March over these points, and calculate the proportional editing distances */ + if (propedit && (head != tail)) { + /* XXX: for now, we are similar enough that this works... */ + calc_distanceCurveVerts(head, tail - 1); + } + } + } + } + } +} + + void createTransData(bContext *C, TransInfo *t) { Scene *scene = t->scene; @@ -7220,6 +7528,16 @@ void createTransData(bContext *C, TransInfo *t) sort_trans_data_dist(t); } } + else if (t->options & CTX_GPENCIL_STROKES) { + t->flag |= T_POINTS; // XXX... + createTransGPencil(C, t); + + if (t->data && (t->flag & T_PROP_EDIT)) { + sort_trans_data(t); // makes selected become first in array + set_prop_dist(t, 1); + sort_trans_data_dist(t); + } + } else if (t->spacetype == SPACE_IMAGE) { t->flag |= T_POINTS | T_2D_EDIT; if (t->options & CTX_MASK) { diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 24dc6f6e74b..fcf789546e8 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -109,21 +109,7 @@ void getViewVector(TransInfo *t, float coord[3], float vec[3]) { if (t->persp != RV3D_ORTHO) { - float p1[4], p2[4]; - - copy_v3_v3(p1, coord); - p1[3] = 1.0f; - copy_v3_v3(p2, p1); - p2[3] = 1.0f; - mul_m4_v4(t->viewmat, p2); - - p2[0] = 2.0f * p2[0]; - p2[1] = 2.0f * p2[1]; - p2[2] = 2.0f * p2[2]; - - mul_m4_v4(t->viewinv, p2); - - sub_v3_v3v3(vec, p1, p2); + sub_v3_v3v3(vec, coord, t->viewinv[3]); } else { copy_v3_v3(vec, t->viewinv[2]); @@ -779,7 +765,7 @@ static void recalcData_objects(TransInfo *t) else if (t->obedit->type == OB_ARMATURE) { /* no recalc flag, does pose */ bArmature *arm = t->obedit->data; ListBase *edbo = arm->edbo; - EditBone *ebo; + EditBone *ebo, *ebo_parent; TransData *td = t->data; int i; @@ -789,17 +775,18 @@ static void recalcData_objects(TransInfo *t) /* Ensure all bones are correctly adjusted */ for (ebo = edbo->first; ebo; ebo = ebo->next) { + ebo_parent = (ebo->flag & BONE_CONNECTED) ? ebo->parent : NULL; - if ((ebo->flag & BONE_CONNECTED) && ebo->parent) { + if (ebo_parent) { /* If this bone has a parent tip that has been moved */ - if (ebo->parent->flag & BONE_TIPSEL) { - copy_v3_v3(ebo->head, ebo->parent->tail); - if (t->mode == TFM_BONE_ENVELOPE) ebo->rad_head = ebo->parent->rad_tail; + if (ebo_parent->flag & BONE_TIPSEL) { + copy_v3_v3(ebo->head, ebo_parent->tail); + if (t->mode == TFM_BONE_ENVELOPE) ebo->rad_head = ebo_parent->rad_tail; } /* If this bone has a parent tip that has NOT been moved */ else { - copy_v3_v3(ebo->parent->tail, ebo->head); - if (t->mode == TFM_BONE_ENVELOPE) ebo->parent->rad_tail = ebo->rad_head; + copy_v3_v3(ebo_parent->tail, ebo->head); + if (t->mode == TFM_BONE_ENVELOPE) ebo_parent->rad_tail = ebo->rad_head; } } @@ -974,6 +961,9 @@ void recalcData(TransInfo *t) else if (t->options & CTX_PAINT_CURVE) { flushTransPaintCurve(t); } + else if (t->options & CTX_GPENCIL_STROKES) { + /* pass? */ + } else if (t->spacetype == SPACE_IMAGE) { recalcData_image(t); } @@ -1202,9 +1192,13 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve } /* exceptional case */ - if (t->around == V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) { + if (t->around == V3D_LOCAL) { if (ELEM(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL)) { - t->options |= CTX_NO_PET; + const bool use_island = transdata_check_local_islands(t, t->around); + + if (!use_island) { + t->options |= CTX_NO_PET; + } } } @@ -1324,6 +1318,9 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve if (t->obedit) { t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional); } + else if (t->options & CTX_GPENCIL_STROKES) { + t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional); + } else if (t->options & CTX_MASK) { if (ts->proportional_mask) { t->flag |= T_PROP_EDIT; @@ -1651,8 +1648,9 @@ void calculateCenterMedian(TransInfo *t, float r_center[3]) } } } - if (i) - mul_v3_fl(partial, 1.0f / total); + if (total) { + mul_v3_fl(partial, 1.0f / (float)total); + } copy_v3_v3(r_center, partial); } diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 37a6d50e149..f2869843dd5 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -1850,7 +1850,6 @@ int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op) } RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis); WM_operator_name_call(C, "TRANSFORM_OT_translate", WM_OP_INVOKE_DEFAULT, op->ptr); - //wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_translate", 0), event, op->ptr, NULL, false); } else if (drawflags & MAN_SCALE_C) { switch (drawflags) { @@ -1881,7 +1880,6 @@ int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op) } RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis); WM_operator_name_call(C, "TRANSFORM_OT_resize", WM_OP_INVOKE_DEFAULT, op->ptr); - //wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_resize", 0), event, op->ptr, NULL, false); } else if (drawflags == MAN_ROT_T) { /* trackball need special case, init is different */ /* Do not pass op->ptr!!! trackball has no "constraint" properties! @@ -1894,8 +1892,7 @@ int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op) if ((prop = RNA_struct_find_property(op->ptr, "release_confirm")) && RNA_property_is_set(op->ptr, prop)) { RNA_property_boolean_set(&props_ptr, prop, RNA_property_boolean_get(op->ptr, prop)); } - WM_operator_name_call(C, ot->idname, WM_OP_INVOKE_DEFAULT, &props_ptr); - //wm_operator_invoke(C, WM_operatortype_find(ot->idname, 0), event, NULL, NULL, false); + WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr); WM_operator_properties_free(&props_ptr); } else if (drawflags & MAN_ROT_C) { @@ -1912,7 +1909,6 @@ int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op) } RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis); WM_operator_name_call(C, "TRANSFORM_OT_rotate", WM_OP_INVOKE_DEFAULT, op->ptr); - //wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_rotate", 0), event, op->ptr, NULL, false); } } /* after transform, restore drawflags */ diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 81e065ee33a..25dee50a192 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -171,12 +171,12 @@ static int select_orientation_invoke(bContext *C, wmOperator *UNUSED(op), const uiPopupMenu *pup; uiLayout *layout; - pup = uiPupMenuBegin(C, IFACE_("Orientation"), ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, IFACE_("Orientation"), ICON_NONE); + layout = UI_popup_menu_layout(pup); uiItemsEnumO(layout, "TRANSFORM_OT_select_orientation", "orientation"); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } static void TRANSFORM_OT_select_orientation(struct wmOperatorType *ot) @@ -324,6 +324,9 @@ static void transformops_loopsel_hack(bContext *C, wmOperator *op) } } } +#else +/* prevent removal by cleanup */ +# error "loopslide hack removed!" #endif /* USE_LOOPSLIDE_HACK */ @@ -543,7 +546,11 @@ void Transform_Properties(struct wmOperatorType *ot, int flags) } } } - + + if (flags & P_GPENCIL_EDIT) { + RNA_def_boolean(ot->srna, "gpencil_strokes", 0, "Edit Grease Pencil", "Edit selected Grease Pencil strokes"); + } + if ((flags & P_OPTIONS) && !(flags & P_NO_TEXSPACE)) { RNA_def_boolean(ot->srna, "texture_space", 0, "Edit Texture Space", "Edit Object data texture space"); prop = RNA_def_boolean(ot->srna, "remove_on_cancel", 0, "Remove on Cancel", "Remove elements on cancel"); @@ -578,7 +585,7 @@ static void TRANSFORM_OT_translate(struct wmOperatorType *ot) RNA_def_float_vector_xyz(ot->srna, "value", 3, NULL, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX); - Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP | P_OPTIONS); + Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP | P_OPTIONS | P_GPENCIL_EDIT); } static void TRANSFORM_OT_resize(struct wmOperatorType *ot) @@ -598,7 +605,7 @@ static void TRANSFORM_OT_resize(struct wmOperatorType *ot) RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX); - Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP | P_OPTIONS); + Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP | P_OPTIONS | P_GPENCIL_EDIT); } static int skin_resize_poll(bContext *C) @@ -652,7 +659,7 @@ static void TRANSFORM_OT_trackball(struct wmOperatorType *ot) prop = RNA_def_float_vector(ot->srna, "value", 2, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX); RNA_def_property_subtype(prop, PROP_ANGLE); - Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP); + Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_GPENCIL_EDIT); } static void TRANSFORM_OT_rotate(struct wmOperatorType *ot) @@ -675,7 +682,7 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot) prop = RNA_def_float(ot->srna, "value", 0.0f, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); RNA_def_property_subtype(prop, PROP_ANGLE); - Transform_Properties(ot, P_AXIS | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP); + Transform_Properties(ot, P_AXIS | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP | P_GPENCIL_EDIT); } static void TRANSFORM_OT_tilt(struct wmOperatorType *ot) @@ -721,7 +728,7 @@ static void TRANSFORM_OT_bend(struct wmOperatorType *ot) RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); - Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP); + Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_GPENCIL_EDIT); } static void TRANSFORM_OT_shear(struct wmOperatorType *ot) @@ -741,7 +748,7 @@ static void TRANSFORM_OT_shear(struct wmOperatorType *ot) RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX); - Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP); + Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_GPENCIL_EDIT); // XXX Shear axis? } @@ -803,7 +810,7 @@ static void TRANSFORM_OT_tosphere(struct wmOperatorType *ot) RNA_def_float_factor(ot->srna, "value", 0, 0, 1, "Factor", "", 0, 1); - Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP); + Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_GPENCIL_EDIT); } static void TRANSFORM_OT_mirror(struct wmOperatorType *ot) @@ -821,7 +828,7 @@ static void TRANSFORM_OT_mirror(struct wmOperatorType *ot) ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; - Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL); + Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_GPENCIL_EDIT); } static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot) @@ -1106,9 +1113,6 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac /* XXX release_confirm is set in the macro operator definition */ WM_keymap_add_item(keymap, "NODE_OT_move_detach_links_release", EVT_TWEAK_A, KM_ANY, KM_ALT, 0); WM_keymap_add_item(keymap, "NODE_OT_move_detach_links", EVT_TWEAK_S, KM_ANY, KM_ALT, 0); - - /* dettach and translate */ - WM_keymap_add_item(keymap, "NODE_OT_detach_translate_attach", FKEY, KM_PRESS, KM_ALT, 0); break; case SPACE_SEQ: WM_keymap_add_item(keymap, OP_SEQ_SLIDE, GKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index c7d63da8281..79262396fb4 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -24,7 +24,6 @@ * \ingroup edtransform */ - #include <string.h> #include <stddef.h> #include <ctype.h> @@ -57,10 +56,6 @@ #include "ED_armature.h" -#include "RNA_define.h" - -#include "UI_interface.h" - #include "transform.h" /* *********************** TransSpace ************************** */ @@ -392,7 +387,7 @@ void BIF_selectTransformOrientationValue(bContext *C, int orientation) int BIF_countTransformOrientation(const bContext *C) { ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; - return BLI_countlist(transform_spaces); + return BLI_listbase_count(transform_spaces); } bool applyTransformOrientation(const bContext *C, float mat[3][3], char *r_name) @@ -738,7 +733,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], v_pair_swap = true; } else if (eed && BM_edge_is_boundary(eed)) { - /* pradictable direction for boundary edges */ + /* predictable direction for boundary edges */ if (eed->l->v != v_pair[0]) { v_pair_swap = true; } diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 8a3e8f19db4..4a2927ace00 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -59,6 +59,7 @@ #include "BKE_anim.h" /* for duplis */ #include "BKE_context.h" #include "BKE_editmesh.h" +#include "BKE_sequencer.h" #include "BKE_main.h" #include "BKE_tracking.h" @@ -341,22 +342,15 @@ void applyProject(TransInfo *t) if (t->tsnap.align && (t->flag & T_OBJECT)) { /* handle alignment as well */ const float *original_normal; - float axis[3]; float mat[3][3]; - float angle; float totmat[3][3], smat[3][3]; - float eul[3], fmat[3][3], quat[4]; + float eul[3], fmat[3][3]; float obmat[3][3]; /* In pose mode, we want to align normals with Y axis of bones... */ original_normal = td->axismtx[2]; - cross_v3_v3v3(axis, original_normal, no); - angle = saacos(dot_v3v3(original_normal, no)); - - axis_angle_to_quat(quat, axis, angle); - - quat_to_mat3(mat, quat); + rotation_between_vecs_to_mat3(mat, original_normal, no); mul_m3_m3m3(totmat, mat, td->mtx); mul_m3_m3m3(smat, td->smtx, totmat); @@ -1543,8 +1537,7 @@ static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMes float ray_start_local[3], ray_normal_local[3], local_scale, len_diff = TRANSFORM_DIST_MAX_RAY; invert_m4_m4(imat, obmat); - copy_m3_m4(timat, imat); - transpose_m3(timat); + transpose_m3_m4(timat, imat); copy_v3_v3(ray_start_local, ray_start); copy_v3_v3(ray_normal_local, ray_normal); @@ -1956,21 +1949,32 @@ static bool snapObjectsRay(Scene *scene, short snap_mode, Base *base_act, View3D (ELEM(mode, SNAP_ALL, SNAP_NOT_OBEDIT) && base != base_act))) { Object *ob = base->object; - + Object *ob_snap = ob; + bool use_obedit = false; + + /* for linked objects, use the same object but a different matrix */ + if (obedit && ob->data == obedit->data) { + use_obedit = true; + ob_snap = obedit; + } + if (ob->transflag & OB_DUPLI) { DupliObject *dupli_ob; ListBase *lb = object_duplilist(G.main->eval_ctx, scene, ob); for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { - retval |= snapObject(scene, snap_mode, ar, dupli_ob->ob, dupli_ob->mat, false, + bool use_obedit_dupli = (obedit && dupli_ob->ob->data == obedit->data); + Object *dupli_snap = (use_obedit_dupli) ? obedit : dupli_ob->ob; + + retval |= snapObject(scene, snap_mode, ar, dupli_snap, dupli_ob->mat, use_obedit_dupli, r_ob, r_obmat, ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_ray_dist); } free_object_duplilist(lb); } - - retval |= snapObject(scene, snap_mode, ar, ob, ob->obmat, false, + + retval |= snapObject(scene, snap_mode, ar, ob_snap, ob->obmat, use_obedit, r_ob, r_obmat, ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_ray_dist); } @@ -2101,8 +2105,7 @@ static bool peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[4][4], invert_m4_m4(imat, obmat); - copy_m3_m4(timat, imat); - transpose_m3(timat); + transpose_m3_m4(timat, imat); copy_v3_v3(ray_start_local, ray_start); copy_v3_v3(ray_normal_local, ray_normal); @@ -2265,7 +2268,7 @@ static bool peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, } } - BLI_sortlist(depth_peels, cmpPeel); + BLI_listbase_sort(depth_peels, cmpPeel); removeDoublesPeel(depth_peels); return retval; @@ -2428,6 +2431,27 @@ void snapGridIncrement(TransInfo *t, float *val) snapGridIncrementAction(t, val, action); } +int snapSequenceBounds(TransInfo *t, const int mval[2]) +{ + float xmouse, ymouse; + int frame; + int mframe; + TransSeq *ts = t->customData; + /* reuse increment, strictly speaking could be another snap mode, but leave as is */ + if (!(t->modifiers & MOD_SNAP_INVERT)) + return 0; + + /* convert to frame range */ + UI_view2d_region_to_view(&t->ar->v2d, mval[0], mval[1], &xmouse, &ymouse); + mframe = iroundf(xmouse); + /* now find the closest sequence */ + frame = BKE_sequencer_find_next_prev_edit(t->scene, mframe, SEQ_SIDE_BOTH, true, false, true); + + if (!ts->snap_left) + frame = frame - (ts->max - ts->min); + + return frame; +} static void applyGridIncrement(TransInfo *t, float *val, int max_index, const float fac[3], GearsType action) { @@ -2455,6 +2479,19 @@ static void applyGridIncrement(TransInfo *t, float *val, int max_index, const fl ED_space_image_get_uv_aspect(t->sa->spacedata.first, asp, asp + 1); } } + else if ((t->spacetype == SPACE_IPO) && (t->mode == TFM_TRANSLATION)) { + View2D *v2d = &t->ar->v2d; + View2DGrid *grid; + SpaceIpo *sipo = t->sa->spacedata.first; + int unity = V2D_UNIT_VALUES; + int unitx = (sipo->flag & SIPO_DRAWTIME) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMESCALE; + + /* grid */ + grid = UI_view2d_grid_calc(t->scene, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP, t->ar->winx, t->ar->winy); + + UI_view2d_grid_size(grid, &asp[0], &asp[1]); + UI_view2d_grid_free(grid); + } for (i = 0; i <= max_index; i++) { val[i] = fac[action] * asp[i] * floorf(val[i] / (fac[action] * asp[i]) + 0.5f); diff --git a/source/blender/editors/util/ed_transverts.c b/source/blender/editors/util/ed_transverts.c index 104b628c25a..c3eef94f4bb 100644 --- a/source/blender/editors/util/ed_transverts.c +++ b/source/blender/editors/util/ed_transverts.c @@ -310,7 +310,7 @@ void ED_transverts_create_from_obedit(TransVertStore *tvs, Object *obedit, const } else if (obedit->type == OB_ARMATURE) { bArmature *arm = obedit->data; - int totmalloc = BLI_countlist(arm->edbo); + int totmalloc = BLI_listbase_count(arm->edbo); totmalloc *= 2; /* probably overkill but bones can have 2 trans verts each */ @@ -441,7 +441,7 @@ void ED_transverts_create_from_obedit(TransVertStore *tvs, Object *obedit, const } else if (obedit->type == OB_MBALL) { MetaBall *mb = obedit->data; - int totmalloc = BLI_countlist(mb->editelems); + int totmalloc = BLI_listbase_count(mb->editelems); tv = tvs->transverts = MEM_callocN(totmalloc * sizeof(TransVert), __func__); diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index ec0471da8d3..86b96968047 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -218,8 +218,8 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha char line[FILE_MAX + 100]; wmOperatorType *ot = WM_operatortype_find(opname, 1); - pup = uiPupMenuBegin(C, IFACE_("Unpack File"), ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, IFACE_("Unpack File"), ICON_NONE); + layout = UI_popup_menu_layout(pup); props_ptr = uiItemFullO_ptr(layout, ot, IFACE_("Remove Pack"), ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); @@ -295,7 +295,7 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha break; } - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); } /* ********************* generic callbacks for drawcall api *********************** */ diff --git a/source/blender/editors/util/editmode_undo.c b/source/blender/editors/util/editmode_undo.c index ef95e4cb3ff..2428ee21367 100644 --- a/source/blender/editors/util/editmode_undo.c +++ b/source/blender/editors/util/editmode_undo.c @@ -48,8 +48,6 @@ #include "ED_util.h" #include "ED_mesh.h" -#include "UI_interface.h" -#include "UI_resources.h" #include "util_intern.h" diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c index a154f12a786..050631362b4 100644 --- a/source/blender/editors/util/numinput.c +++ b/source/blender/editors/util/numinput.c @@ -103,7 +103,7 @@ void outputNumInput(NumInput *n, char *str, UnitSettings *unit_settings) if (n->val_flag[i] & NUM_EDITED) { /* Get the best precision, allows us to draw '10.0001' as '10' instead! */ - prec = uiFloatPrecisionCalc(prec, (double)n->val[i]); + prec = UI_calc_float_precision(prec, (double)n->val[i]); if (i == n->idx) { const char *heading_exp = "", *trailing_exp = ""; char before_cursor[NUM_STR_REP_LEN]; diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c index 189a938e3d8..fac57490b44 100644 --- a/source/blender/editors/util/undo.c +++ b/source/blender/editors/util/undo.c @@ -29,8 +29,6 @@ * \ingroup edutil */ - - #include <stdlib.h> #include <string.h> #include <math.h> @@ -47,6 +45,7 @@ #include "BKE_blender.h" #include "BKE_context.h" #include "BKE_global.h" +#include "BKE_main.h" #include "BKE_screen.h" #include "ED_armature.h" @@ -124,6 +123,7 @@ static int ed_undo_step(bContext *C, int step, const char *undoname) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); + Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Object *obedit = CTX_data_edit_object(C); Object *obact = CTX_data_active_object(C); @@ -146,7 +146,7 @@ static int ed_undo_step(bContext *C, int step, const char *undoname) if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) { if (!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname) && undoname) { if (U.uiflag & USER_GLOBALUNDO) { - ED_viewport_render_kill_jobs(C, true); + ED_viewport_render_kill_jobs(wm, bmain, true); BKE_undo_name(C, undoname); } } @@ -199,7 +199,7 @@ static int ed_undo_step(bContext *C, int step, const char *undoname) /* for example, texface stores image pointers */ undo_editmode_clear(); - ED_viewport_render_kill_jobs(C, true); + ED_viewport_render_kill_jobs(wm, bmain, true); if (undoname) BKE_undo_name(C, undoname); @@ -379,7 +379,7 @@ int ED_undo_operator_repeat(bContext *C, struct wmOperator *op) { int retval; - ED_viewport_render_kill_jobs(C, true); + ED_viewport_render_kill_jobs(wm, CTX_data_main(C), true); if (G.debug & G_DEBUG) printf("redo_cb: operator redo %s\n", op->type->name); @@ -536,8 +536,8 @@ static int undo_history_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE EnumPropertyItem *item = rna_undo_itemf(C, undosys, &totitem); if (totitem > 0) { - uiPopupMenu *pup = uiPupMenuBegin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE); - uiLayout *layout = uiPupMenuLayout(pup); + uiPopupMenu *pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE); + uiLayout *layout = UI_popup_menu_layout(pup); uiLayout *split = uiLayoutSplit(layout, 0.0f, false); uiLayout *column = NULL; const int col_size = 20 + totitem / 12; @@ -558,7 +558,7 @@ static int undo_history_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE MEM_freeN(item); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); } } @@ -583,7 +583,7 @@ static int undo_history_exec(bContext *C, wmOperator *op) ED_undo_paint_step_num(C, UNDO_PAINT_IMAGE, item ); } else { - ED_viewport_render_kill_jobs(C, true); + ED_viewport_render_kill_jobs(CTX_wm_manager(C), CTX_data_main(C), true); BKE_undo_number(C, item); WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, CTX_data_scene(C)); } diff --git a/source/blender/editors/uvedit/uvedit_buttons.c b/source/blender/editors/uvedit/uvedit_buttons.c index 6816e785c1f..a15259e7d2d 100644 --- a/source/blender/editors/uvedit/uvedit_buttons.c +++ b/source/blender/editors/uvedit/uvedit_buttons.c @@ -53,7 +53,6 @@ #include "ED_uvedit.h" #include "UI_interface.h" -#include "UI_resources.h" #include "WM_api.h" #include "WM_types.h" @@ -158,12 +157,12 @@ static void uvedit_vertex_buttons(const bContext *C, uiBlock *block) digits = 2; } - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_UVEDIT_VERTEX, IFACE_("X:"), 0, 0, width, UI_UNIT_Y, &uvedit_old_center[0], + UI_block_align_begin(block); + uiDefButF(block, UI_BTYPE_NUM, B_UVEDIT_VERTEX, IFACE_("X:"), 0, 0, width, UI_UNIT_Y, &uvedit_old_center[0], -10 * imx, 10.0 * imx, step, digits, ""); - uiDefButF(block, NUM, B_UVEDIT_VERTEX, IFACE_("Y:"), width, 0, width, UI_UNIT_Y, &uvedit_old_center[1], + uiDefButF(block, UI_BTYPE_NUM, B_UVEDIT_VERTEX, IFACE_("Y:"), width, 0, width, UI_UNIT_Y, &uvedit_old_center[1], -10 * imy, 10.0 * imy, step, digits, ""); - uiBlockEndAlign(block); + UI_block_align_end(block); } } @@ -212,7 +211,7 @@ static void image_panel_uv(const bContext *C, Panel *pa) uiBlock *block; block = uiLayoutAbsoluteBlock(pa->layout); - uiBlockSetHandleFunc(block, do_uvedit_vertex, NULL); + UI_block_func_handle_set(block, do_uvedit_vertex, NULL); uvedit_vertex_buttons(C, block); } diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 83fd7e6505d..b2c4970479a 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -43,7 +43,6 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_alloca.h" #include "BLI_buffer.h" #include "BLI_bitmap.h" @@ -71,7 +70,7 @@ static void draw_uvs_lineloop_bmface(BMFace *efa, const int cd_loop_uv_offset); -void draw_image_cursor(ARegion *ar, const float cursor[2]) +void ED_image_draw_cursor(ARegion *ar, const float cursor[2]) { float zoom[2], x_fac, y_fac; @@ -325,7 +324,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); a = fabsf(uvang[i] - ang[i]) / (float)M_PI; - weight_to_rgb(col, 1.0f - powf((1.0f - a), 2.0f)); + weight_to_rgb(col, 1.0f - pow2f(1.0f - a)); glColor3fv(col); glVertex2fv(luv->uv); } @@ -506,6 +505,8 @@ static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, Object *ob) mloopuv_base = mloopuv; for (a = me->totpoly; a > 0; a--, mpoly++) { + if ((scene->toolsettings->uv_flag & UV_SHOW_SAME_IMAGE) && mpoly->mat_nr != ob->actcol - 1) + continue; glBegin(GL_LINE_LOOP); mloopuv = mloopuv_base + mpoly->loopstart; @@ -963,7 +964,7 @@ static void draw_uv_shadows_get(SpaceImage *sima, Object *ob, Object *obedit, bo *show_texpaint = (ob && ob->type == OB_MESH && ob->mode == OB_MODE_TEXTURE_PAINT); } -void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedit, Object *obact) +void ED_uvedit_draw_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedit, Object *obact) { ToolSettings *toolsettings = scene->toolsettings; bool show_uvedit, show_uvshadow, show_texpaint_uvshadow; @@ -980,7 +981,7 @@ void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedi draw_uvs_texpaint(sima, scene, obact); if (show_uvedit && !(toolsettings->use_uv_sculpt)) - draw_image_cursor(ar, sima->cursor); + ED_image_draw_cursor(ar, sima->cursor); } } diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index 52365ff3478..d1fd8d969a4 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -41,6 +41,7 @@ struct SpaceImage; struct UvElementMap; struct wmOperatorType; struct BMEditMesh; +struct BMesh; struct BMFace; struct BMLoop; struct BMEdge; @@ -71,7 +72,6 @@ void uv_find_nearest_edge(struct Scene *scene, struct Image *ima, struct BMEditM /* utility tool functions */ void uvedit_live_unwrap_update(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit); -void uvedit_get_aspect(struct Scene *scene, struct Object *ob, struct BMEditMesh *em, float *aspx, float *aspy); /* operators */ diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 4b341547370..c70fcdbbd94 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -668,6 +668,24 @@ bool ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float r_min[2], return changed; } +/* Be careful when using this, it bypasses all synchronization options */ +void ED_uvedit_select_all(BMesh *bm) +{ + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MLoopUV *luv; + + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + luv->flag |= MLOOPUV_VERTSEL; + } + } +} + static bool ED_uvedit_median(Scene *scene, Image *ima, Object *obedit, float co[2]) { BMEditMesh *em = BKE_editmesh_from_object(obedit); @@ -1291,10 +1309,10 @@ static int uv_select_more_less(bContext *C, const bool select) if (ts->uv_flag & UV_SYNC_SELECTION) { if (select) { - EDBM_select_more(em); + EDBM_select_more(em, true); } else { - EDBM_select_less(em); + EDBM_select_less(em, true); } WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); @@ -1753,7 +1771,7 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op) if ((vert_arr[uv_b_index].weld == false) && (len_manhattan_v2v2(uv_a, uv_b) < threshold)) { - minmax_v2v2_v2(uv_max, uv_min, uv_b); + minmax_v2v2_v2(uv_min, uv_max, uv_b); BLI_array_append(loop_arr, vert_arr[uv_b_index].uv_loop); vert_arr[uv_b_index].weld = true; } @@ -3171,8 +3189,8 @@ static void UV_OT_select_lasso(wmOperatorType *ot) static void uv_snap_to_pixel(float uvco[2], float w, float h) { - uvco[0] = ((float)((int)((uvco[0] * w) + 0.5f))) / w; - uvco[1] = ((float)((int)((uvco[1] * h) + 0.5f))) / h; + uvco[0] = roundf(uvco[0] * w) / w; + uvco[1] = roundf(uvco[1] * h) / h; } static void uv_snap_cursor_to_pixels(SpaceImage *sima) @@ -3859,6 +3877,15 @@ static int uv_set_2d_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *e ARegion *ar = CTX_wm_region(C); float location[2]; + if (ar->regiontype == RGN_TYPE_WINDOW) { + if (event->mval[1] <= 16) { + SpaceImage *sima = CTX_wm_space_image(C); + if (sima && ED_space_image_show_cache(sima)) { + return OPERATOR_PASS_THROUGH; + } + } + } + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &location[0], &location[1]); RNA_float_set_array(op->ptr, "location", location); diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index 79f53e1d971..d054ccc1a85 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -35,7 +35,6 @@ #include "BLI_boxpack2d.h" #include "BLI_convexhull2d.h" -#include "uvedit_intern.h" #include "uvedit_parametrizer.h" #include <math.h> @@ -4194,7 +4193,7 @@ void param_delete(ParamHandle *handle) static void p_add_ngon(ParamHandle *handle, ParamKey key, int nverts, ParamKey *vkeys, float **co, float **uv, - ParamBool *pin, ParamBool *select, float normal[3]) + ParamBool *pin, ParamBool *select, const float normal[3]) { int *boundary = BLI_array_alloca(boundary, nverts); int i; diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index fcd5267fd44..eab3d5965f6 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -1660,7 +1660,7 @@ static int stitch_init(bContext *C, wmOperator *op) return 0; } - uvedit_get_aspect(scene, obedit, em, &aspx, &aspy); + ED_uvedit_get_aspect(scene, obedit, em->bm, &aspx, &aspy); state->aspect = aspx / aspy; /* Entirely possible if redoing last operator that static island is bigger than total number of islands. diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 335d8e6589e..b5e27ab0cf6 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -190,21 +190,21 @@ static bool uvedit_have_selection(Scene *scene, BMEditMesh *em, bool implicit) return false; } -void uvedit_get_aspect(Scene *scene, Object *ob, BMEditMesh *em, float *aspx, float *aspy) +void ED_uvedit_get_aspect(Scene *scene, Object *ob, BMesh *bm, float *aspx, float *aspy) { bool sloppy = true; bool selected = false; BMFace *efa; Image *ima; - efa = BM_mesh_active_face_get(em->bm, sloppy, selected); + efa = BM_mesh_active_face_get(bm, sloppy, selected); if (efa) { if (BKE_scene_use_new_shading_nodes(scene)) { ED_object_get_active_image(ob, efa->mat_nr + 1, &ima, NULL, NULL, NULL); } else { - MTexPoly *tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + MTexPoly *tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY); ima = tf->tpage; } @@ -247,11 +247,10 @@ static void construct_param_handle_face_add(ParamHandle *handle, Scene *scene, param_face_add(handle, key, i, vkeys, co, uv, pin, select, efa->no); } -static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh *em, +static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMesh *bm, const bool implicit, const bool fill, const bool sel, const bool correct_aspect) { - BMesh *bm = em->bm; ParamHandle *handle; BMFace *efa; BMLoop *l; @@ -262,20 +261,19 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh handle = param_construct_begin(); - if (correct_aspect) { float aspx, aspy; - uvedit_get_aspect(scene, ob, em, &aspx, &aspy); + ED_uvedit_get_aspect(scene, ob, bm, &aspx, &aspy); if (aspx != aspy) param_aspect_ratio(handle, aspx, aspy); } /* we need the vert indices */ - BM_mesh_elem_index_ensure(em->bm, BM_VERT); + BM_mesh_elem_index_ensure(bm, BM_VERT); - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || (sel && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) { continue; @@ -299,7 +297,7 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh } if (!implicit) { - BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { + BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SEAM)) { ParamKey vkeys[2]; vkeys[0] = (ParamKey)BM_elem_index_get(eed->v1); @@ -378,7 +376,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B if (correct_aspect) { float aspx, aspy; - uvedit_get_aspect(scene, ob, em, &aspx, &aspy); + ED_uvedit_get_aspect(scene, ob, em->bm, &aspx, &aspy); if (aspx != aspy) param_aspect_ratio(handle, aspx, aspy); @@ -522,7 +520,7 @@ static bool minimize_stretch_init(bContext *C, wmOperator *op) ms->blend = RNA_float_get(op->ptr, "blend"); ms->iterations = RNA_int_get(op->ptr, "iterations"); ms->i = 0; - ms->handle = construct_param_handle(scene, obedit, em, implicit, fill_holes, 1, 1); + ms->handle = construct_param_handle(scene, obedit, em->bm, implicit, fill_holes, 1, 1); ms->lasttime = PIL_check_seconds_timer(); param_stretch_begin(ms->handle); @@ -701,16 +699,23 @@ void UV_OT_minimize_stretch(wmOperatorType *ot) /* ******************** Pack Islands operator **************** */ +void ED_uvedit_pack_islands(Scene *scene, Object *ob, BMesh *bm, bool selected, bool correct_aspect, bool do_rotate) +{ + ParamHandle *handle; + handle = construct_param_handle(scene, ob, bm, true, false, selected, correct_aspect); + param_pack(handle, scene->toolsettings->uvcalc_margin, do_rotate); + param_flush(handle); + param_delete(handle); +} + static int pack_islands_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); - ParamHandle *handle; - bool implicit = true; bool do_rotate = RNA_boolean_get(op->ptr, "rotate"); - if (!uvedit_have_selection(scene, em, implicit)) { + if (!uvedit_have_selection(scene, em, true)) { return OPERATOR_CANCELLED; } @@ -719,10 +724,7 @@ static int pack_islands_exec(bContext *C, wmOperator *op) else RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin); - handle = construct_param_handle(scene, obedit, em, implicit, 0, 1, 1); - param_pack(handle, scene->toolsettings->uvcalc_margin, do_rotate); - param_flush(handle); - param_delete(handle); + ED_uvedit_pack_islands(scene, obedit, em->bm, true, true, do_rotate); DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); @@ -762,7 +764,7 @@ static int average_islands_scale_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_CANCELLED; } - handle = construct_param_handle(scene, obedit, em, implicit, 0, 1, 1); + handle = construct_param_handle(scene, obedit, em->bm, implicit, 0, 1, 1); param_average(handle); param_flush(handle); param_delete(handle); @@ -807,7 +809,7 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit) if (use_subsurf) liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, false, true); else - liveHandle = construct_param_handle(scene, obedit, em, false, fillholes, false, true); + liveHandle = construct_param_handle(scene, obedit, em->bm, false, fillholes, false, true); param_lscm_begin(liveHandle, PARAM_TRUE, abf); } @@ -1008,7 +1010,7 @@ static void correct_uv_aspect(Scene *scene, Object *ob, BMEditMesh *em) const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - uvedit_get_aspect(scene, ob, em, &aspx, &aspy); + ED_uvedit_get_aspect(scene, ob, em->bm, &aspx, &aspy); if (aspx == aspy) return; @@ -1072,7 +1074,7 @@ static void uv_map_clip_correct(Scene *scene, Object *ob, BMEditMesh *em, wmOper if (scale_to_bounds) { INIT_MINMAX2(min, max); - + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) continue; @@ -1082,7 +1084,7 @@ static void uv_map_clip_correct(Scene *scene, Object *ob, BMEditMesh *em, wmOper minmax_v2v2_v2(min, max, luv->uv); } } - + /* rescale UV to be in 1/1 */ dx = (max[0] - min[0]); dy = (max[1] - min[1]); @@ -1098,7 +1100,7 @@ static void uv_map_clip_correct(Scene *scene, Object *ob, BMEditMesh *em, wmOper BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - + luv->uv[0] = (luv->uv[0] - min[0]) * dx; luv->uv[1] = (luv->uv[1] - min[1]) * dy; } @@ -1136,7 +1138,7 @@ void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel) if (use_subsurf) handle = construct_param_handle_subsurfed(scene, obedit, em, fill_holes, sel, correct_aspect); else - handle = construct_param_handle(scene, obedit, em, false, fill_holes, sel, correct_aspect); + handle = construct_param_handle(scene, obedit, em->bm, false, fill_holes, sel, correct_aspect); param_lscm_begin(handle, PARAM_FALSE, scene->toolsettings->unwrapper == 0); param_lscm_solve(handle); @@ -1599,39 +1601,30 @@ void UV_OT_cylinder_project(wmOperatorType *ot) /******************* Cube Project operator ****************/ -static int cube_project_exec(bContext *C, wmOperator *op) +void ED_uvedit_unwrap_cube_project(Object *ob, BMesh *bm, float cube_size, bool use_select) { - Scene *scene = CTX_data_scene(C); - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BKE_editmesh_from_object(obedit); BMFace *efa; BMLoop *l; BMIter iter, liter; /* MTexPoly *tf; */ /* UNUSED */ MLoopUV *luv; - float cube_size, *loc, dx, dy; + float *loc, dx, dy; int cox, coy; int cd_loop_uv_offset; - /* add uvs if they don't exist yet */ - if (!ED_uvedit_ensure_uvs(C, scene, obedit)) { - return OPERATOR_CANCELLED; - } + cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); - cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - - loc = obedit->obmat[3]; - cube_size = RNA_float_get(op->ptr, "cube_size"); + loc = ob->obmat[3]; /* choose x,y,z axis for projection depending on the largest normal * component, but clusters all together around the center of map. */ - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { int first = 1; /* tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */ - if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) + if (use_select && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) continue; axis_dominant_v3(&cox, &coy, efa->no); @@ -1642,19 +1635,34 @@ static int cube_project_exec(bContext *C, wmOperator *op) luv->uv[0] = 0.5f + 0.5f * cube_size * (loc[cox] + l->v->co[cox]); luv->uv[1] = 0.5f + 0.5f * cube_size * (loc[coy] + l->v->co[coy]); - + if (first) { dx = floor(luv->uv[0]); dy = floor(luv->uv[1]); first = 0; } - + luv->uv[0] -= dx; luv->uv[1] -= dy; } } +} + +static int cube_project_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + float cube_size = RNA_float_get(op->ptr, "cube_size"); + + /* add uvs if they don't exist yet */ + if (!ED_uvedit_ensure_uvs(C, scene, obedit)) { + return OPERATOR_CANCELLED; + } + + ED_uvedit_unwrap_cube_project(obedit, em->bm, cube_size, true); uv_map_clip_correct(scene, obedit, em, op); DAG_id_tag_update(obedit->data, 0); diff --git a/source/blender/freestyle/intern/application/AppConfig.cpp b/source/blender/freestyle/intern/application/AppConfig.cpp index cf7959ffaef..44f8e9b135e 100644 --- a/source/blender/freestyle/intern/application/AppConfig.cpp +++ b/source/blender/freestyle/intern/application/AppConfig.cpp @@ -31,7 +31,7 @@ using namespace std; extern "C" { -#include "BLI_path_util.h" +#include "BKE_appdir.h" } namespace Freestyle { @@ -43,7 +43,7 @@ Path::Path() { // get the root directory // soc - setRootDir(BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, NULL)); + setRootDir(BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, NULL)); _pInstance = this; } diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp index 7ecb4164caf..237176df5e3 100644 --- a/source/blender/freestyle/intern/application/Controller.cpp +++ b/source/blender/freestyle/intern/application/Controller.cpp @@ -67,6 +67,7 @@ extern "C" { #include "BKE_global.h" #include "BLI_utildefines.h" +#include "BLI_path_util.h" #include "DNA_freestyle_types.h" @@ -219,11 +220,10 @@ bool Controller::hitViewMapCache() if (!_EnableViewMapCache) { return false; } - real hashCode = sceneHashFunc.getValue(); - if (prevSceneHash == hashCode) { + if (sceneHashFunc.match()) { return (NULL != _ViewMap); } - prevSceneHash = hashCode; + sceneHashFunc.store(); return false; } @@ -280,10 +280,26 @@ int Controller::LoadMesh(Render *re, SceneRenderLayer *srl) return 0; if (_EnableViewMapCache) { + + NodeCamera *cam; + if (freestyle_proj[3][3] != 0.0) + cam = new NodeOrthographicCamera; + else + cam = new NodePerspectiveCamera; + double proj[16]; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + proj[i * 4 + j] = freestyle_proj[i][j]; + } + } + cam->setProjectionMatrix(proj); + _RootNode->AddChild(cam); + sceneHashFunc.reset(); - blenderScene->accept(sceneHashFunc); + //blenderScene->accept(sceneHashFunc); + _RootNode->accept(sceneHashFunc); if (G.debug & G_DEBUG_FREESTYLE) { - printf("Scene hash : %.16e\n", sceneHashFunc.getValue()); + cout << "Scene hash : " << sceneHashFunc.toString() << endl; } if (hitViewMapCache()) { ClearRootNode(); diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp index 57882cbce0c..dfcc77d3b23 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -457,6 +457,7 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id) unsigned nSize = vSize; float *normals = new float[nSize]; unsigned *numVertexPerFaces = new unsigned[numFaces]; + vector<Material *> meshMaterials; vector<FrsMaterial> meshFrsMaterials; IndexedFaceSet::TRIANGLES_STYLE *faceStyle = new IndexedFaceSet::TRIANGLES_STYLE[numFaces]; @@ -588,20 +589,21 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id) tmpMat.setPriority(mat->line_priority); } - if (meshFrsMaterials.empty()) { + if (meshMaterials.empty()) { + meshMaterials.push_back(mat); meshFrsMaterials.push_back(tmpMat); shape->setFrsMaterial(tmpMat); } else { - // find if the material is already in the list + // find if the Blender material is already in the list unsigned int i = 0; bool found = false; - for (vector<FrsMaterial>::iterator it = meshFrsMaterials.begin(), itend = meshFrsMaterials.end(); + for (vector<Material *>::iterator it = meshMaterials.begin(), itend = meshMaterials.end(); it != itend; it++, i++) { - if (*it == tmpMat) { + if (*it == mat) { ls.currentMIndex = i; found = true; break; @@ -609,6 +611,7 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id) } if (!found) { + meshMaterials.push_back(mat); meshFrsMaterials.push_back(tmpMat); ls.currentMIndex = meshFrsMaterials.size() - 1; } diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index 456118d4d2f..09701ab6acd 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -448,7 +448,7 @@ void BlenderStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const BLI_ghash_insert(_nodetree_hash, nt, ma); } - if (strcmp(freestyle_scene->r.engine, "CYCLES") == 0) { + if (STREQ(freestyle_scene->r.engine, RE_engine_id_CYCLES)) { PointerRNA scene_ptr, freestyle_scene_ptr; RNA_pointer_create(NULL, &RNA_Scene, old_scene, &scene_ptr); RNA_pointer_create(NULL, &RNA_Scene, freestyle_scene, &freestyle_scene_ptr); diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp index 4dd4598cc91..cfadf80dcf6 100644 --- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp +++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp @@ -182,7 +182,7 @@ static void init_camera(Render *re) { // It is assumed that imported meshes are in the camera coordinate system. // Therefore, the view point (i.e., camera position) is at the origin, and - // the the model-view matrix is simply the identity matrix. + // the model-view matrix is simply the identity matrix. freestyle_viewpoint[0] = 0.0; freestyle_viewpoint[1] = 0.0; diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp index 5b8d50eb5eb..ee0e7dfab3e 100644 --- a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp +++ b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp @@ -60,6 +60,7 @@ extern "C" { #include "FRS_freestyle.h" #include "RNA_access.h" +#include "BKE_appdir.h" #include "DNA_scene_types.h" #include "bpy_rna.h" /* pyrna_struct_CreatePyObject() */ @@ -492,7 +493,7 @@ PyObject *Freestyle_Init(void) PyDict_SetItemString(PySys_GetObject("modules"), module_definition.m_name, module); // update 'sys.path' for Freestyle Python API modules - const char * const path = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, "freestyle"); + const char * const path = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, "freestyle"); if (path) { char modpath[FILE_MAX]; BLI_join_dirfile(modpath, sizeof(modpath), path, "modules"); diff --git a/source/blender/freestyle/intern/scene_graph/NodeCamera.h b/source/blender/freestyle/intern/scene_graph/NodeCamera.h index 5d84a624830..78c34fdef6d 100644 --- a/source/blender/freestyle/intern/scene_graph/NodeCamera.h +++ b/source/blender/freestyle/intern/scene_graph/NodeCamera.h @@ -53,7 +53,9 @@ public: /*! Default matrices: Identity for both projection and modelview. */ NodeCamera(CameraType camera_type = GENERIC); +#if 0 /* UNUSED, gives warning in gcc */ NodeCamera(const NodeCamera& iBrother); +#endif virtual ~NodeCamera() {} diff --git a/source/blender/freestyle/intern/scene_graph/SceneHash.cpp b/source/blender/freestyle/intern/scene_graph/SceneHash.cpp index 6e8856f1b93..60b95aaf6c5 100644 --- a/source/blender/freestyle/intern/scene_graph/SceneHash.cpp +++ b/source/blender/freestyle/intern/scene_graph/SceneHash.cpp @@ -24,16 +24,47 @@ #include "SceneHash.h" +#include <sstream> + namespace Freestyle { +string SceneHash::toString() +{ + stringstream ss; + ss << hex << _sum; + return ss.str(); +} + +void SceneHash::visitNodeCamera(NodeCamera& cam) +{ + double *proj = cam.projectionMatrix(); + for (int i = 0; i < 16; i++) { + adler32((unsigned char *)&proj[i], sizeof(double)); + } +} + void SceneHash::visitIndexedFaceSet(IndexedFaceSet& ifs) { const real *v = ifs.vertices(); const unsigned n = ifs.vsize(); for (unsigned i = 0; i < n; i++) { - _hashcode += v[i]; + adler32((unsigned char *)&v[i], sizeof(v[i])); + } +} + +static const int MOD_ADLER = 65521; + +void SceneHash::adler32(unsigned char *data, int size) +{ + uint32_t sum1 = _sum & 0xffff; + uint32_t sum2 = (_sum >> 16) & 0xffff; + + for (int i = 0; i < size; i++) { + sum1 = (sum1 + data[i]) % MOD_ADLER; + sum2 = (sum1 + sum2) % MOD_ADLER; } + _sum = sum1 | (sum2 << 16); } } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/scene_graph/SceneHash.h b/source/blender/freestyle/intern/scene_graph/SceneHash.h index 8f5f847eaab..5521b792e89 100644 --- a/source/blender/freestyle/intern/scene_graph/SceneHash.h +++ b/source/blender/freestyle/intern/scene_graph/SceneHash.h @@ -26,8 +26,11 @@ */ #include "IndexedFaceSet.h" +#include "NodeCamera.h" #include "SceneVisitor.h" +#include "BLI_sys_types.h" + #ifdef WITH_CXX_GUARDEDALLOC #include "MEM_guardedalloc.h" #endif @@ -39,23 +42,33 @@ class SceneHash : public SceneVisitor public: inline SceneHash() : SceneVisitor() { - _hashcode = 0.0; + _sum = 1; } virtual ~SceneHash() {} + VISIT_DECL(NodeCamera) VISIT_DECL(IndexedFaceSet) - inline real getValue() { - return _hashcode; + string toString(); + + inline bool match() { + return _sum == _prevSum; + } + + inline void store() { + _prevSum = _sum; } inline void reset() { - _hashcode = 0.0; + _sum = 1; } private: - real _hashcode; + void adler32(unsigned char *data, int size); + + uint32_t _sum; + uint32_t _prevSum; #ifdef WITH_CXX_GUARDEDALLOC MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SceneHash") diff --git a/source/blender/freestyle/intern/stroke/ChainingIterators.h b/source/blender/freestyle/intern/stroke/ChainingIterators.h index 5d05ed2776d..4ece24c5ecf 100644 --- a/source/blender/freestyle/intern/stroke/ChainingIterators.h +++ b/source/blender/freestyle/intern/stroke/ChainingIterators.h @@ -101,7 +101,7 @@ public: return _internalIterator.isBegin(); } - /*! Returns true if the current ViewEdge is is coming towards the iteration vertex. False otherwise. */ + /*! Returns true if the current ViewEdge is coming towards the iteration vertex. False otherwise. */ bool isIncoming() const; /*! Returns a *pointer* to the pointed ViewEdge. */ diff --git a/source/blender/freestyle/intern/stroke/Curve.cpp b/source/blender/freestyle/intern/stroke/Curve.cpp index 32cfac016d6..69c5dcdfe28 100644 --- a/source/blender/freestyle/intern/stroke/Curve.cpp +++ b/source/blender/freestyle/intern/stroke/Curve.cpp @@ -25,6 +25,8 @@ * \date 11/01/2003 */ +#include <stdio.h> /* printf */ + #include "Curve.h" #include "CurveIterators.h" #include "CurveAdvancedIterators.h" diff --git a/source/blender/freestyle/intern/system/StringUtils.h b/source/blender/freestyle/intern/system/StringUtils.h index 77b543c7886..e11798762e4 100644 --- a/source/blender/freestyle/intern/system/StringUtils.h +++ b/source/blender/freestyle/intern/system/StringUtils.h @@ -36,7 +36,8 @@ extern "C" { #include "BKE_utildefines.h" -#include "BLI_blenlib.h" +#include "BLI_string.h" +#include "BLI_path_util.h" } using namespace std; diff --git a/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp b/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp index a5e526fc490..9827ec68c5d 100644 --- a/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp +++ b/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp @@ -497,7 +497,7 @@ void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace) } } } - // Once we have K1 along the the ppal direction compute the derivative : K1b - K1a put it in DotP + // Once we have K1 along the ppal direction compute the derivative : K1b - K1a put it in DotP //real d = fabs(K1_b) - fabs(K1_a); real d = 0; real threshold = _meanK1 + (_maxK1 - _meanK1) / 7.0; diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 63eea9486ed..361c247767f 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -73,6 +73,7 @@ data_to_c_simple(shaders/gpu_shader_sep_gaussian_blur_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_simple_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_simple_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_vertex.glsl SRC) +data_to_c_simple(shaders/gpu_shader_vertex_world.glsl SRC) data_to_c_simple(shaders/gpu_shader_vsm_store_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_vsm_store_vert.glsl SRC) diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index ba461d5f8a2..e9b600a9267 100644 --- a/source/blender/gpu/GPU_buffers.h +++ b/source/blender/gpu/GPU_buffers.h @@ -54,6 +54,7 @@ typedef struct GPUBuffer { int size; /* in bytes */ void *pointer; /* used with vertex arrays */ unsigned int id; /* used with vertex buffer objects */ + bool use_vbo; /* true for VBOs, false for vertex arrays */ } GPUBuffer; typedef struct GPUBufferMaterial { @@ -85,6 +86,7 @@ typedef struct GPUDrawObject { GPUBuffer *points; GPUBuffer *normals; GPUBuffer *uv; + GPUBuffer *uv_tex; GPUBuffer *colors; GPUBuffer *edges; GPUBuffer *uvedges; @@ -113,10 +115,6 @@ typedef struct GPUDrawObject { /* caches of the original DerivedMesh values */ int totvert; int totedge; - - /* if there was a failure allocating some buffer, use old - * rendering code */ - bool legacy; } GPUDrawObject; /* used for GLSL materials */ @@ -129,7 +127,7 @@ typedef struct GPUAttrib { void GPU_global_buffer_pool_free(void); void GPU_global_buffer_pool_free_unused(void); -GPUBuffer *GPU_buffer_alloc(int size); +GPUBuffer *GPU_buffer_alloc(int size, bool force_vertex_arrays); void GPU_buffer_free(GPUBuffer *buffer); GPUDrawObject *GPU_drawobject_new(struct DerivedMesh *dm); @@ -161,9 +159,6 @@ void GPU_buffer_draw_elements(GPUBuffer *elements, unsigned int mode, int start, /* called after drawing */ void GPU_buffer_unbind(void); -/* used to check whether to use the old (without buffers) code */ -bool GPU_buffer_legacy(struct DerivedMesh *dm); - /* Buffers for non-DerivedMesh drawing */ typedef struct GPU_PBVH_Buffers GPU_PBVH_Buffers; diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h index 3daf8585539..bb0cf2dd2b9 100644 --- a/source/blender/gpu/GPU_extensions.h +++ b/source/blender/gpu/GPU_extensions.h @@ -140,12 +140,15 @@ int GPU_texture_opengl_bindcode(GPUTexture *tex); * - after any of the GPU_framebuffer_* functions, GPU_framebuffer_restore must * be called before rendering to the window framebuffer again */ +void GPU_texture_bind_as_framebuffer(GPUTexture *tex); + GPUFrameBuffer *GPU_framebuffer_create(void); -int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, char err_out[256]); -void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex); -void GPU_framebuffer_texture_bind(GPUFrameBuffer *fb, GPUTexture *tex, int w, int h); +int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, char err_out[256]); +void GPU_framebuffer_texture_detach(GPUTexture *tex); +void GPU_framebuffer_slot_bind(GPUFrameBuffer *fb, int slot); void GPU_framebuffer_texture_unbind(GPUFrameBuffer *fb, GPUTexture *tex); void GPU_framebuffer_free(GPUFrameBuffer *fb); +bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256]); void GPU_framebuffer_restore(void); void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *blurfb, GPUTexture *blurtex); diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index a111401343e..09a5653b1ec 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -58,6 +58,7 @@ struct GPUMaterial; struct GPUTexture; struct GPULamp; struct PreviewImage; +struct World; typedef struct GPUNode GPUNode; typedef struct GPUNodeLink GPUNodeLink; @@ -95,6 +96,12 @@ typedef enum GPUOpenGLBuiltin { GPU_COLOR = 2, } GPUOpenGLBuiltin; +typedef enum GPUMatType { + GPU_MATERIAL_TYPE_MESH = 1, + GPU_MATERIAL_TYPE_WORLD = 2, +} GPUMatType; + + typedef enum GPUBlendMode { GPU_BLEND_SOLID = 0, GPU_BLEND_ADD = 1, @@ -131,10 +138,11 @@ void GPU_material_enable_alpha(GPUMaterial *material); GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4]); /* High level functions to create and use GPU materials */ +GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo); GPUMaterial *GPU_material_from_blender(struct Scene *scene, struct Material *ma); GPUMaterial *GPU_material_matcap(struct Scene *scene, struct Material *ma); -void GPU_material_free(struct Material *ma); +void GPU_material_free(struct ListBase *gpumaterial); void GPU_materials_free(void); @@ -144,6 +152,7 @@ void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float void GPU_material_unbind(GPUMaterial *material); int GPU_material_bound(GPUMaterial *material); struct Scene *GPU_material_scene(GPUMaterial *material); +GPUMatType GPU_Material_get_type(GPUMaterial *material); void GPU_material_vertex_attributes(GPUMaterial *material, struct GPUVertexAttribs *attrib); @@ -159,6 +168,7 @@ typedef struct GPUShadeInput { GPUNodeLink *rgb, *specrgb, *vn, *view, *vcol, *ref; GPUNodeLink *alpha, *refl, *spec, *emit, *har, *amb; + GPUNodeLink *spectra; } GPUShadeInput; typedef struct GPUShadeResult { diff --git a/source/blender/gpu/SConscript b/source/blender/gpu/SConscript index f11ecafc986..e44a99286a8 100644 --- a/source/blender/gpu/SConscript +++ b/source/blender/gpu/SConscript @@ -69,6 +69,7 @@ sources.extend(( os.path.join(env['DATA_SOURCES'], "gpu_shader_sep_gaussian_blur_frag.glsl.c"), os.path.join(env['DATA_SOURCES'], "gpu_shader_sep_gaussian_blur_vert.glsl.c"), os.path.join(env['DATA_SOURCES'], "gpu_shader_vertex.glsl.c"), + os.path.join(env['DATA_SOURCES'], "gpu_shader_vertex_world.glsl.c"), os.path.join(env['DATA_SOURCES'], "gpu_shader_vsm_store_frag.glsl.c"), os.path.join(env['DATA_SOURCES'], "gpu_shader_vsm_store_vert.glsl.c"), )) diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index b5a576b509c..f0ef55ae673 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -46,13 +46,11 @@ #include "BLI_ghash.h" #include "BLI_threads.h" -#include "DNA_material_types.h" #include "DNA_meshdata_types.h" #include "BKE_ccg.h" #include "BKE_DerivedMesh.h" #include "BKE_paint.h" -#include "BKE_material.h" #include "BKE_pbvh.h" #include "DNA_userdef_types.h" @@ -76,7 +74,6 @@ typedef enum { #define BUFFER_OFFSET(n) ((GLubyte *)NULL + (n)) /* -1 - undefined, 0 - vertex arrays, 1 - VBOs */ -static int useVBOs = -1; static GPUBufferState GLStates = 0; static GPUAttrib attribData[MAX_GPU_ATTRIB_DATA] = { { -1, 0, 0 } }; @@ -111,10 +108,6 @@ static GPUBufferPool *gpu_buffer_pool_new(void) { GPUBufferPool *pool; - /* enable VBOs if supported */ - if (useVBOs == -1) - useVBOs = (GLEW_ARB_vertex_buffer_object ? 1 : 0); - pool = MEM_callocN(sizeof(GPUBufferPool), "GPUBuffer_Pool"); pool->maxsize = MAX_FREE_GPU_BUFFERS; @@ -158,7 +151,7 @@ static void gpu_buffer_pool_delete_last(GPUBufferPool *pool) return; /* delete the buffer's data */ - if (useVBOs) + if (last->use_vbo) glDeleteBuffersARB(1, &last->id); else MEM_freeN(last->pointer); @@ -226,7 +219,7 @@ void GPU_global_buffer_pool_free_unused(void) * * Thread-unsafe version for internal usage only. */ -static GPUBuffer *gpu_buffer_alloc_intern(int size) +static GPUBuffer *gpu_buffer_alloc_intern(int size, bool use_VBO) { GPUBufferPool *pool; GPUBuffer *buf; @@ -251,6 +244,10 @@ static GPUBuffer *gpu_buffer_alloc_intern(int size) for (i = 0; i < pool->totbuf; i++) { bufsize = pool->buffers[i]->size; + /* only return a buffer that matches the VBO preference */ + if (pool->buffers[i]->use_vbo != use_VBO) + continue; + /* check for an exact size match */ if (bufsize == size) { bestfit = i; @@ -279,8 +276,9 @@ static GPUBuffer *gpu_buffer_alloc_intern(int size) /* no acceptable buffer found in the pool, create a new one */ buf = MEM_callocN(sizeof(GPUBuffer), "GPUBuffer"); buf->size = size; + buf->use_vbo = use_VBO; - if (useVBOs == 1) { + if (use_VBO) { /* create a new VBO and initialize it to the requested * size */ glGenBuffersARB(1, &buf->id); @@ -307,9 +305,10 @@ static GPUBuffer *gpu_buffer_alloc_intern(int size) } /* Same as above, but safe for threading. */ -GPUBuffer *GPU_buffer_alloc(int size) +GPUBuffer *GPU_buffer_alloc(int size, bool force_vertex_arrays) { GPUBuffer *buffer; + bool use_VBOs = (GLEW_ARB_vertex_buffer_object) && !(U.gameflags & USER_DISABLE_VBO) && !force_vertex_arrays; if (size == 0) { /* Early out, no lock needed in this case. */ @@ -317,7 +316,7 @@ GPUBuffer *GPU_buffer_alloc(int size) } BLI_mutex_lock(&buffer_mutex); - buffer = gpu_buffer_alloc_intern(size); + buffer = gpu_buffer_alloc_intern(size, use_VBOs); BLI_mutex_unlock(&buffer_mutex); return buffer; @@ -577,6 +576,7 @@ void GPU_drawobject_free(DerivedMesh *dm) GPU_buffer_free(gdo->points); GPU_buffer_free(gdo->normals); GPU_buffer_free(gdo->uv); + GPU_buffer_free(gdo->uv_tex); GPU_buffer_free(gdo->colors); GPU_buffer_free(gdo->edges); GPU_buffer_free(gdo->uvedges); @@ -585,6 +585,22 @@ void GPU_drawobject_free(DerivedMesh *dm) dm->drawObject = NULL; } +static GPUBuffer *gpu_try_realloc(GPUBufferPool *pool, GPUBuffer *buffer, int size, bool use_VBOs) +{ + gpu_buffer_free_intern(buffer); + gpu_buffer_pool_delete_last(pool); + buffer = NULL; + + /* try freeing an entry from the pool + * and reallocating the buffer */ + if (pool->totbuf > 0) { + gpu_buffer_pool_delete_last(pool); + buffer = gpu_buffer_alloc_intern(size, use_VBOs); + } + + return buffer; +} + typedef void (*GPUBufferCopyFunc)(DerivedMesh *dm, float *varray, int *index, int *mat_orig_to_new, void *user_data); @@ -598,7 +614,7 @@ static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object, int *mat_orig_to_new; int *cur_index_per_mat; int i; - bool success; + bool use_VBOs = (GLEW_ARB_vertex_buffer_object) && !(U.gameflags & USER_DISABLE_VBO); GLboolean uploaded; pool = gpu_get_global_buffer_pool(); @@ -606,11 +622,7 @@ static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object, BLI_mutex_lock(&buffer_mutex); /* alloc a GPUBuffer; fall back to legacy mode on failure */ - if (!(buffer = gpu_buffer_alloc_intern(size))) - dm->drawObject->legacy = 1; - - /* nothing to do for legacy mode */ - if (dm->drawObject->legacy) { + if (!(buffer = gpu_buffer_alloc_intern(size, use_VBOs))) { BLI_mutex_unlock(&buffer_mutex); return NULL; } @@ -628,8 +640,8 @@ static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object, mat_orig_to_new[object->materials[i].mat_nr] = i; } - if (useVBOs) { - success = 0; + if (use_VBOs) { + bool success = false; while (!success) { /* bind the buffer and discard previous data, @@ -639,32 +651,22 @@ static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object, /* attempt to map the buffer */ if (!(varray = glMapBufferARB(target, GL_WRITE_ONLY_ARB))) { - /* failed to map the buffer; delete it */ - gpu_buffer_free_intern(buffer); - gpu_buffer_pool_delete_last(pool); - buffer = NULL; - - /* try freeing an entry from the pool - * and reallocating the buffer */ - if (pool->totbuf > 0) { - gpu_buffer_pool_delete_last(pool); - buffer = gpu_buffer_alloc_intern(size); - } - + buffer = gpu_try_realloc(pool, buffer, size, true); + /* allocation still failed; fall back * to legacy mode */ if (!buffer) { - dm->drawObject->legacy = 1; - success = 1; + use_VBOs = false; + success = true; } } else { - success = 1; + success = true; } } /* check legacy fallback didn't happen */ - if (dm->drawObject->legacy == 0) { + if (use_VBOs) { uploaded = GL_FALSE; /* attempt to upload the data to the VBO */ while (uploaded == GL_FALSE) { @@ -677,15 +679,16 @@ static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object, } glBindBufferARB(target, 0); } - else { + if (!use_VBOs) { /* VBO not supported, use vertex array fallback */ - if (buffer->pointer) { + if (!buffer || !buffer->pointer) { + buffer = gpu_try_realloc(pool, buffer, size, false); + } + + if (buffer) { varray = buffer->pointer; (*copy_f)(dm, varray, cur_index_per_mat, mat_orig_to_new, user); } - else { - dm->drawObject->legacy = 1; - } } MEM_freeN(cur_index_per_mat); @@ -1019,7 +1022,7 @@ static GPUBuffer **gpu_drawobject_buffer_from_type(GPUDrawObject *gdo, GPUBuffer case GPU_BUFFER_UV: return &gdo->uv; case GPU_BUFFER_UV_TEXPAINT: - return &gdo->uv; + return &gdo->uv_tex; case GPU_BUFFER_EDGE: return &gdo->edges; case GPU_BUFFER_UVEDGE: @@ -1105,7 +1108,7 @@ void GPU_vertex_setup(DerivedMesh *dm) return; glEnableClientState(GL_VERTEX_ARRAY); - if (useVBOs) { + if (dm->drawObject->points->use_vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->points->id); glVertexPointer(3, GL_FLOAT, 0, 0); } @@ -1122,7 +1125,7 @@ void GPU_normal_setup(DerivedMesh *dm) return; glEnableClientState(GL_NORMAL_ARRAY); - if (useVBOs) { + if (dm->drawObject->normals->use_vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->normals->id); glNormalPointer(GL_FLOAT, 0, 0); } @@ -1139,7 +1142,7 @@ void GPU_uv_setup(DerivedMesh *dm) return; glEnableClientState(GL_TEXTURE_COORD_ARRAY); - if (useVBOs) { + if (dm->drawObject->uv->use_vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->uv->id); glTexCoordPointer(2, GL_FLOAT, 0, 0); } @@ -1156,8 +1159,8 @@ void GPU_texpaint_uv_setup(DerivedMesh *dm) return; glEnableClientState(GL_TEXTURE_COORD_ARRAY); - if (useVBOs) { - glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->uv->id); + if (dm->drawObject->uv_tex->use_vbo) { + glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->uv_tex->id); glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), 0); glClientActiveTexture(GL_TEXTURE2); glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -1165,10 +1168,10 @@ void GPU_texpaint_uv_setup(DerivedMesh *dm) glClientActiveTexture(GL_TEXTURE0); } else { - glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), dm->drawObject->uv->pointer); + glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), dm->drawObject->uv_tex->pointer); glClientActiveTexture(GL_TEXTURE2); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), (char *)dm->drawObject->uv->pointer + 2 * sizeof(float)); + glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), (char *)dm->drawObject->uv_tex->pointer + 2 * sizeof(float)); glClientActiveTexture(GL_TEXTURE0); } @@ -1202,7 +1205,7 @@ void GPU_color_setup(DerivedMesh *dm, int colType) return; glEnableClientState(GL_COLOR_ARRAY); - if (useVBOs) { + if (dm->drawObject->colors->use_vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->colors->id); glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0); } @@ -1222,7 +1225,7 @@ void GPU_edge_setup(DerivedMesh *dm) return; glEnableClientState(GL_VERTEX_ARRAY); - if (useVBOs) { + if (dm->drawObject->points->use_vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->points->id); glVertexPointer(3, GL_FLOAT, 0, 0); } @@ -1232,7 +1235,7 @@ void GPU_edge_setup(DerivedMesh *dm) GLStates |= GPU_BUFFER_VERTEX_STATE; - if (useVBOs) + if (dm->drawObject->edges->use_vbo) glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, dm->drawObject->edges->id); GLStates |= GPU_BUFFER_ELEMENT_STATE; @@ -1244,7 +1247,7 @@ void GPU_uvedge_setup(DerivedMesh *dm) return; glEnableClientState(GL_VERTEX_ARRAY); - if (useVBOs) { + if (dm->drawObject->uvedges->use_vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->uvedges->id); glVertexPointer(2, GL_FLOAT, 0, 0); } @@ -1290,6 +1293,7 @@ void GPU_interleaved_attrib_setup(GPUBuffer *buffer, GPUAttrib data[], int numda int i; int elementsize; intptr_t offset = 0; + char *basep; for (i = 0; i < MAX_GPU_ATTRIB_DATA; i++) { if (attribData[i].index != -1) { @@ -1300,28 +1304,26 @@ void GPU_interleaved_attrib_setup(GPUBuffer *buffer, GPUAttrib data[], int numda } elementsize = GPU_attrib_element_size(data, numdata); - if (useVBOs) { + if (buffer->use_vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer->id); - for (i = 0; i < numdata; i++) { - glEnableVertexAttribArrayARB(data[i].index); - glVertexAttribPointerARB(data[i].index, data[i].size, data[i].type, - GL_FALSE, elementsize, (void *)offset); - offset += data[i].size * GPU_typesize(data[i].type); - - attribData[i].index = data[i].index; - attribData[i].size = data[i].size; - attribData[i].type = data[i].type; - } - attribData[numdata].index = -1; + basep = NULL; } else { - for (i = 0; i < numdata; i++) { - glEnableVertexAttribArrayARB(data[i].index); - glVertexAttribPointerARB(data[i].index, data[i].size, data[i].type, - GL_FALSE, elementsize, (char *)buffer->pointer + offset); - offset += data[i].size * GPU_typesize(data[i].type); - } + basep = buffer->pointer; } + + for (i = 0; i < numdata; i++) { + glEnableVertexAttribArrayARB(data[i].index); + glVertexAttribPointerARB(data[i].index, data[i].size, data[i].type, + GL_FALSE, elementsize, (void *)(basep + offset)); + offset += data[i].size * GPU_typesize(data[i].type); + + attribData[i].index = data[i].index; + attribData[i].size = data[i].size; + attribData[i].type = data[i].type; + } + + attribData[numdata].index = -1; } @@ -1343,7 +1345,8 @@ void GPU_buffer_unbind(void) if (GLStates & GPU_BUFFER_COLOR_STATE) glDisableClientState(GL_COLOR_ARRAY); if (GLStates & GPU_BUFFER_ELEMENT_STATE) { - if (useVBOs) { + /* not guaranteed we used VBOs but in that case it's just a no-op */ + if (GLEW_ARB_vertex_buffer_object) { glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); } } @@ -1359,7 +1362,8 @@ void GPU_buffer_unbind(void) break; } - if (useVBOs) + /* not guaranteed we used VBOs but in that case it's just a no-op */ + if (GLEW_ARB_vertex_buffer_object) glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); } @@ -1377,19 +1381,6 @@ void GPU_color_switch(int mode) } } -/* return 1 if drawing should be done using old immediate-mode - * code, 0 otherwise */ -bool GPU_buffer_legacy(DerivedMesh *dm) -{ - int test = (U.gameflags & USER_DISABLE_VBO); - if (test) - return 1; - - if (dm->drawObject == NULL) - dm->drawObject = GPU_drawobject_new(dm); - return dm->drawObject->legacy; -} - void *GPU_buffer_lock(GPUBuffer *buffer) { float *varray; @@ -1397,7 +1388,7 @@ void *GPU_buffer_lock(GPUBuffer *buffer) if (!buffer) return 0; - if (useVBOs) { + if (buffer->use_vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer->id); varray = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); return varray; @@ -1414,7 +1405,7 @@ void *GPU_buffer_lock_stream(GPUBuffer *buffer) if (!buffer) return 0; - if (useVBOs) { + if (buffer->use_vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer->id); /* discard previous data, avoid stalling gpu */ glBufferDataARB(GL_ARRAY_BUFFER_ARB, buffer->size, 0, GL_STREAM_DRAW_ARB); @@ -1428,12 +1419,10 @@ void *GPU_buffer_lock_stream(GPUBuffer *buffer) void GPU_buffer_unlock(GPUBuffer *buffer) { - if (useVBOs) { - if (buffer) { - /* note: this operation can fail, could return - * an error code from this function? */ - glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); - } + if (buffer->use_vbo) { + /* note: this operation can fail, could return + * an error code from this function? */ + glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); } } @@ -1442,7 +1431,7 @@ void GPU_buffer_unlock(GPUBuffer *buffer) void GPU_buffer_draw_elements(GPUBuffer *elements, unsigned int mode, int start, int count) { glDrawElements(mode, count, GL_UNSIGNED_INT, - (useVBOs ? + (elements->use_vbo ? (void *)(start * sizeof(unsigned int)) : ((int *)elements->pointer) + start)); } @@ -2748,7 +2737,7 @@ void GPU_free_pbvh_buffers(GPU_PBVH_Buffers *buffers) /* debug function, draws the pbvh BB */ void GPU_draw_pbvh_BB(float min[3], float max[3], bool leaf) { - float quads[4][4][3] = { + const float quads[4][4][3] = { { {min[0], min[1], min[2]}, {max[0], min[1], min[2]}, diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 322d37055db..e29d955407c 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -51,13 +51,12 @@ #include "gpu_codegen.h" -#include "node_util.h" /* For muting node stuff... */ - #include <string.h> #include <stdarg.h> extern char datatoc_gpu_shader_material_glsl[]; extern char datatoc_gpu_shader_vertex_glsl[]; +extern char datatoc_gpu_shader_vertex_world_glsl[]; static char *glsl_material_library = NULL; @@ -252,7 +251,7 @@ void gpu_codegen_exit(void) extern Material defmaterial; // render module abuse... if (defmaterial.gpumaterial.first) - GPU_material_free(&defmaterial); + GPU_material_free(&defmaterial.gpumaterial); if (FUNCTION_HASH) { BLI_ghash_free(FUNCTION_HASH, NULL, MEM_freeN); @@ -624,8 +623,7 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, const ch if (builtins & GPU_VIEW_NORMAL) BLI_dynstr_append(ds, "\tvec3 facingnormal = (gl_FrontFacing)? varnormal: -varnormal;\n"); - - + codegen_declare_tmps(ds, nodes); codegen_call_functions(ds, nodes, output); @@ -640,12 +638,13 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, const ch return code; } -static char *code_generate_vertex(ListBase *nodes) +static char *code_generate_vertex(ListBase *nodes, int type) { DynStr *ds = BLI_dynstr_new(); GPUNode *node; GPUInput *input; char *code; + char *vertcode; for (node=nodes->first; node; node=node->next) { for (input=node->inputs.first; input; input=input->next) { @@ -659,13 +658,26 @@ static char *code_generate_vertex(ListBase *nodes) } BLI_dynstr_append(ds, "\n"); - BLI_dynstr_append(ds, datatoc_gpu_shader_vertex_glsl); + switch (type) { + case GPU_MATERIAL_TYPE_MESH: + vertcode = datatoc_gpu_shader_vertex_glsl; + break; + case GPU_MATERIAL_TYPE_WORLD: + vertcode = datatoc_gpu_shader_vertex_world_glsl; + break; + default: + fprintf(stderr, "invalid material type, set one after GPU_material_construct_begin\n"); + break; + } + + BLI_dynstr_append(ds, vertcode); + for (node=nodes->first; node; node=node->next) for (input=node->inputs.first; input; input=input->next) if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { if (input->attribtype == CD_TANGENT) { /* silly exception */ - BLI_dynstr_appendf(ds, "\tvar%d.xyz = normalize((gl_ModelViewMatrix * vec4(att%d.xyz, 0)).xyz);\n", input->attribid, input->attribid); + BLI_dynstr_appendf(ds, "\tvar%d.xyz = normalize(gl_NormalMatrix * att%d.xyz);\n", input->attribid, input->attribid); BLI_dynstr_appendf(ds, "\tvar%d.w = att%d.w;\n", input->attribid, input->attribid); } else @@ -1386,7 +1398,7 @@ static void gpu_nodes_prune(ListBase *nodes, GPUNodeLink *outlink) } } -GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttribs *attribs, int *builtins, const char *name) +GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttribs *attribs, int *builtins, int type, const char *name) { GPUShader *shader; GPUPass *pass; @@ -1405,7 +1417,7 @@ GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttri /* generate code and compile with opengl */ fragmentcode = code_generate_fragment(nodes, outlink->output, name); - vertexcode = code_generate_vertex(nodes); + vertexcode = code_generate_vertex(nodes, type); shader = GPU_shader_create(vertexcode, fragmentcode, glsl_material_library, NULL); /* failed? */ diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h index 69213925931..a0698235db6 100644 --- a/source/blender/gpu/intern/gpu_codegen.h +++ b/source/blender/gpu/intern/gpu_codegen.h @@ -175,7 +175,7 @@ struct GPUPass { typedef struct GPUPass GPUPass; GPUPass *GPU_generate_pass(ListBase *nodes, struct GPUNodeLink *outlink, - struct GPUVertexAttribs *attribs, int *builtin, const char *name); + struct GPUVertexAttribs *attribs, int *builtin, int type, const char *name); struct GPUShader *GPU_pass_shader(GPUPass *pass); diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 622e7b5ce9e..6e3fc76703a 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -1389,9 +1389,10 @@ static struct GPUMaterialState { } GMS = {NULL}; /* fixed function material, alpha handed by caller */ -static void gpu_material_to_fixed(GPUMaterialFixed *smat, const Material *bmat, const int gamma, const Object *ob, const int new_shading_nodes) +static void gpu_material_to_fixed(GPUMaterialFixed *smat, const Material *bmat, const int gamma, const Object *ob, const int new_shading_nodes, + const bool dimdown) { - if (new_shading_nodes || bmat->mode & MA_SHLESS) { + if (bmat->mode & MA_SHLESS) { copy_v3_v3(smat->diff, &bmat->r); smat->diff[3]= 1.0; @@ -1401,6 +1402,24 @@ static void gpu_material_to_fixed(GPUMaterialFixed *smat, const Material *bmat, zero_v4(smat->spec); smat->hard= 0; } + else if (new_shading_nodes) { + copy_v3_v3(smat->diff, &bmat->r); + smat->diff[3]= 1.0; + + copy_v3_v3(smat->spec, &bmat->specr); + smat->spec[3] = 1.0; + smat->hard= CLAMPIS(bmat->har, 0, 128); + + if (dimdown) { + mul_v3_fl(smat->diff, 0.8f); + mul_v3_fl(smat->spec, 0.5f); + } + + if (gamma) { + linearrgb_to_srgb_v3_v3(smat->diff, smat->diff); + linearrgb_to_srgb_v3_v3(smat->spec, smat->spec); + } + } else { mul_v3_v3fl(smat->diff, &bmat->r, bmat->ref + bmat->emit); smat->diff[3]= 1.0; /* caller may set this to bmat->alpha */ @@ -1501,7 +1520,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O /* no materials assigned? */ if (ob->totcol==0) { - gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob, new_shading_nodes); + gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob, new_shading_nodes, true); /* do material 1 too, for displists! */ memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed)); @@ -1531,7 +1550,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O } else { /* fixed function opengl materials */ - gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob, new_shading_nodes); + gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob, new_shading_nodes, false); if (GMS.use_alpha_pass && ((ma->mode & MA_TRANSP) || (new_shading_nodes && ma->alpha != 1.0f))) { GMS.matbuf[a].diff[3]= ma->alpha; diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index 04f8e68431a..05c40d65df5 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -49,7 +49,6 @@ #include "GPU_extensions.h" #include "GPU_simple_shader.h" -#include "intern/gpu_codegen.h" #include "intern/gpu_extensions_private.h" #include <stdlib.h> @@ -103,6 +102,16 @@ static struct GPUGlobal { GPUTexture *invalid_tex_3D; } GG = {1, 0}; +/* Number of maximum output slots. We support 4 outputs for now (usually we wouldn't need more to preserve fill rate) */ +#define GPU_FB_MAX_SLOTS 4 + +struct GPUFrameBuffer { + GLuint object; + GPUTexture *colortex[GPU_FB_MAX_SLOTS]; + GPUTexture *depthtex; +}; + + /* GPU Types */ int GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver) @@ -259,7 +268,7 @@ int GPU_print_error(const char *str) { GLenum errCode; - if (G.debug & G_DEBUG) { + if ((G.debug & G_DEBUG)) { if ((errCode = glGetError()) != GL_NO_ERROR) { fprintf(stderr, "%s opengl error: %s\n", str, gluErrorString(errCode)); return 1; @@ -323,6 +332,7 @@ struct GPUTexture { int fromblender; /* we got the texture from Blender */ GPUFrameBuffer *fb; /* GPUFramebuffer this texture is attached to */ + int fb_attachment; /* slot the texture is attached to */ int depth; /* is a depth texture? */ }; @@ -370,6 +380,7 @@ static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, in tex->refcount = 1; tex->target = (n == 1)? GL_TEXTURE_1D: GL_TEXTURE_2D; tex->depth = depth; + tex->fb_attachment = -1; glGenTextures(1, &tex->bindcode); @@ -737,7 +748,13 @@ void GPU_texture_bind(GPUTexture *tex, int number) return; } - if (number == -1) + if ((G.debug & G_DEBUG)) { + if (tex->fb && tex->fb->object == GG.currentfb) { + fprintf(stderr, "Feedback loop warning!: Attempting to bind texture attached to current framebuffer!\n"); + } + } + + if (number < 0) return; GPU_print_error("Pre Texture Bind"); @@ -791,7 +808,7 @@ void GPU_texture_free(GPUTexture *tex) if (tex->refcount == 0) { if (tex->fb) - GPU_framebuffer_texture_detach(tex->fb, tex); + GPU_framebuffer_texture_detach(tex); if (tex->bindcode && !tex->fromblender) glDeleteTextures(1, &tex->bindcode); @@ -831,12 +848,6 @@ GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex) /* GPUFrameBuffer */ -struct GPUFrameBuffer { - GLuint object; - GPUTexture *colortex; - GPUTexture *depthtex; -}; - GPUFrameBuffer *GPU_framebuffer_create(void) { GPUFrameBuffer *fb; @@ -854,19 +865,35 @@ GPUFrameBuffer *GPU_framebuffer_create(void) return NULL; } + /* make sure no read buffer is enabled, so completeness check will not fail. We set those at binding time */ + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object); + glReadBuffer(GL_NONE); + glDrawBuffer(GL_NONE); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + return fb; } -int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, char err_out[256]) +int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, char err_out[256]) { - GLenum status; GLenum attachment; GLenum error; + if (slot >= GPU_FB_MAX_SLOTS) { + fprintf(stderr, "Attaching to index %d framebuffer slot unsupported in blender use at most %d\n", slot, GPU_FB_MAX_SLOTS); + return 0; + } + + if ((G.debug & G_DEBUG)) { + if (tex->number != -1) { + fprintf(stderr, "Feedback loop warning!: Attempting to attach texture to framebuffer while still bound to texture unit for drawing!"); + } + } + if (tex->depth) attachment = GL_DEPTH_ATTACHMENT_EXT; else - attachment = GL_COLOR_ATTACHMENT0_EXT; + attachment = GL_COLOR_ATTACHMENT0_EXT + slot; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object); GG.currentfb = fb->object; @@ -885,42 +912,29 @@ int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, char err return 0; } - if (tex->depth) { - glDrawBuffer(GL_NONE); - glReadBuffer(GL_NONE); - } - else { - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); - } - - status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { - GPU_framebuffer_restore(); - GPU_print_framebuffer_error(status, err_out); - return 0; - } - if (tex->depth) fb->depthtex = tex; else - fb->colortex = tex; + fb->colortex[slot] = tex; tex->fb= fb; + tex->fb_attachment = slot; return 1; } -void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex) +void GPU_framebuffer_texture_detach(GPUTexture *tex) { GLenum attachment; + GPUFrameBuffer *fb; if (!tex->fb) return; - if (GG.currentfb != tex->fb->object) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tex->fb->object); + fb = tex->fb; + + if (GG.currentfb != fb->object) { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object); GG.currentfb = tex->fb->object; } @@ -929,18 +943,25 @@ void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex) attachment = GL_DEPTH_ATTACHMENT_EXT; } else { - fb->colortex = NULL; - attachment = GL_COLOR_ATTACHMENT0_EXT; + BLI_assert(fb->colortex[tex->fb_attachment] == tex); + fb->colortex[tex->fb_attachment] = NULL; + attachment = GL_COLOR_ATTACHMENT0_EXT + tex->fb_attachment; } glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, tex->target, 0, 0); tex->fb = NULL; + tex->fb_attachment = -1; } -void GPU_framebuffer_texture_bind(GPUFrameBuffer *UNUSED(fb), GPUTexture *tex, int w, int h) +void GPU_texture_bind_as_framebuffer(GPUTexture *tex) { + if (!tex->fb) { + fprintf(stderr, "Error, texture not bound to framebuffer!"); + return; + } + /* push attributes */ glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT); glDisable(GL_SCISSOR_TEST); @@ -948,8 +969,18 @@ void GPU_framebuffer_texture_bind(GPUFrameBuffer *UNUSED(fb), GPUTexture *tex, i /* bind framebuffer */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tex->fb->object); + if (tex->depth) { + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + } + else { + /* last bound prevails here, better allow explicit control here too */ + glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + tex->fb_attachment); + glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + tex->fb_attachment); + } + /* push matrices and set default viewport and matrix */ - glViewport(0, 0, w, h); + glViewport(0, 0, tex->w, tex->h); GG.currentfb = tex->fb->object; glMatrixMode(GL_PROJECTION); @@ -958,6 +989,35 @@ void GPU_framebuffer_texture_bind(GPUFrameBuffer *UNUSED(fb), GPUTexture *tex, i glPushMatrix(); } +void GPU_framebuffer_slot_bind(GPUFrameBuffer *fb, int slot) +{ + if (!fb->colortex[slot]) { + fprintf(stderr, "Error, framebuffer slot empty!"); + return; + } + + /* push attributes */ + glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT); + glDisable(GL_SCISSOR_TEST); + + /* bind framebuffer */ + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object); + + /* last bound prevails here, better allow explicit control here too */ + glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + slot); + glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + slot); + + /* push matrices and set default viewport and matrix */ + glViewport(0, 0, fb->colortex[slot]->w, fb->colortex[slot]->h); + GG.currentfb = fb->object; + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); +} + + void GPU_framebuffer_texture_unbind(GPUFrameBuffer *UNUSED(fb), GPUTexture *UNUSED(tex)) { /* restore matrix */ @@ -968,15 +1028,42 @@ void GPU_framebuffer_texture_unbind(GPUFrameBuffer *UNUSED(fb), GPUTexture *UNUS /* restore attributes */ glPopAttrib(); - glEnable(GL_SCISSOR_TEST); } + +bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256]) +{ + GLenum status; + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object); + GG.currentfb = fb->object; + + /* Clean glError buffer. */ + while (glGetError() != GL_NO_ERROR) {} + + status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { + GPU_framebuffer_restore(); + GPU_print_framebuffer_error(status, err_out); + return false; + } + + return true; +} + + void GPU_framebuffer_free(GPUFrameBuffer *fb) { + int i; if (fb->depthtex) - GPU_framebuffer_texture_detach(fb, fb->depthtex); - if (fb->colortex) - GPU_framebuffer_texture_detach(fb, fb->colortex); + GPU_framebuffer_texture_detach(fb->depthtex); + + for (i = 0; i < GPU_FB_MAX_SLOTS; i++) { + if (fb->colortex[i]) { + GPU_framebuffer_texture_detach(fb->colortex[i]); + } + } if (fb->object) { glDeleteFramebuffersEXT(1, &fb->object); @@ -1017,6 +1104,10 @@ void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *b /* We do the bind ourselves rather than using GPU_framebuffer_texture_bind() to avoid * pushing unnecessary matrices onto the OpenGL stack. */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, blurfb->object); + glDrawBuffer(GL_COLOR_ATTACHMENT0); + + /* avoid warnings from texture binding */ + GG.currentfb = blurfb->object; GPU_shader_bind(blur_shader); GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, (float *)scaleh); @@ -1046,6 +1137,10 @@ void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *b /* Blurring vertically */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object); + glDrawBuffer(GL_COLOR_ATTACHMENT0); + + GG.currentfb = fb->object; + glViewport(0, 0, GPU_texture_opengl_width(tex), GPU_texture_opengl_height(tex)); GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, (float *)scalev); GPU_shader_uniform_texture(blur_shader, texture_source_uniform, blurtex); @@ -1067,10 +1162,6 @@ struct GPUOffScreen { GPUFrameBuffer *fb; GPUTexture *color; GPUTexture *depth; - - /* requested width/height, may be smaller than actual texture size due - * to missing non-power of two support, so we compensate for that */ - int w, h; }; GPUOffScreen *GPU_offscreen_create(int width, int height, char err_out[256]) @@ -1078,8 +1169,6 @@ GPUOffScreen *GPU_offscreen_create(int width, int height, char err_out[256]) GPUOffScreen *ofs; ofs= MEM_callocN(sizeof(GPUOffScreen), "GPUOffScreen"); - ofs->w= width; - ofs->h= height; ofs->fb = GPU_framebuffer_create(); if (!ofs->fb) { @@ -1093,7 +1182,7 @@ GPUOffScreen *GPU_offscreen_create(int width, int height, char err_out[256]) return NULL; } - if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, err_out)) { + if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, 0, err_out)) { GPU_offscreen_free(ofs); return NULL; } @@ -1104,10 +1193,16 @@ GPUOffScreen *GPU_offscreen_create(int width, int height, char err_out[256]) return NULL; } - if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->color, err_out)) { + if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->color, 0, err_out)) { GPU_offscreen_free(ofs); return NULL; } + + /* check validity at the very end! */ + if (!GPU_framebuffer_check_valid(ofs->fb, err_out)) { + GPU_offscreen_free(ofs); + return NULL; + } GPU_framebuffer_restore(); @@ -1129,7 +1224,7 @@ void GPU_offscreen_free(GPUOffScreen *ofs) void GPU_offscreen_bind(GPUOffScreen *ofs) { glDisable(GL_SCISSOR_TEST); - GPU_framebuffer_texture_bind(ofs->fb, ofs->color, ofs->w, ofs->h); + GPU_texture_bind_as_framebuffer(ofs->color); } void GPU_offscreen_unbind(GPUOffScreen *ofs) @@ -1141,17 +1236,17 @@ void GPU_offscreen_unbind(GPUOffScreen *ofs) void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels) { - glReadPixels(0, 0, ofs->w, ofs->h, GL_RGBA, type, pixels); + glReadPixels(0, 0, ofs->color->w, ofs->color->h, GL_RGBA, type, pixels); } int GPU_offscreen_width(GPUOffScreen *ofs) { - return ofs->w; + return ofs->color->w; } int GPU_offscreen_height(GPUOffScreen *ofs) { - return ofs->h; + return ofs->color->h; } /* GPUShader */ @@ -1173,8 +1268,8 @@ static void shader_print_errors(const char *task, char *log, const char **code, for (i = 0; i < totcode; i++) { const char *c, *pos, *end = code[i] + strlen(code[i]); int line = 1; - - if (G.debug & G_DEBUG) { + + if ((G.debug & G_DEBUG)) { fprintf(stderr, "===== shader string %d ====\n", i + 1); c = code[i]; diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c index 912774cd345..fd99595b6a4 100644 --- a/source/blender/gpu/intern/gpu_init_exit.c +++ b/source/blender/gpu/intern/gpu_init_exit.c @@ -31,7 +31,6 @@ #include "BLI_sys_types.h" #include "GPU_init_exit.h" /* interface */ -#include "GPU_extensions.h" /* library */ #include "intern/gpu_codegen.h" #include "intern/gpu_extensions_private.h" diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index f91fd7a8c1e..75a9572f54f 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -76,10 +76,15 @@ typedef enum DynMatProperty { DYN_LAMP_PERSMAT = 8, } DynMatProperty; + struct GPUMaterial { Scene *scene; Material *ma; + /* material for mesh surface, worlds or something else. + * some code generation is done differently depending on the use case */ + int type; + /* for creating the material */ ListBase nodes; GPUNodeLink *outlink; @@ -194,7 +199,7 @@ static void gpu_material_set_attrib_id(GPUMaterial *material) attribs->totlayer = b; } -static int GPU_material_construct_end(GPUMaterial *material) +static int GPU_material_construct_end(GPUMaterial *material, const char *passname) { if (material->outlink) { GPUNodeLink *outlink; @@ -202,7 +207,7 @@ static int GPU_material_construct_end(GPUMaterial *material) outlink = material->outlink; material->pass = GPU_generate_pass(&material->nodes, outlink, - &material->attribs, &material->builtins, material->ma->id.name); + &material->attribs, &material->builtins, material->type, passname); if (!material->pass) return 0; @@ -229,12 +234,12 @@ static int GPU_material_construct_end(GPUMaterial *material) return 0; } -void GPU_material_free(Material *ma) +void GPU_material_free(ListBase *gpumaterial) { LinkData *link; LinkData *nlink, *mlink, *next; - for (link=ma->gpumaterial.first; link; link=link->next) { + for (link=gpumaterial->first; link; link=link->next) { GPUMaterial *material = link->data; if (material->pass) @@ -243,19 +248,23 @@ void GPU_material_free(Material *ma) for (nlink=material->lamps.first; nlink; nlink=nlink->next) { GPULamp *lamp = nlink->data; - for (mlink=lamp->materials.first; mlink; mlink=next) { - next = mlink->next; - if (mlink->data == ma) - BLI_freelinkN(&lamp->materials, mlink); + if (material->ma) { + Material *ma = material->ma; + + for (mlink=lamp->materials.first; mlink; mlink=next) { + next = mlink->next; + if (mlink->data == ma) + BLI_freelinkN(&lamp->materials, mlink); + } } } - + BLI_freelistN(&material->lamps); MEM_freeN(material); } - BLI_freelistN(&ma->gpumaterial); + BLI_freelistN(gpumaterial); } bool GPU_lamp_override_visible(GPULamp *lamp, SceneRenderLayer *srl, Material *ma) @@ -280,42 +289,44 @@ void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double tim viewlay &= srl->lay; /* handle layer lamps */ - for (nlink=material->lamps.first; nlink; nlink=nlink->next) { - lamp= nlink->data; - - if (!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay)) - && GPU_lamp_override_visible(lamp, srl, material->ma)) { - lamp->dynenergy = lamp->energy; - copy_v3_v3(lamp->dyncol, lamp->col); - } - else { - lamp->dynenergy = 0.0f; - lamp->dyncol[0]= lamp->dyncol[1]= lamp->dyncol[2] = 0.0f; - } - - if (material->dynproperty & DYN_LAMP_VEC) { - copy_v3_v3(lamp->dynvec, lamp->vec); - normalize_v3(lamp->dynvec); - negate_v3(lamp->dynvec); - mul_mat3_m4_v3(viewmat, lamp->dynvec); - } - - if (material->dynproperty & DYN_LAMP_CO) { - copy_v3_v3(lamp->dynco, lamp->co); - mul_m4_v3(viewmat, lamp->dynco); - } - - if (material->dynproperty & DYN_LAMP_IMAT) { - mul_m4_m4m4(lamp->dynimat, lamp->imat, viewinv); - } - - if (material->dynproperty & DYN_LAMP_PERSMAT) { - if (!GPU_lamp_has_shadow_buffer(lamp)) /* The lamp matrices are already updated if we're using shadow buffers */ - GPU_lamp_update_buffer_mats(lamp); - mul_m4_m4m4(lamp->dynpersmat, lamp->persmat, viewinv); + if (material->type == GPU_MATERIAL_TYPE_MESH) { + for (nlink=material->lamps.first; nlink; nlink=nlink->next) { + lamp= nlink->data; + + if (!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay)) + && GPU_lamp_override_visible(lamp, srl, material->ma)) { + lamp->dynenergy = lamp->energy; + copy_v3_v3(lamp->dyncol, lamp->col); + } + else { + lamp->dynenergy = 0.0f; + lamp->dyncol[0]= lamp->dyncol[1]= lamp->dyncol[2] = 0.0f; + } + + if (material->dynproperty & DYN_LAMP_VEC) { + copy_v3_v3(lamp->dynvec, lamp->vec); + normalize_v3(lamp->dynvec); + negate_v3(lamp->dynvec); + mul_mat3_m4_v3(viewmat, lamp->dynvec); + } + + if (material->dynproperty & DYN_LAMP_CO) { + copy_v3_v3(lamp->dynco, lamp->co); + mul_m4_v3(viewmat, lamp->dynco); + } + + if (material->dynproperty & DYN_LAMP_IMAT) { + mul_m4_m4m4(lamp->dynimat, lamp->imat, viewinv); + } + + if (material->dynproperty & DYN_LAMP_PERSMAT) { + if (!GPU_lamp_has_shadow_buffer(lamp)) /* The lamp matrices are already updated if we're using shadow buffers */ + GPU_lamp_update_buffer_mats(lamp); + mul_m4_m4m4(lamp->dynpersmat, lamp->persmat, viewinv); + } } } - + /* note material must be bound before setting uniforms */ GPU_pass_bind(material->pass, time, mipmap); @@ -376,6 +387,12 @@ Scene *GPU_material_scene(GPUMaterial *material) return material->scene; } +GPUMatType GPU_Material_get_type(GPUMaterial *material) +{ + return material->type; +} + + void GPU_material_vertex_attributes(GPUMaterial *material, GPUVertexAttribs *attribs) { *attribs = material->attribs; @@ -1169,7 +1186,7 @@ static void do_material_tex(GPUShadeInput *shi) } else if (mtex->normapspace == MTEX_NSPACE_OBJECT) { /* transform normal by object then view matrix */ - GPU_link(mat, "mtex_nspace_object", GPU_builtin(GPU_VIEW_MATRIX), GPU_builtin(GPU_OBJECT_MATRIX), tnor, &newnor); + GPU_link(mat, "mtex_nspace_object", tnor, &newnor); } else if (mtex->normapspace == MTEX_NSPACE_WORLD) { /* transform normal by view matrix */ @@ -1426,6 +1443,7 @@ void GPU_shadeinput_set(GPUMaterial *mat, Material *ma, GPUShadeInput *shi) GPU_link(mat, "set_value", GPU_uniform(&ma->emit), &shi->emit); GPU_link(mat, "set_value", GPU_uniform(&hard), &shi->har); GPU_link(mat, "set_value", GPU_uniform(&ma->amb), &shi->amb); + GPU_link(mat, "set_value", GPU_uniform(&ma->spectra), &shi->spectra); GPU_link(mat, "shade_view", GPU_builtin(GPU_VIEW_POSITION), &shi->view); GPU_link(mat, "vcol_attribute", GPU_attribute(CD_MCOL, ""), &shi->vcol); if (GPU_material_do_color_management(mat)) @@ -1497,6 +1515,12 @@ void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr) } } + if (ma->mode & MA_TRANSP && (ma->mode & (MA_ZTRANSP|MA_RAYTRANSP))) { + if (GPU_link_changed(shi->spectra) || ma->spectra != 0.0f) + GPU_link(mat, "alpha_spec_correction", shr->spec, shi->spectra, + shi->alpha, &shr->alpha); + } + if (ma->mode & MA_RAMP_COL) ramp_diffuse_result(shi, &shr->combined); if (ma->mode & MA_RAMP_SPEC) ramp_spec_result(shi, &shr->spec); @@ -1582,6 +1606,7 @@ GPUMaterial *GPU_material_matcap(Scene *scene, Material *ma) /* allocate material */ mat = GPU_material_construct_begin(ma); mat->scene = scene; + mat->type = GPU_MATERIAL_TYPE_MESH; if (ma->preview && ma->preview->rect[0]) { outlink = gpu_material_preview_matcap(mat, ma); @@ -1592,7 +1617,7 @@ GPUMaterial *GPU_material_matcap(Scene *scene, Material *ma) GPU_material_output_link(mat, outlink); - GPU_material_construct_end(mat); + GPU_material_construct_end(mat, "matcap_pass"); /* note that even if building the shader fails in some way, we still keep * it to avoid trying to compile again and again, and simple do not use @@ -1605,6 +1630,45 @@ GPUMaterial *GPU_material_matcap(Scene *scene, Material *ma) return mat; } +GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo) +{ + LinkData *link; + GPUMaterial *mat; + + for (link=wo->gpumaterial.first; link; link=link->next) + if (((GPUMaterial*)link->data)->scene == scene) + return link->data; + + /* allocate material */ + mat = GPU_material_construct_begin(NULL); + mat->scene = scene; + mat->type = GPU_MATERIAL_TYPE_WORLD; + + /* create nodes */ + if (BKE_scene_use_new_shading_nodes(scene) && wo->nodetree && wo->use_nodes) + ntreeGPUMaterialNodes(wo->nodetree, mat, NODE_NEW_SHADING); + else { + /* old fixed function world */ + } + + if (GPU_material_do_color_management(mat)) + if (mat->outlink) + GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink); + + GPU_material_construct_end(mat, wo->id.name); + + /* note that even if building the shader fails in some way, we still keep + * it to avoid trying to compile again and again, and simple do not use + * the actual shader on drawing */ + + link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink"); + link->data = mat; + BLI_addtail(&wo->gpumaterial, link); + + return mat; +} + + GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma) { GPUMaterial *mat; @@ -1618,6 +1682,7 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma) /* allocate material */ mat = GPU_material_construct_begin(ma); mat->scene = scene; + mat->type = GPU_MATERIAL_TYPE_MESH; /* render pipeline option */ if (ma->mode & MA_TRANSP) @@ -1647,7 +1712,7 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma) if (mat->outlink) GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink); - GPU_material_construct_end(mat); + GPU_material_construct_end(mat, ma->id.name); /* note that even if building the shader fails in some way, we still keep * it to avoid trying to compile again and again, and simple do not use @@ -1664,12 +1729,16 @@ void GPU_materials_free(void) { Object *ob; Material *ma; + World *wo; extern Material defmaterial; for (ma=G.main->mat.first; ma; ma=ma->id.next) - GPU_material_free(ma); + GPU_material_free(&ma->gpumaterial); - GPU_material_free(&defmaterial); + for (wo=G.main->world.first; wo; wo=wo->id.next) + GPU_material_free(&wo->gpumaterial); + + GPU_material_free(&defmaterial.gpumaterial); for (ob=G.main->object.first; ob; ob=ob->id.next) GPU_lamp_free(ob); @@ -1844,7 +1913,7 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par) return lamp; } - if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->depthtex, NULL)) { + if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->depthtex, 0, NULL)) { gpu_lamp_shadow_free(lamp); return lamp; } @@ -1856,11 +1925,16 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par) return lamp; } - if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, NULL)) { + if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0, NULL)) { gpu_lamp_shadow_free(lamp); return lamp; } + if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) { + gpu_lamp_shadow_free(lamp); + return lamp; + } + /* FBO and texture for blurring */ lamp->blurfb = GPU_framebuffer_create(); if (!lamp->blurfb) { @@ -1874,10 +1948,20 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par) return lamp; } - if (!GPU_framebuffer_texture_attach(lamp->blurfb, lamp->blurtex, NULL)) { + if (!GPU_framebuffer_texture_attach(lamp->blurfb, lamp->blurtex, 0, NULL)) { gpu_lamp_shadow_free(lamp); return lamp; } + + /* we need to properly bind to test for completeness */ + GPU_texture_bind_as_framebuffer(lamp->blurtex); + + if (!GPU_framebuffer_check_valid(lamp->blurfb, NULL)) { + gpu_lamp_shadow_free(lamp); + return lamp; + } + + GPU_framebuffer_texture_unbind(lamp->blurfb, lamp->blurtex); } else { lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NULL); @@ -1886,10 +1970,15 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par) return lamp; } - if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, NULL)) { + if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0, NULL)) { gpu_lamp_shadow_free(lamp); return lamp; } + + if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) { + gpu_lamp_shadow_free(lamp); + return lamp; + } } GPU_framebuffer_restore(); @@ -1923,7 +2012,7 @@ void GPU_lamp_free(Object *ob) BLI_freelinkN(&lamp->materials, nlink); if (ma->gpumaterial.first) - GPU_material_free(ma); + GPU_material_free(&ma->gpumaterial); } gpu_lamp_shadow_free(lamp); @@ -1972,8 +2061,7 @@ void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsiz /* opengl */ glDisable(GL_SCISSOR_TEST); - GPU_framebuffer_texture_bind(lamp->fb, lamp->tex, - GPU_texture_opengl_width(lamp->tex), GPU_texture_opengl_height(lamp->tex)); + GPU_texture_bind_as_framebuffer(lamp->tex); if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) GPU_shader_bind(GPU_shader_get_builtin_shader(GPU_SHADER_VSM_STORE)); diff --git a/source/blender/gpu/intern/gpu_select.c b/source/blender/gpu/intern/gpu_select.c index afd6af9efae..d8e1fab9f80 100644 --- a/source/blender/gpu/intern/gpu_select.c +++ b/source/blender/gpu/intern/gpu_select.c @@ -33,12 +33,12 @@ #include "GPU_extensions.h" #include "GPU_glew.h" -#include "BLI_utildefines.h" - #include "MEM_guardedalloc.h" #include "DNA_userdef_types.h" +#include "BLI_utildefines.h" + /* Ad hoc number of queries to allocate to skip doing many glGenQueries */ #define ALLOC_QUERIES 200 diff --git a/source/blender/gpu/intern/gpu_simple_shader.c b/source/blender/gpu/intern/gpu_simple_shader.c index c0d7ebd4abb..3fa5975ef15 100644 --- a/source/blender/gpu/intern/gpu_simple_shader.c +++ b/source/blender/gpu/intern/gpu_simple_shader.c @@ -47,9 +47,6 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "DNA_mesh_types.h" -#include "DNA_object_types.h" - #include "GPU_extensions.h" #include "GPU_simple_shader.h" diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 23716c8105d..3a04a36cd75 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -357,6 +357,12 @@ void normal(vec3 dir, vec3 nor, out vec3 outnor, out float outdot) outdot = -dot(dir, nor); } +void normal_new_shading(vec3 dir, vec3 nor, out vec3 outnor, out float outdot) +{ + outnor = normalize(nor); + outdot = dot(normalize(dir), nor); +} + void curves_vec(float fac, vec3 vec, sampler2D curvemap, out vec3 outvec) { outvec.x = texture2D(curvemap, vec2((vec.x + 1.0)*0.5, 0.0)).x; @@ -722,6 +728,16 @@ void invert(float fac, vec4 col, out vec4 outcol) outcol.w = col.w; } +void clamp_vec3(vec3 vec, vec3 min, vec3 max, out vec3 out_vec) +{ + out_vec = clamp(vec, min, max); +} + +void clamp_val(float value, float min, float max, out float out_value) +{ + out_value = clamp(value, min, max); +} + void hue_sat(float hue, float sat, float value, float fac, vec4 col, out vec4 outcol) { vec4 hsv; @@ -1507,9 +1523,9 @@ void mtex_nspace_world(mat4 viewmat, vec3 texnormal, out vec3 outnormal) outnormal = normalize((viewmat*vec4(texnormal, 0.0)).xyz); } -void mtex_nspace_object(mat4 viewmat, mat4 obmat, vec3 texnormal, out vec3 outnormal) +void mtex_nspace_object(vec3 texnormal, out vec3 outnormal) { - outnormal = normalize((viewmat*(obmat*vec4(texnormal, 0.0))).xyz); + outnormal = normalize(gl_NormalMatrix * texnormal); } void mtex_blend_normal(float norfac, vec3 normal, vec3 newnormal, out vec3 outnormal) @@ -1925,6 +1941,17 @@ void shade_add_spec(float t, vec3 lampcol, vec3 speccol, out vec3 outcol) outcol = t*lampcol*speccol; } +void alpha_spec_correction(vec3 spec, float spectra, float alpha, out float outalpha) +{ + if (spectra > 0.0) { + float t = clamp(max(max(spec.r, spec.g), spec.b) * spectra, 0.0, 1.0); + outalpha = (1.0 - t) * alpha + t; + } + else { + outalpha = alpha; + } +} + void shade_add(vec4 col1, vec4 col2, out vec4 outcol) { outcol = col1 + col2; @@ -2235,6 +2262,22 @@ void node_emission(vec4 color, float strength, vec3 N, out vec4 result) result = color*strength; } +/* background */ + +void background_transform_to_world(vec3 viewvec, out vec3 worldvec) +{ + vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0); + vec4 co_homogenous = (gl_ProjectionMatrixInverse * v); + + vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0); + worldvec = (gl_ModelViewMatrixInverse * co).xyz; +} + +void node_background(vec4 color, float strength, vec3 N, out vec4 result) +{ + result = color*strength; +} + /* closures */ void node_mix_shader(float fac, vec4 shader1, vec4 shader2, out vec4 shader) @@ -2264,10 +2307,12 @@ void node_layer_weight(float blend, vec3 N, vec3 I, out float fresnel, out float { /* fresnel */ float eta = max(1.0 - blend, 0.00001); - fresnel = fresnel_dielectric(normalize(I), N, (gl_FrontFacing)? 1.0/eta : eta ); + vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0)? normalize(I): vec3(0.0, 0.0, -1.0); + + fresnel = fresnel_dielectric(I_view, N, (gl_FrontFacing)? 1.0/eta : eta ); /* facing */ - facing = abs(dot(normalize(I), N)); + facing = abs(dot(I_view, N)); if(blend != 0.5) { blend = clamp(blend, 0.0, 0.99999); blend = (blend < 0.5)? 2.0*blend: 0.5/(1.0 - blend); @@ -2341,6 +2386,30 @@ void node_tex_coord(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, reflection = (viewinvmat*vec4(view_reflection, 0.0)).xyz; } +void node_tex_coord_background(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, + vec3 attr_orco, vec3 attr_uv, + out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object, + out vec3 camera, out vec3 window, out vec3 reflection) +{ + vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0); + vec4 co_homogenous = (gl_ProjectionMatrixInverse * v); + + vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0); + + co = normalize(co); + vec3 coords = (gl_ModelViewMatrixInverse * co).xyz; + + generated = coords; + normal = -coords; + uv = attr_uv; + object = coords; + + camera = co.xyz; + window = mtex_2d_mapping(I); + + reflection = -coords; +} + /* textures */ void node_tex_gradient(vec3 co, out vec4 color, out float fac) @@ -2367,17 +2436,34 @@ void node_tex_clouds(vec3 co, float size, out vec4 color, out float fac) fac = 1.0; } -void node_tex_environment(vec3 co, sampler2D ima, out vec4 color) +void node_tex_environment_equirectangular(vec3 co, sampler2D ima, out vec4 color) { - float u = (atan(co.y, co.x) + M_PI)/(2.0*M_PI); - float v = atan(co.z, hypot(co.x, co.y))/M_PI + 0.5; + vec3 nco = normalize(co); + float u = -atan(nco.y, nco.x)/(2.0*M_PI) + 0.5; + float v = atan(nco.z, hypot(nco.x, nco.y))/M_PI + 0.5; + + color = texture2D(ima, vec2(u, v)); +} + +void node_tex_environment_mirror_ball(vec3 co, sampler2D ima, out vec4 color) +{ + vec3 nco = normalize(co); + + nco.y -= 1.0; + + float div = 2.0*sqrt(max(-0.5*nco.y, 0.0)); + if(div > 0.0) + nco /= div; + + float u = 0.5*(nco.x + 1.0); + float v = 0.5*(nco.z + 1.0); color = texture2D(ima, vec2(u, v)); } void node_tex_environment_empty(vec3 co, out vec4 color) { - color = vec4(0.0); + color = vec4(1.0, 0.0, 1.0, 1.0); } void node_tex_image(vec3 co, sampler2D ima, out vec4 color, out float alpha) @@ -2485,6 +2571,11 @@ void node_output_material(vec4 surface, vec4 volume, float displacement, out vec result = surface; } +void node_output_world(vec4 surface, vec4 volume, out vec4 result) +{ + result = surface; +} + /* ********************** matcap style render ******************** */ void material_preview_matcap(vec4 color, sampler2D ima, vec4 N, vec4 mask, out vec4 result) diff --git a/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl b/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl index 978b6db1b9a..5f406c959f1 100644 --- a/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl @@ -10,7 +10,7 @@ void main() color += texture2D( textureSource, gl_TexCoord[0].st + vec2(0.0, 0.0)) * 0.3125; color += texture2D( textureSource, gl_TexCoord[0].st + vec2(1.0 * ScaleU.x, 1.0 * ScaleU.y ) ) * 0.234375; color += texture2D( textureSource, gl_TexCoord[0].st + vec2(2.0 * ScaleU.x, 2.0 * ScaleU.y ) ) * 0.09375; - color += texture2D( textureSource, gl_TexCoord[0].st + vec2(3.0 * ScaleU.x, -3.0 * ScaleU.y ) ) * 0.015625; + color += texture2D( textureSource, gl_TexCoord[0].st + vec2(3.0 * ScaleU.x, 3.0 * ScaleU.y ) ) * 0.015625; gl_FragColor = color; } diff --git a/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl b/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl new file mode 100644 index 00000000000..9dbcaeb7a32 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl @@ -0,0 +1,13 @@ + +varying vec3 varposition; +varying vec3 varnormal; + +void main() +{ + /* position does not need to be transformed, we already have it */ + gl_Position = gl_Vertex; + + varposition = gl_Vertex.xyz; + + varnormal = normalize(-varposition); + diff --git a/source/blender/ikplugin/intern/ikplugin_api.c b/source/blender/ikplugin/intern/ikplugin_api.c index 2ca50afb0f2..0f81fb34a63 100644 --- a/source/blender/ikplugin/intern/ikplugin_api.c +++ b/source/blender/ikplugin/intern/ikplugin_api.c @@ -30,19 +30,12 @@ * \ingroup ikplugin */ - - #include "BIK_api.h" #include "BLI_blenlib.h" -#include "BLI_math.h" - -#include "BKE_armature.h" #include "DNA_object_types.h" #include "DNA_action_types.h" #include "DNA_scene_types.h" -#include "DNA_constraint_types.h" -#include "DNA_armature_types.h" #include "ikplugin_api.h" diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c index cd09b56b262..5da06ed91ec 100644 --- a/source/blender/ikplugin/intern/iksolver_plugin.c +++ b/source/blender/ikplugin/intern/iksolver_plugin.c @@ -307,8 +307,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree) /* compute rest basis and its inverse */ copy_m3_m3(rest_basis, bone->bone_mat); - copy_m3_m3(irest_basis, bone->bone_mat); - transpose_m3(irest_basis); + transpose_m3_m3(irest_basis, bone->bone_mat); /* compute basis with rest_basis removed */ invert_m3_m3(iR_parmat, R_parmat); diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c index 612517775f4..556c4beeae7 100644 --- a/source/blender/imbuf/intern/allocimbuf.c +++ b/source/blender/imbuf/intern/allocimbuf.c @@ -47,8 +47,8 @@ #include "MEM_guardedalloc.h" -#include "BLI_threads.h" #include "BLI_utildefines.h" +#include "BLI_threads.h" static SpinLock refcounter_spin; diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index eef7964ef3f..b8f6e66adfe 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -70,12 +70,8 @@ #include "MEM_guardedalloc.h" -#include "DNA_userdef_types.h" - #include "BKE_global.h" -#include "imbuf.h" - #ifdef WITH_AVI # include "AVI_avi.h" #endif @@ -89,7 +85,6 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#include "IMB_allocimbuf.h" #include "IMB_anim.h" #include "IMB_indexer.h" diff --git a/source/blender/imbuf/intern/bmp.c b/source/blender/imbuf/intern/bmp.c index dabeec74a62..8853fe449ba 100644 --- a/source/blender/imbuf/intern/bmp.c +++ b/source/blender/imbuf/intern/bmp.c @@ -36,7 +36,6 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#include "IMB_allocimbuf.h" #include "IMB_filetype.h" #include "IMB_colormanagement.h" diff --git a/source/blender/imbuf/intern/cache.c b/source/blender/imbuf/intern/cache.c index 677c3dbe700..759f8cc82c2 100644 --- a/source/blender/imbuf/intern/cache.c +++ b/source/blender/imbuf/intern/cache.c @@ -22,7 +22,6 @@ * \ingroup imbuf */ - #include "MEM_guardedalloc.h" #include "BLI_utildefines.h" @@ -31,8 +30,6 @@ #include "BLI_memarena.h" #include "BLI_threads.h" - - #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" #include "IMB_filetype.h" diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 5dd6b366a93..43b766f161b 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -44,7 +44,6 @@ #include "DNA_scene_types.h" #include "DNA_space_types.h" -#include "IMB_filter.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" #include "IMB_filetype.h" @@ -53,14 +52,13 @@ #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" -#include "BLI_fileops.h" #include "BLI_math.h" #include "BLI_math_color.h" -#include "BLI_path_util.h" #include "BLI_string.h" #include "BLI_threads.h" #include "BLI_rect.h" +#include "BKE_appdir.h" #include "BKE_colortools.h" #include "BKE_context.h" #include "BKE_image.h" @@ -625,7 +623,7 @@ void colormanagement_init(void) } if (config == NULL) { - configdir = BLI_get_folder(BLENDER_DATAFILES, "colormanagement"); + configdir = BKE_appdir_folder_id(BLENDER_DATAFILES, "colormanagement"); if (configdir) { BLI_join_dirfile(configfile, sizeof(configfile), configdir, BCM_CONFIG_FILE); diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c index 03cd5ecd646..81aef4ac6e4 100644 --- a/source/blender/imbuf/intern/divers.c +++ b/source/blender/imbuf/intern/divers.c @@ -37,7 +37,6 @@ #include "imbuf.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#include "IMB_allocimbuf.h" #include "IMB_filter.h" #include "IMB_colormanagement.h" diff --git a/source/blender/imbuf/intern/filetype.c b/source/blender/imbuf/intern/filetype.c index b6b46c72384..c6e358dd3d2 100644 --- a/source/blender/imbuf/intern/filetype.c +++ b/source/blender/imbuf/intern/filetype.c @@ -51,8 +51,6 @@ #include "quicktime_import.h" #endif -#include "imbuf.h" - static int imb_ftype_default(ImFileType *type, ImBuf *ibuf) { return (ibuf->ftype & type->filetype); diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c index cf875bb247b..8234b01992b 100644 --- a/source/blender/imbuf/intern/imageprocess.c +++ b/source/blender/imbuf/intern/imageprocess.c @@ -166,6 +166,10 @@ void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char outI[4], if (x2 >= in->x) x2 = x2 - in->x; if (y2 >= in->y) y2 = y2 - in->y; + a = u - floorf(u); + b = v - floorf(v); + a_b = a * b; ma_b = (1.0f - a) * b; a_mb = a * (1.0f - b); ma_mb = (1.0f - a) * (1.0f - b); + if (outF) { /* sample including outside of edges of image */ row1 = in->rect_float + in->x * y1 * 4 + 4 * x1; @@ -173,14 +177,16 @@ void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char outI[4], row3 = in->rect_float + in->x * y1 * 4 + 4 * x2; row4 = in->rect_float + in->x * y2 * 4 + 4 * x2; - a = u - floorf(u); - b = v - floorf(v); - a_b = a * b; ma_b = (1.0f - a) * b; a_mb = a * (1.0f - b); ma_mb = (1.0f - a) * (1.0f - b); - outF[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0]; outF[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1]; outF[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2]; outF[3] = ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] + a_b * row4[3]; + + /* clamp here or else we can easily get off-range */ + CLAMP(outF[0], 0.0f, 1.0f); + CLAMP(outF[1], 0.0f, 1.0f); + CLAMP(outF[2], 0.0f, 1.0f); + CLAMP(outF[3], 0.0f, 1.0f); } if (outI) { /* sample including outside of edges of image */ @@ -188,10 +194,6 @@ void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char outI[4], row2I = (unsigned char *)in->rect + in->x * y2 * 4 + 4 * x1; row3I = (unsigned char *)in->rect + in->x * y1 * 4 + 4 * x2; row4I = (unsigned char *)in->rect + in->x * y2 * 4 + 4 * x2; - - a = u - floorf(u); - b = v - floorf(v); - a_b = a * b; ma_b = (1.0f - a) * b; a_mb = a * (1.0f - b); ma_mb = (1.0f - a) * (1.0f - b); /* need to add 0.5 to avoid rounding down (causes darken with the smear brush) * tested with white images and this should not wrap back to zero */ diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c index 547a8df4438..e66be77ecaf 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -1170,7 +1170,7 @@ IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim, IMB_Timecod return context; - (void)tcs_in_use, (void)proxy_sizes_in_use, (void)quality; + UNUSED_VARS(tcs_in_use, proxy_sizes_in_use, quality); } void IMB_anim_index_rebuild(struct IndexBuildContext *context, @@ -1189,7 +1189,7 @@ void IMB_anim_index_rebuild(struct IndexBuildContext *context, #endif } - (void)stop, (void)do_update, (void)progress; + UNUSED_VARS(stop, do_update, progress); } void IMB_anim_index_rebuild_finish(IndexBuildContext *context, short stop) @@ -1207,8 +1207,8 @@ void IMB_anim_index_rebuild_finish(IndexBuildContext *context, short stop) #endif } - (void)stop; - (void)proxy_sizes; /* static defined at top of the file */ + /* static defined at top of the file */ + UNUSED_VARS(stop, proxy_sizes); } diff --git a/source/blender/imbuf/intern/iris.c b/source/blender/imbuf/intern/iris.c index 8f98f240053..ea5acf27e99 100644 --- a/source/blender/imbuf/intern/iris.c +++ b/source/blender/imbuf/intern/iris.c @@ -40,7 +40,6 @@ #include "imbuf.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#include "IMB_allocimbuf.h" #include "IMB_filetype.h" #include "IMB_colormanagement.h" diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c index 18c096450af..8750b825fb6 100644 --- a/source/blender/imbuf/intern/jp2.c +++ b/source/blender/imbuf/intern/jp2.c @@ -29,11 +29,8 @@ #include "BLI_math.h" #include "BLI_fileops.h" -#include "imbuf.h" - #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#include "IMB_allocimbuf.h" #include "IMB_filetype.h" #include "IMB_colormanagement.h" diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c index d00a836667e..3266dc97c78 100644 --- a/source/blender/imbuf/intern/png.c +++ b/source/blender/imbuf/intern/png.c @@ -41,8 +41,6 @@ #include "MEM_guardedalloc.h" -#include "imbuf.h" - #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c index db268546480..318bb7e96e3 100644 --- a/source/blender/imbuf/intern/radiance_hdr.c +++ b/source/blender/imbuf/intern/radiance_hdr.c @@ -38,7 +38,7 @@ */ #ifdef WIN32 -# include <io.h> +# include "BLI_utildefines.h" #endif #include "MEM_guardedalloc.h" @@ -72,10 +72,13 @@ typedef float fCOLOR[3]; #define COPY_RGBE(c1, c2) (c2[RED] = c1[RED], c2[GRN] = c1[GRN], c2[BLU] = c1[BLU], c2[EXP] = c1[EXP]) /* read routines */ -static unsigned char *oldreadcolrs(RGBE *scan, unsigned char *mem, int xmax) +static unsigned char *oldreadcolrs(RGBE *scan, unsigned char *mem, int xmax, unsigned char *mem_eof) { int i, rshift = 0, len = xmax; while (len > 0) { + if (mem_eof - mem < 4) { + return NULL; + } scan[0][RED] = *mem++; scan[0][GRN] = *mem++; scan[0][BLU] = *mem++; @@ -97,34 +100,62 @@ static unsigned char *oldreadcolrs(RGBE *scan, unsigned char *mem, int xmax) return mem; } -static unsigned char *freadcolrs(RGBE *scan, unsigned char *mem, int xmax) +static unsigned char *freadcolrs(RGBE *scan, unsigned char *mem, int xmax, unsigned char *mem_eof) { int i, j, code, val; - if ((xmax < MINELEN) | (xmax > MAXELEN)) return oldreadcolrs(scan, mem, xmax); + if (mem_eof - mem < 4) { + return NULL; + } + + if ((xmax < MINELEN) | (xmax > MAXELEN)) { + return oldreadcolrs(scan, mem, xmax, mem_eof); + } i = *mem++; - if (i != 2) return oldreadcolrs(scan, mem - 1, xmax); + if (i != 2) { + return oldreadcolrs(scan, mem - 1, xmax, mem_eof); + } scan[0][GRN] = *mem++; scan[0][BLU] = *mem++; i = *mem++; - if (((scan[0][BLU] << 8) | i) != xmax) return NULL; - for (i = 0; i < 4; i++) + if (scan[0][GRN] != 2 || scan[0][BLU] & 128) { + scan[0][RED] = 2; + scan[0][EXP] = i; + return oldreadcolrs(scan + 1, mem, xmax - 1, mem_eof); + } + + if (((scan[0][BLU] << 8) | i) != xmax) { + return NULL; + } + + for (i = 0; i < 4; i++) { + if (mem_eof - mem < 2) { + return NULL; + } for (j = 0; j < xmax; ) { code = *mem++; if (code > 128) { code &= 127; val = *mem++; - while (code--) + while (code--) { scan[j++][i] = (unsigned char)val; + } } - else - while (code--) + else { + if (mem_eof - mem < code) { + return NULL; + } + while (code--) { scan[j++][i] = *mem++; + } + } } + } + return mem; } @@ -182,7 +213,7 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, size_t size, int flags, char color int found = 0; int width = 0, height = 0; int x, y; - unsigned char *ptr; + unsigned char *ptr, *mem_eof = mem + size; char oriY[80], oriX[80]; if (imb_is_a_hdr((void *)mem)) { @@ -218,15 +249,14 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, size_t size, int flags, char color if (flags & IB_test) return ibuf; /* read in and decode the actual data */ - sline = (RGBE *)MEM_mallocN(sizeof(RGBE) * width, "radhdr_read_tmpscan"); + sline = (RGBE *)MEM_mallocN(sizeof(*sline) * width, __func__); rect_float = ibuf->rect_float; for (y = 0; y < height; y++) { - ptr = freadcolrs(sline, ptr, width); + ptr = freadcolrs(sline, ptr, width, mem_eof); if (ptr == NULL) { - printf("HDR decode error\n"); - MEM_freeN(sline); - return ibuf; + printf("WARNING! HDR decode error, image may be just truncated, or completely wrong...\n"); + break; } for (x = 0; x < width; x++) { /* convert to ldr */ diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c index dd2406e234e..4001b681ad9 100644 --- a/source/blender/imbuf/intern/rectop.c +++ b/source/blender/imbuf/intern/rectop.c @@ -39,11 +39,9 @@ #include "BLI_math_color_blend.h" #include "BLI_math_vector.h" -#include "imbuf.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#include "IMB_allocimbuf.h" #include "IMB_colormanagement.h" void IMB_blend_color_byte(unsigned char dst[4], unsigned char src1[4], unsigned char src2[4], IMB_BlendMode mode) diff --git a/source/blender/imbuf/intern/rotate.c b/source/blender/imbuf/intern/rotate.c index e98757883be..886944f6190 100644 --- a/source/blender/imbuf/intern/rotate.c +++ b/source/blender/imbuf/intern/rotate.c @@ -39,8 +39,6 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#include "IMB_allocimbuf.h" - void IMB_flipy(struct ImBuf *ibuf) { int x, y; diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c index e480f06da2b..2601fe62c2f 100644 --- a/source/blender/imbuf/intern/scaling.c +++ b/source/blender/imbuf/intern/scaling.c @@ -33,7 +33,6 @@ #include "BLI_utildefines.h" -#include "BLI_math_base.h" #include "BLI_math_color.h" #include "BLI_math_interp.h" #include "MEM_guardedalloc.h" @@ -42,7 +41,6 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#include "IMB_allocimbuf.h" #include "IMB_filter.h" #include "BLI_sys_types.h" // for intptr_t support diff --git a/source/blender/imbuf/intern/targa.c b/source/blender/imbuf/intern/targa.c index 2dcb27a05d4..70b71ec4182 100644 --- a/source/blender/imbuf/intern/targa.c +++ b/source/blender/imbuf/intern/targa.c @@ -44,7 +44,6 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#include "IMB_allocimbuf.h" #include "IMB_filetype.h" #include "IMB_colormanagement.h" diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c index 9a97a142198..94e95c06fea 100644 --- a/source/blender/imbuf/intern/thumbs.c +++ b/source/blender/imbuf/intern/thumbs.c @@ -30,12 +30,13 @@ */ #include <stdio.h> +#include <stdlib.h> #include "BLI_utildefines.h" #include "BLI_string.h" #include "BLI_path_util.h" #include "BLI_fileops.h" -#include "BLI_md5.h" +#include "BLI_hash_md5.h" #include "BLI_system.h" #include BLI_SYSTEM_PID_H @@ -243,9 +244,9 @@ static void thumbname_from_uri(const char *uri, char *thumb, const int thumb_len char hexdigest[33]; unsigned char digest[16]; - md5_buffer(uri, strlen(uri), digest); + BLI_hash_md5_buffer(uri, strlen(uri), digest); hexdigest[0] = '\0'; - BLI_snprintf(thumb, thumb_len, "%s.png", md5_to_hexdigest(digest, hexdigest)); + BLI_snprintf(thumb, thumb_len, "%s.png", BLI_hash_md5_to_hexdigest(digest, hexdigest)); // printf("%s: '%s' --> '%s'\n", __func__, uri, thumb); } diff --git a/source/blender/imbuf/intern/thumbs_blend.c b/source/blender/imbuf/intern/thumbs_blend.c index 73ced4095f9..af353461f1f 100644 --- a/source/blender/imbuf/intern/thumbs_blend.c +++ b/source/blender/imbuf/intern/thumbs_blend.c @@ -29,8 +29,6 @@ #include "zlib.h" -#include "MEM_guardedalloc.h" - #include "BLI_utildefines.h" #include "BLI_endian_switch.h" #include "BLI_fileops.h" diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c index eb8f94cbc6e..e3b8e271387 100644 --- a/source/blender/imbuf/intern/tiff.c +++ b/source/blender/imbuf/intern/tiff.c @@ -53,9 +53,7 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#include "IMB_allocimbuf.h" #include "IMB_filetype.h" -#include "IMB_filter.h" #include "IMB_colormanagement.h" #include "IMB_colormanagement_intern.h" diff --git a/source/blender/imbuf/intern/writeimage.c b/source/blender/imbuf/intern/writeimage.c index d4a9bf7dc09..087330d10d2 100644 --- a/source/blender/imbuf/intern/writeimage.c +++ b/source/blender/imbuf/intern/writeimage.c @@ -41,8 +41,6 @@ #include "IMB_colormanagement.h" #include "IMB_colormanagement_intern.h" -#include "imbuf.h" - static ImBuf *prepare_write_imbuf(ImFileType *type, ImBuf *ibuf) { ImBuf *write_ibuf = ibuf; diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 33d1445fb93..64543709252 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -44,54 +44,65 @@ struct FileData; struct ID; struct PackedFile; struct GPUTexture; - + typedef struct IDPropertyData { void *pointer; ListBase group; - int val, val2; /*note, we actually fit a double into these two ints*/ + int val, val2; /* note, we actually fit a double into these two ints */ } IDPropertyData; typedef struct IDProperty { struct IDProperty *next, *prev; char type, subtype; short flag; - char name[64]; /* MAX_IDPROP_NAME */ - int saved; /* saved is used to indicate if this struct has been saved yet. - * seemed like a good idea as a pad var was needed anyway :)*/ - IDPropertyData data; /* note, alignment for 64 bits */ - int len; /* array length, also (this is important!) string length + 1. - * the idea is to be able to reuse array realloc functions on strings.*/ + char name[64]; /* MAX_IDPROP_NAME */ + + /* saved is used to indicate if this struct has been saved yet. + * seemed like a good idea as a pad var was needed anyway :) */ + int saved; + IDPropertyData data; /* note, alignment for 64 bits */ + + /* array length, also (this is important!) string length + 1. + * the idea is to be able to reuse array realloc functions on strings.*/ + int len; + + /* Strings and arrays are both buffered, though the buffer isn't saved. */ /* totallen is total length of allocated array/string, including a buffer. - * Note that the buffering is mild; the code comes from python's list implementation.*/ - int totallen; /*strings and arrays are both buffered, though the buffer isn't saved.*/ + * Note that the buffering is mild; the code comes from python's list implementation. */ + int totallen; } IDProperty; -#define MAX_IDPROP_NAME 64 -#define DEFAULT_ALLOC_FOR_NULL_STRINGS 64 +#define MAX_IDPROP_NAME 64 +#define DEFAULT_ALLOC_FOR_NULL_STRINGS 64 /*->type*/ -#define IDP_STRING 0 -#define IDP_INT 1 -#define IDP_FLOAT 2 -#define IDP_ARRAY 5 -#define IDP_GROUP 6 -/* the ID link property type hasn't been implemented yet, this will require - * some cleanup of blenkernel, most likely.*/ -#define IDP_ID 7 -#define IDP_DOUBLE 8 -#define IDP_IDPARRAY 9 -#define IDP_NUMTYPES 10 +enum { + IDP_STRING = 0, + IDP_INT = 1, + IDP_FLOAT = 2, + IDP_ARRAY = 5, + IDP_GROUP = 6, + /* the ID link property type hasn't been implemented yet, this will require + * some cleanup of blenkernel, most likely. */ + IDP_ID = 7, + IDP_DOUBLE = 8, + IDP_IDPARRAY = 9, + IDP_NUMTYPES = 10, +}; /*->subtype */ /* IDP_STRING */ -#define IDP_STRING_SUB_UTF8 0 /* default */ -#define IDP_STRING_SUB_BYTE 1 /* arbitrary byte array, _not_ null terminated */ -/*->flag*/ -#define IDP_FLAG_GHOST (1<<7) /* this means the property is set but RNA will return - * false when checking 'RNA_property_is_set', - * currently this is a runtime flag */ +enum { + IDP_STRING_SUB_UTF8 = 0, /* default */ + IDP_STRING_SUB_BYTE = 1, /* arbitrary byte array, _not_ null terminated */ +}; +/*->flag*/ +enum { + IDP_FLAG_GHOST = 1 << 7, /* this means the property is set but RNA will return false when checking + * 'RNA_property_is_set', currently this is a runtime flag */ +}; /* add any future new id property types here.*/ @@ -102,7 +113,7 @@ typedef struct IDProperty { * */ /* 2 characters for ID code and 64 for actual name */ -#define MAX_ID_NAME 66 +#define MAX_ID_NAME 66 /* There's a nasty circular dependency here.... 'void *' to the rescue! I * really wonder why this is needed. */ @@ -129,14 +140,14 @@ typedef struct Library { ID id; ID *idblock; struct FileData *filedata; - char name[1024]; /* path name used for reading, can be relative and edited in the outliner */ - char filepath[1024]; /* absolute filepath, this is only for convenience, - * 'name' is the real path used on file read but in - * some cases its useful to access the absolute one, - * This is set on file read. - * Use BKE_library_filepath_set() rather than - * setting 'name' directly and it will be kept in - * sync - campbell */ + char name[1024]; /* path name used for reading, can be relative and edited in the outliner */ + + /* absolute filepath, this is only for convenience, 'name' is the real path used on file read but in + * some cases its useful to access the absolute one. + * This is set on file read. + * Use BKE_library_filepath_set() rather than setting 'name' directly and it will be kept in sync - campbell */ + char filepath[1024]; + struct Library *parent; /* set for indirectly linked libs, used in the outliner and while reading */ struct PackedFile *packedfile; @@ -239,26 +250,28 @@ typedef struct PreviewImage { #define ID_NEW_US(a) if ( (a)->id.newid) { (a) = (void *)(a)->id.newid; (a)->id.us++; } #define ID_NEW_US2(a) if (((ID *)a)->newid) { (a) = ((ID *)a)->newid; ((ID *)a)->us++; } -/* id->flag: set frist 8 bits always at zero while reading */ -#define LIB_LOCAL 0 -#define LIB_EXTERN 1 -#define LIB_INDIRECT 2 -#define LIB_NEED_EXPAND 8 -#define LIB_TESTEXT (LIB_NEED_EXPAND | LIB_EXTERN) -#define LIB_TESTIND (LIB_NEED_EXPAND | LIB_INDIRECT) -#define LIB_READ 16 -#define LIB_NEED_LINK 32 - -#define LIB_NEW 256 -#define LIB_FAKEUSER 512 -/* free test flag */ -#define LIB_DOIT 1024 -/* tag existing data before linking so we know what is new */ -#define LIB_PRE_EXISTING 2048 -/* runtime */ -#define LIB_ID_RECALC 4096 -#define LIB_ID_RECALC_DATA 8192 -#define LIB_ANIM_NO_RECALC 16384 +/* id->flag: set first 8 bits always at zero while reading */ +enum { + LIB_LOCAL = 0, + LIB_EXTERN = 1 << 0, + LIB_INDIRECT = 1 << 1, + LIB_NEED_EXPAND = 1 << 3, + LIB_TESTEXT = (LIB_NEED_EXPAND | LIB_EXTERN), + LIB_TESTIND = (LIB_NEED_EXPAND | LIB_INDIRECT), + LIB_READ = 1 << 4, + LIB_NEED_LINK = 1 << 5, + + LIB_NEW = 1 << 8, + LIB_FAKEUSER = 1 << 9, + /* free test flag */ + LIB_DOIT = 1 << 10, + /* tag existing data before linking so we know what is new */ + LIB_PRE_EXISTING = 1 << 11, + /* runtime */ + LIB_ID_RECALC = 1 << 12, + LIB_ID_RECALC_DATA = 1 << 13, + LIB_ANIM_NO_RECALC = 1 << 14, +}; #ifdef __cplusplus } diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index dab825c856e..243e747c006 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -250,6 +250,7 @@ typedef enum ePchan_Flag { POSE_ROT = (1 << 1), POSE_SIZE = (1 << 2), /* old IK/cache stuff... */ +#if 0 POSE_IK_MAT = (1 << 3), POSE_UNUSED2 = (1 << 4), POSE_UNUSED3 = (1 << 5), @@ -257,6 +258,7 @@ typedef enum ePchan_Flag { POSE_UNUSED5 = (1 << 7), /* has Standard IK */ POSE_HAS_IK = (1 << 8), +#endif /* IK/Pose solving*/ POSE_CHAIN = (1 << 9), POSE_DONE = (1 << 10), @@ -265,8 +267,10 @@ typedef enum ePchan_Flag { POSE_STRIDE = (1 << 12), /* standard IK solving */ POSE_IKTREE = (1 << 13), +#if 0 /* has Spline IK */ POSE_HAS_IKS = (1 << 14), +#endif /* spline IK solving */ POSE_IKSPLINE = (1 << 15) } ePchan_Flag; @@ -541,7 +545,7 @@ typedef enum eDopeSheet_FilterFlag { ADS_FILTER_ONLYNLA = (1 << 2), /* for 'NLA' editor - only include NLA data from AnimData */ ADS_FILTER_SELEDIT = (1 << 3), /* for Graph Editor - used to indicate whether to include a filtering flag or not */ - /* general filtering 2 */ + /* general filtering */ ADS_FILTER_SUMMARY = (1 << 4), /* for 'DopeSheet' Editors - include 'summary' line */ ADS_FILTER_ONLYOBGROUP = (1 << 5), /* only the objects in the specified object group get used */ @@ -564,6 +568,8 @@ typedef enum eDopeSheet_FilterFlag { ADS_FILTER_NOSPK = (1 << 21), ADS_FILTER_NOLINESTYLE = (1 << 22), ADS_FILTER_NOMODIFIERS = (1 << 23), + ADS_FILTER_NOGPENCIL = (1 << 24), + /* NOTE: all new datablock filters will have to go in filterflag2 (see below) */ /* NLA-specific filters */ ADS_FILTER_NLA_NOACT = (1 << 25), /* if the AnimData block has no NLA data, don't include to just show Action-line */ @@ -581,6 +587,8 @@ typedef enum eDopeSheet_FilterFlag { typedef enum eDopeSheet_Flag { ADS_FLAG_SUMMARY_COLLAPSED = (1 << 0), /* when summary is shown, it is collapsed, so all other channels get hidden */ ADS_FLAG_SHOW_DBFILTERS = (1 << 1) /* show filters for datablocks */ + + /* NOTE: datablock filter flags continued (1 << 10) onwards... */ } eDopeSheet_Flag; diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h index dcde9007cd8..bdf1b62646d 100644 --- a/source/blender/makesdna/DNA_actuator_types.h +++ b/source/blender/makesdna/DNA_actuator_types.h @@ -57,7 +57,7 @@ typedef struct bActionActuator { short blendin; /* Number of frames of blending */ short priority; /* Execution priority */ short layer; /* Animation layer */ - short end_reset; /* Ending the actuator (negative pulse) wont reset the the action to its starting frame */ + short end_reset; /* Ending the actuator (negative pulse) wont reset the action to its starting frame */ short strideaxis; /* Displacement axis */ short blend_mode; /* Layer blending mode */ float stridelength; /* Displacement incurred by cycle */ // not in use diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index b14861fcf47..2fce2be8eaf 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -102,7 +102,7 @@ typedef struct Brush { char vertexpaint_tool; /* active vertex/weight paint blend mode (poorly named) */ char imagepaint_tool; /* active image paint tool */ char mask_tool; /* enum BrushMaskTool, only used if sculpt_tool is SCULPT_TOOL_MASK */ - + float autosmooth_factor; float crease_pinch_factor; diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 87496fb491f..288743d5e2f 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -270,86 +270,101 @@ typedef struct Curve { /* **************** CURVE ********************* */ -/* texflag */ -#define CU_AUTOSPACE 1 - -/* drawflag */ -#define CU_HIDE_HANDLES (1 << 0) -#define CU_HIDE_NORMALS (1 << 1) - -/* flag */ -#define CU_3D 1 -#define CU_FRONT 2 -#define CU_BACK 4 -#define CU_PATH 8 -#define CU_FOLLOW 16 -#define CU_UV_ORCO 32 -#define CU_DEFORM_BOUNDS_OFF 64 -#define CU_STRETCH 128 -/* #define CU_OFFS_PATHDIST 256 */ /* DEPRECATED */ -#define CU_FAST 512 /* Font: no filling inside editmode */ -/* #define CU_RETOPO 1024 */ /* DEPRECATED */ -#define CU_DS_EXPAND 2048 -#define CU_PATH_RADIUS 4096 /* make use of the path radius if this is enabled (default for new curves) */ -#define CU_DEFORM_FILL 8192 /* fill 2d curve after deformation */ -#define CU_FILL_CAPS 16384 /* fill bevel caps */ -#define CU_MAP_TAPER 32768 /* map taper object to beveled area */ - -/* twist mode */ -#define CU_TWIST_Z_UP 0 -// #define CU_TWIST_Y_UP 1 // not used yet -// #define CU_TWIST_X_UP 2 -#define CU_TWIST_MINIMUM 3 -#define CU_TWIST_TANGENT 4 - -/* bevel factor mapping */ +/* Curve.texflag */ enum { - CU_BEVFAC_MAP_RESOLU = 0, + CU_AUTOSPACE = 1, +}; + +/* Curve.drawflag */ +enum { + CU_HIDE_HANDLES = 1 << 0, + CU_HIDE_NORMALS = 1 << 1, +}; + +/* Curve.flag */ +enum { + CU_3D = 1 << 0, + CU_FRONT = 1 << 1, + CU_BACK = 1 << 2, + CU_PATH = 1 << 3, + CU_FOLLOW = 1 << 4, + CU_UV_ORCO = 1 << 5, + CU_DEFORM_BOUNDS_OFF = 1 << 6, + CU_STRETCH = 1 << 7, + /* CU_OFFS_PATHDIST = 1 << 8, */ /* DEPRECATED */ + CU_FAST = 1 << 9, /* Font: no filling inside editmode */ + /* CU_RETOPO = 1 << 10, */ /* DEPRECATED */ + CU_DS_EXPAND = 1 << 11, + CU_PATH_RADIUS = 1 << 12, /* make use of the path radius if this is enabled (default for new curves) */ + CU_DEFORM_FILL = 1 << 13, /* fill 2d curve after deformation */ + CU_FILL_CAPS = 1 << 14, /* fill bevel caps */ + CU_MAP_TAPER = 1 << 15, /* map taper object to beveled area */ +}; + +/* Curve.twist_mode */ +enum { + CU_TWIST_Z_UP = 0, + /* CU_TWIST_Y_UP = 1, */ /* not used yet */ + /* CU_TWIST_X_UP = 2, */ + CU_TWIST_MINIMUM = 3, + CU_TWIST_TANGENT = 4, +}; + +/* Curve.bevfac1_mapping, Curve.bevfac2_mapping, bevel factor mapping */ +enum { + CU_BEVFAC_MAP_RESOLU = 0, CU_BEVFAC_MAP_SEGMENT = 1, - CU_BEVFAC_MAP_SPLINE = 2 + CU_BEVFAC_MAP_SPLINE = 2, +}; + +/* Curve.spacemode */ +enum { + CU_LEFT = 0, + CU_MIDDLE = 1, + CU_RIGHT = 2, + CU_JUSTIFY = 3, + CU_FLUSH = 4, }; -/* spacemode */ -#define CU_LEFT 0 -#define CU_MIDDLE 1 -#define CU_RIGHT 2 -#define CU_JUSTIFY 3 -#define CU_FLUSH 4 - -/* flag (nurb) */ -#define CU_SMOOTH 1 -#define CU_2D 8 /* moved from type since 2.4x */ - -/* type (nurb) */ -#define CU_POLY 0 -#define CU_BEZIER 1 -#define CU_BSPLINE 2 -#define CU_CARDINAL 3 -#define CU_NURBS 4 -#define CU_TYPE (CU_POLY|CU_BEZIER|CU_BSPLINE|CU_CARDINAL|CU_NURBS) - - /* only for adding */ -#define CU_PRIMITIVE 0xF00 - - /* 2 or 4 points */ -#define CU_PRIM_CURVE 0x100 - /* 8 points circle */ -#define CU_PRIM_CIRCLE 0x200 - /* 4x4 patch Nurb */ -#define CU_PRIM_PATCH 0x300 -#define CU_PRIM_TUBE 0x400 -#define CU_PRIM_SPHERE 0x500 -#define CU_PRIM_DONUT 0x600 - /* 5 points, 5th order straight line (for anim path) */ -#define CU_PRIM_PATH 0x700 - - -/* flagu flagv (nurb) */ -#define CU_NURB_CYCLIC 1 -#define CU_NURB_ENDPOINT 2 -#define CU_NURB_BEZIER 4 - -#define CU_ACT_NONE -1 +/* Nurb.flag */ +enum { + CU_SMOOTH = 1 << 0, + CU_2D = 1 << 3, /* moved from type since 2.4x */ +}; + +/* Nurb.type */ +enum { + CU_POLY = 0, + CU_BEZIER = 1, + CU_BSPLINE = 2, + CU_CARDINAL = 3, + CU_NURBS = 4, + CU_TYPE = (CU_POLY | CU_BEZIER | CU_BSPLINE | CU_CARDINAL | CU_NURBS), + + /* only for adding */ + CU_PRIMITIVE = 0xF00, + + /* 2 or 4 points */ + CU_PRIM_CURVE = 0x100, + /* 8 points circle */ + CU_PRIM_CIRCLE = 0x200, + /* 4x4 patch Nurb */ + CU_PRIM_PATCH = 0x300, + CU_PRIM_TUBE = 0x400, + CU_PRIM_SPHERE = 0x500, + CU_PRIM_DONUT = 0x600, + /* 5 points, 5th order straight line (for anim path) */ + CU_PRIM_PATH = 0x700, +}; + +/* Nurb.flagu, Nurb.flagv */ +enum { + CU_NURB_CYCLIC = 1 << 0, + CU_NURB_ENDPOINT = 1 << 1, + CU_NURB_BEZIER = 1 << 2, +}; + +#define CU_ACT_NONE -1 /* *************** BEZTRIPLE **************** */ @@ -366,9 +381,9 @@ typedef enum eBezTriple_Handle { /* interpolation modes (used only for BezTriple->ipo) */ typedef enum eBezTriple_Interpolation { /* traditional interpolation */ - BEZT_IPO_CONST = 0, /* constant interpolation */ - BEZT_IPO_LIN = 1, /* linear interpolation */ - BEZT_IPO_BEZ = 2, /* bezier interpolation */ + BEZT_IPO_CONST = 0, /* constant interpolation */ + BEZT_IPO_LIN = 1, /* linear interpolation */ + BEZT_IPO_BEZ = 2, /* bezier interpolation */ /* easing equations */ BEZT_IPO_BACK = 3, @@ -380,7 +395,7 @@ typedef enum eBezTriple_Interpolation { BEZT_IPO_QUAD = 9, BEZT_IPO_QUART = 10, BEZT_IPO_QUINT = 11, - BEZT_IPO_SINE = 12 + BEZT_IPO_SINE = 12, } eBezTriple_Interpolation; /* easing modes (used only for Keyframes - BezTriple->easing) */ @@ -389,15 +404,15 @@ typedef enum eBezTriple_Easing { BEZT_IPO_EASE_IN = 1, BEZT_IPO_EASE_OUT = 2, - BEZT_IPO_EASE_IN_OUT = 3 + BEZT_IPO_EASE_IN_OUT = 3, } eBezTriple_Easing; /* types of keyframe (used only for BezTriple->hide when BezTriple is used in F-Curves) */ typedef enum eBezTriple_KeyframeType { - BEZT_KEYTYPE_KEYFRAME = 0, /* default - 'proper' Keyframe */ - BEZT_KEYTYPE_EXTREME = 1, /* 'extreme' keyframe */ - BEZT_KEYTYPE_BREAKDOWN = 2, /* 'breakdown' keyframe */ - BEZT_KEYTYPE_JITTER = 3, /* 'jitter' keyframe (for adding 'filler' secondary motion) */ + BEZT_KEYTYPE_KEYFRAME = 0, /* default - 'proper' Keyframe */ + BEZT_KEYTYPE_EXTREME = 1, /* 'extreme' keyframe */ + BEZT_KEYTYPE_BREAKDOWN = 2, /* 'breakdown' keyframe */ + BEZT_KEYTYPE_JITTER = 3, /* 'jitter' keyframe (for adding 'filler' secondary motion) */ } eBezTriple_KeyframeType; /* checks if the given BezTriple is selected */ @@ -406,14 +421,16 @@ typedef enum eBezTriple_KeyframeType { /* *************** CHARINFO **************** */ -/* flag */ -/* note: CU_CHINFO_WRAP and CU_CHINFO_SMALLCAPS_TEST are set dynamically */ -#define CU_CHINFO_BOLD (1<<0) -#define CU_CHINFO_ITALIC (1<<1) -#define CU_CHINFO_UNDERLINE (1<<2) -#define CU_CHINFO_WRAP (1<<3) /* wordwrap occurred here */ -#define CU_CHINFO_SMALLCAPS (1<<4) -#define CU_CHINFO_SMALLCAPS_CHECK (1<<5) /* set at runtime, checks if case switching is needed */ +/* CharInfo.flag */ +enum { + /* note: CU_CHINFO_WRAP and CU_CHINFO_SMALLCAPS_TEST are set dynamically */ + CU_CHINFO_BOLD = 1 << 0, + CU_CHINFO_ITALIC = 1 << 1, + CU_CHINFO_UNDERLINE = 1 << 2, + CU_CHINFO_WRAP = 1 << 3, /* wordwrap occurred here */ + CU_CHINFO_SMALLCAPS = 1 << 4, + CU_CHINFO_SMALLCAPS_CHECK = 1 << 5, /* set at runtime, checks if case switching is needed */ +}; /* mixed with KEY_LINEAR but define here since only curve supports */ #define KEY_CU_EASE 3 diff --git a/source/blender/makesdna/DNA_dynamicpaint_types.h b/source/blender/makesdna/DNA_dynamicpaint_types.h index d2b95c959b3..dece93af122 100644 --- a/source/blender/makesdna/DNA_dynamicpaint_types.h +++ b/source/blender/makesdna/DNA_dynamicpaint_types.h @@ -33,55 +33,71 @@ struct CurveMapping; struct PaintSurfaceData; /* surface format */ -#define MOD_DPAINT_SURFACE_F_PTEX 0 -#define MOD_DPAINT_SURFACE_F_VERTEX 1 -#define MOD_DPAINT_SURFACE_F_IMAGESEQ 2 +enum { + MOD_DPAINT_SURFACE_F_PTEX = 0, + MOD_DPAINT_SURFACE_F_VERTEX = 1, + MOD_DPAINT_SURFACE_F_IMAGESEQ = 2, +}; /* surface type */ -#define MOD_DPAINT_SURFACE_T_PAINT 0 -#define MOD_DPAINT_SURFACE_T_DISPLACE 1 -#define MOD_DPAINT_SURFACE_T_WEIGHT 2 -#define MOD_DPAINT_SURFACE_T_WAVE 3 +enum { + MOD_DPAINT_SURFACE_T_PAINT = 0, + MOD_DPAINT_SURFACE_T_DISPLACE = 1, + MOD_DPAINT_SURFACE_T_WEIGHT = 2, + MOD_DPAINT_SURFACE_T_WAVE = 3, +}; /* surface flags */ -#define MOD_DPAINT_ACTIVE (1<<0) /* Is surface enabled */ +enum { + MOD_DPAINT_ACTIVE = 1 << 0, /* Is surface enabled */ -#define MOD_DPAINT_ANTIALIAS (1<<1) /* do antialiasing */ -#define MOD_DPAINT_DISSOLVE (1<<2) /* do dissolve */ -#define MOD_DPAINT_MULALPHA (1<<3) /* Multiply color by alpha when saving image */ -#define MOD_DPAINT_DISSOLVE_LOG (1<<4) /* Use 1/x for surface dissolve */ -#define MOD_DPAINT_DRY_LOG (1<<5) /* Use 1/x for drying paint */ -#define MOD_DPAINT_PREVIEW (1<<6) /* preview this surface on viewport*/ + MOD_DPAINT_ANTIALIAS = 1 << 1, /* do antialiasing */ + MOD_DPAINT_DISSOLVE = 1 << 2, /* do dissolve */ + MOD_DPAINT_MULALPHA = 1 << 3, /* Multiply color by alpha when saving image */ + MOD_DPAINT_DISSOLVE_LOG = 1 << 4, /* Use 1/x for surface dissolve */ + MOD_DPAINT_DRY_LOG = 1 << 5, /* Use 1/x for drying paint */ + MOD_DPAINT_PREVIEW = 1 << 6, /* preview this surface on viewport*/ -#define MOD_DPAINT_WAVE_OPEN_BORDERS (1<<7) /* passes waves through mesh edges */ -#define MOD_DPAINT_DISP_INCREMENTAL (1<<8) /* builds displace on top of earlier values */ -#define MOD_DPAINT_USE_DRYING (1<<9) /* use drying */ + MOD_DPAINT_WAVE_OPEN_BORDERS = 1 << 7, /* passes waves through mesh edges */ + MOD_DPAINT_DISP_INCREMENTAL = 1 << 8, /* builds displace on top of earlier values */ + MOD_DPAINT_USE_DRYING = 1 << 9, /* use drying */ -#define MOD_DPAINT_OUT1 (1<<10) /* output primary surface */ -#define MOD_DPAINT_OUT2 (1<<11) /* output secondary surface */ + MOD_DPAINT_OUT1 = 1 << 10, /* output primary surface */ + MOD_DPAINT_OUT2 = 1 << 11, /* output secondary surface */ +}; /* image_fileformat */ -#define MOD_DPAINT_IMGFORMAT_PNG 0 -#define MOD_DPAINT_IMGFORMAT_OPENEXR 1 +enum { + MOD_DPAINT_IMGFORMAT_PNG = 0, + MOD_DPAINT_IMGFORMAT_OPENEXR = 1, +}; /* disp_format */ -#define MOD_DPAINT_DISP_DISPLACE 0 /* displacement output displace map */ -#define MOD_DPAINT_DISP_DEPTH 1 /* displacement output depth data */ +enum { + MOD_DPAINT_DISP_DISPLACE = 0, /* displacement output displace map */ + MOD_DPAINT_DISP_DEPTH = 1, /* displacement output depth data */ +}; /* effect */ -#define MOD_DPAINT_EFFECT_DO_SPREAD (1<<0) /* do spread effect */ -#define MOD_DPAINT_EFFECT_DO_DRIP (1<<1) /* do drip effect */ -#define MOD_DPAINT_EFFECT_DO_SHRINK (1<<2) /* do shrink effect */ +enum { + MOD_DPAINT_EFFECT_DO_SPREAD = 1 << 0, /* do spread effect */ + MOD_DPAINT_EFFECT_DO_DRIP = 1 << 1, /* do drip effect */ + MOD_DPAINT_EFFECT_DO_SHRINK = 1 << 2, /* do shrink effect */ +}; /* preview_id */ -#define MOD_DPAINT_SURFACE_PREV_PAINT 0 -#define MOD_DPAINT_SURFACE_PREV_WETMAP 1 +enum { + MOD_DPAINT_SURFACE_PREV_PAINT = 0, + MOD_DPAINT_SURFACE_PREV_WETMAP = 1, +}; /* init_color_type */ -#define MOD_DPAINT_INITIAL_NONE 0 -#define MOD_DPAINT_INITIAL_COLOR 1 -#define MOD_DPAINT_INITIAL_TEXTURE 2 -#define MOD_DPAINT_INITIAL_VERTEXCOLOR 3 +enum { + MOD_DPAINT_INITIAL_NONE = 0, + MOD_DPAINT_INITIAL_COLOR = 1, + MOD_DPAINT_INITIAL_TEXTURE = 2, + MOD_DPAINT_INITIAL_VERTEXCOLOR = 3, +}; typedef struct DynamicPaintSurface { @@ -136,11 +152,14 @@ typedef struct DynamicPaintSurface { } DynamicPaintSurface; /* canvas flags */ -#if 0 /* This should not be needed, having a valid WEIGHT_MCOL layer should be enough. - * And if not, should be a general flag. But seems unnecessary for now... */ -#define MOD_DPAINT_PREVIEW_READY (1<<0) /* if viewport preview is ready */ +enum { + /* This should not be needed, having a valid WEIGHT_MCOL layer should be enough. + * And if not, should be a general flag. But seems unnecessary for now... */ +#if 0 + MOD_DPAINT_PREVIEW_READY = 1 << 0, /* if viewport preview is ready */ #endif -#define MOD_DPAINT_BAKING (1<<1) /* surface is already baking, so it wont get updated (loop) */ + MOD_DPAINT_BAKING = 1 << 1, /* surface is already baking, so it wont get updated (loop) */ +}; /* Canvas settings */ typedef struct DynamicPaintCanvasSettings { @@ -157,47 +176,56 @@ typedef struct DynamicPaintCanvasSettings { /* flags */ -#define MOD_DPAINT_PART_RAD (1<<0) /* use particle radius */ -#define MOD_DPAINT_USE_MATERIAL (1<<1) /* use object material */ -#define MOD_DPAINT_ABS_ALPHA (1<<2) /* don't increase alpha unless - * paint alpha is higher than existing */ -#define MOD_DPAINT_ERASE (1<<3) /* removes paint */ - -#define MOD_DPAINT_RAMP_ALPHA (1<<4) /* only read falloff ramp alpha */ -#define MOD_DPAINT_PROX_PROJECT (1<<5) /* do proximity check only in defined dir */ -#define MOD_DPAINT_INVERSE_PROX (1<<6) /* inverse proximity painting */ -#define MOD_DPAINT_NEGATE_VOLUME (1<<7) /* negates volume influence on "volume + prox" mode */ - -#define MOD_DPAINT_DO_SMUDGE (1<<8) /* brush smudges existing paint */ -#define MOD_DPAINT_VELOCITY_ALPHA (1<<9) /* multiply brush influence by velocity */ -#define MOD_DPAINT_VELOCITY_COLOR (1<<10) /* replace brush color by velocity color ramp */ -#define MOD_DPAINT_VELOCITY_DEPTH (1<<11) /* multiply brush intersection depth by velocity */ - -#define MOD_DPAINT_USES_VELOCITY ((1<<8)|(1<<9)|(1<<10)|(1<<11)) +enum { + MOD_DPAINT_PART_RAD = 1 << 0, /* use particle radius */ + MOD_DPAINT_USE_MATERIAL = 1 << 1, /* use object material */ + MOD_DPAINT_ABS_ALPHA = 1 << 2, /* don't increase alpha unless paint alpha is higher than existing */ + MOD_DPAINT_ERASE = 1 << 3, /* removes paint */ + + MOD_DPAINT_RAMP_ALPHA = 1 << 4, /* only read falloff ramp alpha */ + MOD_DPAINT_PROX_PROJECT = 1 << 5, /* do proximity check only in defined dir */ + MOD_DPAINT_INVERSE_PROX = 1 << 6, /* inverse proximity painting */ + MOD_DPAINT_NEGATE_VOLUME = 1 << 7, /* negates volume influence on "volume + prox" mode */ + + MOD_DPAINT_DO_SMUDGE = 1 << 8, /* brush smudges existing paint */ + MOD_DPAINT_VELOCITY_ALPHA = 1 << 9, /* multiply brush influence by velocity */ + MOD_DPAINT_VELOCITY_COLOR = 1 << 10, /* replace brush color by velocity color ramp */ + MOD_DPAINT_VELOCITY_DEPTH = 1 << 11, /* multiply brush intersection depth by velocity */ + + MOD_DPAINT_USES_VELOCITY = (MOD_DPAINT_DO_SMUDGE | MOD_DPAINT_VELOCITY_ALPHA | + MOD_DPAINT_VELOCITY_COLOR | MOD_DPAINT_VELOCITY_DEPTH), +}; /* collision type */ -#define MOD_DPAINT_COL_VOLUME 0 /* paint with mesh volume */ -#define MOD_DPAINT_COL_DIST 1 /* paint using distance to mesh surface */ -#define MOD_DPAINT_COL_VOLDIST 2 /* use both volume and distance */ -#define MOD_DPAINT_COL_PSYS 3 /* use particle system */ -#define MOD_DPAINT_COL_POINT 4 /* use distance to object center point */ +enum { + MOD_DPAINT_COL_VOLUME = 0, /* paint with mesh volume */ + MOD_DPAINT_COL_DIST = 1, /* paint using distance to mesh surface */ + MOD_DPAINT_COL_VOLDIST = 2, /* use both volume and distance */ + MOD_DPAINT_COL_PSYS = 3, /* use particle system */ + MOD_DPAINT_COL_POINT = 4, /* use distance to object center point */ +}; /* proximity_falloff */ -#define MOD_DPAINT_PRFALL_CONSTANT 0 /* no-falloff */ -#define MOD_DPAINT_PRFALL_SMOOTH 1 /* smooth, linear falloff */ -#define MOD_DPAINT_PRFALL_RAMP 2 /* use color ramp */ +enum { + MOD_DPAINT_PRFALL_CONSTANT = 0, /* no-falloff */ + MOD_DPAINT_PRFALL_SMOOTH = 1, /* smooth, linear falloff */ + MOD_DPAINT_PRFALL_RAMP = 2, /* use color ramp */ +}; /* wave_brush_type */ -#define MOD_DPAINT_WAVEB_DEPTH 0 /* use intersection depth */ -#define MOD_DPAINT_WAVEB_FORCE 1 /* act as a force on intersection area */ -#define MOD_DPAINT_WAVEB_REFLECT 2 /* obstacle that reflects waves */ -#define MOD_DPAINT_WAVEB_CHANGE 3 /* use change of intersection depth from previous frame */ +enum { + MOD_DPAINT_WAVEB_DEPTH = 0, /* use intersection depth */ + MOD_DPAINT_WAVEB_FORCE = 1, /* act as a force on intersection area */ + MOD_DPAINT_WAVEB_REFLECT = 2, /* obstacle that reflects waves */ + MOD_DPAINT_WAVEB_CHANGE = 3, /* use change of intersection depth from previous frame */ +}; /* brush ray_dir */ -#define MOD_DPAINT_RAY_CANVAS 0 -#define MOD_DPAINT_RAY_BRUSH_AVG 1 -#define MOD_DPAINT_RAY_ZPLUS 2 - +enum { + MOD_DPAINT_RAY_CANVAS = 0, + MOD_DPAINT_RAY_BRUSH_AVG = 1, + MOD_DPAINT_RAY_ZPLUS = 2, +}; /* Brush settings */ typedef struct DynamicPaintBrushSettings { diff --git a/source/blender/makesdna/DNA_freestyle_types.h b/source/blender/makesdna/DNA_freestyle_types.h index d099511a088..2359d1e9738 100644 --- a/source/blender/makesdna/DNA_freestyle_types.h +++ b/source/blender/makesdna/DNA_freestyle_types.h @@ -44,60 +44,74 @@ struct Group; struct Text; /* FreestyleConfig::flags */ -#define FREESTYLE_SUGGESTIVE_CONTOURS_FLAG (1 << 0) -#define FREESTYLE_RIDGES_AND_VALLEYS_FLAG (1 << 1) -#define FREESTYLE_MATERIAL_BOUNDARIES_FLAG (1 << 2) -#define FREESTYLE_FACE_SMOOTHNESS_FLAG (1 << 3) -#define FREESTYLE_ADVANCED_OPTIONS_FLAG (1 << 4) -#define FREESTYLE_CULLING (1 << 5) -#define FREESTYLE_VIEW_MAP_CACHE (1 << 6) +enum { + FREESTYLE_SUGGESTIVE_CONTOURS_FLAG = 1 << 0, + FREESTYLE_RIDGES_AND_VALLEYS_FLAG = 1 << 1, + FREESTYLE_MATERIAL_BOUNDARIES_FLAG = 1 << 2, + FREESTYLE_FACE_SMOOTHNESS_FLAG = 1 << 3, + FREESTYLE_ADVANCED_OPTIONS_FLAG = 1 << 4, + FREESTYLE_CULLING = 1 << 5, + FREESTYLE_VIEW_MAP_CACHE = 1 << 6, +}; /* FreestyleConfig::mode */ -#define FREESTYLE_CONTROL_SCRIPT_MODE 1 -#define FREESTYLE_CONTROL_EDITOR_MODE 2 +enum { + FREESTYLE_CONTROL_SCRIPT_MODE = 1, + FREESTYLE_CONTROL_EDITOR_MODE = 2, +}; /* FreestyleLineSet::flags */ -#define FREESTYLE_LINESET_CURRENT (1 << 0) -#define FREESTYLE_LINESET_ENABLED (1 << 1) -#define FREESTYLE_LINESET_FE_NOT (1 << 2) -#define FREESTYLE_LINESET_FE_AND (1 << 3) -#define FREESTYLE_LINESET_GR_NOT (1 << 4) -#define FREESTYLE_LINESET_FM_NOT (1 << 5) -#define FREESTYLE_LINESET_FM_BOTH (1 << 6) +enum { + FREESTYLE_LINESET_CURRENT = 1 << 0, + FREESTYLE_LINESET_ENABLED = 1 << 1, + FREESTYLE_LINESET_FE_NOT = 1 << 2, + FREESTYLE_LINESET_FE_AND = 1 << 3, + FREESTYLE_LINESET_GR_NOT = 1 << 4, + FREESTYLE_LINESET_FM_NOT = 1 << 5, + FREESTYLE_LINESET_FM_BOTH = 1 << 6, +}; /* FreestyleLineSet::selection */ -#define FREESTYLE_SEL_VISIBILITY (1 << 0) -#define FREESTYLE_SEL_EDGE_TYPES (1 << 1) -#define FREESTYLE_SEL_GROUP (1 << 2) -#define FREESTYLE_SEL_IMAGE_BORDER (1 << 3) -#define FREESTYLE_SEL_FACE_MARK (1 << 4) +enum { + FREESTYLE_SEL_VISIBILITY = 1 << 0, + FREESTYLE_SEL_EDGE_TYPES = 1 << 1, + FREESTYLE_SEL_GROUP = 1 << 2, + FREESTYLE_SEL_IMAGE_BORDER = 1 << 3, + FREESTYLE_SEL_FACE_MARK = 1 << 4, +}; /* FreestyleLineSet::edge_types, exclude_edge_types */ -#define FREESTYLE_FE_SILHOUETTE (1 << 0) -#define FREESTYLE_FE_BORDER (1 << 1) -#define FREESTYLE_FE_CREASE (1 << 2) -#define FREESTYLE_FE_RIDGE_VALLEY (1 << 3) -/* Note: FREESTYLE_FE_VALLEY = (1 << 4) is no longer used */ -#define FREESTYLE_FE_SUGGESTIVE_CONTOUR (1 << 5) -#define FREESTYLE_FE_MATERIAL_BOUNDARY (1 << 6) -#define FREESTYLE_FE_CONTOUR (1 << 7) -#define FREESTYLE_FE_EXTERNAL_CONTOUR (1 << 8) -#define FREESTYLE_FE_EDGE_MARK (1 << 9) +enum { + FREESTYLE_FE_SILHOUETTE = 1 << 0, + FREESTYLE_FE_BORDER = 1 << 1, + FREESTYLE_FE_CREASE = 1 << 2, + FREESTYLE_FE_RIDGE_VALLEY = 1 << 3, + /* FREESTYLE_FE_VALLEY = 1 << 4, */ /* No longer used */ + FREESTYLE_FE_SUGGESTIVE_CONTOUR = 1 << 5, + FREESTYLE_FE_MATERIAL_BOUNDARY = 1 << 6, + FREESTYLE_FE_CONTOUR = 1 << 7, + FREESTYLE_FE_EXTERNAL_CONTOUR = 1 << 8, + FREESTYLE_FE_EDGE_MARK = 1 << 9, +}; /* FreestyleLineSet::qi */ -#define FREESTYLE_QI_VISIBLE 1 -#define FREESTYLE_QI_HIDDEN 2 -#define FREESTYLE_QI_RANGE 3 +enum { + FREESTYLE_QI_VISIBLE = 1, + FREESTYLE_QI_HIDDEN = 2, + FREESTYLE_QI_RANGE = 3, +}; /* FreestyleConfig::raycasting_algorithm */ /* Defines should be replaced with ViewMapBuilder::visibility_algo */ -#define FREESTYLE_ALGO_REGULAR 1 -#define FREESTYLE_ALGO_FAST 2 -#define FREESTYLE_ALGO_VERYFAST 3 -#define FREESTYLE_ALGO_CULLED_ADAPTIVE_TRADITIONAL 4 -#define FREESTYLE_ALGO_ADAPTIVE_TRADITIONAL 5 -#define FREESTYLE_ALGO_CULLED_ADAPTIVE_CUMULATIVE 6 -#define FREESTYLE_ALGO_ADAPTIVE_CUMULATIVE 7 +enum { + FREESTYLE_ALGO_REGULAR = 1, + FREESTYLE_ALGO_FAST = 2, + FREESTYLE_ALGO_VERYFAST = 3, + FREESTYLE_ALGO_CULLED_ADAPTIVE_TRADITIONAL = 4, + FREESTYLE_ALGO_ADAPTIVE_TRADITIONAL = 5, + FREESTYLE_ALGO_CULLED_ADAPTIVE_CUMULATIVE = 6, + FREESTYLE_ALGO_ADAPTIVE_CUMULATIVE = 7, +}; typedef struct FreestyleLineSet { struct FreestyleLineSet *next, *prev; diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h index 2bf874d3a85..3fb047ebbe7 100644 --- a/source/blender/makesdna/DNA_gpencil_types.h +++ b/source/blender/makesdna/DNA_gpencil_types.h @@ -33,6 +33,9 @@ #include "DNA_listBase.h" #include "DNA_ID.h" +struct AnimData; + + /* Grease-Pencil Annotations - 'Stroke Point' * -> Coordinates may either be 2d or 3d depending on settings at the time * -> Coordinates of point on stroke, in proportions of window size @@ -42,8 +45,15 @@ typedef struct bGPDspoint { float x, y, z; /* co-ordinates of point (usually 2d, but can be 3d as well) */ float pressure; /* pressure of input device (from 0 to 1) at this point */ float time; /* seconds since start of stroke */ + int flag; /* additional options (NOTE: can shrink this field down later if needed) */ } bGPDspoint; +/* bGPDspoint->flag */ +typedef enum eGPDspoint_Flag { + /* stroke point is selected (for editing) */ + GP_SPOINT_SELECT = (1 << 0) +} eGPSPoint_Flag; + /* Grease-Pencil Annotations - 'Stroke' * -> A stroke represents a (simplified version) of the curve * drawn by the user in one 'mousedown'->'mouseup' operation @@ -61,15 +71,18 @@ typedef struct bGPDstroke { } bGPDstroke; /* bGPDstroke->flag */ +typedef enum eGPDstroke_Flag { /* stroke is in 3d-space */ -#define GP_STROKE_3DSPACE (1<<0) + GP_STROKE_3DSPACE = (1 << 0), /* stroke is in 2d-space */ -#define GP_STROKE_2DSPACE (1<<1) + GP_STROKE_2DSPACE = (1 << 1), /* stroke is in 2d-space (but with special 'image' scaling) */ -#define GP_STROKE_2DIMAGE (1<<2) + GP_STROKE_2DIMAGE = (1 << 2), + /* stroke is selected */ + GP_STROKE_SELECT = (1 << 3), /* only for use with stroke-buffer (while drawing eraser) */ -#define GP_STROKE_ERASER (1<<15) - + GP_STROKE_ERASER = (1 << 15) +} eGPDstroke_Flag; /* Grease-Pencil Annotations - 'Frame' * -> Acts as storage for the 'image' formed by strokes @@ -80,15 +93,18 @@ typedef struct bGPDframe { ListBase strokes; /* list of the simplified 'strokes' that make up the frame's data */ int framenum; /* frame number of this frame */ - int flag; /* temp settings */ + + short flag; /* temp settings */ + short key_type; /* keyframe type (eBezTriple_KeyframeType) */ } bGPDframe; -/* bGPDframe->flag */ +/* bGPDframe->flag */ +typedef enum eGPDframe_Flag { /* frame is being painted on */ -#define GP_FRAME_PAINT (1<<0) + GP_FRAME_PAINT = (1 << 0), /* for editing in Action Editor */ -#define GP_FRAME_SELECT (1<<1) - + GP_FRAME_SELECT = (1 << 1) +} eGPDframe_Flag; /* Grease-Pencil Annotations - 'Layer' */ typedef struct bGPDlayer { @@ -97,38 +113,52 @@ typedef struct bGPDlayer { ListBase frames; /* list of annotations to display for frames (bGPDframe list) */ bGPDframe *actframe; /* active frame (should be the frame that is currently being displayed) */ - int flag; /* settings for layer */ + short flag; /* settings for layer */ short thickness; /* current thickness to apply to strokes */ - short gstep; /* max number of frames between active and ghost to show (0=only those on either side) */ + + short gstep; /* Ghosts Before: max number of ghost frames to show between active frame and the one before it (0 = only the ghost itself) */ + short gstep_next; /* Ghosts After: max number of ghost frames to show after active frame and the following it (0 = only the ghost itself) */ + + float gcolor_prev[3]; /* optional color for ghosts before the active frame */ + float gcolor_next[3]; /* optional color for ghosts after the active frame */ float color[4]; /* color that should be used to draw all the strokes in this layer */ + float fill[4]; /* color that should be used for drawing "fills" for strokes */ char info[128]; /* optional reference info about this layer (i.e. "director's comments, 12/3") * this is used for the name of the layer too and kept unique. */ } bGPDlayer; /* bGPDlayer->flag */ +typedef enum eGPDlayer_Flag { /* don't display layer */ -#define GP_LAYER_HIDE (1<<0) + GP_LAYER_HIDE = (1 << 0), /* protected from further editing */ -#define GP_LAYER_LOCKED (1<<1) + GP_LAYER_LOCKED = (1 << 1), /* layer is 'active' layer being edited */ -#define GP_LAYER_ACTIVE (1<<2) + GP_LAYER_ACTIVE = (1 << 2), /* draw points of stroke for debugging purposes */ -#define GP_LAYER_DRAWDEBUG (1<<3) - /* do onionskinning */ -#define GP_LAYER_ONIONSKIN (1<<4) + GP_LAYER_DRAWDEBUG = (1 << 3), + /* do onion skinning */ + GP_LAYER_ONIONSKIN = (1 << 4), /* for editing in Action Editor */ -#define GP_LAYER_SELECT (1<<5) + GP_LAYER_SELECT = (1 << 5), /* current frame for layer can't be changed */ -#define GP_LAYER_FRAMELOCK (1<<6) + GP_LAYER_FRAMELOCK = (1 << 6), /* don't render xray (which is default) */ -#define GP_LAYER_NO_XRAY (1<<7) - + GP_LAYER_NO_XRAY = (1 << 7), + /* use custom color for ghosts before current frame */ + GP_LAYER_GHOST_PREVCOL = (1 << 8), + /* use custom color for ghosts after current frame */ + GP_LAYER_GHOST_NEXTCOL = (1 << 9), + /* "volumetric" strokes (i.e. GLU Quadric discs in 3D) */ + GP_LAYER_VOLUMETRIC = (1 << 10), +} eGPDlayer_Flag; /* Grease-Pencil Annotations - 'DataBlock' */ typedef struct bGPdata { - ID id; /* Grease Pencil data is */ + ID id; /* Grease Pencil data is a datablock */ + struct AnimData *adt; /* animation data - for animating draw settings */ /* saved Grease-Pencil data */ ListBase layers; /* bGPDlayers */ @@ -144,23 +174,33 @@ typedef struct bGPdata { } bGPdata; /* bGPdata->flag */ -// XXX many of these flags should be deprecated for more general ideas in 2.5 +/* NOTE: A few flags have been deprecated since early 2.5, + * since they have been made redundant by interaction + * changes made during the porting process. + */ +typedef enum eGPdata_Flag { /* don't allow painting to occur at all */ - // XXX is deprecated - not well understood -// #define GP_DATA_LMBPLOCK (1<<0) + /* GP_DATA_LMBPLOCK = (1 << 0), */ + /* show debugging info in viewport (i.e. status print) */ -#define GP_DATA_DISPINFO (1<<1) + GP_DATA_DISPINFO = (1 << 1), /* in Action Editor, show as expanded channel */ -#define GP_DATA_EXPAND (1<<2) + GP_DATA_EXPAND = (1 << 2), + /* is the block overriding all clicks? */ - // XXX is deprecated - nasty old concept -// #define GP_DATA_EDITPAINT (1<<3) + /* GP_DATA_EDITPAINT = (1 << 3), */ + /* new strokes are added in viewport space */ -#define GP_DATA_VIEWALIGN (1<<4) - /* Project into the screens Z values */ -#define GP_DATA_DEPTH_VIEW (1<<5) -#define GP_DATA_DEPTH_STROKE (1<<6) + GP_DATA_VIEWALIGN = (1 << 4), + + /* Project into the screen's Z values */ + GP_DATA_DEPTH_VIEW = (1 << 5), + GP_DATA_DEPTH_STROKE = (1 << 6), -#define GP_DATA_DEPTH_STROKE_ENDPOINTS (1<<7) + GP_DATA_DEPTH_STROKE_ENDPOINTS = (1 << 7), + + /* Stroke Editing Mode - Toggle to enable alternative keymap for easier editing of stroke points */ + GP_DATA_STROKE_EDITMODE = (1 << 8) +} eGPdata_Flag; #endif /* __DNA_GPENCIL_TYPES_H__ */ diff --git a/source/blender/makesdna/DNA_key_types.h b/source/blender/makesdna/DNA_key_types.h index f5ce3c8d8c1..16e40fa52e1 100644 --- a/source/blender/makesdna/DNA_key_types.h +++ b/source/blender/makesdna/DNA_key_types.h @@ -92,7 +92,7 @@ typedef struct Key { ID *from; short type; /* absolute or relative shape key */ - short totkey; /* (totkey == BLI_countlist(&key->block)) */ + short totkey; /* (totkey == BLI_listbase_count(&key->block)) */ short slurph; /* quaint feature to delay moving points based on their order (Key->type == KEY_NORMAL) only */ short flag; diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index e535e6012b3..8067fa5db2d 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -148,16 +148,20 @@ typedef struct TFace { /* **************** MESH ********************* */ /* texflag */ -#define ME_AUTOSPACE 1 +enum { + ME_AUTOSPACE = 1, +}; /* me->editflag */ -#define ME_EDIT_MIRROR_X (1 << 0) -#define ME_EDIT_MIRROR_Y (1 << 1) // unused so far -#define ME_EDIT_MIRROR_Z (1 << 2) // unused so far +enum { + ME_EDIT_MIRROR_X = 1 << 0, + ME_EDIT_MIRROR_Y = 1 << 1, /* unused so far */ + ME_EDIT_MIRROR_Z = 1 << 2, /* unused so far */ -#define ME_EDIT_PAINT_FACE_SEL (1 << 3) -#define ME_EDIT_MIRROR_TOPO (1 << 4) -#define ME_EDIT_PAINT_VERT_SEL (1 << 5) + ME_EDIT_PAINT_FACE_SEL = 1 << 3, + ME_EDIT_MIRROR_TOPO = 1 << 4, + ME_EDIT_PAINT_VERT_SEL = 1 << 5, +}; /* we cant have both flags enabled at once, * flags defined in DNA_scene_types.h */ @@ -168,57 +172,65 @@ typedef struct TFace { ) /* me->flag */ -/* #define ME_ISDONE 1 */ -/* #define ME_DEPRECATED 2 */ -#define ME_TWOSIDED 4 -#define ME_UVEFFECT 8 -#define ME_VCOLEFFECT 16 -#define ME_AUTOSMOOTH 32 -#define ME_SMESH 64 -#define ME_SUBSURF 128 -#define ME_OPT_EDGES 256 -#define ME_DS_EXPAND 512 -#define ME_SCULPT_DYNAMIC_TOPOLOGY 1024 +enum { +/* ME_ISDONE = 1 << 0, */ +/* ME_DEPRECATED = 1 << 1, */ + ME_TWOSIDED = 1 << 2, + ME_UVEFFECT = 1 << 3, + ME_VCOLEFFECT = 1 << 4, + ME_AUTOSMOOTH = 1 << 5, + ME_SMESH = 1 << 6, + ME_SUBSURF = 1 << 7, + ME_OPT_EDGES = 1 << 8, + ME_DS_EXPAND = 1 << 9, + ME_SCULPT_DYNAMIC_TOPOLOGY = 1 << 10, +}; /* me->cd_flag */ -#define ME_CDFLAG_VERT_BWEIGHT (1 << 0) -#define ME_CDFLAG_EDGE_BWEIGHT (1 << 1) -#define ME_CDFLAG_EDGE_CREASE (1 << 2) +enum { + ME_CDFLAG_VERT_BWEIGHT = 1 << 0, + ME_CDFLAG_EDGE_BWEIGHT = 1 << 1, + ME_CDFLAG_EDGE_CREASE = 1 << 2, +}; /* me->drawflag, short */ -#define ME_DRAWEDGES (1 << 0) -#define ME_DRAWFACES (1 << 1) -#define ME_DRAWNORMALS (1 << 2) -#define ME_DRAW_VNORMALS (1 << 3) +enum { + ME_DRAWEDGES = 1 << 0, + ME_DRAWFACES = 1 << 1, + ME_DRAWNORMALS = 1 << 2, + ME_DRAW_VNORMALS = 1 << 3, -#define ME_DRAWEIGHT (1 << 4) -#define ME_HIDDENEDGES (1 << 5) + ME_DRAWEIGHT = 1 << 4, + /* ME_HIDDENEDGES = 1 << 5, */ /* DEPRECATED */ -#define ME_DRAWCREASES (1 << 6) -#define ME_DRAWSEAMS (1 << 7) -#define ME_DRAWSHARP (1 << 8) -#define ME_DRAWBWEIGHTS (1 << 9) + ME_DRAWCREASES = 1 << 6, + ME_DRAWSEAMS = 1 << 7, + ME_DRAWSHARP = 1 << 8, + ME_DRAWBWEIGHTS = 1 << 9, -#define ME_DRAWEXTRA_EDGELEN (1 << 10) -#define ME_DRAWEXTRA_FACEAREA (1 << 11) -#define ME_DRAWEXTRA_FACEANG (1 << 12) -#define ME_DRAWEXTRA_EDGEANG (1 << 13) + ME_DRAWEXTRA_EDGELEN = 1 << 10, + ME_DRAWEXTRA_FACEAREA = 1 << 11, + ME_DRAWEXTRA_FACEANG = 1 << 12, + ME_DRAWEXTRA_EDGEANG = 1 << 13, /* debug only option */ -#define ME_DRAWEXTRA_INDICES (1 << 14) + ME_DRAWEXTRA_INDICES = 1 << 14, -#define ME_DRAW_FREESTYLE_EDGE (1 << 15) -#define ME_DRAW_FREESTYLE_FACE (1 << 16) + ME_DRAW_FREESTYLE_EDGE = 1 << 15, + ME_DRAW_FREESTYLE_FACE = 1 << 16, /* draw stats */ -#define ME_DRAW_STATVIS (1 << 17) + ME_DRAW_STATVIS = 1 << 17, /* draw loop normals */ -#define ME_DRAW_LNORMALS (1 << 18) + ME_DRAW_LNORMALS = 1 << 18, +}; /* Subsurf Type */ -#define ME_CC_SUBSURF 0 -#define ME_SIMPLE_SUBSURF 1 +enum { + ME_CC_SUBSURF = 0, + ME_SIMPLE_SUBSURF = 1, +}; #define MESH_MAX_VERTS 2000000000L @@ -229,6 +241,6 @@ typedef struct TFace { #define USE_BMESH_SAVE_WITHOUT_MFACE /* enable this so meshes get tessfaces calculated by default */ -// #define USE_TESSFACE_DEFAULT +/* #define USE_TESSFACE_DEFAULT */ #endif diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index a7d067cd1ff..39700257413 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -976,6 +976,36 @@ typedef struct NodeSunBeams { #define SHD_NORMAL_MAP_BLENDER_OBJECT 3 #define SHD_NORMAL_MAP_BLENDER_WORLD 4 +/* math node clamp */ +#define SHD_MATH_CLAMP 1 + +/* Math node operation/ */ +enum { + NODE_MATH_ADD = 0, + NODE_MATH_SUB = 1, + NODE_MATH_MUL = 2, + NODE_MATH_DIVIDE = 3, + NODE_MATH_SIN = 4, + NODE_MATH_COS = 5, + NODE_MATH_TAN = 6, + NODE_MATH_ASIN = 7, + NODE_MATH_ACOS = 8, + NODE_MATH_ATAN = 9, + NODE_MATH_POW = 10, + NODE_MATH_LOG = 11, + NODE_MATH_MIN = 12, + NODE_MATH_MAX = 13, + NODE_MATH_ROUND = 14, + NODE_MATH_LESS = 15, + NODE_MATH_GREATER = 16, + NODE_MATH_MOD = 17, + NODE_MATH_ABS = 18, +}; + +/* mix rgb node flags */ +#define SHD_MIXRGB_USE_ALPHA 1 +#define SHD_MIXRGB_CLAMP 2 + /* subsurface */ enum { SHD_SUBSURFACE_COMPATIBLE = 0, // Deprecated diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index a2a724b6a32..dd25a49c476 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -293,7 +293,7 @@ typedef struct ParticleSystem { short vgroup[12], vg_neg, rt3; /* vertex groups, 0==disable, 1==starting index */ /* temporary storage during render */ - void *renderdata; + struct ParticleRenderData *renderdata; /* point cache */ struct PointCache *pointcache; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index f8f962107f6..27b5da90d55 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1093,9 +1093,10 @@ typedef struct ToolSettings { short autoik_chainlen; /* runtime only */ /* Grease Pencil */ - char gpencil_flags; + char gpencil_flags; /* flags/options for how the tool works */ + char gpencil_src; /* for main 3D view Grease Pencil, where data comes from */ - char pad[5]; + char pad[4]; /* Image Paint (8 byttse aligned please!) */ struct ImagePaintSettings imapaint; @@ -1484,7 +1485,10 @@ enum { /* sequencer seq_prev_type seq_rend_type */ - +/* scene->r.engine (scene.c) */ +extern const char *RE_engine_id_BLENDER_RENDER; +extern const char *RE_engine_id_BLENDER_GAME; +extern const char *RE_engine_id_CYCLES; /* **************** SCENE ********************* */ @@ -1766,6 +1770,12 @@ typedef enum ImagePaintMode { /* toolsettings->gpencil_flags */ #define GP_TOOL_FLAG_PAINTSESSIONS_ON (1<<0) +/* toolsettings->gpencil_src */ +typedef enum eGPencil_Source_3D { + GP_TOOL_SOURCE_SCENE = 0, + GP_TOOL_SOURCE_OBJECT = 1 +} eGPencil_Source_3d; + /* toolsettings->particle flag */ #define PE_KEEP_LENGTHS 1 #define PE_LOCK_FIRST 2 diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index 8a900c3946e..47a08c62f95 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -60,7 +60,7 @@ typedef struct bScreen { int redraws_flag; /* user-setting for which editors get redrawn during anim playback (used to be time->redraws) */ int pad1; - short full; /* temp screen for image render display or fileselect */ + short state; /* temp screen for image render display or fileselect */ short temp; /* temp screen in a temp window, don't save (like user prefs) */ short winid; /* winid from WM, starts with 1 */ short do_draw; /* notifier for drawing edges */ @@ -247,7 +247,8 @@ typedef struct ARegion { short do_draw_overlay; /* private, cached notifier events */ short swap; /* private, indicator to survive swap-exchange */ short overlap; /* private, set for indicate drawing overlapped */ - short pad[2]; + short flagfullscreen; /* temporary copy of flag settings for clean fullscreen */ + short pad; struct ARegionType *type; /* callbacks for this region type */ @@ -287,9 +288,12 @@ typedef struct ARegion { #define HEADERDOWN 1 #define HEADERTOP 2 -/* screen->full */ -#define SCREENNORMAL 0 -#define SCREENFULL 1 +/* screen->state */ +enum { + SCREENNORMAL = 0, + SCREENMAXIMIZED = 1, /* one editor taking over the screen */ + SCREENFULL = 2, /* one editor taking over the screen with no bare-minimum UI elements */ +}; /* Panel->flag */ enum { diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index 4795048d346..20678bdae49 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -131,10 +131,11 @@ typedef struct Sequence { int flag, type; /*flags bitmap (see below) and the type of sequence*/ int len; /* the length of the contents of this strip - before handles are applied */ - int start, startofs, endofs; - int startstill, endstill; + int start; /* start frame of contents of strip in absolute frame coordinates. For metastrips start of first strip startdisp */ + int startofs, endofs; /* frames after the first frame where display starts, frames before the last frame where display ends */ + int startstill, endstill; /* frames that use the first frame before data begins, frames that use the last frame after data ends */ int machine, depth; /*machine - the strip channel, depth - the depth in the sequence when dealing with metastrips */ - int startdisp, enddisp; /*starting and ending points in the sequence*/ + int startdisp, enddisp; /* starting and ending points of the strip in the sequence*/ float sat; float mul, handsize; @@ -193,6 +194,8 @@ typedef struct MetaStack { struct MetaStack *next, *prev; ListBase *oldbasep; Sequence *parseq; + /* the startdisp/enddisp when entering the meta */ + int disp_range[2]; } MetaStack; typedef struct Editing { @@ -360,6 +363,9 @@ enum { SEQ_AUDIO_PITCH_ANIMATED = (1 << 25), SEQ_AUDIO_PAN_ANIMATED = (1 << 26), SEQ_AUDIO_DRAW_WAVEFORM = (1 << 27), + + /* don't include Grease Pencil in OpenGL previews of Scene strips */ + SEQ_SCENE_NO_GPENCIL = (1 << 28), SEQ_INVALID_EFFECT = (1 << 31), }; diff --git a/source/blender/makesdna/DNA_sound_types.h b/source/blender/makesdna/DNA_sound_types.h index d7a51359777..4ab22e4f7b7 100644 --- a/source/blender/makesdna/DNA_sound_types.h +++ b/source/blender/makesdna/DNA_sound_types.h @@ -95,6 +95,8 @@ typedef struct bSound { */ void *playback_handle; + /* mutex for asynchronous loading of sounds */ + void *mutex; /* XXX unused currently (SOUND_TYPE_LIMITER) */ /* float start, end; */ } bSound; @@ -116,9 +118,10 @@ enum { }; enum { - SOUND_FLAGS_3D = (1 << 3), /* deprecated! used for sound actuator loading */ - SOUND_FLAGS_CACHING = (1 << 4), - SOUND_FLAGS_MONO = (1 << 5), + SOUND_FLAGS_3D = (1 << 3), /* deprecated! used for sound actuator loading */ + SOUND_FLAGS_CACHING = (1 << 4), + SOUND_FLAGS_MONO = (1 << 5), + SOUND_FLAGS_WAVEFORM_LOADING = (1 << 6), }; #if (DNA_DEPRECATED_GCC_POISON == 1) diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index a267217abf6..339b232f8a0 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -497,6 +497,8 @@ typedef struct SpaceSeq { float zoom DNA_DEPRECATED; /* deprecated, handled by View2D now */ int view; /* see SEQ_VIEW_* below */ int overlay_type; + int draw_flag; /* overlay an image of the editing on below the strips */ + int pad; struct bGPdata *gpd; /* grease-pencil data */ @@ -513,6 +515,13 @@ typedef enum eSpaceSeq_RegionType { SEQ_DRAW_IMG_HISTOGRAM = 4, } eSpaceSeq_RegionType; +/* sseq->draw_flag */ +typedef enum eSpaceSeq_DrawFlag { + SEQ_DRAW_BACKDROP = (1 << 0), + SEQ_DRAW_OFFSET_EXT = (1 << 1), +} eSpaceSeq_DrawFlag; + + /* sseq->flag */ typedef enum eSpaceSeq_Flag { SEQ_DRAWFRAMES = (1 << 0), @@ -522,6 +531,8 @@ typedef enum eSpaceSeq_Flag { SEQ_SHOW_GPENCIL = (1 << 4), SEQ_NO_DRAW_CFRANUM = (1 << 5), SEQ_USE_ALPHA = (1 << 6), /* use RGBA display mode for preview */ + SEQ_ALL_WAVEFORMS = (1 << 7), /* draw all waveforms */ + SEQ_NO_WAVEFORMS = (1 << 8), /* draw no waveforms */ } eSpaceSeq_Flag; /* sseq->view */ @@ -565,8 +576,9 @@ typedef enum eSpaceSeq_OverlayType { /* Config and Input for File Selector */ typedef struct FileSelectParams { char title[96]; /* title, also used for the text of the execute button */ - char dir[1056]; /* directory, FILE_MAX_LIBEXTRA, 1024 + 32, this is for extreme case when 1023 length path + char dir[1090]; /* directory, FILE_MAX_LIBEXTRA, 1024 + 66, this is for extreme case when 1023 length path * needs to be linked in, where foo.blend/Armature need adding */ + char pad_c1[2]; char file[256]; /* file */ char renamefile[256]; char renameedit[256]; /* annoying but the first is only used for initialization */ @@ -809,7 +821,7 @@ typedef enum eSpaceImage_Flag { SI_COLOR_CORRECTION = (1 << 24), - SI_NO_DRAW_TEXPAINT = (1 << 25) + SI_NO_DRAW_TEXPAINT = (1 << 25), } eSpaceImage_Flag; /* Text Editor ============================================ */ diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 769e2573aa4..73902e9c090 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -168,11 +168,13 @@ typedef struct ThemeUI { uiPanelColors panel; /* depricated, but we keep it for do_versions (2.66.1) */ + char widget_emboss[4]; + /* fac: 0 - 1 for blend factor, width in pixels */ float menu_shadow_fac; short menu_shadow_width; - short pad; + short pad[3]; char iconfile[256]; // FILE_MAXFILE length float icon_alpha; diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 3efba488299..0eee28e73d9 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -201,7 +201,9 @@ typedef struct View3D { char gridflag; /* transform widget info */ - char twtype, twmode, twflag, pad2[2]; + char twtype, twmode, twflag; + + short flag3; /* afterdraw, for xray & transparent */ struct ListBase afterdraw_transp; @@ -267,21 +269,24 @@ typedef struct View3D { ((view >= RV3D_VIEW_FRONT) && (view <= RV3D_VIEW_BOTTOM)) /* View3d->flag2 (short) */ -#define V3D_RENDER_OVERRIDE 4 -#define V3D_SOLID_TEX 8 -#define V3D_SHOW_GPENCIL 16 -#define V3D_LOCK_CAMERA 32 -#define V3D_RENDER_SHADOW 64 /* This is a runtime only flag that's used to tell draw_mesh_object() that we're doing a shadow pass instead of a regular draw */ -#define V3D_SHOW_RECONSTRUCTION 128 -#define V3D_SHOW_CAMERAPATH 256 -#define V3D_SHOW_BUNDLENAME 512 -#define V3D_BACKFACE_CULLING 1024 -#define V3D_RENDER_BORDER 2048 -#define V3D_SOLID_MATCAP 4096 /* user flag */ -#define V3D_SHOW_SOLID_MATCAP 8192 /* runtime flag */ -#define V3D_OCCLUDE_WIRE 16384 -#define V3D_SHADELESS_TEX 32768 - +#define V3D_RENDER_OVERRIDE (1 << 2) +#define V3D_SOLID_TEX (1 << 3) +#define V3D_SHOW_GPENCIL (1 << 4) +#define V3D_LOCK_CAMERA (1 << 5) +#define V3D_RENDER_SHADOW (1 << 6) /* This is a runtime only flag that's used to tell draw_mesh_object() that we're doing a shadow pass instead of a regular draw */ +#define V3D_SHOW_RECONSTRUCTION (1 << 7) +#define V3D_SHOW_CAMERAPATH (1 << 8) +#define V3D_SHOW_BUNDLENAME (1 << 9) +#define V3D_BACKFACE_CULLING (1 << 10) +#define V3D_RENDER_BORDER (1 << 11) +#define V3D_SOLID_MATCAP (1 << 12) /* user flag */ +#define V3D_SHOW_SOLID_MATCAP (1 << 13) /* runtime flag */ +#define V3D_OCCLUDE_WIRE (1 << 14) +#define V3D_SHADELESS_TEX (1 << 15) + + +/* View3d->flag3 (short) */ +#define V3D_SHOW_WORLD (1 << 0) /* View3D->around */ #define V3D_CENTER 0 diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 4cf6bfe9a8f..1a0562ae8c5 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -165,6 +165,13 @@ enum { WM_INIT_KEYMAP = (1<<1), }; +/* IME is win32 only! */ +#ifndef WIN32 +# ifdef __GNUC__ +# define ime_data ime_data __attribute__ ((deprecated)) +# endif +#endif + /* the savable part, rest of data is local in ghostwinlay */ typedef struct wmWindow { struct wmWindow *next, *prev; @@ -197,6 +204,10 @@ typedef struct wmWindow { struct wmGesture *tweak; /* internal for wm_operators.c */ + /* Input Method Editor data - complex character input (esp. for asian character input) + * Currently WIN32, runtime-only data */ + struct wmIMEData *ime_data; + int drawmethod, drawfail; /* internal for wm_draw.c only */ void *drawdata; /* internal for wm_draw.c only */ @@ -208,6 +219,10 @@ typedef struct wmWindow { ListBase gesture; /* gesture stuff */ } wmWindow; +#ifdef ime_data +# undef ime_data +#endif + /* These two Lines with # tell makesdna this struct can be excluded. */ /* should be something like DNA_EXCLUDE * but the preprocessor first removes all comments, spaces etc */ @@ -352,13 +367,22 @@ enum { OPERATOR_RUNNING_MODAL = (1 << 0), OPERATOR_CANCELLED = (1 << 1), OPERATOR_FINISHED = (1 << 2), -/* add this flag if the event should pass through */ + /* add this flag if the event should pass through */ OPERATOR_PASS_THROUGH = (1 << 3), -/* in case operator got executed outside WM code... like via fileselect */ + /* in case operator got executed outside WM code... like via fileselect */ OPERATOR_HANDLED = (1 << 4), + /* used for operators that act indirectly (eg. popup menu) + * note: this isn't great design (using operators to trigger UI) avoid where possible. */ + OPERATOR_INTERFACE = (1 << 5), }; -#define OPERATOR_FLAGS_ALL (OPERATOR_RUNNING_MODAL | OPERATOR_CANCELLED | OPERATOR_FINISHED | \ - OPERATOR_PASS_THROUGH | OPERATOR_HANDLED) +#define OPERATOR_FLAGS_ALL ( \ + OPERATOR_RUNNING_MODAL | \ + OPERATOR_CANCELLED | \ + OPERATOR_FINISHED | \ + OPERATOR_PASS_THROUGH | \ + OPERATOR_HANDLED | \ + OPERATOR_INTERFACE | \ + 0) /* sanity checks for debug mode only */ #define OPERATOR_RETVAL_CHECK(ret) (void)ret, BLI_assert(ret != 0 && (ret & OPERATOR_FLAGS_ALL) == ret) diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h index 50542797f0b..2a9bcc20a9f 100644 --- a/source/blender/makesdna/DNA_world_types.h +++ b/source/blender/makesdna/DNA_world_types.h @@ -128,6 +128,7 @@ typedef struct World { /* nodes */ struct bNodeTree *nodetree; + ListBase gpumaterial; /* runtime */ } World; /* **************** WORLD ********************* */ diff --git a/source/blender/makesdna/intern/dna_genfile.c b/source/blender/makesdna/intern/dna_genfile.c index f60562f1ac9..4615a1ce9e4 100644 --- a/source/blender/makesdna/intern/dna_genfile.c +++ b/source/blender/makesdna/intern/dna_genfile.c @@ -92,7 +92,7 @@ * * While writing a file, the names of a struct is indicated with a type number, * to be found with: ``type = DNA_struct_find_nr(SDNA *, const char *)`` - * The value of ``type`` corresponds with the the index within the structs array + * The value of ``type`` corresponds with the index within the structs array * * For the moment: the complete DNA file is included in a .blend file. For * the future we can think of smarter methods, like only included the used diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript index 4e7a564e9d4..0d215fbcf81 100644 --- a/source/blender/makesrna/SConscript +++ b/source/blender/makesrna/SConscript @@ -122,6 +122,9 @@ if env['WITH_BF_CYCLES']: defs.append('WITH_CYCLES_DEBUG') if env['WITH_BF_SDL']: + if env['WITH_BF_SDL_DYNLOAD']: + defs.append('WITH_SDL_DYNLOAD') + incs += ' #extern/sdlew/include' defs.append('WITH_SDL') if env['WITH_BF_OPENAL']: diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index 5d736f9c011..e64743c5536 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -241,6 +241,12 @@ if(WITH_MOD_OCEANSIM) endif() if(WITH_SDL) + if(WITH_SDL_DYNLOAD) + add_definitions(-DWITH_SDL_DYNLOAD) + list(APPEND INC + ../../../../extern/sdlew/include + ) + endif() add_definitions(-DWITH_SDL) endif() diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript index d1eab5ca9db..28151fe5db1 100644 --- a/source/blender/makesrna/intern/SConscript +++ b/source/blender/makesrna/intern/SConscript @@ -123,6 +123,9 @@ if env['WITH_BF_FFTW3']: defs.append('WITH_FFTW3') if env['WITH_BF_SDL']: + if env['WITH_BF_SDL_DYNLOAD']: + defs.append('WITH_SDL_DYNLOAD') + incs += ' #extern/sdlew/include' defs.append('WITH_SDL') if env['WITH_BF_OPENAL']: diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 9023f25e3d5..f0a0f470ccf 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -35,7 +35,6 @@ #include "BLI_utildefines.h" -#include "RNA_access.h" #include "RNA_define.h" #include "RNA_types.h" @@ -47,6 +46,14 @@ # endif #endif +/* stub for BLI_abort() */ +#ifndef NDEBUG +void BLI_system_backtrace(FILE *fp) +{ + (void)fp; +} +#endif + /* Replace if different */ #define TMP_EXT ".tmp" @@ -1150,7 +1157,7 @@ static char *rna_def_property_lookup_int_func(FILE *f, StructRNA *srna, Property const char *manualfunc, const char *nextfunc) { /* note on indices, this is for external functions and ignores skipped values. - * so the the index can only be checked against the length when there is no 'skip' function. */ + * so the index can only be checked against the length when there is no 'skip' function. */ char *func; if (prop->flag & PROP_IDPROPERTY && manualfunc == NULL) @@ -3675,7 +3682,7 @@ static const char *cpp_classes = "" " int length;\n" "\n" " DynamicArray() : data(NULL), length(0) {}\n" -" DynamicArray(int new_length) : data(NULL), length(new_length) { data = (float *)malloc(sizeof(T) * new_length); }\n" +" DynamicArray(int new_length) : data(NULL), length(new_length) { data = (T *)malloc(sizeof(T) * new_length); }\n" " DynamicArray(const DynamicArray<T>& other) { copy_from(other); }\n" " const DynamicArray<T>& operator = (const DynamicArray<T>& other) { copy_from(other); return *this; }\n" "\n" @@ -3686,7 +3693,7 @@ static const char *cpp_classes = "" "protected:\n" " void copy_from(const DynamicArray<T>& other) {\n" " if (data) free(data);\n" -" data = (float *)malloc(sizeof(T) * other.length);\n" +" data = (T *)malloc(sizeof(T) * other.length);\n" " memcpy(data, other.data, sizeof(T) * other.length);\n" " length = other.length;\n" " }\n" diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 34e78018b03..e681552103b 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -903,7 +903,7 @@ int RNA_property_array_item_index(PropertyRNA *prop, char name) return 3; } } - else if (ELEM(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, + else if (ELEM(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_XYZ_LENGTH, PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION)) { switch (name) { @@ -1630,9 +1630,10 @@ bool RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop) if (RNA_property_array_check(prop)) len = RNA_property_array_length(ptr, prop); - for (index = 0; index < len; index++) - if (rna_get_fcurve(ptr, prop, index, NULL, &driven)) + for (index = 0; index < len; index++) { + if (rna_get_fcurve(ptr, prop, index, NULL, NULL, &driven)) return true; + } return false; } @@ -4959,7 +4960,7 @@ bool RNA_enum_is_equal(bContext *C, PointerRNA *ptr, const char *name, const cha if (prop) { int i; - bool cmp; + bool cmp = false; RNA_property_enum_items(C, ptr, prop, &item, NULL, &free); i = RNA_enum_from_identifier(item, enumname); diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c index 750c98a536d..e256d145016 100644 --- a/source/blender/makesrna/intern/rna_action.c +++ b/source/blender/makesrna/intern/rna_action.c @@ -60,7 +60,7 @@ static void rna_ActionGroup_channels_next(CollectionPropertyIterator *iter) FCurve *fcu = (FCurve *)internal->link; bActionGroup *grp = fcu->grp; - /* only continue if the next F-Curve (if existant) belongs in the same group */ + /* only continue if the next F-Curve (if existent) belongs in the same group */ if ((fcu->next) && (fcu->next->grp == grp)) internal->link = (Link *)fcu->next; else @@ -197,7 +197,7 @@ static void rna_Action_active_pose_marker_index_range(PointerRNA *ptr, int *min, bAction *act = (bAction *)ptr->data; *min = 0; - *max = max_ii(0, BLI_countlist(&act->markers) - 1); + *max = max_ii(0, BLI_listbase_count(&act->markers) - 1); } @@ -462,6 +462,12 @@ static void rna_def_dopesheet(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Display Speaker", "Include visualization of speaker related animation data"); RNA_def_property_ui_icon(prop, ICON_SPEAKER, 0); RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); + + prop = RNA_def_property(srna, "show_gpencil", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOGPENCIL); + RNA_def_property_ui_text(prop, "Display Grease Pencil", "Include visualization of Grease Pencil related animation data and frames"); + RNA_def_property_ui_icon(prop, ICON_GREASEPENCIL, 0); + RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); } static void rna_def_action_group(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c index f2881bf2541..12fa754e636 100644 --- a/source/blender/makesrna/intern/rna_animation.c +++ b/source/blender/makesrna/intern/rna_animation.c @@ -414,7 +414,7 @@ static void rna_KeyingSet_active_ksPath_index_range(PointerRNA *ptr, int *min, i KeyingSet *ks = (KeyingSet *)ptr->data; *min = 0; - *max = max_ii(0, BLI_countlist(&ks->paths) - 1); + *max = max_ii(0, BLI_listbase_count(&ks->paths) - 1); } static PointerRNA rna_KeyingSet_typeinfo_get(PointerRNA *ptr) @@ -445,7 +445,7 @@ static KS_Path *rna_KeyingSet_paths_add(KeyingSet *keyingset, ReportList *report /* if data is valid, call the API function for this */ if (keyingset) { ksp = BKE_keyingset_add_path(keyingset, id, group_name, rna_path, index, flag, group_method); - keyingset->active_path = BLI_countlist(&keyingset->paths); + keyingset->active_path = BLI_listbase_count(&keyingset->paths); } else { BKE_report(reports, RPT_ERROR, "Keying set path could not be added"); diff --git a/source/blender/makesrna/intern/rna_boid.c b/source/blender/makesrna/intern/rna_boid.c index 6233649fb12..33048a7196b 100644 --- a/source/blender/makesrna/intern/rna_boid.c +++ b/source/blender/makesrna/intern/rna_boid.c @@ -169,7 +169,7 @@ static void rna_BoidState_active_boid_rule_index_range(PointerRNA *ptr, int *min { BoidState *state = (BoidState *)ptr->data; *min = 0; - *max = max_ii(0, BLI_countlist(&state->rules) - 1); + *max = max_ii(0, BLI_listbase_count(&state->rules) - 1); } static int rna_BoidState_active_boid_rule_index_get(PointerRNA *ptr) @@ -235,7 +235,7 @@ static void rna_BoidSettings_active_boid_state_index_range(PointerRNA *ptr, int { BoidSettings *boids = (BoidSettings *)ptr->data; *min = 0; - *max = max_ii(0, BLI_countlist(&boids->states) - 1); + *max = max_ii(0, BLI_listbase_count(&boids->states) - 1); } static int rna_BoidSettings_active_boid_state_index_get(PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index aab2d35c0e4..77355dbad0e 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -1377,12 +1377,12 @@ static void rna_def_constraint_stretch_to(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); prop = RNA_def_property(srna, "bulge_min", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.0, 100.f); + RNA_def_property_range(prop, 0.0, 1.0f); RNA_def_property_ui_text(prop, "Volume Variation Minimum", "Minimum volume stretching factor"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); prop = RNA_def_property(srna, "bulge_max", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.0, 100.f); + RNA_def_property_range(prop, 1.0, 100.0f); RNA_def_property_ui_text(prop, "Volume Variation Maximum", "Maximum volume stretching factor"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 6668ce812cf..54c08009792 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -639,7 +639,7 @@ void RNA_struct_free(BlenderRNA *brna, StructRNA *srna) if (srna->flag & STRUCT_RUNTIME) rna_freelinkN(&brna->structs, srna); #else - (void)brna, (void)srna; + UNUSED_VARS(brna, srna); #endif } diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c index 4288bf2dddb..229cdaa6005 100644 --- a/source/blender/makesrna/intern/rna_dynamicpaint.c +++ b/source/blender/makesrna/intern/rna_dynamicpaint.c @@ -203,7 +203,7 @@ static void rna_Surface_active_point_range(PointerRNA *ptr, int *min, int *max, DynamicPaintCanvasSettings *canvas = (DynamicPaintCanvasSettings *)ptr->data; *min = 0; - *max = BLI_countlist(&canvas->surfaces) - 1; + *max = BLI_listbase_count(&canvas->surfaces) - 1; } /* uvlayer */ diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index cdedb3576b0..96d02016336 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -44,6 +44,8 @@ #ifdef RNA_RUNTIME +#include "BLI_math.h" + #include "WM_api.h" #include "BKE_gpencil.h" @@ -53,6 +55,16 @@ static void rna_GPencil_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Pointe WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); } +static char *rna_GPencilLayer_path(PointerRNA *ptr) +{ + bGPDlayer *gpl = (bGPDlayer *)ptr->data; + char name_esc[sizeof(gpl->info) * 2]; + + BLI_strescape(name_esc, gpl->info, sizeof(name_esc)); + + return BLI_sprintfN("layers[\"%s\"]", name_esc); +} + static int rna_GPencilLayer_active_frame_editable(PointerRNA *ptr) { bGPDlayer *gpl = (bGPDlayer *)ptr->data; @@ -64,9 +76,36 @@ static int rna_GPencilLayer_active_frame_editable(PointerRNA *ptr) return 1; } -static PointerRNA rna_GPencil_active_layer_get(PointerRNA *ptr) +static void rna_GPencilLayer_line_width_range(PointerRNA *ptr, int *min, int *max, + int *softmin, int *softmax) { + bGPDlayer *gpl = ptr->data; + + /* The restrictions on max width here are due to OpenGL on Windows not supporting + * any widths greater than 10 (for driver-drawn) strokes/points. + * + * Although most of our 2D strokes also don't suffer from this restriction, + * it's relatively hard to test for that. So, for now, only volumetric strokes + * get to be larger... + */ + if (gpl->flag & GP_LAYER_VOLUMETRIC) { + *min = 1; + *max = 300; + + *softmin = 1; + *softmax = 100; + } + else { + *min = 1; + *max = 10; + + *softmin = 1; + *softmax = 10; + } +} +static PointerRNA rna_GPencil_active_layer_get(PointerRNA *ptr) +{ bGPdata *gpd = ptr->id.data; if (GS(gpd->id.name) == ID_GD) { /* why would this ever be not GD */ @@ -101,9 +140,38 @@ static void rna_GPencil_active_layer_set(PointerRNA *ptr, PointerRNA value) gl->flag &= ~GP_LAYER_ACTIVE; } } + + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); } } +static int rna_GPencil_active_layer_index_get(PointerRNA *ptr) +{ + bGPdata *gpd = (bGPdata *)ptr->id.data; + bGPDlayer *gpl = gpencil_layer_getactive(gpd); + + return BLI_findindex(&gpd->layers, gpl); +} + +static void rna_GPencil_active_layer_index_set(PointerRNA *ptr, int value) +{ + bGPdata *gpd = (bGPdata *)ptr->id.data; + bGPDlayer *gpl = BLI_findlink(&gpd->layers, value); + + gpencil_layer_setactive(gpd, gpl); +} + +static void rna_GPencil_active_layer_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax) +{ + bGPdata *gpd = (bGPdata *)ptr->id.data; + + *min = 0; + *max = max_ii(0, BLI_listbase_count(&gpd->layers) - 1); + + *softmin = *min; + *softmax = *max; +} + static void rna_GPencilLayer_info_set(PointerRNA *ptr, const char *value) { bGPdata *gpd = ptr->id.data; @@ -115,6 +183,63 @@ static void rna_GPencilLayer_info_set(PointerRNA *ptr, const char *value) BLI_uniquename(&gpd->layers, gpl, DATA_("GP_Layer"), '.', offsetof(bGPDlayer, info), sizeof(gpl->info)); } + +static bGPDstroke *rna_GPencil_stroke_point_find_stroke(const bGPdata *gpd, const bGPDspoint *pt, bGPDlayer **r_gpl, bGPDframe **r_gpf) +{ + bGPDlayer *gpl; + bGPDstroke *gps; + + /* sanity checks */ + if (ELEM(NULL, gpd, pt)) { + return NULL; + } + + if (r_gpl) *r_gpl = NULL; + if (r_gpf) *r_gpf = NULL; + + /* there's no faster alternative than just looping over everything... */ + for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { + if (gpl->actframe) { + for (gps = gpl->actframe->strokes.first; gps; gps = gps->next) { + if ((pt >= gps->points) && (pt < &gps->points[gps->totpoints])) { + /* found it */ + if (r_gpl) *r_gpl = gpl; + if (r_gpf) *r_gpf = gpl->actframe; + + return gps; + } + } + } + } + + /* didn't find it */ + return NULL; +} + +static void rna_GPencil_stroke_point_select_set(PointerRNA *ptr, const int value) +{ + bGPdata *gpd = ptr->id.data; + bGPDspoint *pt = ptr->data; + bGPDstroke *gps = NULL; + + /* Ensure that corresponding stroke is set + * - Since we don't have direct access, we're going to have to search + * - We don't apply selection value unless we can find the corresponding + * stroke, so that they don't get out of sync + */ + gps = rna_GPencil_stroke_point_find_stroke(gpd, pt, NULL, NULL); + if (gps) { + /* Set the new selection state for the point */ + if (value) + pt->flag |= GP_SPOINT_SELECT; + else + pt->flag &= ~GP_SPOINT_SELECT; + + /* Check if the stroke should be selected or not... */ + gpencil_stroke_sync_selection(gps); + } +} + static void rna_GPencil_stroke_point_add(bGPDstroke *stroke, int count) { if (count > 0) { @@ -178,6 +303,27 @@ static void rna_GPencil_stroke_remove(bGPDframe *frame, ReportList *reports, Poi WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); } +static void rna_GPencil_stroke_select_set(PointerRNA *ptr, const int value) +{ + bGPDstroke *gps = ptr->data; + bGPDspoint *pt; + int i; + + /* set new value */ + if (value) + gps->flag |= GP_STROKE_SELECT; + else + gps->flag &= ~GP_STROKE_SELECT; + + /* ensure that the stroke's points are selected in the same way */ + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (value) + pt->flag |= GP_SPOINT_SELECT; + else + pt->flag &= ~GP_SPOINT_SELECT; + } +} + static bGPDframe *rna_GPencil_frame_new(bGPDlayer *layer, ReportList *reports, int frame_number) { bGPDframe *frame; @@ -289,6 +435,12 @@ static void rna_def_gpencil_stroke_point(BlenderRNA *brna) RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Pressure", "Pressure of tablet at point when drawing it"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SPOINT_SELECT); + RNA_def_property_boolean_funcs(prop, NULL, "rna_GPencil_stroke_point_select_set"); + RNA_def_property_ui_text(prop, "Select", "Point is selected for viewport editing"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); } static void rna_def_gpencil_stroke_points_api(BlenderRNA *brna, PropertyRNA *cprop) @@ -336,12 +488,19 @@ static void rna_def_gpencil_stroke(BlenderRNA *brna) RNA_def_property_struct_type(prop, "GPencilStrokePoint"); RNA_def_property_ui_text(prop, "Stroke Points", "Stroke data points"); rna_def_gpencil_stroke_points_api(brna, prop); - + + /* Settings */ prop = RNA_def_property(srna, "draw_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); RNA_def_property_enum_items(prop, stroke_draw_mode_items); RNA_def_property_ui_text(prop, "Draw Mode", ""); RNA_def_property_update(prop, 0, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STROKE_SELECT); + RNA_def_property_boolean_funcs(prop, NULL, "rna_GPencil_stroke_select_set"); + RNA_def_property_ui_text(prop, "Select", "Stroke is selected for viewport editing"); + RNA_def_property_update(prop, 0, "rna_GPencil_update"); } static void rna_def_gpencil_strokes_api(BlenderRNA *brna, PropertyRNA *cprop) @@ -453,6 +612,7 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) srna = RNA_def_struct(brna, "GPencilLayer", NULL); RNA_def_struct_sdna(srna, "bGPDlayer"); RNA_def_struct_ui_text(srna, "Grease Pencil Layer", "Collection of related sketches"); + RNA_def_struct_path_func(srna, "rna_GPencilLayer_path"); /* Name */ prop = RNA_def_property(srna, "info", PROP_STRING, PROP_NONE); @@ -475,7 +635,14 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) RNA_def_property_editable_func(prop, "rna_GPencilLayer_active_frame_editable"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - /* Drawing Color */ + /* Draw Style */ + // TODO: replace these with a "draw type" combo (i.e. strokes only, filled strokes, strokes + fills, volumetric)? + prop = RNA_def_property(srna, "use_volumetric_strokes", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_VOLUMETRIC); + RNA_def_property_ui_text(prop, "Volumetric Strokes", "Draw strokes as a series of circular blobs, resulting in a volumetric effect"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + /* Stroke Drawing Color */ prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); RNA_def_property_range(prop, 0.0f, 1.0f); @@ -484,14 +651,29 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) prop = RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "color[3]"); - RNA_def_property_range(prop, 0.3, 1.0f); + RNA_def_property_range(prop, 0.0, 1.0f); RNA_def_property_ui_text(prop, "Opacity", "Layer Opacity"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + /* Fill Drawing Color */ + prop = RNA_def_property(srna, "fill_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "fill"); + RNA_def_property_array(prop, 3); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Fill Color", "Color for filling region bounded by each stroke"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "fill_alpha", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "fill[3]"); + RNA_def_property_range(prop, 0.0, 1.0f); + RNA_def_property_ui_text(prop, "Fill Opacity", "Opacity for filling region bounded by each stroke"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + /* Line Thickness */ prop = RNA_def_property(srna, "line_width", PROP_INT, PROP_PIXEL); RNA_def_property_int_sdna(prop, NULL, "thickness"); - RNA_def_property_range(prop, 1, 10); + //RNA_def_property_range(prop, 1, 10); /* 10 px limit comes from Windows OpenGL limits for natively-drawn strokes */ + RNA_def_property_int_funcs(prop, NULL, NULL, "rna_GPencilLayer_line_width_range"); RNA_def_property_ui_text(prop, "Thickness", "Thickness of strokes (in pixels)"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); @@ -501,29 +683,59 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Onion Skinning", "Ghost frames on either side of frame"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); - prop = RNA_def_property(srna, "ghost_range_max", PROP_INT, PROP_NONE); + prop = RNA_def_property(srna, "ghost_before_range", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "gstep"); RNA_def_property_range(prop, 0, 120); - RNA_def_property_ui_text(prop, "Max Ghost Range", - "Maximum number of frames on either side of the active frame to show " - "(0 = show the 'first' available sketch on either side)"); + RNA_def_property_ui_text(prop, "Frames Before", + "Maximum number of frames to show before current frame " + "(0 = show only the previous sketch)"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "ghost_after_range", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "gstep_next"); + RNA_def_property_range(prop, 0, 120); + RNA_def_property_ui_text(prop, "Frames After", + "Maximum number of frames to show after current frame " + "(0 = show only the next sketch)"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "use_ghost_custom_colors", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_GHOST_PREVCOL | GP_LAYER_GHOST_NEXTCOL); + RNA_def_property_ui_text(prop, "Use Custom Ghost Colors", "Use custom colors for ghost frames"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "before_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "gcolor_prev"); + RNA_def_property_array(prop, 3); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Before Color", "Base color for ghosts before the active frame"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "after_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "gcolor_next"); + RNA_def_property_array(prop, 3); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "After Color", "Base color for ghosts after the active frame"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); /* Flags */ prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_HIDE); + RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 1); RNA_def_property_ui_text(prop, "Hide", "Set layer Visibility"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); prop = RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_LOCKED); + RNA_def_property_ui_icon(prop, ICON_UNLOCKED, 1); RNA_def_property_ui_text(prop, "Locked", "Protect layer from further editing and/or frame changes"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); prop = RNA_def_property(srna, "lock_frame", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_FRAMELOCK); + RNA_def_property_ui_icon(prop, ICON_UNLOCKED, 1); RNA_def_property_ui_text(prop, "Frame Locked", "Lock current frame displayed by layer"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); /* expose as layers.active */ #if 0 @@ -537,7 +749,7 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_SELECT); RNA_def_property_ui_text(prop, "Select", "Layer is selected for editing in the Dope Sheet"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); /* XXX keep this option? */ prop = RNA_def_property(srna, "show_points", PROP_BOOLEAN, PROP_NONE); @@ -586,10 +798,18 @@ static void rna_def_gpencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); - RNA_def_property_struct_type(prop, "GreasePencil"); + RNA_def_property_struct_type(prop, "GPencilLayer"); RNA_def_property_pointer_funcs(prop, "rna_GPencil_active_layer_get", "rna_GPencil_active_layer_set", NULL, NULL); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Active Layer", "Active grease pencil layer"); + + prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); + + RNA_def_property_int_funcs(prop, + "rna_GPencil_active_layer_index_get", + "rna_GPencil_active_layer_index_set", + "rna_GPencil_active_layer_index_range"); + RNA_def_property_ui_text(prop, "Active Layer Index", "Index of active grease pencil layer"); } static void rna_def_gpencil_data(BlenderRNA *brna) @@ -618,6 +838,9 @@ static void rna_def_gpencil_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Layers", ""); rna_def_gpencil_layers_api(brna, prop); + /* Animation Data */ + rna_def_animdata_common(srna); + /* Flags */ prop = RNA_def_property(srna, "draw_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); @@ -629,7 +852,13 @@ static void rna_def_gpencil_data(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_DEPTH_STROKE_ENDPOINTS); RNA_def_property_ui_text(prop, "Only Endpoints", "Only use the first and last parts of the stroke for snapping"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - + + prop = RNA_def_property(srna, "use_stroke_edit_mode", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_STROKE_EDITMODE); + RNA_def_property_ui_text(prop, "Stroke Edit Mode", "Enable alternative keymap to make editing stroke points easier"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, "rna_GPencil_update"); + + /* API Functions */ func = RNA_def_function(srna, "clear", "rna_GPencil_clear"); RNA_def_function_ui_description(func, "Remove all the grease pencil data"); } diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 83b7a81c649..051e7277425 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -207,6 +207,7 @@ void rna_def_render_layer_common(struct StructRNA *srna, int scene); void rna_def_actionbone_group_common(struct StructRNA *srna, int update_flag, const char *update_cb); void rna_ActionGroup_colorset_set(struct PointerRNA *ptr, int value); +int rna_ActionGroup_is_custom_colorset_get(struct PointerRNA *ptr); void rna_ID_name_get(struct PointerRNA *ptr, char *value); int rna_ID_name_length(struct PointerRNA *ptr); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index b0b99dcd2ca..3d6eab2bc88 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1415,8 +1415,6 @@ static char *rna_FaceCustomData_data_path(PointerRNA *ptr, const char *collectio } - - static char *rna_MeshUVLoop_path(PointerRNA *ptr) { return rna_LoopCustomData_data_path(ptr, "uv_layers", CD_MLOOPUV); diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 4911c106f53..cc7c9782927 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -130,6 +130,7 @@ EnumPropertyItem modifier_triangulate_ngon_method_items[] = { #ifdef RNA_RUNTIME #include "DNA_particle_types.h" +#include "DNA_curve_types.h" #include "DNA_smoke_types.h" #include "BKE_context.h" @@ -604,6 +605,40 @@ static int rna_LaplacianDeformModifier_is_bind_get(PointerRNA *ptr) return ((lmd->flag & MOD_LAPLACIANDEFORM_BIND) && (lmd->cache_system != NULL)); } +/* NOTE: Curve and array modifiers requires curve path to be evaluated, + * dependency graph will make sure that curve eval would create such a path, + * but if curve was already evaluated we might miss path. + * + * So what we do here is: if path was not calculated for target curve we + * tag it for update. + */ + +static void rna_CurveModifier_dependency_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + CurveModifierData *cmd = (CurveModifierData *)ptr->data; + rna_Modifier_update(bmain, scene, ptr); + DAG_relations_tag_update(bmain); + if (cmd->object != NULL) { + Curve *curve = cmd->object->data; + if ((curve->flag & CU_PATH) == 0) { + DAG_id_tag_update(&curve->id, OB_RECALC_DATA); + } + } +} + +static void rna_ArrayModifier_dependency_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + ArrayModifierData *amd = (ArrayModifierData *)ptr->data; + rna_Modifier_update(bmain, scene, ptr); + DAG_relations_tag_update(bmain); + if (amd->curve_ob != NULL) { + Curve *curve = amd->curve_ob->data; + if ((curve->flag & CU_PATH) == 0) { + DAG_id_tag_update(&curve->id, OB_RECALC_DATA); + } + } +} + #else static PropertyRNA *rna_def_property_subdivision_common(StructRNA *srna, const char type[]) @@ -876,7 +911,7 @@ static void rna_def_modifier_curve(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Object", "Curve object to deform with"); RNA_def_property_pointer_funcs(prop, NULL, "rna_CurveModifier_object_set", NULL, "rna_Curve_object_poll"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK); - RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_CurveModifier_dependency_update"); prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "name"); @@ -1399,7 +1434,7 @@ static void rna_def_modifier_array(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Curve", "Curve object to fit array length to"); RNA_def_property_pointer_funcs(prop, NULL, "rna_ArrayModifier_curve_ob_set", NULL, "rna_Curve_object_poll"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK); - RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_ArrayModifier_dependency_update"); /* Offset parameters */ prop = RNA_def_property(srna, "use_constant_offset", PROP_BOOLEAN, PROP_NONE); @@ -2453,7 +2488,7 @@ static void rna_def_modifier_simpledeform(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop = RNA_def_property(srna, "origin", PROP_POINTER, PROP_NONE); - RNA_def_property_ui_text(prop, "Origin", "Origin of modifier space coordinates"); + RNA_def_property_ui_text(prop, "Origin", "Offset the origin and orientation of the deformation"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK); RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); diff --git a/source/blender/makesrna/intern/rna_movieclip.c b/source/blender/makesrna/intern/rna_movieclip.c index 170856a3061..e891ab520f9 100644 --- a/source/blender/makesrna/intern/rna_movieclip.c +++ b/source/blender/makesrna/intern/rna_movieclip.c @@ -317,8 +317,8 @@ static void rna_def_movieclip(BlenderRNA *brna) /* grease pencil */ prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "gpd"); - RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "GreasePencil"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this movie clip"); RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index e90de3631d6..e672037837a 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -112,25 +112,25 @@ EnumPropertyItem node_icon_items[] = { #undef DEF_VICO EnumPropertyItem node_math_items[] = { - { 0, "ADD", 0, "Add", ""}, - { 1, "SUBTRACT", 0, "Subtract", ""}, - { 2, "MULTIPLY", 0, "Multiply", ""}, - { 3, "DIVIDE", 0, "Divide", ""}, - { 4, "SINE", 0, "Sine", ""}, - { 5, "COSINE", 0, "Cosine", ""}, - { 6, "TANGENT", 0, "Tangent", ""}, - { 7, "ARCSINE", 0, "Arcsine", ""}, - { 8, "ARCCOSINE", 0, "Arccosine", ""}, - { 9, "ARCTANGENT", 0, "Arctangent", ""}, - {10, "POWER", 0, "Power", ""}, - {11, "LOGARITHM", 0, "Logarithm", ""}, - {12, "MINIMUM", 0, "Minimum", ""}, - {13, "MAXIMUM", 0, "Maximum", ""}, - {14, "ROUND", 0, "Round", ""}, - {15, "LESS_THAN", 0, "Less Than", ""}, - {16, "GREATER_THAN", 0, "Greater Than", ""}, - {17, "MODULO", 0, "Modulo", ""}, - {18, "ABSOLUTE", 0, "Absolute", ""}, + {NODE_MATH_ADD, "ADD", 0, "Add", ""}, + {NODE_MATH_SUB, "SUBTRACT", 0, "Subtract", ""}, + {NODE_MATH_MUL, "MULTIPLY", 0, "Multiply", ""}, + {NODE_MATH_DIVIDE, "DIVIDE", 0, "Divide", ""}, + {NODE_MATH_SIN, "SINE", 0, "Sine", ""}, + {NODE_MATH_COS, "COSINE", 0, "Cosine", ""}, + {NODE_MATH_TAN, "TANGENT", 0, "Tangent", ""}, + {NODE_MATH_ASIN, "ARCSINE", 0, "Arcsine", ""}, + {NODE_MATH_ACOS, "ARCCOSINE", 0, "Arccosine", ""}, + {NODE_MATH_ATAN, "ARCTANGENT", 0, "Arctangent", ""}, + {NODE_MATH_POW, "POWER", 0, "Power", ""}, + {NODE_MATH_LOG, "LOGARITHM", 0, "Logarithm", ""}, + {NODE_MATH_MIN, "MINIMUM", 0, "Minimum", ""}, + {NODE_MATH_MAX, "MAXIMUM", 0, "Maximum", ""}, + {NODE_MATH_ROUND, "ROUND", 0, "Round", ""}, + {NODE_MATH_LESS, "LESS_THAN", 0, "Less Than", ""}, + {NODE_MATH_GREATER, "GREATER_THAN", 0, "Greater Than", ""}, + {NODE_MATH_MOD, "MODULO", 0, "Modulo", ""}, + {NODE_MATH_ABS, "ABSOLUTE", 0, "Absolute", ""}, {0, NULL, 0, NULL, NULL} }; @@ -3051,7 +3051,7 @@ static void def_math(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); prop = RNA_def_property(srna, "use_clamp", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "custom2", 1); + RNA_def_property_boolean_sdna(prop, NULL, "custom2", SHD_MATH_CLAMP); RNA_def_property_ui_text(prop, "Clamp", "Clamp result of the node to 0..1 range"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } @@ -3132,12 +3132,12 @@ static void def_mix_rgb(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "custom2", 1); + RNA_def_property_boolean_sdna(prop, NULL, "custom2", SHD_MIXRGB_USE_ALPHA); RNA_def_property_ui_text(prop, "Alpha", "Include alpha of second input in this operation"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); prop = RNA_def_property(srna, "use_clamp", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "custom2", 2); + RNA_def_property_boolean_sdna(prop, NULL, "custom2", SHD_MIXRGB_CLAMP); RNA_def_property_ui_text(prop, "Clamp", "Clamp result of the node to 0..1 range"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } @@ -7572,8 +7572,8 @@ static void rna_def_nodetree(BlenderRNA *brna) /* Grease Pencil */ prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "gpd"); - RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "GreasePencil"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Grease Pencil Data", "Grease Pencil datablock"); RNA_def_property_update(prop, NC_NODE, NULL); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 690468a5278..9741c75d68f 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -46,6 +46,8 @@ #include "BKE_editmesh.h" #include "BKE_group.h" /* needed for BKE_group_object_exists() */ #include "BKE_object.h" /* Needed for BKE_object_matrix_local_get() */ +#include "BKE_object_deform.h" + #include "RNA_access.h" #include "RNA_define.h" #include "RNA_enum_types.h" @@ -583,7 +585,7 @@ static void rna_Object_active_vertex_group_index_range(PointerRNA *ptr, int *min Object *ob = (Object *)ptr->id.data; *min = 0; - *max = max_ii(0, BLI_countlist(&ob->defbase) - 1); + *max = max_ii(0, BLI_listbase_count(&ob->defbase) - 1); } void rna_object_vgroup_name_index_get(PointerRNA *ptr, char *value, int index) @@ -736,7 +738,7 @@ static void rna_Object_active_particle_system_index_range(PointerRNA *ptr, int * { Object *ob = (Object *)ptr->id.data; *min = 0; - *max = max_ii(0, BLI_countlist(&ob->particlesystem) - 1); + *max = max_ii(0, BLI_listbase_count(&ob->particlesystem) - 1); } static int rna_Object_active_particle_system_index_get(PointerRNA *ptr) @@ -941,6 +943,7 @@ static void rna_MaterialSlot_name_get(PointerRNA *ptr, char *str) static void rna_MaterialSlot_update(Main *bmain, Scene *scene, PointerRNA *ptr) { rna_Object_internal_update(bmain, scene, ptr); + WM_main_add_notifier(NC_OBJECT | ND_OB_SHADING, ptr->id.data); WM_main_add_notifier(NC_MATERIAL | ND_SHADING_LINKS, NULL); } @@ -1240,7 +1243,7 @@ static void rna_Object_active_shape_key_index_range(PointerRNA *ptr, int *min, i *min = 0; if (key) { - *max = BLI_countlist(&key->block) - 1; + *max = BLI_listbase_count(&key->block) - 1; if (*max < 0) *max = 0; } else { @@ -1388,7 +1391,7 @@ static void rna_Object_boundbox_get(PointerRNA *ptr, float *values) static bDeformGroup *rna_Object_vgroup_new(Object *ob, const char *name) { - bDeformGroup *defgroup = ED_vgroup_add_name(ob, name); + bDeformGroup *defgroup = BKE_object_defgroup_add_name(ob, name); WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob); @@ -1403,7 +1406,7 @@ static void rna_Object_vgroup_remove(Object *ob, ReportList *reports, PointerRNA return; } - ED_vgroup_delete(ob, defgroup); + BKE_object_defgroup_remove(ob, defgroup); RNA_POINTER_INVALIDATE(defgroup_ptr); WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob); @@ -1411,7 +1414,7 @@ static void rna_Object_vgroup_remove(Object *ob, ReportList *reports, PointerRNA static void rna_Object_vgroup_clear(Object *ob) { - ED_vgroup_clear(ob); + BKE_object_defgroup_remove_all(ob); WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob); } @@ -1421,7 +1424,7 @@ static void rna_VertexGroup_vertex_add(ID *id, bDeformGroup *def, ReportList *re { Object *ob = (Object *)id; - if (ED_vgroup_object_is_edit_mode(ob)) { + if (BKE_object_is_in_editmode_vgroup(ob)) { BKE_report(reports, RPT_ERROR, "VertexGroup.add(): cannot be called while object is in edit mode"); return; } @@ -1436,7 +1439,7 @@ static void rna_VertexGroup_vertex_remove(ID *id, bDeformGroup *dg, ReportList * { Object *ob = (Object *)id; - if (ED_vgroup_object_is_edit_mode(ob)) { + if (BKE_object_is_in_editmode_vgroup(ob)) { BKE_report(reports, RPT_ERROR, "VertexGroup.remove(): cannot be called while object is in edit mode"); return; } @@ -2426,7 +2429,9 @@ static void rna_def_object(BlenderRNA *brna) prop = RNA_def_property(srna, "matrix_local", PROP_FLOAT, PROP_MATRIX); 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, "Local Matrix", "Parent relative transformation matrix"); + RNA_def_property_ui_text(prop, "Local Matrix", "Parent relative transformation matrix - " + "WARNING: Only takes into account 'Object' parenting, so e.g. in case of bone parenting " + "you get a matrix relative to the Armature object, not to the actual parent bone"); RNA_def_property_float_funcs(prop, "rna_Object_matrix_local_get", "rna_Object_matrix_local_set", NULL); RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, NULL); @@ -2726,16 +2731,16 @@ static void rna_def_object(BlenderRNA *brna) /* Grease Pencil */ prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "gpd"); - RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "GreasePencil"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Grease Pencil Data", "Grease Pencil datablock"); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); /* pose */ prop = RNA_def_property(srna, "pose_library", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "poselib"); - RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "Action"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Pose Library", "Action used as a pose library for armatures"); prop = RNA_def_property(srna, "pose", PROP_POINTER, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 8da869417ff..cd28c608667 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -243,7 +243,7 @@ static void rna_Cache_active_point_cache_index_range(PointerRNA *ptr, int *min, for (pid = pidlist.first; pid; pid = pid->next) { if (pid->cache == cache) { - *max = max_ii(0, BLI_countlist(pid->ptcaches) - 1); + *max = max_ii(0, BLI_listbase_count(pid->ptcaches) - 1); break; } } diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 113311383f4..dd32bb189e2 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -589,8 +589,14 @@ static void rna_ParticleSystem_set_resolution(ParticleSystem *particlesystem, Sc particle_system_update(scene, object, particlesystem); } else { - if (particlesystem->renderdata) + ParticleSystemModifierData *psmd = psys_get_modifier(object, particlesystem); + + if (particlesystem->renderdata) { psys_render_restore(object, particlesystem); + } + + psmd->flag &= ~eParticleSystemFlag_psys_updated; + particle_system_update(scene, object, particlesystem); } } @@ -886,7 +892,7 @@ static void rna_ParticleSystem_active_particle_target_index_range(PointerRNA *pt { ParticleSystem *psys = (ParticleSystem *)ptr->data; *min = 0; - *max = max_ii(0, BLI_countlist(&psys->targets) - 1); + *max = max_ii(0, BLI_listbase_count(&psys->targets) - 1); } static int rna_ParticleSystem_active_particle_target_index_get(PointerRNA *ptr) @@ -1009,7 +1015,7 @@ static void rna_ParticleDupliWeight_active_index_range(PointerRNA *ptr, int *min { ParticleSettings *part = (ParticleSettings *)ptr->id.data; *min = 0; - *max = max_ii(0, BLI_countlist(&part->dupliweights) - 1); + *max = max_ii(0, BLI_listbase_count(&part->dupliweights) - 1); } static int rna_ParticleDupliWeight_active_index_get(PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 9f05d61eeff..f72f97b1681 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -179,6 +179,13 @@ void rna_ActionGroup_colorset_set(PointerRNA *ptr, int value) } } +int rna_ActionGroup_is_custom_colorset_get(PointerRNA *ptr) +{ + bActionGroup *grp = ptr->data; + + return (bool)(grp->customCol < 0); +} + static void rna_BoneGroup_name_set(PointerRNA *ptr, const char *value) { Object *ob = ptr->id.data; @@ -414,7 +421,7 @@ static void rna_PoseChannel_bone_group_index_range(PointerRNA *ptr, int *min, in bPose *pose = (ob) ? ob->pose : NULL; *min = 0; - *max = pose ? max_ii(0, BLI_countlist(&pose->agroups) - 1) : 0; + *max = pose ? max_ii(0, BLI_listbase_count(&pose->agroups) - 1) : 0; } static PointerRNA rna_Pose_active_bone_group_get(PointerRNA *ptr) @@ -447,7 +454,7 @@ static void rna_Pose_active_bone_group_index_range(PointerRNA *ptr, int *min, in bPose *pose = (bPose *)ptr->data; *min = 0; - *max = max_ii(0, BLI_countlist(&pose->agroups) - 1); + *max = max_ii(0, BLI_listbase_count(&pose->agroups) - 1); } #if 0 @@ -675,6 +682,11 @@ void rna_def_actionbone_group_common(StructRNA *srna, int update_flag, const cha RNA_def_property_ui_text(prop, "Color Set", "Custom color set to use"); RNA_def_property_update(prop, update_flag, update_cb); + prop = RNA_def_property(srna, "is_custom_color_set", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_ActionGroup_is_custom_colorset_get", NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Custom Color Set", "Color set is user-defined instead of a fixed theme color set"); + /* TODO: editing the colors for this should result in changes to the color type... */ prop = RNA_def_property(srna, "colors", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL); diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 0ee654d4ecc..6db9c8e9cd9 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -38,7 +38,6 @@ #include "RE_engine.h" #include "RE_pipeline.h" -#include "RE_engine.h" EnumPropertyItem render_pass_type_items[] = { @@ -520,6 +519,11 @@ static void rna_def_render_engine(BlenderRNA *brna) prop = RNA_def_string(func, "message", NULL, 0, "Report Message", ""); RNA_def_property_flag(prop, PROP_REQUIRED); + func = RNA_def_function(srna, "error_set", "RE_engine_set_error_message"); + RNA_def_function_ui_description(func, "Set error message displaying after the render is finished"); + prop = RNA_def_string(func, "message", NULL, 0, "Report Message", ""); + RNA_def_property_flag(prop, PROP_REQUIRED); + func = RNA_def_function(srna, "bind_display_space_shader", "engine_bind_display_space_shader"); RNA_def_function_ui_description(func, "Bind GLSL fragment shader that converts linear colors to display space colors using scene color management settings"); prop = RNA_def_pointer(func, "scene", "Scene", "", ""); diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c index 78cd8d4bad4..58a12f62644 100644 --- a/source/blender/makesrna/intern/rna_rigidbody.c +++ b/source/blender/makesrna/intern/rna_rigidbody.c @@ -94,6 +94,8 @@ static EnumPropertyItem rigidbody_mesh_source_items[] = { #include "BKE_depsgraph.h" #include "BKE_rigidbody.h" +#include "WM_api.h" + #define RB_FLAG_SET(dest, value, flag) { \ if (value) \ dest |= flag; \ @@ -151,6 +153,15 @@ static void rna_RigidBodyOb_reset(Main *UNUSED(bmain), Scene *scene, PointerRNA BKE_rigidbody_cache_reset(rbw); } +static void rna_RigidBodyOb_shape_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + Object *ob = ptr->id.data; + + rna_RigidBodyOb_reset(bmain, scene, ptr); + + WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob); +} + static void rna_RigidBodyOb_shape_reset(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr) { RigidBodyWorld *rbw = scene->rigidbody_world; @@ -633,8 +644,7 @@ static void rna_RigidBodyWorld_convex_sweep_test( BKE_report(reports, RPT_ERROR, "Rigidbody world was not properly initialized, need to step the simulation first"); } #else - (void)rbw, (void)reports, (void)object, (void)ray_start, (void)ray_end; - (void)r_location, (void)r_hitpoint, (void)r_normal, (void)r_hit; + UNUSED_VARS(rbw, reports, object, ray_start, ray_end, r_location, r_hitpoint, r_normal, r_hit); #endif } @@ -797,7 +807,7 @@ static void rna_def_rigidbody_object(BlenderRNA *brna) RNA_def_property_enum_funcs(prop, NULL, "rna_RigidBodyOb_shape_set", NULL); RNA_def_property_ui_text(prop, "Collision Shape", "Collision Shape of object in Rigid Body Simulations"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_shape_update"); prop = RNA_def_property(srna, "kinematic", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", RBO_FLAG_KINEMATIC); diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index 8f2537105c1..4f51ec5468c 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -984,7 +984,7 @@ static void rna_BlenderRNA_structs_begin(CollectionPropertyIterator *iter, Point /* optional, for faster lookups */ static int rna_BlenderRNA_structs_length(PointerRNA *ptr) { - return BLI_countlist(&((BlenderRNA *)ptr->data)->structs); + return BLI_listbase_count(&((BlenderRNA *)ptr->data)->structs); } static int rna_BlenderRNA_structs_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr) { diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 70ce87ab68b..d9587b8d983 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -737,7 +737,7 @@ static int rna_RenderSettings_threads_mode_get(PointerRNA *ptr) return (rd->mode & R_FIXED_THREADS); } -static int rna_RenderSettings_is_movie_fomat_get(PointerRNA *ptr) +static int rna_RenderSettings_is_movie_format_get(PointerRNA *ptr) { RenderData *rd = (RenderData *)ptr->data; return BKE_imtype_is_movie(rd->im_format.imtype); @@ -1063,7 +1063,7 @@ static int rna_RenderSettings_active_layer_index_get(PointerRNA *ptr) static void rna_RenderSettings_active_layer_index_set(PointerRNA *ptr, int value) { RenderData *rd = (RenderData *)ptr->data; - int num_layers = BLI_countlist(&rd->layers); + int num_layers = BLI_listbase_count(&rd->layers); rd->actlay = min_ff(value, num_layers - 1); } @@ -1073,7 +1073,7 @@ static void rna_RenderSettings_active_layer_index_range(PointerRNA *ptr, int *mi RenderData *rd = (RenderData *)ptr->data; *min = 0; - *max = max_ii(0, BLI_countlist(&rd->layers) - 1); + *max = max_ii(0, BLI_listbase_count(&rd->layers) - 1); } static PointerRNA rna_RenderSettings_active_layer_get(PointerRNA *ptr) @@ -1228,7 +1228,7 @@ static char *rna_SceneRenderLayer_path(PointerRNA *ptr) static int rna_RenderSettings_multiple_engines_get(PointerRNA *UNUSED(ptr)) { - return (BLI_countlist(&R_engines) > 1); + return (BLI_listbase_count(&R_engines) > 1); } static int rna_RenderSettings_use_shading_nodes_get(PointerRNA *ptr) @@ -1485,7 +1485,7 @@ static KeyingSet *rna_Scene_keying_set_new(Scene *sce, ReportList *reports, cons ks = BKE_keyingset_add(&sce->keyingsets, idname, name, KEYINGSET_ABSOLUTE, 0); if (ks) { - sce->active_keyingset = BLI_countlist(&sce->keyingsets); + sce->active_keyingset = BLI_listbase_count(&sce->keyingsets); return ks; } else { @@ -1645,7 +1645,7 @@ static void rna_FreestyleSettings_active_lineset_index_range(PointerRNA *ptr, in FreestyleConfig *config = (FreestyleConfig *)ptr->data; *min = 0; - *max = max_ii(0, BLI_countlist(&config->linesets) - 1); + *max = max_ii(0, BLI_listbase_count(&config->linesets) - 1); } static int rna_FreestyleSettings_active_lineset_index_get(PointerRNA *ptr) @@ -1773,6 +1773,14 @@ static void rna_def_tool_settings(BlenderRNA *brna) {WT_VGROUP_BONE_DEFORM_OFF, "OTHER_DEFORM", 0, "Other", "Vertex Groups assigned to non Deform Bones"}, {0, NULL, 0, NULL, NULL} }; + + static EnumPropertyItem gpencil_source_3d_items[] = { + {GP_TOOL_SOURCE_SCENE, "SCENE", 0, "Scene", + "Grease Pencil data attached to the current scene is used, unless the active object already has Grease Pencil data (i.e. for old files)"}, + {GP_TOOL_SOURCE_OBJECT, "OBJECT", 0, "Object", + "Grease Pencil datablocks attached to the active object are used (required using pre 2.73 add-ons, e.g. BSurfaces)"}, + {0, NULL, 0, NULL, NULL} + }; srna = RNA_def_struct(brna, "ToolSettings", NULL); @@ -1965,6 +1973,13 @@ static void rna_def_tool_settings(BlenderRNA *brna) "Allow drawing multiple strokes at a time with Grease Pencil"); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* xxx: need toolbar to be redrawn... */ + prop = RNA_def_property(srna, "grease_pencil_source", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "gpencil_src"); + RNA_def_property_enum_items(prop, gpencil_source_3d_items); + RNA_def_property_ui_text(prop, "Grease Pencil Source", + "Datablock where active Grease Pencil data is found from"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + /* Auto Keying */ prop = RNA_def_property(srna, "use_keyframe_insert_auto", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "autokey_mode", AUTOKEY_ON); @@ -4801,7 +4816,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); prop = RNA_def_property(srna, "is_movie_format", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_is_movie_fomat_get", NULL); + RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_is_movie_format_get", NULL); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Movie Format", "When true the format is a movie"); @@ -5459,7 +5474,7 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "lay", 1); RNA_def_property_array(prop, 20); RNA_def_property_boolean_funcs(prop, NULL, "rna_Scene_layer_set"); - RNA_def_property_ui_text(prop, "Layers", "Visible layers - Shift-Click to select multiple layers"); + RNA_def_property_ui_text(prop, "Layers", "Visible layers - Shift-Click/Drag to select multiple layers"); RNA_def_property_update(prop, NC_SCENE | ND_LAYER, "rna_Scene_layer_update"); /* active layer */ @@ -5738,10 +5753,10 @@ void RNA_def_scene(BlenderRNA *brna) /* Grease Pencil */ prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "gpd"); - RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "GreasePencil"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Grease Pencil Data", "Grease Pencil datablock"); - RNA_def_property_update(prop, NC_SCENE, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); /* Transform Orientations */ prop = RNA_def_property(srna, "orientations", PROP_COLLECTION, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index 84134e7cd3a..be618c5d1a3 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -47,12 +47,14 @@ #include "BKE_animsys.h" #include "BKE_depsgraph.h" +#include "BKE_editmesh.h" #include "BKE_global.h" #include "BKE_image.h" #include "BKE_scene.h" #include "BKE_writeavi.h" #include "ED_transform.h" +#include "ED_uvedit.h" #ifdef WITH_PYTHON # include "BPY_extern.h" @@ -90,6 +92,20 @@ static void rna_Scene_frame_set(Scene *scene, int frame, float subframe) } } +static void rna_Scene_uvedit_aspect(Scene *scene, Object *ob, float *aspect) +{ + if ((ob->type == OB_MESH) && (ob->mode == OB_MODE_EDIT)) { + BMEditMesh *em; + em = BKE_editmesh_from_object(ob); + if (EDBM_mtexpoly_check(em)) { + ED_uvedit_get_aspect(scene, ob, em->bm, aspect, aspect + 1); + return; + } + } + + aspect[0] = aspect[1] = 1.0f; +} + static void rna_Scene_update_tagged(Scene *scene) { #ifdef WITH_PYTHON @@ -191,6 +207,15 @@ void RNA_api_scene(StructRNA *srna) RNA_def_function_ui_description(func, "Update data tagged to be updated from previous access to data or operators"); + func = RNA_def_function(srna, "uvedit_aspect", "rna_Scene_uvedit_aspect"); + RNA_def_function_ui_description(func, "Get uv aspect for current object"); + parm = RNA_def_pointer(func, "object", "Object", "", "Object"); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + + parm = RNA_def_float_vector(func, "result", 2, NULL, 0.0f, FLT_MAX, "", "aspect", 0.0f, FLT_MAX); + RNA_def_property_flag(parm, PROP_THICK_WRAP); + RNA_def_function_output(func, parm); + /* Ray Cast */ func = RNA_def_function(srna, "ray_cast", "rna_Scene_ray_cast"); RNA_def_function_ui_description(func, "Cast a ray onto in object space"); diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c index cf591dc7750..7b01acff6a5 100644 --- a/source/blender/makesrna/intern/rna_screen.c +++ b/source/blender/makesrna/intern/rna_screen.c @@ -110,13 +110,15 @@ static void rna_Screen_redraw_update(Main *UNUSED(bmain), Scene *UNUSED(scene), static int rna_Screen_is_animation_playing_get(PointerRNA *UNUSED(ptr)) { - return (ED_screen_animation_playing(G.main->wm.first) != NULL); + /* can be NULL on file load, T42619 */ + wmWindowManager *wm = G.main->wm.first; + return wm ? (ED_screen_animation_playing(wm) != NULL) : 0; } static int rna_Screen_fullscreen_get(PointerRNA *ptr) { bScreen *sc = (bScreen *)ptr->data; - return (sc->full != 0); + return (sc->state == SCREENMAXIMIZED); } /* UI compatible list: should not be needed, but for now we need to keep EMPTY @@ -398,7 +400,7 @@ static void rna_def_screen(BlenderRNA *brna) prop = RNA_def_property(srna, "show_fullscreen", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_boolean_funcs(prop, "rna_Screen_fullscreen_get", NULL); - RNA_def_property_ui_text(prop, "Fullscreen", "An area is maximized, filling this screen"); + RNA_def_property_ui_text(prop, "Maximize", "An area is maximized, filling this screen"); /* Define Anim Playback Areas */ prop = RNA_def_property(srna, "use_play_top_left_3d_editor", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 09e42e48e93..0463250d1bb 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -289,7 +289,8 @@ static char *rna_ParticleBrush_path(PointerRNA *UNUSED(ptr)) static void rna_Paint_brush_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { - Brush *br = (Brush *)ptr->data; + Paint *paint = ptr->data; + Brush *br = paint->brush; BKE_paint_invalidate_overlay_all(); WM_main_add_notifier(NC_BRUSH | NA_EDITED, br); } @@ -342,9 +343,11 @@ static void rna_ImaPaint_canvas_update(Main *bmain, Scene *scene, PointerRNA *UN } } - GPU_drawobject_free(ob->derivedFinal); - BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); - WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL); + if (ob && ob->type == OB_MESH) { + GPU_drawobject_free(ob->derivedFinal); + BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); + WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL); + } } static int rna_ImaPaint_detect_data(ImagePaintSettings *imapaint) diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 00f0a6ff487..dda0e8493d9 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -1846,6 +1846,11 @@ static void rna_def_scene(BlenderRNA *brna) RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Camera_object_poll"); RNA_def_property_ui_text(prop, "Camera Override", "Override the scenes active camera"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); + + prop = RNA_def_property(srna, "use_grease_pencil", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SEQ_SCENE_NO_GPENCIL); + RNA_def_property_ui_text(prop, "Use Grease Pencil", "Show Grease Pencil strokes in OpenGL previews"); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); rna_def_filter_video(srna); rna_def_proxy(srna); diff --git a/source/blender/makesrna/intern/rna_sound.c b/source/blender/makesrna/intern/rna_sound.c index 206a72a01b0..aa39e81d390 100644 --- a/source/blender/makesrna/intern/rna_sound.c +++ b/source/blender/makesrna/intern/rna_sound.c @@ -38,6 +38,7 @@ #include "BKE_sound.h" #include "BKE_context.h" +#include "BKE_sequencer.h" static void rna_Sound_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { @@ -59,9 +60,9 @@ static void rna_Sound_caching_set(PointerRNA *ptr, const int value) sound_delete_cache(sound); } -static void rna_Sound_caching_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) +static void rna_Sound_caching_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr) { - sound_update_sequencer(bmain, (bSound *)(ptr->data)); + BKE_sequencer_update_sound(scene, (bSound *)(ptr->data)); } #else diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 5ca38aae9bc..17d4c1bfebb 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -485,7 +485,7 @@ static void rna_SpaceView3D_matcap_update(Main *UNUSED(bmain), Scene *UNUSED(sce BKE_previewimg_free(&ma->preview); if (ma->gpumaterial.first) - GPU_material_free(ma); + GPU_material_free(&ma->gpumaterial); WM_main_add_notifier(NC_MATERIAL | ND_SHADING_DRAW, ma); } @@ -1117,12 +1117,12 @@ static void rna_SpaceDopeSheetEditor_action_update(Main *UNUSED(bmain), Scene *s if (saction->mode == SACTCONT_ACTION) { /* TODO: context selector could help decide this with more control? */ - adt = BKE_id_add_animdata(&obact->id); /* this only adds if non-existant */ + adt = BKE_id_add_animdata(&obact->id); /* this only adds if non-existent */ } else if (saction->mode == SACTCONT_SHAPEKEY) { Key *key = BKE_key_from_object(obact); if (key) - adt = BKE_id_add_animdata(&key->id); /* this only adds if non-existant */ + adt = BKE_id_add_animdata(&key->id); /* this only adds if non-existent */ } /* set action */ @@ -1944,6 +1944,7 @@ static void rna_def_space_view3d(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "grid"); RNA_def_property_ui_text(prop, "Grid Scale", "Distance between 3D View grid lines"); RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.001f, 1000.0f, 0.1f, 3); RNA_def_property_float_default(prop, 1.0f); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); @@ -2040,6 +2041,11 @@ static void rna_def_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Only Render", "Display only objects which will be rendered"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "show_world", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag3", V3D_SHOW_WORLD); + RNA_def_property_ui_text(prop, "World Background", "Display world colors in the background"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "use_occlude_geometry", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_ZBUF_SELECT); RNA_def_property_ui_text(prop, "Occlude Geometry", "Limit selection to visible (clipped with depth buffer)"); @@ -2424,8 +2430,8 @@ static void rna_def_space_image(BlenderRNA *brna) /* grease pencil */ prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "gpd"); - RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "GreasePencil"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this space"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL); @@ -2508,6 +2514,16 @@ static void rna_def_space_sequencer(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem waveform_type_draw_items[] = { + {SEQ_NO_WAVEFORMS, "NO_WAVEFORMS", 0, "Waveforms Off", + "No waveforms drawn for any sound strips"}, + {SEQ_ALL_WAVEFORMS, "ALL_WAVEFORMS", 0, "Waveforms On", + "Waveforms drawn for all sound strips"}, + {0, "DEFAULT_WAVEFORMS", 0, "Use Strip Option", + "Waveforms drawn according to strip setting"}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "SpaceSequenceEditor", "Space"); RNA_def_struct_sdna(srna, "SpaceSeq"); RNA_def_struct_ui_text(srna, "Space Sequence Editor", "Sequence editor space data"); @@ -2577,6 +2593,12 @@ static void rna_def_space_sequencer(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Draw Channels", "Channels of the preview to draw"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); + prop = RNA_def_property(srna, "waveform_draw_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, waveform_type_draw_items); + RNA_def_property_ui_text(prop, "Waveform Drawing", "How Waveforms are drawn"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); + prop = RNA_def_property(srna, "draw_overexposed", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "zebra"); RNA_def_property_ui_text(prop, "Show Overexposed", "Show overexposed areas with zebra stripes"); @@ -2593,8 +2615,8 @@ static void rna_def_space_sequencer(BlenderRNA *brna) /* grease pencil */ prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "gpd"); - RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "GreasePencil"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this space"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); @@ -2603,6 +2625,16 @@ static void rna_def_space_sequencer(BlenderRNA *brna) RNA_def_property_enum_items(prop, overlay_type_items); RNA_def_property_ui_text(prop, "Overlay Type", "Overlay draw type"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); + + prop = RNA_def_property(srna, "show_backdrop", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "draw_flag", SEQ_DRAW_BACKDROP); + RNA_def_property_ui_text(prop, "Use Backdrop", "Display result under strips"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); + + prop = RNA_def_property(srna, "show_strip_offset", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "draw_flag", SEQ_DRAW_OFFSET_EXT); + RNA_def_property_ui_text(prop, "Show Offsets", "Display strip in/out offsets"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); } static void rna_def_space_text(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index f098a659671..188a30d23ce 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -119,6 +119,7 @@ static EnumPropertyItem blend_type_items[] = { #include "BKE_main.h" #include "ED_node.h" +#include "ED_render.h" static StructRNA *rna_Texture_refine(struct PointerRNA *ptr) { @@ -443,8 +444,10 @@ static void rna_Envmap_source_update(Main *bmain, Scene *scene, PointerRNA *ptr) { Tex *tex = ptr->id.data; - if (tex->env) + if (tex->env) { + ED_preview_kill_jobs(bmain->wm.first, bmain); BKE_free_envmapdata(tex->env); + } rna_Texture_update(bmain, scene, ptr); } diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 899da62d9d3..5a70d47a19a 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -1435,8 +1435,8 @@ static void rna_def_trackingTrack(BlenderRNA *brna) /* grease pencil */ prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "gpd"); - RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "GreasePencil"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this track"); RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index b13bdedaffd..4f889c91665 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -137,9 +137,7 @@ static void rna_uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const /* Get translated name (label). */ name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate); - - /* XXX This will search property again :( */ - uiItemMenuEnumR(layout, ptr, propname, name, icon); + uiItemMenuEnumR_prop(layout, ptr, prop, name, icon); } static void rna_uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *value, @@ -178,7 +176,7 @@ static void rna_uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const c } static PointerRNA rna_uiItemO(uiLayout *layout, const char *opname, const char *name, const char *text_ctxt, - int translate, int icon, int emboss) + int translate, int icon, int emboss, int icon_value) { wmOperatorType *ot; int flag; @@ -192,6 +190,10 @@ static PointerRNA rna_uiItemO(uiLayout *layout, const char *opname, const char * /* Get translated name (label). */ name = rna_translate_ui_text(name, text_ctxt, ot->srna, NULL, translate); + if (icon_value && !icon) { + icon = icon_value; + } + flag = UI_ITEM_O_RETURN_PROPS; flag |= (emboss) ? 0 : UI_ITEM_R_NO_BG; @@ -551,6 +553,10 @@ void RNA_api_ui_layout(StructRNA *srna) func = RNA_def_function(srna, "operator", "rna_uiItemO"); api_ui_item_op_common(func); RNA_def_boolean(func, "emboss", true, "", "Draw the button itself, just the icon/text"); + parm = RNA_def_property(func, "icon_value", PROP_INT, PROP_UNSIGNED); + RNA_def_property_ui_text(parm, "Icon Value", + "Override automatic icon of the item " + "(use it e.g. with custom material icons returned by icon()...)"); parm = RNA_def_pointer(func, "properties", "OperatorProperties", "", "Operator properties to fill in, return when 'properties' is set to true"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 3af48b2c0ca..6519781dfd0 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -35,6 +35,8 @@ #include "BLI_utildefines.h" +#include "BKE_appdir.h" +#include "BKE_DerivedMesh.h" #include "BKE_sound.h" #include "BKE_addon.h" @@ -48,6 +50,7 @@ #include "WM_types.h" #include "BLF_translation.h" +#include "GPU_buffers.h" #ifdef WITH_CYCLES static EnumPropertyItem compute_device_type_items[] = { @@ -104,6 +107,10 @@ EnumPropertyItem navigation_mode_items[] = { #include "BKE_addon.h" +#ifdef WITH_SDL_DYNLOAD +# include "sdlew.h" +#endif + static void rna_userdef_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) { WM_main_add_notifier(NC_WINDOW, NULL); @@ -137,6 +144,15 @@ static void rna_userdef_language_update(Main *UNUSED(bmain), Scene *UNUSED(scene UI_reinit_font(); } +static void rna_userdef_vbo_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) +{ + Object *ob; + + for (ob = bmain->object.first; ob; ob = ob->id.next) { + GPU_drawobject_free(ob->derivedFinal); + } +} + static void rna_userdef_show_manipulator_update(Main *bmain, Scene *scene, PointerRNA *ptr) { UserDef *userdef = (UserDef *)ptr->data; @@ -209,6 +225,14 @@ static void rna_userdef_gl_use_16bit_textures(Main *bmain, Scene *scene, Pointer rna_userdef_update(bmain, scene, ptr); } +static void rna_userdef_undo_steps_set(PointerRNA *ptr, int value) +{ + UserDef *userdef = (UserDef *)ptr->data; + + /* Do not allow 1 undo steps, useless and breaks undo/redo process (see T42531). */ + userdef->undosteps = (value == 1) ? 2 : value; +} + static void rna_userdef_select_mouse_set(PointerRNA *ptr, int value) { UserDef *userdef = (UserDef *)ptr->data; @@ -402,7 +426,7 @@ static void rna_userdef_pathcompare_remove(ReportList *reports, PointerRNA *path static void rna_userdef_temp_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) { - BLI_temp_dir_init(U.tempdir); + BKE_tempdir_init(U.tempdir); } static void rna_userdef_text_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) @@ -502,37 +526,38 @@ static EnumPropertyItem *rna_userdef_compute_device_itemf(bContext *UNUSED(C), P static EnumPropertyItem *rna_userdef_audio_device_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) { -#ifdef WITH_JACK - int jack_supported = sound_is_jack_supported(); - - if (jack_supported) { - return audio_device_items; - } - else { - int index = 0; - int totitem = 0; - EnumPropertyItem *item = NULL; + int index = 0; + int totitem = 0; + EnumPropertyItem *item = NULL; - /* NONE */ - RNA_enum_item_add(&item, &totitem, &audio_device_items[index++]); + /* NONE */ + RNA_enum_item_add(&item, &totitem, &audio_device_items[index++]); #ifdef WITH_SDL - RNA_enum_item_add(&item, &totitem, &audio_device_items[index++]); +# ifdef WITH_SDL_DYNLOAD + if (sdlewInit() == SDLEW_SUCCESS) +# endif + { + RNA_enum_item_add(&item, &totitem, &audio_device_items[index]); + } + index++; #endif #ifdef WITH_OPENAL - RNA_enum_item_add(&item, &totitem, &audio_device_items[index++]); + RNA_enum_item_add(&item, &totitem, &audio_device_items[index++]); #endif - RNA_enum_item_end(&item, &totitem); - *r_free = true; - - return item; +#ifdef WITH_JACK + if (sound_is_jack_supported()) { + RNA_enum_item_add(&item, &totitem, &audio_device_items[index]); } -#else - (void)r_free; - return audio_device_items; + index++; #endif + + RNA_enum_item_end(&item, &totitem); + *r_free = true; + + return item; } #ifdef WITH_INTERNATIONAL @@ -1018,6 +1043,12 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Icon Alpha", "Transparency of icons in the interface, to reduce contrast"); RNA_def_property_update(prop, 0, "rna_userdef_update"); + prop = RNA_def_property(srna, "widget_emboss", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "widget_emboss"); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Widget Emboss", "Color of the 1px shadow line underlying widgets"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + /* axis */ prop = RNA_def_property(srna, "axis_x", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "xaxis"); @@ -3253,7 +3284,8 @@ static void rna_def_userdef_view(BlenderRNA *brna) prop = RNA_def_property(srna, "pie_menu_confirm", PROP_INT, PROP_PIXEL); RNA_def_property_range(prop, 0, 1000); - RNA_def_property_ui_text(prop, "Confirm Threshold", "Distance from center after which selection is made"); + RNA_def_property_ui_text(prop, "Confirm Threshold", + "Distance threshold after which selection is made (zero to disable)"); prop = RNA_def_property(srna, "use_quit_dialog", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_QUIT_PROMPT); @@ -3458,6 +3490,7 @@ static void rna_def_userdef_edit(BlenderRNA *brna) prop = RNA_def_property(srna, "undo_steps", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "undosteps"); RNA_def_property_range(prop, 0, 64); + RNA_def_property_int_funcs(prop, NULL, "rna_userdef_undo_steps_set", NULL); RNA_def_property_ui_text(prop, "Undo Steps", "Number of undo steps available (smaller values conserve memory)"); prop = RNA_def_property(srna, "undo_memory_limit", PROP_INT, PROP_NONE); @@ -3930,7 +3963,7 @@ static void rna_def_userdef_system(BlenderRNA *brna) RNA_def_property_ui_text(prop, "VBOs", "Use Vertex Buffer Objects (or Vertex Arrays, if unsupported) for viewport rendering"); /* this isn't essential but nice to check if VBO draws any differently */ - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_WINDOW, "rna_userdef_vbo_update"); prop = RNA_def_property(srna, "anisotropic_filter", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "anisotropic_filter"); @@ -4427,18 +4460,18 @@ static void rna_def_userdef_addon_collection(BlenderRNA *brna, PropertyRNA *cpro RNA_def_property_srna(cprop, "Addons"); srna = RNA_def_struct(brna, "Addons", NULL); RNA_def_struct_clear_flag(srna, STRUCT_UNDO); - RNA_def_struct_ui_text(srna, "User Addons", "Collection of addons"); + RNA_def_struct_ui_text(srna, "User Add-ons", "Collection of add-ons"); func = RNA_def_function(srna, "new", "rna_userdef_addon_new"); RNA_def_function_flag(func, FUNC_NO_SELF); - RNA_def_function_ui_description(func, "Add a new addon"); + RNA_def_function_ui_description(func, "Add a new add-on"); /* return type */ parm = RNA_def_pointer(func, "addon", "Addon", "", "Addon datablock"); RNA_def_function_return(func, parm); func = RNA_def_function(srna, "remove", "rna_userdef_addon_remove"); RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_REPORTS); - RNA_def_function_ui_description(func, "Remove addon"); + RNA_def_function_ui_description(func, "Remove add-on"); parm = RNA_def_pointer(func, "addon", "Addon", "", "Addon to remove"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); @@ -4479,7 +4512,7 @@ void RNA_def_userdef(BlenderRNA *brna) {USER_SECTION_INTERFACE, "INTERFACE", 0, "Interface", ""}, {USER_SECTION_EDIT, "EDITING", 0, "Editing", ""}, {USER_SECTION_INPUT, "INPUT", 0, "Input", ""}, - {USER_SECTION_ADDONS, "ADDONS", 0, "Addons", ""}, + {USER_SECTION_ADDONS, "ADDONS", 0, "Add-ons", ""}, {USER_SECTION_THEME, "THEMES", 0, "Themes", ""}, {USER_SECTION_FILE, "FILES", 0, "File", ""}, {USER_SECTION_SYSTEM, "SYSTEM", 0, "System", ""}, diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index 7513a687978..3b97508dd67 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -429,6 +429,7 @@ EnumPropertyItem operator_return_items[] = { {OPERATOR_FINISHED, "FINISHED", 0, "Finished", "When the operator is complete, operator exits"}, /* used as a flag */ {OPERATOR_PASS_THROUGH, "PASS_THROUGH", 0, "Pass Through", "Do nothing and pass the event on"}, + {OPERATOR_INTERFACE, "INTERFACE", 0, "Interface", "Handled but not executed (popup menus)"}, {0, NULL, 0, NULL, NULL} }; @@ -586,7 +587,7 @@ static void rna_Event_tilt_get(PointerRNA *ptr, float *values) static PointerRNA rna_PopupMenu_layout_get(PointerRNA *ptr) { struct uiPopupMenu *pup = ptr->data; - uiLayout *layout = uiPupMenuLayout(pup); + uiLayout *layout = UI_popup_menu_layout(pup); PointerRNA rptr; RNA_pointer_create(ptr->id.data, &RNA_UILayout, layout, &rptr); @@ -597,7 +598,7 @@ static PointerRNA rna_PopupMenu_layout_get(PointerRNA *ptr) static PointerRNA rna_PieMenu_layout_get(PointerRNA *ptr) { struct uiPieMenu *pie = ptr->data; - uiLayout *layout = uiPieMenuLayout(pie); + uiLayout *layout = UI_pie_menu_layout(pie); PointerRNA rptr; RNA_pointer_create(ptr->id.data, &RNA_UILayout, layout, &rptr); diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c index ad638f2187c..e819d331124 100644 --- a/source/blender/makesrna/intern/rna_wm_api.c +++ b/source/blender/makesrna/intern/rna_wm_api.c @@ -298,7 +298,7 @@ static PointerRNA rna_PupMenuBegin(bContext *C, const char *title, int icon) PointerRNA r_ptr; void *data; - data = (void *)uiPupMenuBegin(C, title, icon); + data = (void *)UI_popup_menu_begin(C, title, icon); RNA_pointer_create(NULL, &RNA_UIPopupMenu, data, &r_ptr); @@ -307,7 +307,7 @@ static PointerRNA rna_PupMenuBegin(bContext *C, const char *title, int icon) static void rna_PupMenuEnd(bContext *C, PointerRNA *handle) { - uiPupMenuEnd(C, handle->data); + UI_popup_menu_end(C, handle->data); } /* pie menu wrapper */ @@ -316,7 +316,7 @@ static PointerRNA rna_PieMenuBegin(bContext *C, const char *title, int icon, Poi PointerRNA r_ptr; void *data; - data = (void *)uiPieMenuBegin(C, title, icon, event->data); + data = (void *)UI_pie_menu_begin(C, title, icon, event->data); RNA_pointer_create(NULL, &RNA_UIPieMenu, data, &r_ptr); @@ -325,7 +325,7 @@ static PointerRNA rna_PieMenuBegin(bContext *C, const char *title, int icon, Poi static void rna_PieMenuEnd(bContext *C, PointerRNA *handle) { - uiPieMenuEnd(C, handle->data); + UI_pie_menu_end(C, handle->data); } #else @@ -462,7 +462,7 @@ void RNA_api_wm(StructRNA *srna) rna_generic_op_invoke(func, WM_GEN_INVOKE_EVENT | WM_GEN_INVOKE_RETURN); - /* wrap uiPupMenuBegin */ + /* wrap UI_popup_menu_begin */ func = RNA_def_function(srna, "pupmenu_begin__internal", "rna_PupMenuBegin"); RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT); parm = RNA_def_string(func, "title", NULL, 0, "", ""); @@ -474,7 +474,7 @@ void RNA_api_wm(StructRNA *srna) RNA_def_property_flag(parm, PROP_RNAPTR | PROP_NEVER_NULL); RNA_def_function_return(func, parm); - /* wrap uiPupMenuEnd */ + /* wrap UI_popup_menu_end */ func = RNA_def_function(srna, "pupmenu_end__internal", "rna_PupMenuEnd"); RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT); parm = RNA_def_pointer(func, "menu", "UIPopupMenu", "", ""); diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index f63350ea0ae..721cbaf21c7 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -89,7 +89,7 @@ static void rna_World_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerR World *wo = ptr->id.data; DAG_id_tag_update(&wo->id, 0); - WM_main_add_notifier(NC_WORLD, wo); + WM_main_add_notifier(NC_WORLD | ND_WORLD, wo); } static void rna_World_draw_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) diff --git a/source/blender/modifiers/SConscript b/source/blender/modifiers/SConscript index c15a562abc0..b4c8299250e 100644 --- a/source/blender/modifiers/SConscript +++ b/source/blender/modifiers/SConscript @@ -52,6 +52,9 @@ defs = [] if env['WITH_BF_BOOLEAN']: incs.append('#/extern/carve') defs.append('WITH_MOD_BOOLEAN') +else: + from os import path + sources.remove(path.join('intern', 'MOD_boolean_util.c')) if env['WITH_BF_REMESH']: incs.append('#/intern/dualcon') diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index 40db49afef2..6046de2cf61 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -323,8 +323,8 @@ static void dm_merge_transform( /* needed for subsurf so arrays are allocated */ cap_dm->getVertArray(cap_dm); cap_dm->getEdgeArray(cap_dm); - cap_dm->getNumLoops(cap_dm); - cap_dm->getNumPolys(cap_dm); + cap_dm->getLoopArray(cap_dm); + cap_dm->getPolyArray(cap_dm); DM_copy_vert_data(cap_dm, result, 0, cap_verts_index, cap_nverts); DM_copy_edge_data(cap_dm, result, 0, cap_edges_index, cap_nedges); diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 2de3220e683..1dca18dce37 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -121,7 +121,12 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob, BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (!BM_vert_is_manifold(v)) continue; - if (vgroup != -1) { + if (bmd->lim_flags & MOD_BEVEL_WEIGHT) { + weight = BM_elem_float_data_get(&bm->vdata, v, CD_BWEIGHT); + if (weight == 0.0f) + continue; + } + else if (vgroup != -1) { weight = defvert_array_find_weight_safe(dvert, BM_elem_index_get(v), vgroup); /* Check is against 0.5 rather than != 0.0 because cascaded bevel modifiers will * interpolate weights for newly created vertices, and may cause unexpected "selection" */ diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c index 49c0c091dee..22636e7c4d0 100644 --- a/source/blender/modifiers/intern/MOD_boolean.c +++ b/source/blender/modifiers/intern/MOD_boolean.c @@ -39,8 +39,6 @@ #include "BLI_utildefines.h" -#include "BLF_translation.h" - #include "BKE_cdderivedmesh.h" #include "BKE_modifier.h" @@ -49,8 +47,6 @@ #include "MOD_boolean_util.h" #include "MOD_util.h" -#include "PIL_time.h" - static void copyData(ModifierData *md, ModifierData *target) { #if 0 diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c index 6e62a21ec4c..061b1198f7e 100644 --- a/source/blender/modifiers/intern/MOD_boolean_util.c +++ b/source/blender/modifiers/intern/MOD_boolean_util.c @@ -365,14 +365,6 @@ BLI_INLINE MPoly *which_mpoly(ExportMeshData *export_data, int which_mesh) return mpoly; } -static void allocate_custom_layers(CustomData *data, int type, int num_elements, int num_layers) -{ - int i; - for (i = 0; i < num_layers; i++) { - CustomData_add_layer(data, type, CD_DEFAULT, NULL, num_elements); - } -} - /* Create new external mesh */ static void exporter_InitGeomArrays(ExportMeshData *export_data, int num_verts, int num_edges, @@ -392,24 +384,15 @@ static void exporter_InitGeomArrays(ExportMeshData *export_data, export_data->mloop = dm->getLoopArray(dm); export_data->mpoly = dm->getPolyArray(dm); - /* Allocate layers for UV layers and vertex colors. - * Without this interpolation of those data will not happen. - */ - allocate_custom_layers(&dm->loopData, CD_MLOOPCOL, num_loops, - CustomData_number_of_layers(&dm_left->loopData, CD_MLOOPCOL)); - allocate_custom_layers(&dm->loopData, CD_MLOOPUV, num_loops, - CustomData_number_of_layers(&dm_left->loopData, CD_MLOOPUV)); - - allocate_custom_layers(&dm->loopData, CD_MLOOPCOL, num_loops, - CustomData_number_of_layers(&dm_right->loopData, CD_MLOOPCOL)); - allocate_custom_layers(&dm->loopData, CD_MLOOPUV, num_loops, - CustomData_number_of_layers(&dm_right->loopData, CD_MLOOPUV)); - /* Merge custom data layers from operands. * * Will only create custom data layers for all the layers which appears in * the operand. Data for those layers will not be allocated or initialized. */ + + CustomData_merge(&dm_left->loopData, &dm->loopData, merge_mask, CD_DEFAULT, num_loops); + CustomData_merge(&dm_right->loopData, &dm->loopData, merge_mask, CD_DEFAULT, num_loops); + CustomData_merge(&dm_left->polyData, &dm->polyData, merge_mask, CD_DEFAULT, num_polys); CustomData_merge(&dm_right->polyData, &dm->polyData, merge_mask, CD_DEFAULT, num_polys); diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c index f6ade2bf303..f30529bc40f 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.c @@ -40,16 +40,16 @@ #include "BLI_math_vector.h" #include "BLI_ghash.h" -#include "DNA_scene_types.h" #include "DNA_meshdata_types.h" #include "BKE_cdderivedmesh.h" -#include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_particle.h" #include "BKE_scene.h" -#include "MOD_util.h" +#ifdef _OPENMP +# include "BKE_mesh.h" /* BKE_MESH_OMP_LIMIT */ +#endif static void initData(ModifierData *md) { diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c index 8f6c533ae4c..130e332ef69 100644 --- a/source/blender/modifiers/intern/MOD_collision.c +++ b/source/blender/modifiers/intern/MOD_collision.c @@ -32,7 +32,6 @@ * \ingroup modifiers */ - #include "DNA_object_types.h" #include "DNA_meshdata_types.h" @@ -49,8 +48,6 @@ #include "BKE_pointcache.h" #include "BKE_scene.h" -#include "MOD_util.h" - static void initData(ModifierData *md) { CollisionModifierData *collmd = (CollisionModifierData *) md; diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c index fbc72cef0e8..9c3ccf033a5 100644 --- a/source/blender/modifiers/intern/MOD_curve.c +++ b/source/blender/modifiers/intern/MOD_curve.c @@ -32,7 +32,6 @@ * \ingroup modifiers */ - #include <string.h> #include "DNA_scene_types.h" @@ -47,7 +46,6 @@ #include "depsgraph_private.h" -#include "MOD_util.h" static void initData(ModifierData *md) { diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index b844b9e3bde..8a92deec8eb 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -35,17 +35,12 @@ #include "DNA_object_types.h" #include "BLI_math.h" -#include "BLI_string.h" #include "BLI_utildefines.h" -#include "BLF_translation.h" - #include "MEM_guardedalloc.h" -#include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_deform.h" -#include "BKE_particle.h" #include "BKE_cdderivedmesh.h" #include "bmesh.h" diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c index 838ceb5cfe0..5236365da70 100644 --- a/source/blender/modifiers/intern/MOD_dynamicpaint.c +++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c @@ -28,7 +28,6 @@ #include <stddef.h> #include "DNA_dynamicpaint_types.h" -#include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -40,8 +39,6 @@ #include "depsgraph_private.h" -#include "MOD_util.h" - static void initData(ModifierData *md) { diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index d3c7e7d4779..86e9dc7dc25 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -54,7 +54,6 @@ #include "MEM_guardedalloc.h" -#include "MOD_util.h" static void initData(ModifierData *md) { diff --git a/source/blender/modifiers/intern/MOD_fluidsim.c b/source/blender/modifiers/intern/MOD_fluidsim.c index d3c56b8d7f7..9c973cd0d50 100644 --- a/source/blender/modifiers/intern/MOD_fluidsim.c +++ b/source/blender/modifiers/intern/MOD_fluidsim.c @@ -45,7 +45,6 @@ #include "depsgraph_private.h" -#include "MOD_util.h" #include "MOD_fluidsim_util.h" #include "MEM_guardedalloc.h" diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c index ffadcda3e8c..a4f6d005d94 100644 --- a/source/blender/modifiers/intern/MOD_laplaciandeform.c +++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c @@ -767,7 +767,7 @@ static void LaplacianDeformModifier_do( LaplacianDeformModifierData *lmd, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts) { - (void)lmd, (void)ob, (void)dm, (void)vertexCos, (void)numVerts; + UNUSED_VARS(lmd, ob, dm, vertexCos, numVerts); } #endif /* WITH_OPENNL */ diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c index 9ba0bfc7ce9..6f33bfa73fc 100644 --- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c +++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c @@ -41,7 +41,6 @@ #include "BKE_deform.h" #include "BKE_modifier.h" -#include "MOD_modifiertypes.h" #include "MOD_util.h" #ifdef WITH_OPENNL @@ -613,7 +612,7 @@ static void laplaciansmoothModifier_do( LaplacianSmoothModifierData *smd, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts) { - (void)smd, (void)ob, (void)dm, (void)vertexCos, (void)numVerts; + UNUSED_VARS(smd, ob, dm, vertexCos, numVerts); } #endif /* WITH_OPENNL */ diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c index e4a359a93e2..86687865d02 100644 --- a/source/blender/modifiers/intern/MOD_lattice.c +++ b/source/blender/modifiers/intern/MOD_lattice.c @@ -38,7 +38,6 @@ #include "DNA_object_types.h" #include "BLI_utildefines.h" -#include "BLI_string.h" #include "BKE_cdderivedmesh.h" #include "BKE_lattice.h" diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c index 838336a8f8a..254ca0bda08 100644 --- a/source/blender/modifiers/intern/MOD_mask.c +++ b/source/blender/modifiers/intern/MOD_mask.c @@ -51,8 +51,6 @@ #include "depsgraph_private.h" -#include "MOD_util.h" - static void copyData(ModifierData *md, ModifierData *target) { #if 0 @@ -150,7 +148,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, bDeformGroup *def; bool *bone_select_array; int bone_select_tot = 0; - const int defbase_tot = BLI_countlist(&ob->defbase); + const int defbase_tot = BLI_listbase_count(&ob->defbase); /* check that there is armature object with bones to use, otherwise return original mesh */ if (ELEM(NULL, oba, oba->pose, ob->defbase.first)) diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c index 925d9691892..db50d49f790 100644 --- a/source/blender/modifiers/intern/MOD_meshcache.c +++ b/source/blender/modifiers/intern/MOD_meshcache.c @@ -48,8 +48,6 @@ #include "MOD_modifiertypes.h" -#include "MOD_util.h" - static void initData(ModifierData *md) { MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md; diff --git a/source/blender/modifiers/intern/MOD_meshcache_pc2.c b/source/blender/modifiers/intern/MOD_meshcache_pc2.c index 3ef0ee54886..679bdcd1d47 100644 --- a/source/blender/modifiers/intern/MOD_meshcache_pc2.c +++ b/source/blender/modifiers/intern/MOD_meshcache_pc2.c @@ -31,7 +31,6 @@ #include "BLI_sys_types.h" #include "BLI_utildefines.h" #include "BLI_fileops.h" -#include "BLI_math.h" #ifdef __BIG_ENDIAN__ # include "BLI_endian_switch.h" #endif diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index 959bbdcbca9..584b5b5fc76 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -37,10 +37,9 @@ #include "DNA_scene_types.h" #include "BLI_math.h" +#include "BLI_task.h" #include "BLI_utildefines.h" -#include "BLF_translation.h" - #include "BKE_cdderivedmesh.h" #include "BKE_global.h" #include "BKE_modifier.h" @@ -53,6 +52,9 @@ #include "MOD_util.h" +#ifdef __SSE2__ +# include <emmintrin.h> +#endif static void initData(ModifierData *md) { @@ -80,9 +82,16 @@ static void copyData(ModifierData *md, ModifierData *target) MeshDeformModifierData *mmd = (MeshDeformModifierData *) md; MeshDeformModifierData *tmmd = (MeshDeformModifierData *) target; - tmmd->gridsize = mmd->gridsize; - tmmd->flag = mmd->flag; - tmmd->object = mmd->object; + *tmmd = *mmd; + + if (mmd->bindinfluences) tmmd->bindinfluences = MEM_dupallocN(mmd->bindinfluences); + if (mmd->bindoffsets) tmmd->bindoffsets = MEM_dupallocN(mmd->bindoffsets); + if (mmd->bindcagecos) tmmd->bindcagecos = MEM_dupallocN(mmd->bindcagecos); + if (mmd->dyngrid) tmmd->dyngrid = MEM_dupallocN(mmd->dyngrid); + if (mmd->dyninfluences) tmmd->dyninfluences = MEM_dupallocN(mmd->dyninfluences); + if (mmd->dynverts) tmmd->dynverts = MEM_dupallocN(mmd->dynverts); + if (mmd->bindweights) tmmd->dynverts = MEM_dupallocN(mmd->bindweights); /* deprecated */ + if (mmd->bindcos) tmmd->dynverts = MEM_dupallocN(mmd->bindcos); /* deprecated */ } static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) @@ -133,11 +142,15 @@ static float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float (*dco)[3 { MDefCell *cell; MDefInfluence *inf; - float gridvec[3], dvec[3], ivec[3], co[3], wx, wy, wz; + float gridvec[3], dvec[3], ivec[3], wx, wy, wz; float weight, cageweight, totweight, *cageco; int i, j, a, x, y, z, size; +#ifdef __SSE2__ + __m128 co = _mm_setzero_ps(); +#else + float co[3] = {0.0f, 0.0f, 0.0f}; +#endif - zero_v3(co); totweight = 0.0f; size = mmd->dyngridsize; @@ -169,18 +182,100 @@ static float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float (*dco)[3 for (j = 0; j < cell->totinfluence; j++, inf++) { cageco = dco[inf->vertex]; cageweight = weight * inf->weight; +#ifdef __SSE2__ + { + __m128 cageweight_r = _mm_set1_ps(cageweight); + /* This will load one extra element, this is ok because + * we ignore that part of register anyway. + */ + __m128 cageco_r = _mm_loadu_ps(cageco); + co = _mm_add_ps(co, + _mm_mul_ps(cageco_r, cageweight_r)); + } +#else co[0] += cageweight * cageco[0]; co[1] += cageweight * cageco[1]; co[2] += cageweight * cageco[2]; +#endif totweight += cageweight; } } +#ifdef __SSE2__ + copy_v3_v3(vec, (float *)&co); +#else copy_v3_v3(vec, co); +#endif return totweight; } +typedef struct MeshdeformUserdata { + /*const*/ MeshDeformModifierData *mmd; + const MDeformVert *dvert; + /*const*/ float (*dco)[3]; + int defgrp_index; + float (*vertexCos)[3]; + float (*cagemat)[4]; + float (*icagemat)[3]; +} MeshdeformUserdata; + +static void meshdeform_vert_task(void * userdata, int iter) +{ + MeshdeformUserdata *data = userdata; + /*const*/ MeshDeformModifierData *mmd = data->mmd; + const MDeformVert *dvert = data->dvert; + const int defgrp_index = data->defgrp_index; + const int *offsets = mmd->bindoffsets; + const MDefInfluence *influences = mmd->bindinfluences; + /*const*/ float (*dco)[3] = data->dco; + float (*vertexCos)[3] = data->vertexCos; + float co[3]; + float weight, totweight, fac = 1.0f; + + if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) + if (!mmd->dynverts[iter]) + return; + + if (dvert) { + fac = defvert_find_weight(&dvert[iter], defgrp_index); + + if (mmd->flag & MOD_MDEF_INVERT_VGROUP) { + fac = 1.0f - fac; + } + + if (fac <= 0.0f) { + return; + } + } + + if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) { + /* transform coordinate into cage's local space */ + mul_v3_m4v3(co, data->cagemat, vertexCos[iter]); + totweight = meshdeform_dynamic_bind(mmd, dco, co); + } + else { + int a; + totweight = 0.0f; + zero_v3(co); + + for (a = offsets[iter]; a < offsets[iter + 1]; a++) { + weight = influences[a].weight; + madd_v3_v3fl(co, dco[influences[a].vertex], weight); + totweight += weight; + } + } + + if (totweight > 0.0f) { + mul_v3_fl(co, fac / totweight); + mul_m3_v3(data->icagemat, co); + if (G.debug_value != 527) + add_v3_v3(vertexCos[iter], co); + else + copy_v3_v3(vertexCos[iter], co); + } +} + static void meshdeformModifier_do( ModifierData *md, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts) @@ -188,12 +283,11 @@ static void meshdeformModifier_do( MeshDeformModifierData *mmd = (MeshDeformModifierData *) md; DerivedMesh *tmpdm, *cagedm; MDeformVert *dvert = NULL; - MDefInfluence *influences; - const int *offsets; float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4]; - float weight, totweight, fac, co[3], (*dco)[3], (*bindcagecos)[3]; - int a, b, totvert, totcagevert, defgrp_index; + float co[3], (*dco)[3], (*bindcagecos)[3]; + int a, totvert, totcagevert, defgrp_index; float (*cagecos)[3]; + MeshdeformUserdata data; if (!mmd->object || (!mmd->bindcagecos && !mmd->bindfunc)) return; @@ -273,11 +367,13 @@ static void meshdeformModifier_do( /* setup deformation data */ cagedm->getVertCos(cagedm, cagecos); - influences = mmd->bindinfluences; - offsets = mmd->bindoffsets; bindcagecos = (float(*)[3])mmd->bindcagecos; - dco = MEM_callocN(sizeof(*dco) * totcagevert, "MDefDco"); + /* We allocate 1 element extra to make it possible to + * load the values to SSE registers, which are float4. + */ + dco = MEM_callocN(sizeof(*dco) * (totcagevert + 1), "MDefDco"); + zero_v3(dco[totcagevert]); for (a = 0; a < totcagevert; a++) { /* get cage vertex in world space with binding transform */ copy_v3_v3(co, cagecos[a]); @@ -293,51 +389,17 @@ static void meshdeformModifier_do( modifier_get_vgroup(ob, dm, mmd->defgrp_name, &dvert, &defgrp_index); - /* do deformation */ - fac = 1.0f; - - for (b = 0; b < totvert; b++) { - if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) - if (!mmd->dynverts[b]) - continue; - - if (dvert) { - fac = defvert_find_weight(&dvert[b], defgrp_index); - - if (mmd->flag & MOD_MDEF_INVERT_VGROUP) { - fac = 1.0f - fac; - } - - if (fac <= 0.0f) { - continue; - } - } - - if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) { - /* transform coordinate into cage's local space */ - mul_v3_m4v3(co, cagemat, vertexCos[b]); - totweight = meshdeform_dynamic_bind(mmd, dco, co); - } - else { - totweight = 0.0f; - zero_v3(co); - - for (a = offsets[b]; a < offsets[b + 1]; a++) { - weight = influences[a].weight; - madd_v3_v3fl(co, dco[influences[a].vertex], weight); - totweight += weight; - } - } - - if (totweight > 0.0f) { - mul_v3_fl(co, fac / totweight); - mul_m3_v3(icagemat, co); - if (G.debug_value != 527) - add_v3_v3(vertexCos[b], co); - else - copy_v3_v3(vertexCos[b], co); - } - } + /* Initialize data to be pass to the for body function. */ + data.mmd = mmd; + data.dvert = dvert; + data.dco = dco; + data.defgrp_index = defgrp_index; + data.vertexCos = vertexCos; + data.cagemat = cagemat; + data.icagemat = icagemat; + + /* Do deformation. */ + BLI_task_parallel_range(0, totvert, &data, meshdeform_vert_task); /* release cage derivedmesh */ MEM_freeN(dco); diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c index 5de4a76dcbe..7a7308639f5 100644 --- a/source/blender/modifiers/intern/MOD_mirror.c +++ b/source/blender/modifiers/intern/MOD_mirror.c @@ -42,8 +42,6 @@ #include "BKE_modifier.h" #include "BKE_deform.h" -#include "bmesh.h" - #include "MEM_guardedalloc.h" #include "depsgraph_private.h" diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index deae10b5bcb..4754813a744 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -44,11 +44,8 @@ #include "BKE_mesh.h" #include "BKE_multires.h" #include "BKE_modifier.h" -#include "BKE_paint.h" #include "BKE_subsurf.h" -#include "MOD_util.h" - static void initData(ModifierData *md) { MultiresModifierData *mmd = (MultiresModifierData *)md; diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index a324702a6ae..1c8dcdff46d 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -43,8 +43,6 @@ #include "BKE_modifier.h" #include "BKE_ocean.h" -#include "MOD_util.h" - #ifdef WITH_OCEANSIM static void init_cache_data(Object *ob, struct OceanModifierData *omd) { diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index 7aa81d6a003..768bed19102 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -48,8 +48,6 @@ #include "BKE_particle.h" #include "BKE_pointcache.h" -#include "MOD_util.h" - #include "depsgraph_private.h" diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c index 229f4911ab4..302013b9b07 100644 --- a/source/blender/modifiers/intern/MOD_shrinkwrap.c +++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c @@ -38,7 +38,6 @@ #include "DNA_object_types.h" #include "BLI_math.h" -#include "BLI_string.h" #include "BLI_utildefines.h" #include "BKE_cdderivedmesh.h" diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c index 3314196b776..19761c43cf0 100644 --- a/source/blender/modifiers/intern/MOD_simpledeform.c +++ b/source/blender/modifiers/intern/MOD_simpledeform.c @@ -244,8 +244,6 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object } - - /* SimpleDeform */ static void initData(ModifierData *md) { diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index 1e422806d80..64f10e5036f 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -79,8 +79,6 @@ #include "bmesh.h" -#include "MOD_util.h" - typedef struct { float mat[3][3]; /* Vert that edge is pointing away from, no relation to @@ -328,8 +326,7 @@ static bool build_hull(SkinOutput *so, Frame **frames, int totframe) return true; #else - (void)so, (void)frames, (void)totframe; - (void)skin_frame_find_contained_faces; + UNUSED_VARS(so, frames, totframe, skin_frame_find_contained_faces); return false; #endif } @@ -1263,7 +1260,7 @@ static void skin_fix_hole_no_good_verts(BMesh *bm, Frame *frame, BMFace *split_f BMO_op_callf(bm, BMO_FLAG_DEFAULTS, "subdivide_edges edges=%he cuts=%i quad_corner_type=%i", - BM_ELEM_TAG, 1, SUBD_STRAIGHT_CUT); + BM_ELEM_TAG, 1, SUBD_CORNER_STRAIGHT_CUT); } else if (split_face->len > 4) { /* Maintain a dynamic vert array containing the split_face's diff --git a/source/blender/modifiers/intern/MOD_smoke.c b/source/blender/modifiers/intern/MOD_smoke.c index fcd4cc96410..f260c0491ee 100644 --- a/source/blender/modifiers/intern/MOD_smoke.c +++ b/source/blender/modifiers/intern/MOD_smoke.c @@ -52,9 +52,6 @@ #include "depsgraph_private.h" -#include "MOD_util.h" - - static void initData(ModifierData *md) { SmokeModifierData *smd = (SmokeModifierData *) md; diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c index 4cae3d662db..592ab4194ec 100644 --- a/source/blender/modifiers/intern/MOD_triangulate.c +++ b/source/blender/modifiers/intern/MOD_triangulate.c @@ -31,7 +31,6 @@ #include "BKE_cdderivedmesh.h" #include "BKE_modifier.h" -#include "BKE_editmesh.h" #include "bmesh.h" #include "bmesh_tools.h" diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index 829c2b88995..8c62a0ba816 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -32,7 +32,6 @@ #include <string.h> -#include "DNA_curve_types.h" #include "DNA_image_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" @@ -48,8 +47,6 @@ #include "BKE_image.h" #include "BKE_lattice.h" #include "BKE_mesh.h" -#include "BKE_displist.h" -#include "BKE_scene.h" #include "BKE_modifier.h" @@ -58,8 +55,6 @@ #include "MEM_guardedalloc.h" -#include "RE_shader_ext.h" - #ifdef OPENNL_THREADING_HACK #include "BLI_threads.h" #endif diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c index 2ff93efdb86..75a074a245a 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.c +++ b/source/blender/modifiers/intern/MOD_uvproject.c @@ -49,7 +49,6 @@ #include "BKE_DerivedMesh.h" #include "MOD_modifiertypes.h" -#include "MOD_util.h" #include "MEM_guardedalloc.h" #include "depsgraph_private.h" diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c index 744b6b62c2a..c9de1dc083d 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.c +++ b/source/blender/modifiers/intern/MOD_weightvg_util.c @@ -34,7 +34,6 @@ #include "BLI_utildefines.h" #include "DNA_color_types.h" /* CurveMapping. */ -#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" @@ -43,11 +42,9 @@ #include "BKE_cdderivedmesh.h" #include "BKE_colortools.h" /* CurveMapping. */ #include "BKE_deform.h" -#include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_texture.h" /* Texture masking. */ -#include "depsgraph_private.h" #include "MEM_guardedalloc.h" #include "MOD_util.h" #include "MOD_weightvg_util.h" @@ -235,8 +232,6 @@ void weightvg_do_mask(int num, const int *indices, float *org_w, const float *ne } - - /* Applies weights to given vgroup (defgroup), and optionally add/remove vertices from the group. * If dws is not NULL, it must be an array of MDeformWeight pointers of same length as weights (and * defgrp_idx can then have any value). diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c index f36abcceae0..5a6e958457e 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.c +++ b/source/blender/modifiers/intern/MOD_weightvgedit.c @@ -34,7 +34,6 @@ #include "BLI_rand.h" #include "DNA_color_types.h" /* CurveMapping. */ -#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" @@ -48,7 +47,6 @@ #include "depsgraph_private.h" #include "MEM_guardedalloc.h" -#include "MOD_util.h" #include "MOD_weightvg_util.h" /************************************** diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c index bdc1099d682..099d4c7116e 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.c +++ b/source/blender/modifiers/intern/MOD_weightvgmix.c @@ -44,7 +44,6 @@ #include "depsgraph_private.h" #include "MEM_guardedalloc.h" -#include "MOD_util.h" #include "MOD_weightvg_util.h" diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c index 71d4742980e..766ffe529ab 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.c +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c @@ -47,7 +47,6 @@ #include "depsgraph_private.h" #include "MEM_guardedalloc.h" -#include "MOD_util.h" #include "MOD_weightvg_util.h" // #define USE_TIMEIT diff --git a/source/blender/modifiers/intern/MOD_wireframe.c b/source/blender/modifiers/intern/MOD_wireframe.c index 7349ca9f9ef..8b611f9e6da 100644 --- a/source/blender/modifiers/intern/MOD_wireframe.c +++ b/source/blender/modifiers/intern/MOD_wireframe.c @@ -23,20 +23,14 @@ * \ingroup modifiers */ -#include "MEM_guardedalloc.h" - #include "DNA_object_types.h" -#include "DNA_meshdata_types.h" -#include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_string.h" #include "BKE_cdderivedmesh.h" #include "BKE_deform.h" #include "MOD_modifiertypes.h" -#include "MOD_util.h" #include "bmesh.h" #include "tools/bmesh_wireframe.h" diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index 6d5b85da569..e616680647e 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -36,11 +36,8 @@ #include "DNA_scene_types.h" #include "DNA_node_types.h" -#include "BLI_listbase.h" - #include "BLF_translation.h" -#include "BKE_colortools.h" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_main.h" @@ -50,8 +47,6 @@ #include "node_common.h" #include "node_util.h" -#include "PIL_time.h" - #include "RNA_access.h" #include "NOD_composite.h" @@ -236,11 +231,10 @@ void ntreeCompositExecTree(Scene *scene, bNodeTree *ntree, RenderData *rd, int r #ifdef WITH_COMPOSITOR COM_execute(rd, scene, ntree, rendering, view_settings, display_settings); #else - (void)scene, (void)ntree, (void)rd, (void)rendering, (void)do_preview; - (void)view_settings, (void)display_settings; + UNUSED_VARS(scene, ntree, rd, rendering, view_settings, display_settings); #endif - (void)do_preview; + UNUSED_VARS(do_preview); } /* *********************************************** */ diff --git a/source/blender/nodes/composite/nodes/node_composite_boxmask.c b/source/blender/nodes/composite/nodes/node_composite_boxmask.c index 9cb0f1c75c7..0390eb43da0 100644 --- a/source/blender/nodes/composite/nodes/node_composite_boxmask.c +++ b/source/blender/nodes/composite/nodes/node_composite_boxmask.c @@ -66,7 +66,3 @@ void register_node_type_cmp_boxmask(void) nodeRegisterType(&ntype); } - - - - diff --git a/source/blender/nodes/composite/nodes/node_composite_colorbalance.c b/source/blender/nodes/composite/nodes/node_composite_colorbalance.c index 65f2391983e..70e52d432cd 100644 --- a/source/blender/nodes/composite/nodes/node_composite_colorbalance.c +++ b/source/blender/nodes/composite/nodes/node_composite_colorbalance.c @@ -29,11 +29,8 @@ * \ingroup cmpnodes */ - - #include "node_composite_util.h" - /* ******************* Color Balance ********************************* */ static bNodeSocketTemplate cmp_node_colorbalance_in[] = { {SOCK_FLOAT, 1, N_("Fac"), 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, diff --git a/source/blender/nodes/composite/nodes/node_composite_common.c b/source/blender/nodes/composite/nodes/node_composite_common.c index 36c12693bdf..75e7fa8fbac 100644 --- a/source/blender/nodes/composite/nodes/node_composite_common.c +++ b/source/blender/nodes/composite/nodes/node_composite_common.c @@ -35,7 +35,6 @@ #include "node_composite_util.h" #include "NOD_common.h" #include "node_common.h" -#include "node_exec.h" #include "BKE_node.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_composite.c b/source/blender/nodes/composite/nodes/node_composite_composite.c index 41d417c2cb4..be9ed457150 100644 --- a/source/blender/nodes/composite/nodes/node_composite_composite.c +++ b/source/blender/nodes/composite/nodes/node_composite_composite.c @@ -31,10 +31,6 @@ #include "node_composite_util.h" -#include "BKE_context.h" - -#include "RNA_access.h" - /* **************** COMPOSITE ******************** */ static bNodeSocketTemplate cmp_node_composite_in[] = { { SOCK_RGBA, 1, N_("Image"), 0.0f, 0.0f, 0.0f, 1.0f}, diff --git a/source/blender/nodes/composite/nodes/node_composite_defocus.c b/source/blender/nodes/composite/nodes/node_composite_defocus.c index ef670b760c2..a3311755717 100644 --- a/source/blender/nodes/composite/nodes/node_composite_defocus.c +++ b/source/blender/nodes/composite/nodes/node_composite_defocus.c @@ -33,10 +33,6 @@ #include <limits.h> -#include "BKE_context.h" - -#include "RNA_access.h" - /* ************ qdn: Defocus node ****************** */ static bNodeSocketTemplate cmp_node_defocus_in[] = { { SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f}, diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c index 659e582dc1d..ecc02e732ce 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.c +++ b/source/blender/nodes/composite/nodes/node_composite_image.c @@ -39,8 +39,6 @@ #include "BKE_global.h" #include "BKE_main.h" -#include "RNA_access.h" - /* **************** IMAGE (and RenderResult, multilayer image) ******************** */ static bNodeSocketTemplate cmp_node_rlayers_out[] = { diff --git a/source/blender/nodes/composite/nodes/node_composite_keying.c b/source/blender/nodes/composite/nodes/node_composite_keying.c index 6b5def1ea93..ba179bcbcd3 100644 --- a/source/blender/nodes/composite/nodes/node_composite_keying.c +++ b/source/blender/nodes/composite/nodes/node_composite_keying.c @@ -34,12 +34,8 @@ #include "DNA_movieclip_types.h" -#include "BKE_movieclip.h" - -#include "BLI_listbase.h" #include "BLI_math_base.h" #include "BLI_math_color.h" -#include "BLI_voronoi.h" #include "node_composite_util.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c b/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c index 9965b55e088..0cdf15c0412 100644 --- a/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c +++ b/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c @@ -30,16 +30,10 @@ * \ingroup cmpnodes */ -#include "BLF_translation.h" - #include "DNA_movieclip_types.h" -#include "BKE_movieclip.h" - -#include "BLI_listbase.h" #include "BLI_math_base.h" #include "BLI_math_color.h" -#include "BLI_voronoi.h" #include "node_composite_util.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_mask.c b/source/blender/nodes/composite/nodes/node_composite_mask.c index 83cea47db1b..dd05d5d83ad 100644 --- a/source/blender/nodes/composite/nodes/node_composite_mask.c +++ b/source/blender/nodes/composite/nodes/node_composite_mask.c @@ -30,12 +30,8 @@ * \ingroup cmpnodes */ -#include "BLF_translation.h" - #include "DNA_mask_types.h" -#include "BKE_mask.h" - #include "node_composite_util.h" /* **************** Translate ******************** */ diff --git a/source/blender/nodes/composite/nodes/node_composite_movieclip.c b/source/blender/nodes/composite/nodes/node_composite_movieclip.c index fc0d8060644..0fece9dd4f6 100644 --- a/source/blender/nodes/composite/nodes/node_composite_movieclip.c +++ b/source/blender/nodes/composite/nodes/node_composite_movieclip.c @@ -30,13 +30,10 @@ * \ingroup cmpnodes */ - #include "node_composite_util.h" #include "BKE_context.h" -#include "RNA_access.h" - static bNodeSocketTemplate cmp_node_movieclip_out[] = { { SOCK_RGBA, 0, N_("Image")}, { SOCK_FLOAT, 0, N_("Alpha")}, diff --git a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c index 1d411aafe68..9c54009d2f1 100644 --- a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c +++ b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c @@ -34,8 +34,6 @@ #include "BKE_context.h" -#include "RNA_access.h" - /* **************** Translate ******************** */ static bNodeSocketTemplate cmp_node_moviedistortion_in[] = { diff --git a/source/blender/nodes/composite/nodes/node_composite_outputFile.c b/source/blender/nodes/composite/nodes/node_composite_outputFile.c index 76101409ba7..8e602c6179c 100644 --- a/source/blender/nodes/composite/nodes/node_composite_outputFile.c +++ b/source/blender/nodes/composite/nodes/node_composite_outputFile.c @@ -40,9 +40,6 @@ #include "node_composite_util.h" -#include "IMB_imbuf.h" -#include "IMB_imbuf_types.h" - #include "intern/openexr/openexr_multi.h" @@ -140,7 +137,7 @@ int ntreeCompositOutputFileRemoveActiveSocket(bNodeTree *ntree, bNode *node) { NodeImageMultiFile *nimf = node->storage; bNodeSocket *sock = BLI_findlink(&node->inputs, nimf->active_input); - int totinputs = BLI_countlist(&node->inputs); + int totinputs = BLI_listbase_count(&node->inputs); if (!sock) return 0; diff --git a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c index 28e2a2a205b..00791c278ae 100644 --- a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c +++ b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c @@ -30,13 +30,10 @@ * \ingroup cmpnodes */ - #include "node_composite_util.h" #include "BKE_context.h" -#include "RNA_access.h" - /* **************** Translate ******************** */ static bNodeSocketTemplate cmp_node_stabilize2d_in[] = { diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index c58c9c902ec..0e250dc3aa4 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -29,7 +29,6 @@ * \ingroup nodes */ - #include <string.h> #include <stddef.h> @@ -43,15 +42,12 @@ #include "BKE_node.h" -#include "RNA_access.h" #include "RNA_types.h" #include "MEM_guardedalloc.h" #include "node_common.h" #include "node_util.h" -#include "node_exec.h" -#include "NOD_socket.h" #include "NOD_common.h" diff --git a/source/blender/nodes/intern/node_socket.c b/source/blender/nodes/intern/node_socket.c index 2ac1a2c85f3..282567b797f 100644 --- a/source/blender/nodes/intern/node_socket.c +++ b/source/blender/nodes/intern/node_socket.c @@ -41,7 +41,6 @@ #include "BKE_node.h" #include "RNA_access.h" -#include "RNA_define.h" #include "RNA_types.h" #include "MEM_guardedalloc.h" diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c index d92d0c98a05..7bc8dde3312 100644 --- a/source/blender/nodes/shader/node_shader_tree.c +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -41,16 +41,13 @@ #include "DNA_linestyle_types.h" #include "BLI_listbase.h" -#include "BLI_math.h" #include "BLI_threads.h" #include "BLI_utildefines.h" #include "BLF_translation.h" #include "BKE_context.h" -#include "BKE_global.h" #include "BKE_linestyle.h" -#include "BKE_main.h" #include "BKE_node.h" #include "BKE_scene.h" @@ -70,9 +67,9 @@ static int shader_tree_poll(const bContext *C, bNodeTreeType *UNUSED(treetype)) Scene *scene = CTX_data_scene(C); /* allow empty engine string too, this is from older versions that didn't have registerable engines yet */ return (scene->r.engine[0] == '\0' || - STREQ(scene->r.engine, "BLENDER_RENDER") || - STREQ(scene->r.engine, "BLENDER_GAME") || - STREQ(scene->r.engine, "CYCLES")); + STREQ(scene->r.engine, RE_engine_id_BLENDER_RENDER) || + STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME) || + STREQ(scene->r.engine, RE_engine_id_CYCLES)); } static void shader_get_from_context(const bContext *C, bNodeTreeType *UNUSED(treetype), bNodeTree **r_ntree, ID **r_id, ID **r_from) diff --git a/source/blender/nodes/shader/nodes/node_shader_background.c b/source/blender/nodes/shader/nodes/node_shader_background.c index 2478fb4d38c..b387529e456 100644 --- a/source/blender/nodes/shader/nodes/node_shader_background.c +++ b/source/blender/nodes/shader/nodes/node_shader_background.c @@ -40,6 +40,11 @@ static bNodeSocketTemplate sh_node_background_out[] = { { -1, 0, "" } }; +static int node_shader_gpu_background(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) +{ + return GPU_stack_link(mat, "node_background", in, out, GPU_builtin(GPU_VIEW_NORMAL)); +} + /* node type definition */ void register_node_type_sh_background(void) { @@ -50,6 +55,7 @@ void register_node_type_sh_background(void) node_type_socket_templates(&ntype, sh_node_background_in, sh_node_background_out); node_type_init(&ntype, NULL); node_type_storage(&ntype, "", NULL, NULL); + node_type_gpu(&ntype, node_shader_gpu_background); nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bump.c b/source/blender/nodes/shader/nodes/node_shader_bump.c index 3ce01ce03bf..de152ee45d1 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bump.c +++ b/source/blender/nodes/shader/nodes/node_shader_bump.c @@ -29,11 +29,8 @@ * \ingroup shdnodes */ - - #include "node_shader_util.h" - /* **************** BUMP ******************** */ static bNodeSocketTemplate sh_node_bump_in[] = { { SOCK_FLOAT, 1, N_("Strength"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, diff --git a/source/blender/nodes/shader/nodes/node_shader_material.c b/source/blender/nodes/shader/nodes/node_shader_material.c index 79d66495ad7..b7e10c7e9df 100644 --- a/source/blender/nodes/shader/nodes/node_shader_material.c +++ b/source/blender/nodes/shader/nodes/node_shader_material.c @@ -267,6 +267,8 @@ static int gpu_shader_material(GPUMaterial *mat, bNode *node, bNodeExecData *UNU shi.amb = gpu_get_input_link(&in[MAT_IN_AMB]); if (hasinput[MAT_IN_EMIT]) shi.emit = gpu_get_input_link(&in[MAT_IN_EMIT]); + if (hasinput[MAT_IN_SPECTRA]) + shi.spectra = gpu_get_input_link(&in[MAT_IN_SPECTRA]); if (hasinput[MAT_IN_ALPHA]) shi.alpha = gpu_get_input_link(&in[MAT_IN_ALPHA]); } diff --git a/source/blender/nodes/shader/nodes/node_shader_math.c b/source/blender/nodes/shader/nodes/node_shader_math.c index dc5971909d2..be2e3dcd311 100644 --- a/source/blender/nodes/shader/nodes/node_shader_math.c +++ b/source/blender/nodes/shader/nodes/node_shader_math.c @@ -54,16 +54,16 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode switch (node->custom1) { - case 0: /* Add */ + case NODE_MATH_ADD: r = a + b; break; - case 1: /* Subtract */ + case NODE_MATH_SUB: r = a - b; break; - case 2: /* Multiply */ + case NODE_MATH_MUL: r = a * b; break; - case 3: /* Divide */ + case NODE_MATH_DIVIDE: { if (b == 0) /* We don't want to divide by zero. */ r = 0.0; @@ -71,7 +71,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode r = a / b; break; } - case 4: /* Sine */ + case NODE_MATH_SIN: { if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */ r = sinf(a); @@ -79,7 +79,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode r = sinf(b); break; } - case 5: /* Cosine */ + case NODE_MATH_COS: { if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */ r = cosf(a); @@ -87,7 +87,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode r = cosf(b); break; } - case 6: /* Tangent */ + case NODE_MATH_TAN: { if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */ r = tanf(a); @@ -95,7 +95,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode r = tanf(b); break; } - case 7: /* Arc-Sine */ + case NODE_MATH_ASIN: { if (in[0]->hasinput || !in[1]->hasinput) { /* This one only takes one input, so we've got to choose. */ /* Can't do the impossible... */ @@ -113,7 +113,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode } break; } - case 8: /* Arc-Cosine */ + case NODE_MATH_ACOS: { if (in[0]->hasinput || !in[1]->hasinput) { /* This one only takes one input, so we've got to choose. */ /* Can't do the impossible... */ @@ -131,7 +131,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode } break; } - case 9: /* Arc-Tangent */ + case NODE_MATH_ATAN: { if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */ r = atan(a); @@ -139,7 +139,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode r = atan(b); break; } - case 10: /* Power */ + case NODE_MATH_POW: { /* Only raise negative numbers by full integers */ if (a >= 0) { @@ -159,7 +159,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode break; } - case 11: /* Logarithm */ + case NODE_MATH_LOG: { /* Don't want any imaginary numbers... */ if (a > 0 && b > 0) @@ -168,7 +168,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode r = 0.0; break; } - case 12: /* Minimum */ + case NODE_MATH_MIN: { if (a < b) r = a; @@ -176,7 +176,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode r = b; break; } - case 13: /* Maximum */ + case NODE_MATH_MAX: { if (a > b) r = a; @@ -184,7 +184,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode r = b; break; } - case 14: /* Round */ + case NODE_MATH_ROUND: { if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */ r = (a < 0) ? (int)(a - 0.5f) : (int)(a + 0.5f); @@ -192,7 +192,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode r = (b < 0) ? (int)(b - 0.5f) : (int)(b + 0.5f); break; } - case 15: /* Less Than */ + case NODE_MATH_LESS: { if (a < b) r = 1.0f; @@ -200,7 +200,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode r = 0.0f; break; } - case 16: /* Greater Than */ + case NODE_MATH_GREATER: { if (a > b) r = 1.0f; @@ -208,7 +208,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode r = 0.0f; break; } - case 17: /* Modulo */ + case NODE_MATH_MOD: { if (b == 0.0f) r = 0.0f; @@ -216,13 +216,15 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode r = fmod(a, b); break; } - case 18: /* Absolute */ + case NODE_MATH_ABS: { r = fabsf(a); break; } } - + if (node->custom2 & SHD_MATH_CLAMP) { + CLAMP(r, 0.0f, 1.0f); + } out[0]->vec[0] = r; } @@ -231,29 +233,30 @@ static int gpu_shader_math(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED( static const char *names[] = {"math_add", "math_subtract", "math_multiply", "math_divide", "math_sine", "math_cosine", "math_tangent", "math_asin", "math_acos", "math_atan", "math_pow", "math_log", "math_min", "math_max", - "math_round", "math_less_than", "math_greater_than", "math_modulo", "math_absolute"}; + "math_round", "math_less_than", "math_greater_than", "math_modulo", "math_abs"}; switch (node->custom1) { - case 0: - case 1: - case 2: - case 3: - case 10: - case 11: - case 12: - case 13: - case 15: - case 16: - case 17: + case NODE_MATH_ADD: + case NODE_MATH_SUB: + case NODE_MATH_MUL: + case NODE_MATH_DIVIDE: + case NODE_MATH_POW: + case NODE_MATH_LOG: + case NODE_MATH_MIN: + case NODE_MATH_MAX: + case NODE_MATH_LESS: + case NODE_MATH_GREATER: + case NODE_MATH_MOD: GPU_stack_link(mat, names[node->custom1], in, out); break; - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 14: + case NODE_MATH_SIN: + case NODE_MATH_COS: + case NODE_MATH_TAN: + case NODE_MATH_ASIN: + case NODE_MATH_ACOS: + case NODE_MATH_ATAN: + case NODE_MATH_ROUND: + case NODE_MATH_ABS: if (in[0].hasinput || !in[1].hasinput) { /* use only first item and terminator */ GPUNodeStack tmp_in[2]; @@ -272,7 +275,13 @@ static int gpu_shader_math(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED( default: return 0; } - + + if (node->custom2 & SHD_MATH_CLAMP) { + float min[3] = {0.0f, 0.0f, 0.0f}; + float max[3] = {1.0f, 1.0f, 1.0f}; + GPU_link(mat, "clamp_val", out[0].link, GPU_uniform(min), GPU_uniform(max), &out[0].link); + } + return 1; } diff --git a/source/blender/nodes/shader/nodes/node_shader_mixRgb.c b/source/blender/nodes/shader/nodes/node_shader_mixRgb.c index 2da51c19ef8..f911fa058dc 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mixRgb.c +++ b/source/blender/nodes/shader/nodes/node_shader_mixRgb.c @@ -59,6 +59,9 @@ static void node_shader_exec_mix_rgb(void *UNUSED(data), int UNUSED(thread), bNo nodestack_get_vec(vec, SOCK_VECTOR, in[2]); ramp_blend(node->custom1, col, fac, vec); + if (node->custom2 & SHD_MIXRGB_CLAMP) { + CLAMP3(col, 0.0f, 1.0f); + } copy_v3_v3(out[0]->vec, col); } @@ -68,8 +71,13 @@ static int gpu_shader_mix_rgb(GPUMaterial *mat, bNode *node, bNodeExecData *UNUS "mix_screen", "mix_div", "mix_diff", "mix_dark", "mix_light", "mix_overlay", "mix_dodge", "mix_burn", "mix_hue", "mix_sat", "mix_val", "mix_color", "mix_soft", "mix_linear"}; - - return GPU_stack_link(mat, names[node->custom1], in, out); + int ret = GPU_stack_link(mat, names[node->custom1], in, out); + if (ret && node->custom2 & SHD_MIXRGB_CLAMP) { + float min[3] = {0.0f, 0.0f, 0.0f}; + float max[3] = {1.0f, 1.0f, 1.0f}; + GPU_link(mat, "clamp_vec3", out[0].link, GPU_uniform(min), GPU_uniform(max), &out[0].link); + } + return ret; } diff --git a/source/blender/nodes/shader/nodes/node_shader_normal.c b/source/blender/nodes/shader/nodes/node_shader_normal.c index fcd738f0b15..092fc201aa7 100644 --- a/source/blender/nodes/shader/nodes/node_shader_normal.c +++ b/source/blender/nodes/shader/nodes/node_shader_normal.c @@ -61,12 +61,12 @@ static void node_shader_exec_normal(void *UNUSED(data), int UNUSED(thread), bNod static int gpu_shader_normal(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { GPUNodeLink *vec = GPU_uniform(out[0].vec); - int ret = GPU_stack_link(mat, "normal", in, out, vec); - if (ret && GPU_material_use_new_shading_nodes(mat)) { - float fac[3] = {1.0f, 0.0f, 0.0f}; - GPU_link(mat, "invert", GPU_uniform(fac), out[1].link, &out[1].link); + if (GPU_material_use_new_shading_nodes(mat)) { + return GPU_stack_link(mat, "normal_new_shading", in, out, vec); + } + else { + return GPU_stack_link(mat, "normal", in, out, vec); } - return ret; } void register_node_type_sh_normal(void) diff --git a/source/blender/nodes/shader/nodes/node_shader_output_world.c b/source/blender/nodes/shader/nodes/node_shader_output_world.c index c8e47c47c5f..ad7389fd56e 100644 --- a/source/blender/nodes/shader/nodes/node_shader_output_world.c +++ b/source/blender/nodes/shader/nodes/node_shader_output_world.c @@ -35,6 +35,16 @@ static bNodeSocketTemplate sh_node_output_world_in[] = { { -1, 0, "" } }; +static int node_shader_gpu_output_world(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) +{ + GPUNodeLink *outlink; + + GPU_stack_link(mat, "node_output_world", in, out, &outlink); + GPU_material_output_link(mat, outlink); + + return 1; +} + /* node type definition */ void register_node_type_sh_output_world(void) { @@ -45,7 +55,8 @@ void register_node_type_sh_output_world(void) node_type_socket_templates(&ntype, sh_node_output_world_in, NULL); node_type_init(&ntype, NULL); node_type_storage(&ntype, "", NULL, NULL); - + node_type_gpu(&ntype, node_shader_gpu_output_world); + /* Do not allow muting output node. */ node_type_internal_links(&ntype, NULL); diff --git a/source/blender/nodes/shader/nodes/node_shader_script.c b/source/blender/nodes/shader/nodes/node_shader_script.c index d5ed38297da..f640dd5ea13 100644 --- a/source/blender/nodes/shader/nodes/node_shader_script.c +++ b/source/blender/nodes/shader/nodes/node_shader_script.c @@ -31,8 +31,6 @@ #include "node_shader_util.h" -#include "BKE_idprop.h" - /* **************** Script ******************** */ static void init(bNodeTree *UNUSED(ntree), bNode *node) diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c index 781b1bb5a93..85eca6ae990 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c @@ -46,10 +46,18 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat, bNode *UNUSED(node), bNod { GPUNodeLink *orco = GPU_attribute(CD_ORCO, ""); GPUNodeLink *mtface = GPU_attribute(CD_MTFACE, ""); - - return GPU_stack_link(mat, "node_tex_coord", in, out, - GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL), - GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), orco, mtface); + GPUMatType type = GPU_Material_get_type(mat); + + if (type == GPU_MATERIAL_TYPE_MESH) { + return GPU_stack_link(mat, "node_tex_coord", in, out, + GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL), + GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), orco, mtface); + } + else { + return GPU_stack_link(mat, "node_tex_coord_background", in, out, + GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL), + GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), orco, mtface); + } } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c index dcb3ef3c8a0..8d6a77455bb 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c @@ -27,8 +27,6 @@ #include "../node_shader_util.h" -#include "IMB_colormanagement.h" - /* **************** OUTPUT ******************** */ static bNodeSocketTemplate sh_node_tex_environment_in[] = { @@ -67,13 +65,22 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, bNode *node, bNodeE if (!ima) return GPU_stack_link(mat, "node_tex_environment_empty", in, out); - if (!in[0].link) - in[0].link = GPU_builtin(GPU_VIEW_POSITION); - + if (!in[0].link) { + GPUMatType type = GPU_Material_get_type(mat); + + if (type == GPU_MATERIAL_TYPE_MESH) + in[0].link = GPU_builtin(GPU_VIEW_POSITION); + else + GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &in[0].link); + } + node_shader_gpu_tex_mapping(mat, node, in, out); - ret = GPU_stack_link(mat, "node_tex_environment", in, out, GPU_image(ima, iuser, isdata)); - + if (tex->projection == SHD_PROJ_EQUIRECTANGULAR) + ret = GPU_stack_link(mat, "node_tex_environment_equirectangular", in, out, GPU_image(ima, iuser, isdata)); + else + ret = GPU_stack_link(mat, "node_tex_environment_mirror_ball", in, out, GPU_image(ima, iuser, isdata)); + if (ret) { ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL); if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 && diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c index 0a11ee4a9b6..62db5b70891 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c @@ -27,8 +27,6 @@ #include "../node_shader_util.h" -#include "IMB_colormanagement.h" - /* **************** OUTPUT ******************** */ static bNodeSocketTemplate sh_node_tex_image_in[] = { diff --git a/source/blender/nodes/shader/nodes/node_shader_texture.c b/source/blender/nodes/shader/nodes/node_shader_texture.c index d02d72563ba..5cdbaf444f8 100644 --- a/source/blender/nodes/shader/nodes/node_shader_texture.c +++ b/source/blender/nodes/shader/nodes/node_shader_texture.c @@ -29,11 +29,8 @@ * \ingroup shdnodes */ - #include "DNA_texture_types.h" -#include "IMB_colormanagement.h" - #include "node_shader_util.h" /* **************** TEXTURE ******************** */ diff --git a/source/blender/nodes/shader/nodes/node_shader_uvAlongStroke.c b/source/blender/nodes/shader/nodes/node_shader_uvAlongStroke.c index 48eb4cadba4..67342e1e836 100644 --- a/source/blender/nodes/shader/nodes/node_shader_uvAlongStroke.c +++ b/source/blender/nodes/shader/nodes/node_shader_uvAlongStroke.c @@ -27,8 +27,6 @@ #include "../node_shader_util.h" -#include "DNA_customdata_types.h" - /* **************** OUTPUT ******************** */ static bNodeSocketTemplate sh_node_uvalongstroke_out[] = { diff --git a/source/blender/nodes/shader/nodes/node_shader_vectMath.c b/source/blender/nodes/shader/nodes/node_shader_vectMath.c index f2ea2faa5a7..9e75d915d44 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vectMath.c +++ b/source/blender/nodes/shader/nodes/node_shader_vectMath.c @@ -29,11 +29,8 @@ * \ingroup shdnodes */ - - #include "node_shader_util.h" - /* **************** VECTOR MATH ******************** */ static bNodeSocketTemplate sh_node_vect_math_in[] = { { SOCK_VECTOR, 1, N_("Vector"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE}, diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c index bf97037f626..e04e8f42c30 100644 --- a/source/blender/nodes/texture/node_texture_tree.c +++ b/source/blender/nodes/texture/node_texture_tree.c @@ -43,9 +43,7 @@ #include "BLF_translation.h" #include "BKE_context.h" -#include "BKE_global.h" #include "BKE_linestyle.h" -#include "BKE_main.h" #include "BKE_node.h" #include "BKE_paint.h" @@ -57,7 +55,6 @@ #include "RNA_access.h" -#include "RE_pipeline.h" #include "RE_shader_ext.h" diff --git a/source/blender/nodes/texture/nodes/node_texture_math.c b/source/blender/nodes/texture/nodes/node_texture_math.c index 022e5dbd80f..bae97bea2d7 100644 --- a/source/blender/nodes/texture/nodes/node_texture_math.c +++ b/source/blender/nodes/texture/nodes/node_texture_math.c @@ -58,16 +58,16 @@ static void exec(void *UNUSED(data), switch (node->custom1) { - case 0: /* Add */ + case NODE_MATH_ADD: out[0]->vec[0] = in0 + in1; break; - case 1: /* Subtract */ + case NODE_MATH_SUB: out[0]->vec[0] = in0 - in1; break; - case 2: /* Multiply */ + case NODE_MATH_MUL: out[0]->vec[0] = in0 * in1; break; - case 3: /* Divide */ + case NODE_MATH_DIVIDE: { if (in1 == 0) /* We don't want to divide by zero. */ out[0]->vec[0] = 0.0f; @@ -75,22 +75,22 @@ static void exec(void *UNUSED(data), out[0]->vec[0] = in0 / in1; break; } - case 4: /* Sine */ + case NODE_MATH_SIN: { out[0]->vec[0] = sinf(in0); break; } - case 5: /* Cosine */ + case NODE_MATH_COS: { out[0]->vec[0] = cosf(in0); break; } - case 6: /* Tangent */ + case NODE_MATH_TAN: { out[0]->vec[0] = tanf(in0); break; } - case 7: /* Arc-Sine */ + case NODE_MATH_ASIN: { /* Can't do the impossible... */ if (in0 <= 1.0f && in0 >= -1.0f) @@ -99,7 +99,7 @@ static void exec(void *UNUSED(data), out[0]->vec[0] = 0.0f; break; } - case 8: /* Arc-Cosine */ + case NODE_MATH_ACOS: { /* Can't do the impossible... */ if (in0 <= 1.0f && in0 >= -1.0f) @@ -108,12 +108,12 @@ static void exec(void *UNUSED(data), out[0]->vec[0] = 0.0; break; } - case 9: /* Arc-Tangent */ + case NODE_MATH_ATAN: { out[0]->vec[0] = atan(in0); break; } - case 10: /* Power */ + case NODE_MATH_POW: { /* Only raise negative numbers by full integers */ if (in0 >= 0.0f) { @@ -130,7 +130,7 @@ static void exec(void *UNUSED(data), } break; } - case 11: /* Logarithm */ + case NODE_MATH_LOG: { /* Don't want any imaginary numbers... */ if (in0 > 0.0f && in1 > 0.0f) @@ -139,7 +139,7 @@ static void exec(void *UNUSED(data), out[0]->vec[0] = 0.0; break; } - case 12: /* Minimum */ + case NODE_MATH_MIN: { if (in0 < in1) out[0]->vec[0] = in0; @@ -147,7 +147,7 @@ static void exec(void *UNUSED(data), out[0]->vec[0] = in1; break; } - case 13: /* Maximum */ + case NODE_MATH_MAX: { if (in0 > in1) out[0]->vec[0] = in0; @@ -155,13 +155,13 @@ static void exec(void *UNUSED(data), out[0]->vec[0] = in1; break; } - case 14: /* Round */ + case NODE_MATH_ROUND: { out[0]->vec[0] = (in0 < 0.0f) ? (int)(in0 - 0.5f) : (int)(in0 + 0.5f); break; } - case 15: /* Less Than */ + case NODE_MATH_LESS: { if (in0 < in1) out[0]->vec[0] = 1.0f; @@ -170,7 +170,7 @@ static void exec(void *UNUSED(data), break; } - case 16: /* Greater Than */ + case NODE_MATH_GREATER: { if (in0 > in1) out[0]->vec[0] = 1.0f; @@ -179,7 +179,7 @@ static void exec(void *UNUSED(data), break; } - case 17: /* Modulo */ + case NODE_MATH_MOD: { if (in1 == 0.0f) out[0]->vec[0] = 0.0f; @@ -188,7 +188,7 @@ static void exec(void *UNUSED(data), break; } - case 18: /* Absolute */ + case NODE_MATH_ABS: { out[0]->vec[0] = fabsf(in0); break; diff --git a/source/blender/python/bmesh/bmesh_py_geometry.c b/source/blender/python/bmesh/bmesh_py_geometry.c index 4cd0a3951b3..a48a9dab434 100644 --- a/source/blender/python/bmesh/bmesh_py_geometry.c +++ b/source/blender/python/bmesh/bmesh_py_geometry.c @@ -49,7 +49,7 @@ PyDoc_STRVAR(bpy_bm_geometry_intersect_face_point_doc, " :type face: :class:`bmesh.types.BMFace`\n" " :arg point: The point to test.\n" " :type point: float triplet\n" -" :return: True when the the point is in the face.\n" +" :return: True when the point is in the face.\n" " :rtype: bool\n" ); static PyObject *bpy_bm_geometry_intersect_face_point(BPy_BMFace *UNUSED(self), PyObject *args) diff --git a/source/blender/python/bmesh/bmesh_py_ops.c b/source/blender/python/bmesh/bmesh_py_ops.c index 4fc0160bbd6..ee96c859858 100644 --- a/source/blender/python/bmesh/bmesh_py_ops.c +++ b/source/blender/python/bmesh/bmesh_py_ops.c @@ -37,17 +37,12 @@ #include "MEM_guardedalloc.h" -#include "../generic/py_capi_utils.h" #include "bmesh.h" #include "bmesh_py_ops_call.h" #include "bmesh_py_ops.h" /* own include */ -#include "bmesh_py_types.h" - -#include "bmesh_py_utils.h" - /* bmesh operator 'bmesh.ops.*' callable types * ******************************************* */ static PyTypeObject bmesh_op_Type; diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c index 2c07df98973..ec6810fe49a 100644 --- a/source/blender/python/bmesh/bmesh_py_ops_call.c +++ b/source/blender/python/bmesh/bmesh_py_ops_call.c @@ -39,11 +39,9 @@ #include "bmesh.h" -#include "bmesh_py_ops.h" #include "bmesh_py_ops_call.h" /* own include */ #include "bmesh_py_types.h" -#include "bmesh_py_utils.h" static int bpy_bm_op_as_py_error(BMesh *bm) { diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index a31345cd7f5..8c13a66bea0 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -2311,6 +2311,22 @@ static PyObject *bpy_bmelemseq_index_update(BPy_BMElemSeq *self) Py_RETURN_NONE; } +PyDoc_STRVAR(bpy_bmelemseq_ensure_lookup_table_doc, +".. method:: ensure_lookup_table()\n" +"\n" +" Ensure internal data needed for int subscription is initialized with verts/edges/faces, eg ``bm.verts[index]``.\n" +"\n" +" This needs to be called again after adding/removing data in this sequence." +); +static PyObject *bpy_bmelemseq_ensure_lookup_table(BPy_BMElemSeq *self) +{ + BPY_BM_CHECK_OBJ(self); + + BM_mesh_elem_table_ensure(self->bm, bm_iter_itype_htype_map[self->itype]); + + Py_RETURN_NONE; +} + PyDoc_STRVAR(bpy_bmelemseq_sort_doc, ".. method:: sort(key=None, reverse=False)\n" "\n" @@ -2605,6 +2621,7 @@ static struct PyMethodDef bpy_bmvertseq_methods[] = { /* odd function, initializes index values */ {"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, bpy_bmelemseq_index_update_doc}, + {"ensure_lookup_table", (PyCFunction)bpy_bmelemseq_ensure_lookup_table, METH_NOARGS, bpy_bmelemseq_ensure_lookup_table_doc}, {"sort", (PyCFunction)bpy_bmelemseq_sort, METH_VARARGS | METH_KEYWORDS, bpy_bmelemseq_sort_doc}, {NULL, NULL, 0, NULL} }; @@ -2617,6 +2634,7 @@ static struct PyMethodDef bpy_bmedgeseq_methods[] = { /* odd function, initializes index values */ {"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, bpy_bmelemseq_index_update_doc}, + {"ensure_lookup_table", (PyCFunction)bpy_bmelemseq_ensure_lookup_table, METH_NOARGS, bpy_bmelemseq_ensure_lookup_table_doc}, {"sort", (PyCFunction)bpy_bmelemseq_sort, METH_VARARGS | METH_KEYWORDS, bpy_bmelemseq_sort_doc}, {NULL, NULL, 0, NULL} }; @@ -2629,6 +2647,7 @@ static struct PyMethodDef bpy_bmfaceseq_methods[] = { /* odd function, initializes index values */ {"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, bpy_bmelemseq_index_update_doc}, + {"ensure_lookup_table", (PyCFunction)bpy_bmelemseq_ensure_lookup_table, METH_NOARGS, bpy_bmelemseq_ensure_lookup_table_doc}, {"sort", (PyCFunction)bpy_bmelemseq_sort, METH_VARARGS | METH_KEYWORDS, bpy_bmelemseq_sort_doc}, {NULL, NULL, 0, NULL} }; @@ -2725,9 +2744,43 @@ static PyObject *bpy_bmelemseq_subscript_int(BPy_BMElemSeq *self, int keynum) if (keynum < 0) keynum += bpy_bmelemseq_length(self); /* only get length on negative value, may loop entire seq */ if (keynum >= 0) { - BMHeader *ele = BM_iter_at_index(self->bm, self->itype, self->py_ele ? self->py_ele->ele : NULL, keynum); - if (ele) { - return BPy_BMElem_CreatePyObject(self->bm, ele); + if (self->itype <= BM_FACES_OF_MESH) { + if ((self->bm->elem_table_dirty & bm_iter_itype_htype_map[self->itype]) == 0) { + BMHeader *ele = NULL; + switch (self->itype) { + case BM_VERTS_OF_MESH: + if (keynum < self->bm->totvert) { + ele = (BMHeader *)self->bm->vtable[keynum]; + } + break; + case BM_EDGES_OF_MESH: + if (keynum < self->bm->totedge) { + ele = (BMHeader *)self->bm->etable[keynum]; + } + break; + case BM_FACES_OF_MESH: + if (keynum < self->bm->totface) { + ele = (BMHeader *)self->bm->ftable[keynum]; + } + break; + } + if (ele) { + return BPy_BMElem_CreatePyObject(self->bm, ele); + } + /* fall through to index error below */ + } + else { + PyErr_SetString(PyExc_IndexError, + "BMElemSeq[index]: outdated internal index table, " + "run ensure_lookup_table() first"); + return NULL; + } + } + else { + BMHeader *ele = BM_iter_at_index(self->bm, self->itype, self->py_ele ? self->py_ele->ele : NULL, keynum); + if (ele) { + return BPy_BMElem_CreatePyObject(self->bm, ele); + } } } diff --git a/source/blender/python/bmesh/bmesh_py_types.h b/source/blender/python/bmesh/bmesh_py_types.h index a2c2c312e71..66059a642d1 100644 --- a/source/blender/python/bmesh/bmesh_py_types.h +++ b/source/blender/python/bmesh/bmesh_py_types.h @@ -198,16 +198,17 @@ int bpy_bm_generic_valid_check_source(BMesh *bm_source, const char *error_prefi #define BPY_BM_IS_VALID(obj) (LIKELY((obj)->bm != NULL)) -#define BM_ITER_BPY_BM_SEQ(ele, iter, bpy_bmelemseq) \ - for (ele = BM_iter_new(iter, \ - (bpy_bmelemseq)->bm, \ - (bpy_bmelemseq)->itype, \ - (bpy_bmelemseq)->py_ele ? \ - ((BPy_BMElem *)(bpy_bmelemseq)->py_ele)->ele : \ - NULL \ - ); \ - ele; \ - ele = BM_iter_step(iter)) +#define BM_ITER_BPY_BM_SEQ(ele, iter, bpy_bmelemseq) \ + for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new( \ + iter, \ + (bpy_bmelemseq)->bm, \ + (bpy_bmelemseq)->itype, \ + (bpy_bmelemseq)->py_ele ? \ + ((BPy_BMElem *)(bpy_bmelemseq)->py_ele)->ele : \ + NULL \ + ); \ + ele; \ + BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter)) #ifdef __PY_CAPI_UTILS_H__ diff --git a/source/blender/python/bmesh/bmesh_py_types_select.c b/source/blender/python/bmesh/bmesh_py_types_select.c index 3c72112e7ce..6dd0ec5be0b 100644 --- a/source/blender/python/bmesh/bmesh_py_types_select.c +++ b/source/blender/python/bmesh/bmesh_py_types_select.c @@ -43,12 +43,8 @@ #include "bmesh_py_types.h" #include "bmesh_py_types_select.h" - - #include "../generic/py_capi_utils.h" -#include "bmesh_py_api.h" /* own include */ - PyDoc_STRVAR(bpy_bmeditselseq_active_doc, "The last selected element or None (read-only).\n\n:type: :class:`BMVert`, :class:`BMEdge` or :class:`BMFace`" ); @@ -165,7 +161,7 @@ static Py_ssize_t bpy_bmeditselseq_length(BPy_BMEditSelSeq *self) { BPY_BM_CHECK_INT(self); - return BLI_countlist(&self->bm->selected); + return BLI_listbase_count(&self->bm->selected); } static PyObject *bpy_bmeditselseq_subscript_int(BPy_BMEditSelSeq *self, int keynum) diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c index 8c9e84af8ed..7fe282b2d71 100644 --- a/source/blender/python/generic/idprop_py_api.c +++ b/source/blender/python/generic/idprop_py_api.c @@ -296,10 +296,10 @@ static PyObject *BPy_IDGroup_Map_GetItem(BPy_IDProperty *self, PyObject *item) } /* returns NULL on success, error string on failure */ -static int idp_sequence_type(PyObject *seq_fast) +static char idp_sequence_type(PyObject *seq_fast) { PyObject *item; - int type = IDP_INT; + char type = IDP_INT; Py_ssize_t i, len = PySequence_Fast_GET_SIZE(seq_fast); for (i = 0; i < len; i++) { @@ -403,7 +403,7 @@ bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group, return false; } - if ((val.array.type = idp_sequence_type(ob_seq_fast)) == -1) { + if ((val.array.type = idp_sequence_type(ob_seq_fast)) == (char)-1) { Py_DECREF(ob_seq_fast); PyErr_SetString(PyExc_TypeError, "only floats, ints and dicts are allowed in ID property arrays"); return false; @@ -510,7 +510,26 @@ bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group, MEM_freeN(prop); } else { - IDP_ReplaceInGroup(group, prop); + IDProperty *prop_exist; + + /* avoid freeing when types match in case they are referenced by the UI, see: T37073 + * obviously this isn't a complete solution, but helps for common cases. */ + prop_exist = IDP_GetPropertyFromGroup(group, prop->name); + if ((prop_exist != NULL) && + (prop_exist->type == prop->type) && + (prop_exist->subtype == prop->subtype)) + { + /* Preserve prev/next links!!! See T42593. */ + prop->prev = prop_exist->prev; + prop->next = prop_exist->next; + + IDP_FreeProperty(prop_exist); + *prop_exist = *prop; + MEM_freeN(prop); + } + else { + IDP_ReplaceInGroup_ex(group, prop, prop_exist); + } } return true; diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index 36ae30ada22..26deaf8d033 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -568,7 +568,7 @@ void PyC_MainModule_Restore(PyObject *main_mod) Py_XDECREF(main_mod); } -/* must be called before Py_Initialize, expects output of BLI_get_folder(BLENDER_PYTHON, NULL) */ +/* must be called before Py_Initialize, expects output of BKE_appdir_folder_id(BLENDER_PYTHON, NULL) */ void PyC_SetHomePath(const char *py_path_bundle) { if (py_path_bundle == NULL) { diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c index 134e718bce5..dbeccfdb8e6 100644 --- a/source/blender/python/intern/bpy.c +++ b/source/blender/python/intern/bpy.c @@ -31,10 +31,9 @@ #include <Python.h> #include "BLI_utildefines.h" -#include "BLI_path_util.h" #include "BLI_string.h" -#include "BKE_main.h" +#include "BKE_appdir.h" #include "BKE_global.h" /* XXX, G.main only */ #include "BKE_blender.h" #include "BKE_bpath.h" @@ -53,14 +52,8 @@ #include "../generic/py_capi_utils.h" -#include "MEM_guardedalloc.h" - /* external util modules */ #include "../generic/idprop_py_api.h" -#include "../generic/bgl.h" -#include "../generic/blf_py_api.h" -#include "../generic/blf_py_api.h" -#include "../mathutils/mathutils.h" #ifdef WITH_FREESTYLE # include "BPy_Freestyle.h" @@ -82,11 +75,11 @@ static PyObject *bpy_script_paths(PyObject *UNUSED(self)) PyObject *item; const char *path; - path = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, NULL); + path = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, NULL); item = PyC_UnicodeFromByte(path ? path : ""); BLI_assert(item != NULL); PyTuple_SET_ITEM(ret, 0, item); - path = BLI_get_folder(BLENDER_USER_SCRIPTS, NULL); + path = BKE_appdir_folder_id(BLENDER_USER_SCRIPTS, NULL); item = PyC_UnicodeFromByte(path ? path : ""); BLI_assert(item != NULL); PyTuple_SET_ITEM(ret, 1, item); @@ -168,11 +161,11 @@ static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObj return NULL; } - /* same logic as BLI_get_folder_create(), but best leave it up to the script author to create */ - path = BLI_get_folder(folder_id, subdir); + /* same logic as BKE_appdir_folder_id_create(), but best leave it up to the script author to create */ + path = BKE_appdir_folder_id(folder_id, subdir); if (!path) - path = BLI_get_user_folder_notest(folder_id, subdir); + path = BKE_appdir_folder_id_user_notest(folder_id, subdir); return PyC_UnicodeFromByte(path ? path : ""); } @@ -211,7 +204,7 @@ static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObj return NULL; } - path = BLI_get_folder_version(folder_id, (major * 100) + minor, false); + path = BKE_appdir_folder_id_version(folder_id, (major * 100) + minor, false); return PyC_UnicodeFromByte(path ? path : ""); } @@ -296,7 +289,7 @@ void BPy_init_modules(void) PyObject *mod; /* Needs to be first since this dir is needed for future modules */ - const char * const modpath = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, "modules"); + const char * const modpath = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, "modules"); if (modpath) { // printf("bpy: found module path '%s'.\n", modpath); PyObject *sys_path = PySys_GetObject("path"); /* borrow */ diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c index 16cdd44ce38..25f855d06b2 100644 --- a/source/blender/python/intern/bpy_app.c +++ b/source/blender/python/intern/bpy_app.c @@ -44,11 +44,10 @@ #include "bpy_driver.h" #include "BLI_utildefines.h" -#include "BLI_path_util.h" +#include "BKE_appdir.h" #include "BKE_blender.h" #include "BKE_global.h" -#include "structseq.h" #include "../generic/py_capi_utils.h" @@ -135,7 +134,7 @@ static PyObject *make_app_info(void) SetStrItem(STRINGIFY(BLENDER_VERSION_CHAR)); SetStrItem(STRINGIFY(BLENDER_VERSION_CYCLE)); - SetStrItem(BLI_program_path()); + SetStrItem(BKE_appdir_program_path()); SetObjItem(PyBool_FromLong(G.background)); /* build info, use bytes since we can't assume _any_ encoding: @@ -250,7 +249,7 @@ PyDoc_STRVAR(bpy_app_tempdir_doc, ); static PyObject *bpy_app_tempdir_get(PyObject *UNUSED(self), void *UNUSED(closure)) { - return PyC_UnicodeFromByte(BLI_temp_dir_session()); + return PyC_UnicodeFromByte(BKE_tempdir_session()); } PyDoc_STRVAR(bpy_app_driver_dict_doc, diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c index 44da322efc0..cf20f6fa742 100644 --- a/source/blender/python/intern/bpy_app_handlers.c +++ b/source/blender/python/intern/bpy_app_handlers.c @@ -44,23 +44,24 @@ void bpy_app_generic_callback(struct Main *main, struct ID *id, void *arg); static PyTypeObject BlenderAppCbType; static PyStructSequence_Field app_cb_info_fields[] = { - {(char *)"frame_change_pre", (char *)"Callback list - on frame change for playback and rendering (before)"}, - {(char *)"frame_change_post", (char *)"Callback list - on frame change for playback and rendering (after)"}, - {(char *)"render_pre", (char *)"Callback list - on render (before)"}, - {(char *)"render_post", (char *)"Callback list - on render (after)"}, - {(char *)"render_stats", (char *)"Callback list - on printing render statistics"}, - {(char *)"render_init", (char *)"Callback list - on initialization of a render job"}, - {(char *)"render_complete", (char *)"Callback list - on completion of render job"}, - {(char *)"render_cancel", (char *)"Callback list - on canceling a render job"}, - {(char *)"load_pre", (char *)"Callback list - on loading a new blend file (before)"}, - {(char *)"load_post", (char *)"Callback list - on loading a new blend file (after)"}, - {(char *)"save_pre", (char *)"Callback list - on saving a blend file (before)"}, - {(char *)"save_post", (char *)"Callback list - on saving a blend file (after)"}, - {(char *)"scene_update_pre", (char *)"Callback list - on updating the scenes data (before)"}, - {(char *)"scene_update_post", (char *)"Callback list - on updating the scenes data (after)"}, - {(char *)"game_pre", (char *)"Callback list - on starting the game engine"}, - {(char *)"game_post", (char *)"Callback list - on ending the game engine"}, - {(char *)"version_update", (char *)"Callback list - on ending the versioning code"}, + {(char *)"frame_change_pre", (char *)"on frame change for playback and rendering (before)"}, + {(char *)"frame_change_post", (char *)"on frame change for playback and rendering (after)"}, + {(char *)"render_pre", (char *)"on render (before)"}, + {(char *)"render_post", (char *)"on render (after)"}, + {(char *)"render_write", (char *)"on writing a render frame (directly after the frame is written)"}, + {(char *)"render_stats", (char *)"on printing render statistics"}, + {(char *)"render_init", (char *)"on initialization of a render job"}, + {(char *)"render_complete", (char *)"on completion of render job"}, + {(char *)"render_cancel", (char *)"on canceling a render job"}, + {(char *)"load_pre", (char *)"on loading a new blend file (before)"}, + {(char *)"load_post", (char *)"on loading a new blend file (after)"}, + {(char *)"save_pre", (char *)"on saving a blend file (before)"}, + {(char *)"save_post", (char *)"on saving a blend file (after)"}, + {(char *)"scene_update_pre", (char *)"on updating the scenes data (before)"}, + {(char *)"scene_update_post", (char *)"on updating the scenes data (after)"}, + {(char *)"game_pre", (char *)"on starting the game engine"}, + {(char *)"game_post", (char *)"on ending the game engine"}, + {(char *)"version_update", (char *)"on ending the versioning code"}, /* sets the permanent tag */ # define APP_CB_OTHER_FIELDS 1 @@ -71,7 +72,7 @@ static PyStructSequence_Field app_cb_info_fields[] = { static PyStructSequence_Desc app_cb_info_desc = { (char *)"bpy.app.handlers", /* name */ - (char *)"This module contains callbacks", /* doc */ + (char *)"This module contains callback lists", /* doc */ app_cb_info_fields, /* fields */ ARRAY_SIZE(app_cb_info_fields) - 1 }; diff --git a/source/blender/python/intern/bpy_app_translations.c b/source/blender/python/intern/bpy_app_translations.c index 0114e8e65e4..6d0161c2047 100644 --- a/source/blender/python/intern/bpy_app_translations.c +++ b/source/blender/python/intern/bpy_app_translations.c @@ -44,7 +44,6 @@ #include "BLF_translation.h" #include "RNA_types.h" -#include "RNA_access.h" typedef struct diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c index b51de01103c..df848f6b60c 100644 --- a/source/blender/python/intern/bpy_driver.c +++ b/source/blender/python/intern/bpy_driver.c @@ -245,7 +245,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime) expr_vars = PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1); Py_XDECREF(expr_vars); - expr_vars = PyTuple_New(BLI_countlist(&driver->variables)); + expr_vars = PyTuple_New(BLI_listbase_count(&driver->variables)); PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 1, expr_vars); for (dvar = driver->variables.first, i = 0; dvar; dvar = dvar->next) { diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index d46c95a25b8..5b4db89a41a 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -63,6 +63,7 @@ #include "DNA_text_types.h" +#include "BKE_appdir.h" #include "BKE_context.h" #include "BKE_text.h" #include "BKE_main.h" @@ -243,11 +244,11 @@ void BPY_python_start(int argc, const char **argv) { #ifndef WITH_PYTHON_MODULE PyThreadState *py_tstate = NULL; - const char *py_path_bundle = BLI_get_folder(BLENDER_SYSTEM_PYTHON, NULL); + const char *py_path_bundle = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, NULL); /* not essential but nice to set our name */ static wchar_t program_path_wchar[FILE_MAX]; /* python holds a reference */ - BLI_strncpy_wchar_from_utf8(program_path_wchar, BLI_program_path(), ARRAY_SIZE(program_path_wchar)); + BLI_strncpy_wchar_from_utf8(program_path_wchar, BKE_appdir_program_path(), ARRAY_SIZE(program_path_wchar)); Py_SetProgramName(program_path_wchar); /* must run before python initializes */ diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 1e97d7aeada..86282f251c3 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -367,17 +367,17 @@ static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args) static PyObject *pyop_dir(PyObject *UNUSED(self)) { - GHashIterator *iter = WM_operatortype_iter(); - PyObject *list = PyList_New(0), *name; + GHashIterator iter; + PyObject *list; + int i; - for ( ; !BLI_ghashIterator_done(iter); BLI_ghashIterator_step(iter)) { - wmOperatorType *ot = BLI_ghashIterator_getValue(iter); + WM_operatortype_iter(&iter); + list = PyList_New(BLI_ghash_size(iter.gh)); - name = PyUnicode_FromString(ot->idname); - PyList_Append(list, name); - Py_DECREF(name); + for (i = 0; !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter), i++) { + wmOperatorType *ot = BLI_ghashIterator_getValue(&iter); + PyList_SET_ITEM(list, i, PyUnicode_FromString(ot->idname)); } - BLI_ghashIterator_free(iter); return list; } diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index 9a8c3d89e8d..b0232a4211c 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -192,6 +192,19 @@ static void printf_func_error(PyObject *py_func) ); } +static void bpy_prop_assign_flag(PropertyRNA *prop, const int flag) +{ + const int flag_mask = ((PROP_ANIMATABLE) & ~flag); + + if (flag) { + RNA_def_property_flag(prop, flag); + } + + if (flag_mask) { + RNA_def_property_clear_flag(prop, flag_mask); + } +} + /* operators and classes use this so it can store the args given but defer * running it until the operator runs where these values are used to setup * the default args for that operator instance */ @@ -1361,7 +1374,8 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i (tmp.description = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) && /* TODO, number isn't ensured to be unique from the script author */ (item_size != 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1) && - (item_size != 5 || ((tmp_icon = _PyUnicode_AsString(PyTuple_GET_ITEM(item, 3))) && + (item_size != 5 || ((py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.icon) != -1 || + (tmp_icon = _PyUnicode_AsString(PyTuple_GET_ITEM(item, 3)))) && py_long_as_int(PyTuple_GET_ITEM(item, 4), &tmp.value) != -1))) { if (is_enum_flag) { @@ -1955,10 +1969,7 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) RNA_def_property_ui_text(prop, name ? name : id, description); if (pyopts) { - if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); - if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + bpy_prop_assign_flag(prop, opts); } bpy_prop_callback_assign_update(prop, update_cb); bpy_prop_callback_assign_boolean(prop, get_cb, set_cb); @@ -2054,10 +2065,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject RNA_def_property_ui_text(prop, name ? name : id, description); if (pyopts) { - if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); - if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + bpy_prop_assign_flag(prop, opts); } bpy_prop_callback_assign_update(prop, update_cb); bpy_prop_callback_assign_boolean_array(prop, get_cb, set_cb); @@ -2151,10 +2159,7 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3); if (pyopts) { - if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); - if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + bpy_prop_assign_flag(prop, opts); } bpy_prop_callback_assign_update(prop, update_cb); bpy_prop_callback_assign_int(prop, get_cb, set_cb); @@ -2266,10 +2271,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3); if (pyopts) { - if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); - if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + bpy_prop_assign_flag(prop, opts); } bpy_prop_callback_assign_update(prop, update_cb); bpy_prop_callback_assign_int_array(prop, get_cb, set_cb); @@ -2377,10 +2379,7 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision); if (pyopts) { - if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); - if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + bpy_prop_assign_flag(prop, opts); } bpy_prop_callback_assign_update(prop, update_cb); bpy_prop_callback_assign_float(prop, get_cb, set_cb); @@ -2504,10 +2503,7 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision); if (pyopts) { - if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); - if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + bpy_prop_assign_flag(prop, opts); } bpy_prop_callback_assign_update(prop, update_cb); bpy_prop_callback_assign_float_array(prop, get_cb, set_cb); @@ -2590,10 +2586,7 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw RNA_def_property_ui_text(prop, name ? name : id, description); if (pyopts) { - if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); - if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + bpy_prop_assign_flag(prop, opts); } bpy_prop_callback_assign_update(prop, update_cb); bpy_prop_callback_assign_string(prop, get_cb, set_cb); @@ -2618,8 +2611,8 @@ PyDoc_STRVAR(BPy_EnumProperty_doc, " [(identifier, name, description, icon, number), ...] where the identifier is used\n" " for python access and other values are used for the interface.\n" " The three first elements of the tuples are mandatory.\n" -" The forth one is either the (unique!) number id of the item or, if followed by a fith element \n" -" (which must be the numid), an icon string identifier.\n" +" The forth one is either the (unique!) number id of the item or, if followed by a fith element\n" +" (which must be the numid), an icon string identifier or integer icon value (e.g. returned by icon()...).\n" " Note the item is optional.\n" " For dynamic values a callback can be passed which returns a list in\n" " the same format as the static list.\n" @@ -2722,10 +2715,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) else prop = RNA_def_enum(srna, id, eitems, defvalue, name ? name : id, description); if (pyopts) { - if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); - if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + bpy_prop_assign_flag(prop, opts); } bpy_prop_callback_assign_update(prop, update_cb); bpy_prop_callback_assign_enum(prop, get_cb, set_cb, (is_itemf ? items : NULL)); @@ -2828,10 +2818,7 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k prop = RNA_def_pointer_runtime(srna, id, ptype, name ? name : id, description); if (pyopts) { - if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); - if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + bpy_prop_assign_flag(prop, opts); } bpy_prop_callback_assign_update(prop, update_cb); RNA_def_property_duplicate_pointers(srna, prop); @@ -2885,10 +2872,7 @@ static PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject prop = RNA_def_collection_runtime(srna, id, ptype, name ? name : id, description); if (pyopts) { - if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); - if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + bpy_prop_assign_flag(prop, opts); } RNA_def_property_duplicate_pointers(srna, prop); } diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index f6e97d6a2d8..b06907b6208 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -77,10 +77,6 @@ #include "../generic/idprop_py_api.h" /* for IDprop lookups */ #include "../generic/py_capi_utils.h" -#ifdef WITH_INTERNATIONAL -# include "BLF_translation.h" -#endif - #define USE_PEDANTIC_WRITE #define USE_MATHUTILS #define USE_STRING_COERCE diff --git a/source/blender/python/intern/bpy_utils_units.c b/source/blender/python/intern/bpy_utils_units.c index cdbd57bcebe..a6df8f54cc3 100644 --- a/source/blender/python/intern/bpy_utils_units.c +++ b/source/blender/python/intern/bpy_utils_units.c @@ -35,9 +35,7 @@ #include "BLI_utildefines.h" #include "BLI_string.h" -#include "BLI_ghash.h" -#include "BPY_extern.h" #include "bpy_utils_units.h" #include "../generic/py_capi_utils.h" diff --git a/source/blender/python/intern/gpu.c b/source/blender/python/intern/gpu.c index 26e3bde57a3..e4580e8035b 100644 --- a/source/blender/python/intern/gpu.c +++ b/source/blender/python/intern/gpu.c @@ -40,7 +40,6 @@ #include <Python.h> #include "DNA_scene_types.h" -#include "DNA_image_types.h" #include "DNA_material_types.h" #include "DNA_ID.h" #include "DNA_customdata_types.h" @@ -200,7 +199,7 @@ static PyObject *GPU_export_shader(PyObject *UNUSED(self), PyObject *args, PyObj if (shader->vertex) { PY_DICT_ADD_STRING(result, shader, vertex); } - seq = PyList_New(BLI_countlist(&shader->uniforms)); + seq = PyList_New(BLI_listbase_count(&shader->uniforms)); for (i = 0, uniform = shader->uniforms.first; uniform; uniform = uniform->next, i++) { dict = PyDict_New(); PY_DICT_ADD_STRING(dict, uniform, varname); @@ -229,7 +228,7 @@ static PyObject *GPU_export_shader(PyObject *UNUSED(self), PyObject *args, PyObj PyDict_SetItemString(result, "uniforms", seq); Py_DECREF(seq); - seq = PyList_New(BLI_countlist(&shader->attributes)); + seq = PyList_New(BLI_listbase_count(&shader->attributes)); for (i = 0, attribute = shader->attributes.first; attribute; attribute = attribute->next, i++) { dict = PyDict_New(); PY_DICT_ADD_STRING(dict, attribute, varname); diff --git a/source/blender/python/mathutils/mathutils_Euler.c b/source/blender/python/mathutils/mathutils_Euler.c index f6d124938a4..1c49774cd0f 100644 --- a/source/blender/python/mathutils/mathutils_Euler.c +++ b/source/blender/python/mathutils/mathutils_Euler.c @@ -233,7 +233,7 @@ static PyObject *Euler_rotate_axis(EulerObject *self, PyObject *args) PyDoc_STRVAR(Euler_rotate_doc, ".. method:: rotate(other)\n" "\n" -" Rotates the euler a by another mathutils value.\n" +" Rotates the euler by another mathutils value.\n" "\n" " :arg other: rotation component of mathutils value\n" " :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n" diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index 282f29b4934..b773d603e16 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -1258,9 +1258,9 @@ static PyObject *Matrix_to_3x3(MatrixObject *self) PyDoc_STRVAR(Matrix_to_translation_doc, ".. method:: to_translation()\n" "\n" -" Return a the translation part of a 4 row matrix.\n" +" Return the translation part of a 4 row matrix.\n" "\n" -" :return: Return a the translation of a matrix.\n" +" :return: Return the translation of a matrix.\n" " :rtype: :class:`Vector`\n" ); static PyObject *Matrix_to_translation(MatrixObject *self) @@ -1281,9 +1281,9 @@ static PyObject *Matrix_to_translation(MatrixObject *self) PyDoc_STRVAR(Matrix_to_scale_doc, ".. method:: to_scale()\n" "\n" -" Return a the scale part of a 3x3 or 4x4 matrix.\n" +" Return the scale part of a 3x3 or 4x4 matrix.\n" "\n" -" :return: Return a the scale of a matrix.\n" +" :return: Return the scale of a matrix.\n" " :rtype: :class:`Vector`\n" "\n" " .. note:: This method does not return negative a scale on any axis because it is not possible to obtain this data from the matrix alone.\n" @@ -1589,7 +1589,7 @@ static PyObject *Matrix_adjugated(MatrixObject *self) PyDoc_STRVAR(Matrix_rotate_doc, ".. method:: rotate(other)\n" "\n" -" Rotates the matrix a by another mathutils value.\n" +" Rotates the matrix by another mathutils value.\n" "\n" " :arg other: rotation component of mathutils value\n" " :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n" @@ -1715,7 +1715,7 @@ PyDoc_STRVAR(Matrix_determinant_doc, "\n" " Return the determinant of a matrix.\n" "\n" -" :return: Return a the determinant of a matrix.\n" +" :return: Return the determinant of a matrix.\n" " :rtype: float\n" "\n" " .. seealso:: <http://en.wikipedia.org/wiki/Determinant>\n" @@ -1836,7 +1836,6 @@ PyDoc_STRVAR(Matrix_zero_doc, "\n" " Set all the matrix values to zero.\n" "\n" -" :return: an instance of itself\n" " :rtype: :class:`Matrix`\n" ); static PyObject *Matrix_zero(MatrixObject *self) diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c index ae3476f5802..615ffb909dc 100644 --- a/source/blender/python/mathutils/mathutils_Quaternion.c +++ b/source/blender/python/mathutils/mathutils_Quaternion.c @@ -303,7 +303,7 @@ static PyObject *Quaternion_slerp(QuaternionObject *self, PyObject *args) PyDoc_STRVAR(Quaternion_rotate_doc, ".. method:: rotate(other)\n" "\n" -" Rotates the quaternion a by another mathutils value.\n" +" Rotates the quaternion by another mathutils value.\n" "\n" " :arg other: rotation component of mathutils value\n" " :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n" @@ -393,7 +393,6 @@ PyDoc_STRVAR(Quaternion_identity_doc, "\n" " Set the quaternion to an identity quaternion.\n" "\n" -" :return: an instance of itself.\n" " :rtype: :class:`Quaternion`\n" ); static PyObject *Quaternion_identity(QuaternionObject *self) @@ -412,7 +411,6 @@ PyDoc_STRVAR(Quaternion_negate_doc, "\n" " Set the quaternion to its negative.\n" "\n" -" :return: an instance of itself.\n" " :rtype: :class:`Quaternion`\n" ); static PyObject *Quaternion_negate(QuaternionObject *self) diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c index 0f0ffe9fec5..013c87427b3 100644 --- a/source/blender/python/mathutils/mathutils_geometry.c +++ b/source/blender/python/mathutils/mathutils_geometry.c @@ -697,12 +697,12 @@ static PyObject *M_Geometry_intersect_plane_plane(PyObject *UNUSED(self), PyObje PyDoc_STRVAR(M_Geometry_intersect_line_sphere_doc, ".. function:: intersect_line_sphere(line_a, line_b, sphere_co, sphere_radius, clip=True)\n" "\n" -" Takes a lines (as 2 vectors), a sphere as a point and a radius and\n" +" Takes a line (as 2 points) and a sphere (as a point and a radius) and\n" " returns the intersection\n" "\n" -" :arg line_a: First point of the first line\n" +" :arg line_a: First point of the line\n" " :type line_a: :class:`mathutils.Vector`\n" -" :arg line_b: Second point of the first line\n" +" :arg line_b: Second point of the line\n" " :type line_b: :class:`mathutils.Vector`\n" " :arg sphere_co: The center of the sphere\n" " :type sphere_co: :class:`mathutils.Vector`\n" @@ -778,12 +778,12 @@ static PyObject *M_Geometry_intersect_line_sphere(PyObject *UNUSED(self), PyObje PyDoc_STRVAR(M_Geometry_intersect_line_sphere_2d_doc, ".. function:: intersect_line_sphere_2d(line_a, line_b, sphere_co, sphere_radius, clip=True)\n" "\n" -" Takes a lines (as 2 vectors), a sphere as a point and a radius and\n" +" Takes a line (as 2 points) and a sphere (as a point and a radius) and\n" " returns the intersection\n" "\n" -" :arg line_a: First point of the first line\n" +" :arg line_a: First point of the line\n" " :type line_a: :class:`mathutils.Vector`\n" -" :arg line_b: Second point of the first line\n" +" :arg line_b: Second point of the line\n" " :type line_b: :class:`mathutils.Vector`\n" " :arg sphere_co: The center of the sphere\n" " :type sphere_co: :class:`mathutils.Vector`\n" diff --git a/source/blender/python/mathutils/mathutils_kdtree.c b/source/blender/python/mathutils/mathutils_kdtree.c index 519778aea7d..9dc246f0f37 100644 --- a/source/blender/python/mathutils/mathutils_kdtree.c +++ b/source/blender/python/mathutils/mathutils_kdtree.c @@ -126,7 +126,7 @@ static void PyKDTree__tp_dealloc(PyKDTree *self) } PyDoc_STRVAR(py_kdtree_insert_doc, -".. method:: insert(index, co)\n" +".. method:: insert(co, index)\n" "\n" " Insert a point into the KDTree.\n" "\n" @@ -171,6 +171,10 @@ PyDoc_STRVAR(py_kdtree_balance_doc, ".. method:: balance()\n" "\n" " Balance the tree.\n" +"\n" +".. note::\n" +"\n" +" This builds the entire tree, avoid calling after each insertion.\n" ); static PyObject *py_kdtree_balance(PyKDTree *self) { diff --git a/source/blender/python/mathutils/mathutils_noise.c b/source/blender/python/mathutils/mathutils_noise.c index 8dfa7904300..f0837c4ec0a 100644 --- a/source/blender/python/mathutils/mathutils_noise.c +++ b/source/blender/python/mathutils/mathutils_noise.c @@ -34,8 +34,6 @@ #include <Python.h> -#include "structseq.h" - #include "BLI_math.h" #include "BLI_noise.h" #include "BLI_utildefines.h" diff --git a/source/blender/quicktime/apple/qtkit_import.m b/source/blender/quicktime/apple/qtkit_import.m index 9318c896d7c..d42d0ee8ebb 100644 --- a/source/blender/quicktime/apple/qtkit_import.m +++ b/source/blender/quicktime/apple/qtkit_import.m @@ -88,6 +88,7 @@ int anim_is_quicktime(const char *name) ".swf", ".txt", ".mpg", + ".vob", /* disabled, vob is essential .mpg, don't handle */ ".avi", /* wouldn't be appropriate ;) */ ".mov", /* disabled, suboptimal decoding speed */ ".mp4", /* disabled, suboptimal decoding speed */ diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript index 7f459444a39..ebd131082e4 100644 --- a/source/blender/render/SConscript +++ b/source/blender/render/SConscript @@ -38,7 +38,6 @@ incs = [ '../blenkernel', '../blenlib', '../imbuf', - '../include', '../makesdna', '../makesrna', '../../../intern/mikktspace', diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h index 4b0473f7483..5edf970c129 100644 --- a/source/blender/render/extern/include/RE_engine.h +++ b/source/blender/render/extern/include/RE_engine.h @@ -144,6 +144,7 @@ void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char void RE_engine_update_progress(RenderEngine *engine, float progress); void RE_engine_update_memory_stats(RenderEngine *engine, float mem_used, float mem_peak); void RE_engine_report(RenderEngine *engine, int type, const char *msg); +void RE_engine_set_error_message(RenderEngine *engine, const char *msg); int RE_engine_render(struct Render *re, int do_all); diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index b1196ab8371..d0544f605cb 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -144,7 +144,7 @@ typedef struct RenderResult { /* render info text */ char *text; - + char *error; } RenderResult; diff --git a/source/blender/render/intern/source/bake.c b/source/blender/render/intern/source/bake.c index 97ea5aee974..228781ce797 100644 --- a/source/blender/render/intern/source/bake.c +++ b/source/blender/render/intern/source/bake.c @@ -54,8 +54,6 @@ #include "IMB_imbuf.h" #include "IMB_colormanagement.h" -#include "RE_bake.h" - /* local include */ #include "rayintersection.h" #include "rayobject.h" @@ -613,6 +611,10 @@ static int get_next_bake_face(BakeShade *bs) for (; obi; obi = obi->next, v = 0) { obr = obi->obr; + /* only allow non instances here */ + if (obr->flag & R_INSTANCEABLE) + continue; + for (; v < obr->totvlak; v++) { vlr = RE_findOrAddVlak(obr, v); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index deee60dbd1f..6b888dbf11c 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -82,9 +82,7 @@ #include "BKE_particle.h" #include "BKE_scene.h" - #include "PIL_time.h" -#include "IMB_imbuf_types.h" #include "envmap.h" #include "occlusion.h" @@ -103,8 +101,6 @@ #include "zbuf.h" #include "sunsky.h" -#include "RE_render_ext.h" - /* 10 times larger than normal epsilon, test it on default nurbs sphere with ray_transp (for quad detection) */ /* or for checking vertex normal flips */ #define FLT_EPSILON10 1.19209290e-06F @@ -1305,7 +1301,6 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem int totchild=0, step_nbr; int seed, path_nbr=0, orco1=0, num; int totface; - const char **uv_name = NULL; const int *index_mf_to_mpoly = NULL; const int *index_mp_to_orig = NULL; @@ -1427,8 +1422,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem /* 2.5 setup matrices */ mul_m4_m4m4(mat, re->viewmat, ob->obmat); invert_m4_m4(ob->imat, mat); /* need to be that way, for imat texture */ - copy_m3_m4(nmat, ob->imat); - transpose_m3(nmat); + transpose_m3_m4(nmat, ob->imat); if (psys->flag & PSYS_USE_IMAT) { /* psys->imat is the original emitter's inverse matrix, ob->obmat is the duplicated object's matrix */ @@ -1855,9 +1849,6 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if (sd.mcol) MEM_freeN(sd.mcol); - if (uv_name) - MEM_freeN(uv_name); - if (states) MEM_freeN(states); @@ -2652,8 +2643,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) negative_scale = is_negative_m4(mat); /* local object -> world space transform for normals */ - copy_m4_m4(nmat, mat); - transpose_m4(nmat); + transpose_m4_m4(nmat, mat); invert_m4(nmat); /* material array */ @@ -3917,7 +3907,15 @@ static bool is_object_hidden(Render *re, Object *ob) if (re->r.scemode & R_VIEWPORT_PREVIEW) { /* Mesh deform cages and so on mess up the preview. To avoid the problem, * viewport doesn't show mesh object if its draw type is bounding box or wireframe. + * Unless it's an active smoke domain! */ + ModifierData *md = NULL; + + if ((md = modifiers_findByType(ob, eModifierType_Smoke)) && + (modifier_isEnabled(re->scene, md, eModifierMode_Realtime))) + { + return false; + } return ELEM(ob->dt, OB_BOUNDBOX, OB_WIRE); } else { diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 06be00a5a5e..c3c70067836 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -55,14 +55,10 @@ /* this module */ #include "render_types.h" -#include "renderpipeline.h" #include "envmap.h" -#include "rendercore.h" #include "renderdatabase.h" #include "texture.h" #include "zbuf.h" -#include "initrender.h" - /* ------------------------------------------------------------------------- */ diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 54f142184e1..23ca376535e 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -46,9 +46,6 @@ #include "BKE_report.h" #include "BKE_scene.h" -#include "IMB_imbuf.h" -#include "IMB_imbuf_types.h" - #include "RNA_access.h" #ifdef WITH_PYTHON @@ -358,6 +355,19 @@ void RE_engine_report(RenderEngine *engine, int type, const char *msg) BKE_report(engine->reports, type, msg); } +void RE_engine_set_error_message(RenderEngine *engine, const char *msg) +{ + Render *re = engine->re; + if (re != NULL) { + RenderResult *rr = RE_AcquireResultRead(re); + if (rr->error != NULL) { + MEM_freeN(rr->error); + } + rr->error = BLI_strdup(msg); + RE_ReleaseResult(re); + } +} + void RE_engine_get_current_tiles(Render *re, int *total_tiles_r, rcti **tiles_r) { RenderPart *pa; diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 2787ce99b13..833d1a75559 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -50,12 +50,10 @@ #include "BLI_threads.h" #include "BLI_utildefines.h" -#include "BKE_main.h" #include "BKE_image.h" #include "RE_render_ext.h" -#include "renderpipeline.h" #include "render_types.h" #include "texture.h" diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 353ba5d5caa..b5b75f47193 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -36,8 +36,6 @@ #include "MEM_guardedalloc.h" -#include "PIL_time.h" - #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_jitter.h" @@ -48,12 +46,8 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" - #include "BKE_camera.h" -#include "IMB_imbuf_types.h" -#include "IMB_imbuf.h" - #ifdef WITH_QUICKTIME #include "quicktime_export.h" #endif @@ -62,10 +56,6 @@ #include "renderpipeline.h" #include "render_types.h" -#include "rendercore.h" -#include "pixelshading.h" -#include "zbuf.h" - /* Own includes */ #include "initrender.h" @@ -164,8 +154,11 @@ float RE_filter_value(int type, float x) return 1.0f - x; case R_FILTER_GAUSS: - x *= gaussfac; - return (1.0f / expf(x * x) - 1.0f / expf(gaussfac * gaussfac * 2.25f)); + { + const float two_gaussfac2 = 2.0f * gaussfac * gaussfac; + x *= 3.0f * gaussfac; + return 1.0f / sqrtf(M_PI * two_gaussfac2) * expf(-x*x / two_gaussfac2); + } case R_FILTER_MITCH: return filt_mitchell(x * gaussfac); diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index abe0ee2f685..927eb0dcf72 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -56,9 +56,7 @@ #include "render_types.h" #include "rendercore.h" #include "renderdatabase.h" -#include "pixelshading.h" #include "shading.h" -#include "zbuf.h" /* ------------------------- Declarations --------------------------- */ diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 2ab93f3a1f9..3fe5bc7b732 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -90,7 +90,6 @@ #include "renderdatabase.h" #include "rendercore.h" #include "initrender.h" -#include "shadbuf.h" #include "pixelblending.h" #include "zbuf.h" @@ -495,6 +494,12 @@ static int check_mode_full_sample(RenderData *rd) { int scemode = rd->scemode; + if (!STREQ(rd->engine, RE_engine_id_BLENDER_RENDER) && + !STREQ(rd->engine, RE_engine_id_BLENDER_GAME)) + { + scemode &= ~R_FULL_SAMPLE; + } + if ((rd->mode & R_OSA) == 0) scemode &= ~R_FULL_SAMPLE; @@ -2832,6 +2837,9 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr } BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_POST); /* keep after file save */ + if (write_still) { + BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_WRITE); + } } BLI_callback_exec(re->main, (ID *)scene, G.is_break ? BLI_CB_EVT_RENDER_CANCEL : BLI_CB_EVT_RENDER_COMPLETE); @@ -3029,6 +3037,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri if (G.is_break == false) { BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_POST); /* keep after file save */ + BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_WRITE); } } else { @@ -3101,7 +3110,8 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri if (G.is_break == true) { /* remove touched file */ if (BKE_imtype_is_movie(scene->r.im_format.imtype) == 0) { - if (scene->r.mode & R_TOUCH && BLI_exists(name) && BLI_file_size(name) == 0) { + if ((scene->r.mode & R_TOUCH) && (BLI_file_size(name) == 0)) { + /* BLI_exists(name) is implicit */ BLI_delete(name, false, false); } } @@ -3111,6 +3121,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri if (G.is_break == false) { BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_POST); /* keep after file save */ + BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_WRITE); } } } diff --git a/source/blender/render/intern/source/pixelblending.c b/source/blender/render/intern/source/pixelblending.c index 460a6814f07..32fb196e1f3 100644 --- a/source/blender/render/intern/source/pixelblending.c +++ b/source/blender/render/intern/source/pixelblending.c @@ -38,7 +38,6 @@ /* own includes */ #include "render_types.h" -#include "renderpipeline.h" #include "pixelblending.h" /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c index 014df802a78..ac4a7dbdccd 100644 --- a/source/blender/render/intern/source/pixelshading.c +++ b/source/blender/render/intern/source/pixelshading.c @@ -36,8 +36,6 @@ #include "BLI_utildefines.h" /* External modules: */ -#include "IMB_imbuf_types.h" -#include "IMB_imbuf.h" #include "DNA_group_types.h" #include "DNA_material_types.h" @@ -51,14 +49,11 @@ /* own module */ #include "render_types.h" -#include "renderpipeline.h" #include "renderdatabase.h" #include "texture.h" -#include "pixelblending.h" #include "rendercore.h" #include "shadbuf.h" #include "pixelshading.h" -#include "shading.h" #include "sunsky.h" /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index ac2e85a33b3..ff23e3788ab 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -55,7 +55,6 @@ #include "DNA_particle_types.h" #include "render_types.h" -#include "renderdatabase.h" #include "texture.h" #include "pointdensity.h" diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 03cb370c6a0..6e28d172dd8 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -27,7 +27,6 @@ * \ingroup render */ - #include <stdio.h> #include <math.h> #include <string.h> @@ -50,25 +49,18 @@ #include "BKE_node.h" - -#include "PIL_time.h" - #include "render_result.h" #include "render_types.h" -#include "renderpipeline.h" #include "rendercore.h" #include "renderdatabase.h" -#include "pixelblending.h" #include "pixelshading.h" #include "shading.h" -#include "texture.h" #include "volumetric.h" #include "rayintersection.h" #include "rayobject.h" #include "raycounter.h" - #define RAY_TRA 1 #define RAY_INSIDE 2 @@ -1299,7 +1291,7 @@ static void trace_refract(float col[4], ShadeInput *shi, ShadeResult *shr) float v_refract[3], v_refract_new[3]; float sampcol[4], colsq[4]; - float blur = powf(1.0f - shi->mat->gloss_tra, 3); + float blur = pow3f(1.0f - shi->mat->gloss_tra); short max_samples = shi->mat->samp_gloss_tra; float adapt_thresh = shi->mat->adapt_thresh_tra; @@ -1400,7 +1392,7 @@ static void trace_reflect(float col[3], ShadeInput *shi, ShadeResult *shr, float float v_nor_new[3], v_reflect[3]; float sampcol[4], colsq[4]; - float blur = powf(1.0f - shi->mat->gloss_mir, 3); + float blur = pow3f(1.0f - shi->mat->gloss_mir); short max_samples = shi->mat->samp_gloss_mir; float adapt_thresh = shi->mat->adapt_thresh_mir; float aniso = 1.0f - shi->mat->aniso_gloss_mir; @@ -1562,7 +1554,7 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr) } if (shi->combinedflag & SCE_PASS_REFLECT) { - /* values in shr->spec can be greater then 1.0. + /* values in shr->spec can be greater than 1.0. * In this case the mircol uses a zero blending factor, so ignoring it is ok. * Fixes bug #18837 - when the spec is higher then 1.0, * diff can become a negative color - Campbell */ diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index 24797521435..de87fb200ae 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -35,13 +35,13 @@ #include "MEM_guardedalloc.h" +#include "BKE_appdir.h" #include "BLI_utildefines.h" #include "BLI_listbase.h" -#include "BLI_md5.h" +#include "BLI_hash_md5.h" #include "BLI_path_util.h" #include "BLI_rect.h" #include "BLI_string.h" -#include "BLI_system.h" #include "BLI_threads.h" #include "BKE_image.h" @@ -94,6 +94,8 @@ void render_result_free(RenderResult *res) MEM_freeN(res->rectf); if (res->text) MEM_freeN(res->text); + if (res->error) + MEM_freeN(res->error); MEM_freeN(res); } @@ -1072,7 +1074,7 @@ void render_result_exr_file_path(Scene *scene, const char *layname, int sample, BLI_snprintf(name, sizeof(name), "%s_%s_%s%d.exr", fi, scene->id.name + 2, layname, sample); } - BLI_make_file_string("/", filepath, BLI_temp_dir_session(), name); + BLI_make_file_string("/", filepath, BKE_tempdir_session(), name); } /* only for temp buffer, makes exact copy of render result */ @@ -1160,17 +1162,17 @@ static void render_result_exr_file_cache_path(Scene *sce, const char *root, char if (G.main->name[0]) { BLI_split_dirfile(G.main->name, dirname, filename, sizeof(dirname), sizeof(filename)); BLI_replace_extension(filename, sizeof(filename), ""); /* strip '.blend' */ - md5_buffer(G.main->name, strlen(G.main->name), path_digest); + BLI_hash_md5_buffer(G.main->name, strlen(G.main->name), path_digest); } else { - BLI_strncpy(dirname, BLI_temp_dir_base(), sizeof(dirname)); + BLI_strncpy(dirname, BKE_tempdir_base(), sizeof(dirname)); BLI_strncpy(filename, "UNSAVED", sizeof(filename)); } - md5_to_hexdigest(path_digest, path_hexdigest); + BLI_hash_md5_to_hexdigest(path_digest, path_hexdigest); /* Default to *non-volatile* tmp dir. */ if (*root == '\0') { - root = BLI_temp_dir_base(); + root = BKE_tempdir_base(); } BLI_snprintf(filename_full, sizeof(filename_full), "cached_RR_%s_%s_%s.exr", diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 1708f671569..389e53b7540 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -48,7 +48,6 @@ #include "DNA_node_types.h" #include "IMB_imbuf_types.h" -#include "IMB_imbuf.h" #include "IMB_colormanagement.h" #include "BKE_image.h" @@ -68,9 +67,7 @@ #include "envmap.h" #include "pointdensity.h" #include "voxeldata.h" -#include "renderpipeline.h" #include "render_types.h" -#include "rendercore.h" #include "shading.h" #include "texture.h" #include "texture_ocean.h" @@ -738,7 +735,7 @@ static float voronoiTex(Tex *tex, const float texvec[3], TexResult *texres) static int texnoise(Tex *tex, TexResult *texres, int thread) { float div=3.0; - int val, ran, loop, shift = 30; + int val, ran, loop, shift = 29; ran= BLI_rng_thread_rand(random_tex_array, thread); @@ -749,8 +746,8 @@ static int texnoise(Tex *tex, TexResult *texres, int thread) while (loop--) { shift -= 2; - val += ((ran >> shift) & 3); - div += 3.0f; + val *= ((ran >> shift) & 3); + div *= 3.0f; } texres->tin= ((float)val)/div; @@ -3068,7 +3065,7 @@ void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float h switch (mtex->texco) { case TEXCO_ANGMAP: /* only works with texture being "real" */ - /* use saacos(), fixes bug [#22398], float precision caused lo[2] to be slightly less then -1.0 */ + /* use saacos(), fixes bug [#22398], float precision caused lo[2] to be slightly less than -1.0 */ if (lo[0] || lo[1]) { /* check for zero case [#24807] */ fact= (1.0f/(float)M_PI)*saacos(lo[2])/(sqrtf(lo[0]*lo[0] + lo[1]*lo[1])); tempvec[0]= lo[0]*fact; diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index a67140c6334..5b054005bac 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -50,15 +50,7 @@ #include "DNA_material_types.h" #include "DNA_group_types.h" -#include "BKE_main.h" - -#include "IMB_imbuf_types.h" -#include "IMB_imbuf.h" -#include "IMB_colormanagement.h" - /* local include */ -#include "rayintersection.h" -#include "rayobject.h" #include "renderpipeline.h" #include "render_result.h" #include "render_types.h" @@ -71,8 +63,6 @@ #include "sss.h" #include "zbuf.h" -#include "PIL_time.h" - /* own include */ #include "rendercore.h" diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 46c504aaabf..cafdbe2b488 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -78,11 +78,8 @@ #include "rayintersection.h" #include "rayobject.h" -#include "renderpipeline.h" #include "render_types.h" #include "renderdatabase.h" -#include "texture.h" -#include "strand.h" #include "zbuf.h" /* ------------------------------------------------------------------------- */ @@ -1394,7 +1391,7 @@ void RE_makeRenderInstances(Render *re) int tot; /* convert list of object instances to an array for index based lookup */ - tot= BLI_countlist(&re->instancetable); + tot= BLI_listbase_count(&re->instancetable); re->objectinstance= MEM_callocN(sizeof(ObjectInstanceRen)*tot, "ObjectInstance"); re->totinstance= tot; newlist.first= newlist.last= NULL; diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index 9d83ff1d7e8..0bd4815fb73 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -50,7 +50,6 @@ #include "PIL_time.h" -#include "renderpipeline.h" #include "render_types.h" #include "renderdatabase.h" #include "rendercore.h" diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index 552f383c3a0..b3649c570eb 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -46,11 +46,9 @@ /* local include */ #include "raycounter.h" -#include "renderpipeline.h" #include "render_types.h" #include "renderdatabase.h" #include "rendercore.h" -#include "shadbuf.h" #include "shading.h" #include "strand.h" #include "texture.h" diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index f909c585561..93e8c6a275a 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -47,9 +47,7 @@ /* local include */ #include "occlusion.h" -#include "renderpipeline.h" #include "render_types.h" -#include "pixelblending.h" #include "rendercore.h" #include "shadbuf.h" #include "sss.h" diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c index 7e9003aaee7..8ea3a753283 100644 --- a/source/blender/render/intern/source/sss.c +++ b/source/blender/render/intern/source/sss.c @@ -57,7 +57,6 @@ #include "BLF_translation.h" -#include "PIL_time.h" #include "DNA_material_types.h" @@ -68,11 +67,7 @@ /* this module */ #include "render_types.h" -#include "rendercore.h" -#include "renderdatabase.h" -#include "shading.h" #include "sss.h" -#include "zbuf.h" /* Generic Multiple Scattering API */ diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index 485680da76f..6b52d4aa419 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -47,11 +47,8 @@ #include "render_types.h" -#include "initrender.h" #include "rendercore.h" #include "renderdatabase.h" -#include "renderpipeline.h" -#include "pixelblending.h" #include "shading.h" #include "strand.h" #include "zbuf.h" diff --git a/source/blender/render/intern/source/texture_ocean.c b/source/blender/render/intern/source/texture_ocean.c index 55f4bf3794d..5261374b34d 100644 --- a/source/blender/render/intern/source/texture_ocean.c +++ b/source/blender/render/intern/source/texture_ocean.c @@ -56,8 +56,6 @@ extern struct Render R; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - - /* ***** actual texture sampling ***** */ int ocean_texture(Tex *tex, const float texvec[2], TexResult *texres) { diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c index 50b5e392b3f..f21a1e5fa9b 100644 --- a/source/blender/render/intern/source/voxeldata.c +++ b/source/blender/render/intern/source/voxeldata.c @@ -66,7 +66,6 @@ #include "render_types.h" -#include "renderdatabase.h" #include "texture.h" #include "voxeldata.h" diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 87e546ef24e..7e8f0e3e9fc 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -63,12 +63,10 @@ #include "pixelblending.h" #include "render_result.h" #include "render_types.h" -#include "renderpipeline.h" #include "renderdatabase.h" #include "rendercore.h" #include "shadbuf.h" #include "shading.h" -#include "sss.h" #include "strand.h" /* own includes */ @@ -2065,8 +2063,6 @@ static void zmask_rect(int *rectz, int *rectp, int xs, int ys, int neg) } - - /* ***************** ZBUFFER MAIN ROUTINES **************** */ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart *, ZSpan *, int, void *), void *data) diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt index 088bddc8a76..78b5d499644 100644 --- a/source/blender/windowmanager/CMakeLists.txt +++ b/source/blender/windowmanager/CMakeLists.txt @@ -130,10 +130,10 @@ if(WITH_BUILDINFO) add_definitions(-DWITH_BUILDINFO) endif() -if(WIN322) - list(APPEND INC - ../../../intern/utfconv - ) +if(WIN32) + if(WITH_INPUT_IME) + add_definitions(-DWITH_INPUT_IME) + endif() endif() if(WITH_COMPOSITOR) diff --git a/source/blender/windowmanager/SConscript b/source/blender/windowmanager/SConscript index b93192d5067..a6f64f7cdae 100644 --- a/source/blender/windowmanager/SConscript +++ b/source/blender/windowmanager/SConscript @@ -65,11 +65,14 @@ if env['WITH_BF_COLLADA']: if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'): incs += ' ' + env['BF_PTHREADS_INC'] - incs += ' ../../intern/utfconv' if env['BF_BUILDINFO']: defs.append('WITH_BUILDINFO') +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'win64-mingw'): + if env['WITH_BF_IME']: + defs.append('WITH_INPUT_IME') + if env['WITH_BF_INTERNATIONAL']: defs.append('WITH_INTERNATIONAL') diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index e1cd334637a..d2abfd419d1 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -47,6 +47,7 @@ extern "C" { #endif struct bContext; +struct GHashIterator; struct IDProperty; struct wmEvent; struct wmEventHandler; @@ -223,12 +224,13 @@ void WM_operator_stack_clear(struct wmWindowManager *wm); void WM_operator_handlers_clear(wmWindowManager *wm, struct wmOperatorType *ot); struct wmOperatorType *WM_operatortype_find(const char *idname, bool quiet); -struct GHashIterator *WM_operatortype_iter(void); +void WM_operatortype_iter(struct GHashIterator *ghi); void WM_operatortype_append(void (*opfunc)(struct wmOperatorType *)); void WM_operatortype_append_ptr(void (*opfunc)(struct wmOperatorType *, void *), void *userdata); void WM_operatortype_append_macro_ptr(void (*opfunc)(struct wmOperatorType *, void *), void *userdata); void WM_operatortype_remove_ptr(struct wmOperatorType *ot); bool WM_operatortype_remove(const char *idname); +void WM_operatortype_last_properties_clear_all(void); struct wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *name, const char *description, int flag); struct wmOperatorTypeMacro *WM_operatortype_macro_define(struct wmOperatorType *ot, const char *idname); @@ -266,6 +268,7 @@ void WM_operator_properties_select_action_simple(struct wmOperatorType *ot, int bool WM_operator_check_ui_enabled(const struct bContext *C, const char *idname); wmOperator *WM_operator_last_redo(const struct bContext *C); +ID *WM_operator_drop_load_path(struct bContext *C, struct wmOperator *op, const short idcode); bool WM_operator_last_properties_init(struct wmOperator *op); bool WM_operator_last_properties_store(struct wmOperator *op); @@ -395,6 +398,7 @@ enum { WM_JOB_TYPE_CLIP_SOLVE_CAMERA, WM_JOB_TYPE_CLIP_PREFETCH, WM_JOB_TYPE_SEQ_BUILD_PROXY, + WM_JOB_TYPE_SEQ_BUILD_PREVIEW, /* add as needed, screencast, seq proxy build * if having hard coded values is a problem */ }; @@ -458,6 +462,10 @@ void WM_event_ndof_to_quat(const struct wmNDOFMotionData *ndof, float q[4 float WM_event_tablet_data(const struct wmEvent *event, int *pen_flip, float tilt[2]); bool WM_event_is_tablet(const struct wmEvent *event); +#ifdef WITH_INPUT_IME +bool WM_event_is_ime_switch(const struct wmEvent *event); +#endif + #ifdef __cplusplus } #endif diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index ff252f0fc20..2db34bbd392 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -324,6 +324,9 @@ typedef struct wmNotifier { #define ND_NLA_ACTCHANGE (74<<16) #define ND_FCURVES_ORDER (75<<16) + /* NC_GPENCIL */ +#define ND_GPENCIL_EDITMODE (85<<16) + /* NC_GEOM Geometry */ /* Mesh, Curve, MetaBall, Armature, .. */ #define ND_SELECT (90<<16) @@ -554,9 +557,7 @@ typedef struct wmOperatorType { /* pointer to modal keymap, do not free! */ struct wmKeyMap *modalkeymap; - /* only used for operators defined with python - * use to store pointers to python functions */ - void *pyop_data; + /* python needs the operator type as well */ int (*pyop_poll)(struct bContext *, struct wmOperatorType *ot) ATTR_WARN_UNUSED_RESULT; /* RNA integration */ @@ -567,6 +568,24 @@ typedef struct wmOperatorType { } wmOperatorType; +#ifdef WITH_INPUT_IME +/* *********** Input Method Editor (IME) *********** */ + +/* similar to GHOST_TEventImeData */ +typedef struct wmIMEData { + size_t result_len, composite_len; + + char *str_result; /* utf8 encoding */ + char *str_composite; /* utf8 encoding */ + + int cursor_pos; /* cursor position in the IME composition. */ + int sel_start; /* beginning of the selection */ + int sel_end; /* end of the selection */ + + bool is_ime_composing; +} wmIMEData; +#endif + /* **************** Paint Cursor ******************* */ typedef void (*wmPaintCursorDraw)(struct bContext *C, int, int, void *customdata); diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index d05cc572c45..a6a3c6b0a28 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -39,8 +39,6 @@ #include "DNA_windowmanager_types.h" -#include "GHOST_C-api.h" - #include "MEM_guardedalloc.h" #include "BLI_utildefines.h" @@ -59,7 +57,6 @@ #include "WM_types.h" #include "wm_window.h" #include "wm_event_system.h" -#include "wm_event_types.h" #include "wm_draw.h" #include "wm.h" @@ -155,7 +152,7 @@ void wm_operator_register(bContext *C, wmOperator *op) int tot; BLI_addtail(&wm->operators, op); - tot = BLI_countlist(&wm->operators); + tot = BLI_listbase_count(&wm->operators); while (tot > MAX_OP_REGISTERED) { wmOperator *opt = wm->operators.first; diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c index e5bba9285b4..68592b44845 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.c +++ b/source/blender/windowmanager/intern/wm_dragdrop.c @@ -45,10 +45,8 @@ #include "BIF_glutil.h" #include "BKE_context.h" -#include "BKE_screen.h" #include "IMB_imbuf_types.h" -#include "IMB_imbuf.h" #include "UI_interface.h" #include "UI_interface_icons.h" @@ -58,8 +56,6 @@ #include "WM_api.h" #include "WM_types.h" #include "wm_event_system.h" -#include "wm.h" - /* ****************************************************** */ @@ -271,16 +267,16 @@ void wm_drags_check_ops(bContext *C, wmEvent *event) static void wm_drop_operator_draw(const char *name, int x, int y) { - int width = UI_GetStringWidth(name); + int width = UI_fontstyle_string_width(name); int padding = 4 * UI_DPI_FAC; glColor4ub(0, 0, 0, 50); - uiSetRoundBox(UI_CNR_ALL | UI_RB_ALPHA); - uiRoundBox(x, y, x + width + 2 * padding, y + 4 * padding, padding); + UI_draw_roundbox_corner_set(UI_CNR_ALL | UI_RB_ALPHA); + UI_draw_roundbox(x, y, x + width + 2 * padding, y + 4 * padding, padding); glColor4ub(255, 255, 255, 255); - UI_DrawString(x + padding, y + padding, name); + UI_draw_string(x + padding, y + padding, name); } static const char *wm_drag_name(wmDrag *drag) @@ -366,12 +362,12 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect) } if (rect) { - int w = UI_GetStringWidth(wm_drag_name(drag)); + int w = UI_fontstyle_string_width(wm_drag_name(drag)); drag_rect_minmax(rect, x, y, x + w, y + iconsize); } else { glColor4ub(255, 255, 255, 255); - UI_DrawString(x, y, wm_drag_name(drag)); + UI_draw_string(x, y, wm_drag_name(drag)); } /* operator name with roundbox */ @@ -394,7 +390,7 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect) } if (rect) { - int w = UI_GetStringWidth(wm_drag_name(drag)); + int w = UI_fontstyle_string_width(wm_drag_name(drag)); drag_rect_minmax(rect, x, y, x + w, y + iconsize); } else diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 793908ec44b..35542410cd8 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -81,7 +81,6 @@ #include "wm_window.h" #include "wm_event_system.h" #include "wm_event_types.h" -#include "wm_draw.h" #ifndef NDEBUG # include "RNA_enum_types.h" @@ -269,7 +268,7 @@ void wm_event_do_notifiers(bContext *C) if (note->category == NC_SCREEN) { if (note->data == ND_SCREENBROWSE) { /* free popup handlers only [#35434] */ - UI_remove_popup_handlers_all(C, &win->modalhandlers); + UI_popup_handlers_remove_all(C, &win->modalhandlers); ED_screen_set(C, note->reference); // XXX hrms, think this over! @@ -621,7 +620,7 @@ static void wm_operator_reports(bContext *C, wmOperator *op, int retval, bool ca { if (caller_owns_reports == false) { /* popup */ if (op->reports->list.first) { - /* FIXME, temp setting window, see other call to uiPupMenuReports for why */ + /* FIXME, temp setting window, see other call to UI_popup_menu_reports for why */ wmWindow *win_prev = CTX_wm_window(C); ScrArea *area_prev = CTX_wm_area(C); ARegion *ar_prev = CTX_wm_region(C); @@ -629,7 +628,7 @@ static void wm_operator_reports(bContext *C, wmOperator *op, int retval, bool ca if (win_prev == NULL) CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first); - uiPupMenuReports(C, op->reports); + UI_popup_menu_reports(C, op->reports); CTX_wm_window_set(C, win_prev); CTX_wm_area_set(C, area_prev); @@ -1720,7 +1719,7 @@ static int wm_handler_fileselect_do(bContext *C, ListBase *handlers, wmEventHand wm_handler_op_context(C, handler); - /* needed for uiPupMenuReports */ + /* needed for UI_popup_menu_reports */ if (val == EVT_FILESELECT_EXEC) { int retval; @@ -1752,7 +1751,7 @@ static int wm_handler_fileselect_do(bContext *C, ListBase *handlers, wmEventHand CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first); BKE_report_print_level_set(handler->op->reports, RPT_WARNING); - uiPupMenuReports(C, handler->op->reports); + UI_popup_menu_reports(C, handler->op->reports); /* XXX - copied from 'wm_operator_finished()' */ /* add reports to the global list, otherwise they are not seen */ @@ -1955,7 +1954,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers event->customdata = NULL; event->custom = 0; - WM_operator_name_call(C, drop->ot->idname, drop->opcontext, drop->ptr); + WM_operator_name_call_ptr(C, drop->ot, drop->opcontext, drop->ptr); action |= WM_HANDLER_BREAK; /* XXX fileread case */ @@ -3374,6 +3373,33 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U break; } +#ifdef WITH_INPUT_IME + case GHOST_kEventImeCompositionStart: + { + event.val = KM_PRESS; + win->ime_data = customdata; + win->ime_data->is_ime_composing = true; + event.type = WM_IME_COMPOSITE_START; + wm_event_add(win, &event); + break; + } + case GHOST_kEventImeComposition: + { + event.val = KM_PRESS; + event.type = WM_IME_COMPOSITE_EVENT; + wm_event_add(win, &event); + break; + } + case GHOST_kEventImeCompositionEnd: + { + event.val = KM_PRESS; + win->ime_data->is_ime_composing = false; + event.type = WM_IME_COMPOSITE_END; + wm_event_add(win, &event); + break; + } +#endif /* WITH_INPUT_IME */ + } #if 0 @@ -3480,5 +3506,13 @@ bool WM_event_is_tablet(const struct wmEvent *event) return (event->tablet_data) ? true : false; } +#ifdef WITH_INPUT_IME +/* most os using ctrl/oskey + space to switch ime, avoid added space */ +bool WM_event_is_ime_switch(const struct wmEvent *event) +{ + return event->val == KM_PRESS && event->type == SPACEKEY && + (event->ctrl || event->oskey || event->shift || event->alt); +} +#endif /** \} */ diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 832fef404e3..c1c31f6795d 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -69,6 +69,7 @@ #include "DNA_screen_types.h" #include "DNA_windowmanager_types.h" +#include "BKE_appdir.h" #include "BKE_utildefines.h" #include "BKE_autoexec.h" #include "BKE_blender.h" @@ -96,8 +97,6 @@ #include "ED_view3d.h" #include "ED_util.h" -#include "RE_pipeline.h" /* only to report missing engine */ - #include "GHOST_C-api.h" #include "GHOST_Path-api.h" @@ -171,6 +170,28 @@ static void wm_window_match_init(bContext *C, ListBase *wmlist) #endif } +static void wm_window_substitute_old(wmWindowManager *wm, wmWindow *oldwin, wmWindow *win) +{ + win->ghostwin = oldwin->ghostwin; + win->active = oldwin->active; + if (win->active) + wm->winactive = win; + + if (!G.background) /* file loading in background mode still calls this */ + GHOST_SetWindowUserData(win->ghostwin, win); /* pointer back */ + + oldwin->ghostwin = NULL; + + win->eventstate = oldwin->eventstate; + oldwin->eventstate = NULL; + + /* ensure proper screen rescaling */ + win->sizex = oldwin->sizex; + win->sizey = oldwin->sizey; + win->posx = oldwin->posx; + win->posy = oldwin->posy; +} + /* match old WM with new, 4 cases: * 1- no current wm, no read wm: make new default * 2- no current wm, but read wm: that's OK, do nothing @@ -224,6 +245,8 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist) ED_screens_initialize(G.main->wm.first); } else { + bool has_match = false; + /* what if old was 3, and loaded 1? */ /* this code could move to setup_appdata */ oldwm = oldwmlist->first; @@ -243,33 +266,27 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist) /* ensure making new keymaps and set space types */ wm->initialized = 0; wm->winactive = NULL; - + /* only first wm in list has ghostwins */ for (win = wm->windows.first; win; win = win->next) { for (oldwin = oldwm->windows.first; oldwin; oldwin = oldwin->next) { - - if (oldwin->winid == win->winid) { - win->ghostwin = oldwin->ghostwin; - win->active = oldwin->active; - if (win->active) - wm->winactive = win; - if (!G.background) /* file loading in background mode still calls this */ - GHOST_SetWindowUserData(win->ghostwin, win); /* pointer back */ + if (oldwin->winid == win->winid) { + has_match = true; - oldwin->ghostwin = NULL; - - win->eventstate = oldwin->eventstate; - oldwin->eventstate = NULL; - - /* ensure proper screen rescaling */ - win->sizex = oldwin->sizex; - win->sizey = oldwin->sizey; - win->posx = oldwin->posx; - win->posy = oldwin->posy; + wm_window_substitute_old(wm, oldwin, win); } } } + + /* make sure at least one window is kept open so we don't lose the context, check T42303 */ + if (!has_match) { + oldwin = oldwm->windows.first; + win = wm->windows.first; + + wm_window_substitute_old(wm, oldwin, win); + } + wm_close_and_free_all(C, oldwmlist); } } @@ -301,7 +318,7 @@ static void wm_init_userdef(bContext *C, const bool from_memory) } /* update tempdir from user preferences */ - BLI_temp_dir_init(U.tempdir); + BKE_tempdir_init(U.tempdir); BKE_userdef_state(); } @@ -458,6 +475,8 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports) BPY_python_reset(C); #endif + WM_operatortype_last_properties_clear_all(); + /* important to do before NULL'ing the context */ BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_VERSION_UPDATE); BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST); @@ -548,7 +567,7 @@ int wm_homefile_read(bContext *C, ReportList *reports, bool from_memory, const c G.relbase_valid = 0; if (!from_memory) { - const char * const cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL); + const char * const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL); if (custom_file) { BLI_strncpy(startstr, custom_file, FILE_MAX); @@ -594,7 +613,7 @@ int wm_homefile_read(bContext *C, ReportList *reports, bool from_memory, const c if (BLI_listbase_is_empty(&wmbase)) { wm_clear_default_size(C); } - BLI_temp_dir_init(U.tempdir); + BKE_tempdir_init(U.tempdir); #ifdef WITH_PYTHON_SECURITY /* use alternative setting for security nuts @@ -650,6 +669,8 @@ int wm_homefile_read(bContext *C, ReportList *reports, bool from_memory, const c } #endif + WM_operatortype_last_properties_clear_all(); + /* important to do before NULL'ing the context */ BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_VERSION_UPDATE); BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST); @@ -705,7 +726,7 @@ void wm_read_history(void) struct RecentFile *recent; const char *line; int num; - const char * const cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL); + const char * const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL); if (!cfgdir) return; @@ -742,7 +763,7 @@ static void write_history(void) return; /* will be NULL in background mode */ - user_config_dir = BLI_get_folder_create(BLENDER_USER_CONFIG, NULL); + user_config_dir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL); if (!user_config_dir) return; @@ -819,7 +840,7 @@ static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, int **thumb_pt) if (scene->camera) { ibuf = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, - IB_rect, OB_SOLID, false, false, R_ADDSKY, err_out); + IB_rect, OB_SOLID, false, false, false, R_ADDSKY, err_out); } else { ibuf = ED_view3d_draw_offscreen_imbuf(scene, v3d, ar, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, @@ -993,6 +1014,8 @@ int wm_homefile_write_exec(bContext *C, wmOperator *op) char filepath[FILE_MAX]; int fileflags; + BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_PRE); + /* check current window and close it if temp */ if (win && win->screen->temp) wm_window_close(C, wm, win); @@ -1000,7 +1023,7 @@ int wm_homefile_write_exec(bContext *C, wmOperator *op) /* update keymaps in user preferences */ WM_keyconfig_update(wm); - BLI_make_file_string("/", filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE); + BLI_make_file_string("/", filepath, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE); printf("trying to save homefile at %s ", filepath); ED_editors_flush_edits(C, false); @@ -1017,6 +1040,8 @@ int wm_homefile_write_exec(bContext *C, wmOperator *op) G.save_over = 0; + BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_POST); + return OPERATOR_FINISHED; } @@ -1029,7 +1054,7 @@ int wm_userpref_write_exec(bContext *C, wmOperator *op) /* update keymaps in user preferences */ WM_keyconfig_update(wm); - BLI_make_file_string("/", filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_USERPREF_FILE); + BLI_make_file_string("/", filepath, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_USERPREF_FILE); printf("trying to save userpref at %s ", filepath); if (BKE_write_file_userdef(filepath, op->reports) == 0) { @@ -1046,12 +1071,20 @@ int wm_userpref_write_exec(bContext *C, wmOperator *op) void wm_autosave_location(char *filepath) { - char pidstr[32]; + const int pid = abs(getpid()); + char path[1024]; #ifdef WIN32 const char *savedir; #endif - BLI_snprintf(pidstr, sizeof(pidstr), "%d.blend", abs(getpid())); + if (G.main && G.relbase_valid) { + const char *basename = BLI_path_basename(G.main->name); + int len = strlen(basename) - 6; + BLI_snprintf(path, sizeof(path), "%.*s-%d.blend", len, basename, pid); + } + else { + BLI_snprintf(path, sizeof(path), "%d.blend", pid); + } #ifdef WIN32 /* XXX Need to investigate how to handle default location of '/tmp/' @@ -1062,14 +1095,14 @@ void wm_autosave_location(char *filepath) * BLI_make_file_string will create string that has it most likely on C:\ * through get_default_root(). * If there is no C:\tmp autosave fails. */ - if (!BLI_exists(BLI_temp_dir_base())) { - savedir = BLI_get_folder_create(BLENDER_USER_AUTOSAVE, NULL); - BLI_make_file_string("/", filepath, savedir, pidstr); + if (!BLI_exists(BKE_tempdir_base())) { + savedir = BKE_appdir_folder_id_create(BLENDER_USER_AUTOSAVE, NULL); + BLI_make_file_string("/", filepath, savedir, path); return; } #endif - BLI_make_file_string("/", filepath, BLI_temp_dir_base(), pidstr); + BLI_make_file_string("/", filepath, BKE_tempdir_base(), path); } void WM_autosave_init(wmWindowManager *wm) @@ -1133,7 +1166,7 @@ void wm_autosave_delete(void) if (BLI_exists(filename)) { char str[FILE_MAX]; - BLI_make_file_string("/", str, BLI_temp_dir_base(), BLENDER_QUIT_FILE); + BLI_make_file_string("/", str, BKE_tempdir_base(), BLENDER_QUIT_FILE); /* if global undo; remove tempsave, otherwise rename */ if (U.uiflag & USER_GLOBALUNDO) BLI_delete(filename, false, false); diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index 3e287a3907b..46c3909f7bf 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -49,7 +49,6 @@ #include "WM_types.h" #include "wm.h" -#include "wm_event_system.h" #include "wm_subwindow.h" #include "wm_draw.h" diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 139e0101859..d090eec4de7 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -40,9 +40,6 @@ #include "MEM_guardedalloc.h" -#include "IMB_imbuf_types.h" -#include "IMB_imbuf.h" - #include "DNA_scene_types.h" #include "DNA_userdef_types.h" #include "DNA_windowmanager_types.h" @@ -68,6 +65,7 @@ #include "BKE_report.h" #include "BKE_addon.h" +#include "BKE_appdir.h" #include "BKE_sequencer.h" /* free seq clipboard */ #include "BKE_material.h" /* clear_matcopybuf */ #include "BKE_tracking.h" /* free tracking clipboard */ @@ -110,7 +108,6 @@ #include "BLF_translation.h" #include "GPU_buffers.h" -#include "GPU_extensions.h" #include "GPU_draw.h" #include "GPU_init_exit.h" @@ -219,7 +216,7 @@ void WM_init(bContext *C, int argc, const char **argv) /* allow a path of "", this is what happens when making a new file */ #if 0 if (G.main->name[0] == 0) - BLI_make_file_string("/", G.main->name, BLI_getDefaultDocumentFolder(), "untitled.blend"); + BLI_make_file_string("/", G.main->name, BKE_appdir_folder_default(), "untitled.blend"); #endif BLI_strncpy(G.lib, G.main->name, FILE_MAX); @@ -308,7 +305,7 @@ bool WM_init_game(bContext *C) /* full screen the area */ if (!sa->full) { - ED_screen_full_toggle(C, win, sa); + ED_screen_state_toggle(C, win, sa, SCREENMAXIMIZED); } /* Fullscreen */ @@ -414,7 +411,7 @@ void WM_exit_ext(bContext *C, const bool do_python) bool has_edited; int fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY); - BLI_make_file_string("/", filename, BLI_temp_dir_base(), BLENDER_QUIT_FILE); + BLI_make_file_string("/", filename, BKE_tempdir_base(), BLENDER_QUIT_FILE); has_edited = ED_editors_flush_edits(C, false); @@ -543,7 +540,7 @@ void WM_exit_ext(bContext *C, const bool do_python) } wm_autosave_delete(); - BLI_temp_dir_session_purge(); + BKE_tempdir_session_purge(); } void WM_exit(bContext *C) diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c index 74c504050ae..6bc858e861a 100644 --- a/source/blender/windowmanager/intern/wm_jobs.c +++ b/source/blender/windowmanager/intern/wm_jobs.c @@ -45,8 +45,6 @@ #include "WM_api.h" #include "WM_types.h" -#include "wm_window.h" -#include "wm_event_system.h" #include "wm_event_types.h" #include "wm.h" @@ -630,17 +628,22 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt) } } - /* on file load 'winactive' can be NULL, possibly it should not happen but for now do a NULL check - campbell */ - if (wm->winactive) { - /* if there are running jobs, set the global progress indicator */ - if (jobs_progress > 0) { - float progress = total_progress / (float)jobs_progress; - WM_progress_set(wm->winactive, progress); - } - else { - WM_progress_clear(wm->winactive); - } + + /* if there are running jobs, set the global progress indicator */ + if (jobs_progress > 0) { + wmWindow *win; + float progress = total_progress / (float)jobs_progress; + + for (win = wm->windows.first; win; win = win->next) + WM_progress_set(win, progress); } + else { + wmWindow *win; + + for (win = wm->windows.first; win; win = win->next) + WM_progress_clear(win); + } + } bool WM_jobs_has_running(wmWindowManager *wm) diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index ff90de4b3c6..b52f3819d3f 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -56,7 +56,6 @@ #include "WM_api.h" #include "WM_types.h" -#include "wm_window.h" #include "wm_event_system.h" #include "wm_event_types.h" diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 016446e0a63..6324771f5e8 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -38,8 +38,11 @@ #include <stdio.h> #include <stddef.h> #include <assert.h> +#include <errno.h> -#include "GHOST_C-api.h" +#ifdef WIN32 +# include "GHOST_C-api.h" +#endif #include "MEM_guardedalloc.h" @@ -64,6 +67,7 @@ #include "BLO_readfile.h" +#include "BKE_appdir.h" #include "BKE_autoexec.h" #include "BKE_blender.h" #include "BKE_brush.h" @@ -78,6 +82,7 @@ #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_screen.h" /* BKE_ST_MAXNAME */ +#include "BKE_unit.h" #include "BKE_utildefines.h" #include "BKE_idcode.h" @@ -90,6 +95,7 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" +#include "ED_numinput.h" #include "ED_screen.h" #include "ED_util.h" #include "ED_view3d.h" @@ -147,9 +153,9 @@ wmOperatorType *WM_operatortype_find(const char *idname, bool quiet) } /* caller must free */ -GHashIterator *WM_operatortype_iter(void) +void WM_operatortype_iter(GHashIterator *ghi) { - return BLI_ghashIterator_new(global_ops_hash); + BLI_ghashIterator_init(ghi, global_ops_hash); } /* all ops in 1 list (for time being... needs evaluation later) */ @@ -494,6 +500,27 @@ bool WM_operatortype_remove(const char *idname) return true; } +/** + * Remove memory of all previously executed tools. + */ +void WM_operatortype_last_properties_clear_all(void) +{ + GHashIterator iter; + + for (WM_operatortype_iter(&iter); + (!BLI_ghashIterator_done(&iter)); + (BLI_ghashIterator_step(&iter))) + { + wmOperatorType *ot = BLI_ghashIterator_getValue(&iter); + + if (ot->last_properties) { + IDP_FreeProperty(ot->last_properties); + MEM_freeN(ot->last_properties); + ot->last_properties = NULL; + } + } +} + /* SOME_OT_op -> some.op */ void WM_operator_py_idname(char *to, const char *from) { @@ -1052,12 +1079,13 @@ int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) return retval; } else { - pup = uiPupMenuBegin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE); + layout = UI_popup_menu_layout(pup); /* set this so the default execution context is the same as submenus */ uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN); uiItemsFullEnumO(layout, op->type->idname, RNA_property_identifier(prop), op->ptr->data, WM_OP_EXEC_REGION_WIN, 0); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); + return OPERATOR_INTERFACE; } return OPERATOR_CANCELLED; @@ -1074,19 +1102,19 @@ static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op) uiBut *but; wmOperator *op = (wmOperator *)arg_op; - block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS); - uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU); + block = UI_block_begin(C, ar, "_popup", UI_EMBOSS); + UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU); #if 0 /* ok, this isn't so easy... */ - uiDefBut(block, LABEL, 0, RNA_struct_ui_name(op->type->srna), 10, 10, uiSearchBoxWidth(), UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, UI_BTYPE_LABEL, 0, RNA_struct_ui_name(op->type->srna), 10, 10, UI_searchbox_size_x(), UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); #endif but = uiDefSearchButO_ptr(block, op->type, op->ptr->data, search, 0, ICON_VIEWZOOM, sizeof(search), - 10, 10, uiSearchBoxWidth(), UI_UNIT_Y, 0, 0, ""); + 10, 10, UI_searchbox_size_x(), UI_UNIT_Y, 0, 0, ""); /* fake button, it holds space for search items */ - uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 10 - UI_searchbox_size_y(), UI_searchbox_size_x(), UI_searchbox_size_y(), NULL, 0, 0, 0, 0, NULL); - uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */ + UI_block_bounds_set_popup(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */ wm_event_init_from_window(win, &event); event.type = EVT_BUT_OPEN; @@ -1101,8 +1129,8 @@ static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op) int WM_enum_search_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - uiPupBlock(C, wm_enum_search_menu, op); - return OPERATOR_CANCELLED; + UI_popup_block_invoke(C, wm_enum_search_menu, op); + return OPERATOR_INTERFACE; } /* Can't be used as an invoke directly, needs message arg (can be NULL) */ @@ -1119,12 +1147,12 @@ int WM_operator_confirm_message_ex(bContext *C, wmOperator *op, else properties = NULL; - pup = uiPupMenuBegin(C, title, icon); - layout = uiPupMenuLayout(pup); + pup = UI_popup_menu_begin(C, title, icon); + layout = UI_popup_menu_layout(pup); uiItemFullO_ptr(layout, op->type, message, ICON_NONE, properties, WM_OP_EXEC_REGION_WIN, 0); - uiPupMenuEnd(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } int WM_operator_confirm_message(bContext *C, wmOperator *op, const char *message) @@ -1194,31 +1222,32 @@ void WM_operator_properties_filesel(wmOperatorType *ot, int filter, short type, if (action == FILE_SAVE) { /* note, this is only used to check if we should highlight the filename area red when the * filepath is an existing file. */ - prop = RNA_def_boolean(ot->srna, "check_existing", 1, "Check Existing", "Check and warn on overwriting existing files"); + prop = RNA_def_boolean(ot->srna, "check_existing", true, "Check Existing", + "Check and warn on overwriting existing files"); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } - prop = RNA_def_boolean(ot->srna, "filter_blender", (filter & BLENDERFILE), "Filter .blend files", ""); + prop = RNA_def_boolean(ot->srna, "filter_blender", (filter & BLENDERFILE) != 0, "Filter .blend files", ""); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, "filter_backup", (filter & BLENDERFILE_BACKUP), "Filter .blend files", ""); + prop = RNA_def_boolean(ot->srna, "filter_backup", (filter & BLENDERFILE_BACKUP) != 0, "Filter .blend files", ""); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, "filter_image", (filter & IMAGEFILE), "Filter image files", ""); + prop = RNA_def_boolean(ot->srna, "filter_image", (filter & IMAGEFILE) != 0, "Filter image files", ""); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, "filter_movie", (filter & MOVIEFILE), "Filter movie files", ""); + prop = RNA_def_boolean(ot->srna, "filter_movie", (filter & MOVIEFILE) != 0, "Filter movie files", ""); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, "filter_python", (filter & PYSCRIPTFILE), "Filter python files", ""); + prop = RNA_def_boolean(ot->srna, "filter_python", (filter & PYSCRIPTFILE) != 0, "Filter python files", ""); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, "filter_font", (filter & FTFONTFILE), "Filter font files", ""); + prop = RNA_def_boolean(ot->srna, "filter_font", (filter & FTFONTFILE) != 0, "Filter font files", ""); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, "filter_sound", (filter & SOUNDFILE), "Filter sound files", ""); + prop = RNA_def_boolean(ot->srna, "filter_sound", (filter & SOUNDFILE) != 0, "Filter sound files", ""); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, "filter_text", (filter & TEXTFILE), "Filter text files", ""); + prop = RNA_def_boolean(ot->srna, "filter_text", (filter & TEXTFILE) != 0, "Filter text files", ""); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, "filter_btx", (filter & BTXFILE), "Filter btx files", ""); + prop = RNA_def_boolean(ot->srna, "filter_btx", (filter & BTXFILE) != 0, "Filter btx files", ""); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, "filter_collada", (filter & COLLADAFILE), "Filter COLLADA files", ""); + prop = RNA_def_boolean(ot->srna, "filter_collada", (filter & COLLADAFILE) != 0, "Filter COLLADA files", ""); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, "filter_folder", (filter & FOLDERFILE), "Filter folders", ""); + prop = RNA_def_boolean(ot->srna, "filter_folder", (filter & FOLDERFILE) != 0, "Filter folders", ""); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); prop = RNA_def_int(ot->srna, "filemode", type, FILE_LOADLIB, FILE_SPECIAL, @@ -1307,7 +1336,7 @@ void WM_operator_properties_gesture_border(wmOperatorType *ot, bool extend) WM_operator_properties_border(ot); if (extend) { - RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection instead of deselecting everything first"); + RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend selection instead of deselecting everything first"); } } @@ -1315,11 +1344,12 @@ void WM_operator_properties_mouse_select(wmOperatorType *ot) { PropertyRNA *prop; - prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first"); + prop = RNA_def_boolean(ot->srna, "extend", false, "Extend", + "Extend selection instead of deselecting everything first"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Remove from selection"); + prop = RNA_def_boolean(ot->srna, "deselect", false, "Deselect", "Remove from selection"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, "toggle", 0, "Toggle Selection", "Toggle the selection"); + prop = RNA_def_boolean(ot->srna, "toggle", false, "Toggle Selection", "Toggle the selection"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); } @@ -1373,6 +1403,64 @@ wmOperator *WM_operator_last_redo(const bContext *C) return op; } +/** + * Use for drag & drop a path or name with operators invoke() function. + */ +ID *WM_operator_drop_load_path(struct bContext *C, wmOperator *op, const short idcode) +{ + ID *id = NULL; + /* check input variables */ + if (RNA_struct_property_is_set(op->ptr, "filepath")) { + const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path"); + char path[FILE_MAX]; + bool exists = false; + + RNA_string_get(op->ptr, "filepath", path); + + errno = 0; + + if (idcode == ID_IM) { + id = (ID *)BKE_image_load_exists_ex(path, &exists); + } + else { + BLI_assert(0); + } + + if (!id) { + BKE_reportf(op->reports, RPT_ERROR, "Cannot read %s '%s': %s", + BKE_idcode_to_name(idcode), path, + errno ? strerror(errno) : TIP_("unsupported format")); + return NULL; + } + + if (is_relative_path ) { + if (exists == false) { + Main *bmain = CTX_data_main(C); + + if (idcode == ID_IM) { + BLI_path_rel(((Image *)id)->name, bmain->name); + } + else { + BLI_assert(0); + } + } + } + } + else if (RNA_struct_property_is_set(op->ptr, "name")) { + char name[MAX_ID_NAME - 2]; + RNA_string_get(op->ptr, "name", name); + id = BKE_libblock_find_name(idcode, name); + if (!id) { + BKE_reportf(op->reports, RPT_ERROR, "%s '%s' not found", + BKE_idcode_to_name(idcode), name); + return NULL; + } + id_us_plus(id); + } + + return id; +} + static void wm_block_redo_cb(bContext *C, void *arg_op, int UNUSED(arg_event)) { wmOperator *op = arg_op; @@ -1404,19 +1492,19 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) wmOperator *op = arg_op; uiBlock *block; uiLayout *layout; - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_style_get(); int width = 15 * UI_UNIT_X; - block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); - uiBlockClearFlag(block, UI_BLOCK_LOOP); - uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_MOVEMOUSE_QUIT); + block = UI_block_begin(C, ar, __func__, UI_EMBOSS); + UI_block_flag_disable(block, UI_BLOCK_LOOP); + UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_MOVEMOUSE_QUIT); /* if register is not enabled, the operator gets freed on OPERATOR_FINISHED * ui_apply_but_funcs_after calls ED_undo_operator_repeate_cb and crashes */ assert(op->type->flag & OPTYPE_REGISTER); - uiBlockSetHandleFunc(block, wm_block_redo_cb, arg_op); - layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, width, UI_UNIT_Y, 0, style); + UI_block_func_handle_set(block, wm_block_redo_cb, arg_op); + layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, width, UI_UNIT_Y, 0, style); if (op == WM_operator_last_redo(C)) if (!WM_operator_check_ui_enabled(C, op->type->name)) @@ -1431,7 +1519,7 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE); } - uiPopupBoundsBlock(block, 4, 0, 0); + UI_block_bounds_set_popup(block, 4, 0, 0); return block; } @@ -1458,7 +1546,7 @@ static void dialog_exec_cb(bContext *C, void *arg1, void *arg2) /* in this case, wm_operator_ui_popup_cancel wont run */ MEM_freeN(data); - uiPupBlockClose(C, block); + UI_popup_block_close(C, block); } static void dialog_check_cb(bContext *C, void *op_ptr, void *UNUSED(arg)) @@ -1482,23 +1570,23 @@ static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData) wmOperator *op = data->op; uiBlock *block; uiLayout *layout; - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_style_get(); - block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); - uiBlockClearFlag(block, UI_BLOCK_LOOP); + block = UI_block_begin(C, ar, __func__, UI_EMBOSS); + UI_block_flag_disable(block, UI_BLOCK_LOOP); /* intentionally don't use 'UI_BLOCK_MOVEMOUSE_QUIT', some dialogues have many items * where quitting by accident is very annoying */ - uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN); + UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN); - layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style); + layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style); - uiBlockSetFunc(block, dialog_check_cb, op, NULL); + UI_block_func_set(block, dialog_check_cb, op, NULL); uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE); /* clear so the OK button is left alone */ - uiBlockSetFunc(block, NULL, NULL, NULL); + UI_block_func_set(block, NULL, NULL, NULL); /* new column so as not to interfere with custom layouts [#26436] */ { @@ -1509,12 +1597,12 @@ static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData) col = uiLayoutColumn(layout, false); col_block = uiLayoutGetBlock(col); /* Create OK button, the callback of which will execute op */ - btn = uiDefBut(col_block, BUT, 0, IFACE_("OK"), 0, -30, 0, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); - uiButSetFunc(btn, dialog_exec_cb, data, col_block); + btn = uiDefBut(col_block, UI_BTYPE_BUT, 0, IFACE_("OK"), 0, -30, 0, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); + UI_but_func_set(btn, dialog_exec_cb, data, col_block); } /* center around the mouse */ - uiPopupBoundsBlock(block, 4, data->width / -2, data->height / 2); + UI_block_bounds_set_popup(block, 4, data->width / -2, data->height / 2); return block; } @@ -1525,18 +1613,18 @@ static uiBlock *wm_operator_ui_create(bContext *C, ARegion *ar, void *userData) wmOperator *op = data->op; uiBlock *block; uiLayout *layout; - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_style_get(); - block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); - uiBlockClearFlag(block, UI_BLOCK_LOOP); - uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_MOVEMOUSE_QUIT); + block = UI_block_begin(C, ar, __func__, UI_EMBOSS); + UI_block_flag_disable(block, UI_BLOCK_LOOP); + UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_MOVEMOUSE_QUIT); - layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style); + layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style); /* since ui is defined the auto-layout args are not used */ uiLayoutOperatorButs(C, layout, op, NULL, 'V', 0); - uiPopupBoundsBlock(block, 4, 0, 0); + UI_block_bounds_set_popup(block, 4, 0, 0); return block; } @@ -1577,7 +1665,7 @@ int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height) data->width = width; data->height = height; data->free_op = true; /* if this runs and gets registered we may want not to free it */ - uiPupBlockEx(C, wm_operator_ui_create, NULL, wm_operator_ui_popup_cancel, data); + UI_popup_block_ex(C, wm_operator_ui_create, NULL, wm_operator_ui_popup_cancel, data); return OPERATOR_RUNNING_MODAL; } @@ -1607,7 +1695,7 @@ static int wm_operator_props_popup_ex(bContext *C, wmOperator *op, if (!do_redo || !(U.uiflag & USER_GLOBALUNDO)) return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X, UI_UNIT_Y); - uiPupBlockEx(C, wm_block_create_redo, NULL, wm_block_redo_cancel_cb, op); + UI_popup_block_ex(C, wm_block_create_redo, NULL, wm_block_redo_cancel_cb, op); if (do_call) wm_block_redo_cb(C, op, 0); @@ -1647,7 +1735,7 @@ int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, int h data->free_op = true; /* if this runs and gets registered we may want not to free it */ /* op is not executed until popup OK but is clicked */ - uiPupBlockEx(C, wm_block_dialog_create, wm_operator_ui_popup_ok, wm_operator_ui_popup_cancel, data); + UI_popup_block_ex(C, wm_block_dialog_create, wm_operator_ui_popup_ok, wm_operator_ui_popup_cancel, data); return OPERATOR_RUNNING_MODAL; } @@ -1665,7 +1753,7 @@ int WM_operator_redo_popup(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - uiPupBlock(C, wm_block_create_redo, op); + UI_popup_block_invoke(C, wm_block_create_redo, op); return OPERATOR_CANCELLED; } @@ -1730,7 +1818,7 @@ static void WM_OT_operator_defaults(wmOperatorType *ot) static void wm_block_splash_close(bContext *C, void *arg_block, void *UNUSED(arg)) { - uiPupBlockClose(C, arg_block); + UI_popup_block_close(C, arg_block); } static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *arg_unused); @@ -1742,22 +1830,22 @@ static void wm_block_splash_refreshmenu(bContext *UNUSED(C), void *UNUSED(arg_bl /* ugh, causes crashes in other buttons, disabling for now until * a better fix */ #if 0 - uiPupBlockClose(C, arg_block); - uiPupBlock(C, wm_block_create_splash, NULL); + UI_popup_block_close(C, arg_block); + UI_popup_block_invoke(C, wm_block_create_splash, NULL); #endif } static int wm_resource_check_prev(void) { - const char *res = BLI_get_folder_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION, true); + const char *res = BKE_appdir_folder_id_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION, true); // if (res) printf("USER: %s\n", res); #if 0 /* ignore the local folder */ if (res == NULL) { /* with a local dir, copying old files isn't useful since local dir get priority for config */ - res = BLI_get_folder_version(BLENDER_RESOURCE_PATH_LOCAL, BLENDER_VERSION, true); + res = BKE_appdir_folder_id_version(BLENDER_RESOURCE_PATH_LOCAL, BLENDER_VERSION, true); } #endif @@ -1766,7 +1854,7 @@ static int wm_resource_check_prev(void) return false; } else { - return (BLI_get_folder_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION - 1, true) != NULL); + return (BKE_appdir_folder_id_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION - 1, true) != NULL); } } @@ -1775,7 +1863,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar uiBlock *block; uiBut *but; uiLayout *layout, *split, *col; - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_style_get(); const struct RecentFile *recent; int i; MenuType *mt = WM_menutype_find("USERPREF_MT_splash", true); @@ -1821,17 +1909,17 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar } #endif - block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS); + block = UI_block_begin(C, ar, "_popup", UI_EMBOSS); /* note on UI_BLOCK_NO_WIN_CLIP, the window size is not always synchronized * with the OS when the splash shows, window clipping in this case gives * ugly results and clipping the splash isn't useful anyway, just disable it [#32938] */ - uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_NO_WIN_CLIP); + UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_NO_WIN_CLIP); /* XXX splash scales with pixelsize, should become widget-units */ - but = uiDefBut(block, BUT_IMAGE, 0, "", 0, 0.5f * U.widget_unit, U.pixelsize * 501, U.pixelsize * 282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */ - uiButSetFunc(but, wm_block_splash_close, block, NULL); - uiBlockSetFunc(block, wm_block_splash_refreshmenu, block, NULL); + but = uiDefBut(block, UI_BTYPE_IMAGE, 0, "", 0, 0.5f * U.widget_unit, U.pixelsize * 501, U.pixelsize * 282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */ + UI_but_func_set(but, wm_block_splash_close, block, NULL); + UI_block_func_set(block, wm_block_splash_refreshmenu, block, NULL); /* label for 'a' bugfix releases, or 'Release Candidate 1'... * avoids recreating splash for version updates */ @@ -1849,32 +1937,32 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar int w = 240; /* hack to have text draw 'text_sel' */ - uiBlockSetEmboss(block, UI_EMBOSSN); - but = uiDefBut(block, LABEL, 0, version_suffix, x * U.pixelsize, y * U.pixelsize, w * U.pixelsize, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); + UI_block_emboss_set(block, UI_EMBOSS_NONE); + but = uiDefBut(block, UI_BTYPE_LABEL, 0, version_suffix, x * U.pixelsize, y * U.pixelsize, w * U.pixelsize, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); /* XXX, set internal flag - UI_SELECT */ - uiButSetFlag(but, 1); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_but_flag_enable(but, 1); + UI_block_emboss_set(block, UI_EMBOSS); } #ifdef WITH_BUILDINFO if (build_commit_timestamp != 0) { - uiDefBut(block, LABEL, 0, date_buf, U.pixelsize * 494 - date_width, U.pixelsize * 270, date_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, UI_BTYPE_LABEL, 0, date_buf, U.pixelsize * 494 - date_width, U.pixelsize * 270, date_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); label_delta = 12; } - uiDefBut(block, LABEL, 0, hash_buf, U.pixelsize * 494 - hash_width, U.pixelsize * (270 - label_delta), hash_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, UI_BTYPE_LABEL, 0, hash_buf, U.pixelsize * 494 - hash_width, U.pixelsize * (270 - label_delta), hash_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); if (!STREQ(build_branch, "master")) { char branch_buf[128] = "\0"; int branch_width; BLI_snprintf(branch_buf, sizeof(branch_buf), "Branch: %s", build_branch); branch_width = (int)BLF_width(style->widgetlabel.uifont_id, branch_buf, sizeof(branch_buf)) + U.widget_unit; - uiDefBut(block, LABEL, 0, branch_buf, U.pixelsize * 494 - branch_width, U.pixelsize * (258 - label_delta), branch_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, UI_BTYPE_LABEL, 0, branch_buf, U.pixelsize * 494 - branch_width, U.pixelsize * (258 - label_delta), branch_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); } #endif /* WITH_BUILDINFO */ - layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, U.pixelsize * 480, U.pixelsize * 110, 0, style); + layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, U.pixelsize * 480, U.pixelsize * 110, 0, style); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); /* show the splash menu (containing interaction presets), using python */ if (mt) { Menu menu = {NULL}; @@ -1886,7 +1974,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar // uiItemM(layout, C, "USERPREF_MT_keyconfigs", U.keyconfigstr, ICON_NONE); } - uiBlockSetEmboss(block, UI_EMBOSSP); + UI_block_emboss_set(block, UI_EMBOSS_PULLDOWN); uiLayoutSetOperatorContext(layout, WM_OP_EXEC_REGION_WIN); split = uiLayoutSplit(layout, 0.0f, false); @@ -1902,7 +1990,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar BLENDER_VERSION / 100, BLENDER_VERSION % 100); uiItemStringO(col, IFACE_("Release Log"), ICON_URL, "WM_OT_url_open", "url", url); uiItemStringO(col, IFACE_("Manual"), ICON_URL, "WM_OT_url_open", "url", - "http://wiki.blender.org/index.php/Doc:2.6/Manual"); + "http://www.blender.org/manual"); uiItemStringO(col, IFACE_("Blender Website"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org"); if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "release")) { BLI_snprintf(url, sizeof(url), "http://www.blender.org/documentation/blender_python_api_%d_%d" @@ -1935,14 +2023,14 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar uiItemO(col, NULL, ICON_RECOVER_LAST, "WM_OT_recover_last_session"); uiItemL(col, "", ICON_NONE); - uiCenteredBoundsBlock(block, 0); + UI_block_bounds_set_centered(block, 0); return block; } static int wm_splash_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event)) { - uiPupBlock(C, wm_block_create_splash, NULL); + UI_popup_block_invoke(C, wm_block_create_splash, NULL); return OPERATOR_FINISHED; } @@ -1967,16 +2055,16 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *UNUSED(arg_ uiBlock *block; uiBut *but; - block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS); - uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU); + block = UI_block_begin(C, ar, "_popup", UI_EMBOSS); + UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU); - but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 10, uiSearchBoxWidth(), UI_UNIT_Y, 0, 0, ""); - uiOperatorSearch_But(but); + but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 10, UI_searchbox_size_x(), UI_UNIT_Y, 0, 0, ""); + UI_but_func_operator_search(but); /* fake button, it holds space for search items */ - uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 10 - UI_searchbox_size_y(), UI_searchbox_size_x(), UI_searchbox_size_y(), NULL, 0, 0, 0, 0, NULL); - uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */ + UI_block_bounds_set_popup(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */ wm_event_init_from_window(win, &event); event.type = EVT_BUT_OPEN; @@ -1995,9 +2083,9 @@ static int wm_search_menu_exec(bContext *UNUSED(C), wmOperator *UNUSED(op)) static int wm_search_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - uiPupBlock(C, wm_block_search_menu, op); + UI_popup_block_invoke(C, wm_block_search_menu, op); - return OPERATOR_CANCELLED; + return OPERATOR_INTERFACE; } /* op->poll */ @@ -2036,9 +2124,7 @@ static int wm_call_menu_exec(bContext *C, wmOperator *op) char idname[BKE_ST_MAXNAME]; RNA_string_get(op->ptr, "name", idname); - uiPupMenuInvoke(C, idname, op->reports); - - return OPERATOR_CANCELLED; + return UI_popup_menu_invoke(C, idname, op->reports); } static void WM_OT_call_menu(wmOperatorType *ot) @@ -2060,9 +2146,7 @@ static int wm_call_pie_menu_invoke(bContext *C, wmOperator *op, const wmEvent *e char idname[BKE_ST_MAXNAME]; RNA_string_get(op->ptr, "name", idname); - uiPieMenuInvoke(C, idname, event); - - return OPERATOR_CANCELLED; + return UI_pie_menu_invoke(C, idname, event); } static int wm_call_pie_menu_exec(bContext *C, wmOperator *op) @@ -2070,9 +2154,7 @@ static int wm_call_pie_menu_exec(bContext *C, wmOperator *op) char idname[BKE_ST_MAXNAME]; RNA_string_get(op->ptr, "name", idname); - uiPieMenuInvoke(C, idname, CTX_wm_window(C)->eventstate); - - return OPERATOR_CANCELLED; + return UI_pie_menu_invoke(C, idname, CTX_wm_window(C)->eventstate); } static void WM_OT_call_menu_pie(wmOperatorType *ot) @@ -2098,7 +2180,7 @@ static int wm_operator_winactive_normal(bContext *C) { wmWindow *win = CTX_wm_window(C); - if (win == NULL || win->screen == NULL || win->screen->full != SCREENNORMAL) + if (win == NULL || win->screen == NULL || win->screen->state != SCREENNORMAL) return 0; return 1; @@ -2561,6 +2643,13 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) lib = mainl->curlib; BLI_assert(lib); + if (mainl->versionfile < 250) { + BKE_reportf(op->reports, RPT_WARNING, + "Linking or appending from a very old .blend file format (%d.%d), no animation conversion will " + "be done! You may want to re-save your lib file with current Blender", + mainl->versionfile, mainl->subversionfile); + } + if (totfiles == 0) { BLO_library_append_named_part_ex(C, mainl, &bh, name, idcode, flag); } @@ -2667,7 +2756,7 @@ void WM_recover_last_session(bContext *C, ReportList *reports) { char filepath[FILE_MAX]; - BLI_make_file_string("/", filepath, BLI_temp_dir_base(), BLENDER_QUIT_FILE); + BLI_make_file_string("/", filepath, BKE_tempdir_base(), BLENDER_QUIT_FILE); /* if reports==NULL, it's called directly without operator, we add a quick check here */ if (reports || BLI_exists(filepath)) { G.fileflags |= G_FILE_RECOVER; @@ -2763,9 +2852,9 @@ static void save_set_compress(wmOperator *op) { if (!RNA_struct_property_is_set(op->ptr, "compress")) { if (G.save_over) /* keep flag for existing file */ - RNA_boolean_set(op->ptr, "compress", G.fileflags & G_FILE_COMPRESS); + RNA_boolean_set(op->ptr, "compress", (G.fileflags & G_FILE_COMPRESS) != 0); else /* use userdef for new file */ - RNA_boolean_set(op->ptr, "compress", U.flag & USER_FILECOMPRESS); + RNA_boolean_set(op->ptr, "compress", (U.flag & USER_FILECOMPRESS) != 0); } } @@ -2824,6 +2913,8 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op) (RNA_struct_find_property(op->ptr, "use_mesh_compat") && RNA_boolean_get(op->ptr, "use_mesh_compat")), G_FILE_MESH_COMPAT); +#else +# error "don't remove by accident" #endif if (wm_file_write(C, path, fileflags, op->reports) != 0) @@ -2864,14 +2955,14 @@ static void WM_OT_save_as_mainfile(wmOperatorType *ot) WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); - RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file"); - RNA_def_boolean(ot->srna, "relative_remap", 1, "Remap Relative", + RNA_def_boolean(ot->srna, "compress", false, "Compress", "Write compressed .blend file"); + RNA_def_boolean(ot->srna, "relative_remap", true, "Remap Relative", "Remap relative paths when saving in a different directory"); - prop = RNA_def_boolean(ot->srna, "copy", 0, "Save Copy", + prop = RNA_def_boolean(ot->srna, "copy", false, "Save Copy", "Save a copy of the actual working state but does not make saved file active"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); #ifdef USE_BMESH_SAVE_AS_COMPAT - RNA_def_boolean(ot->srna, "use_mesh_compat", 0, "Legacy Mesh Format", + RNA_def_boolean(ot->srna, "use_mesh_compat", false, "Legacy Mesh Format", "Save using legacy mesh format (no ngons) - WARNING: only saves tris and quads, other ngons will " "be lost (no implicit triangulation)"); #endif @@ -2940,13 +3031,14 @@ static void WM_OT_save_mainfile(wmOperatorType *ot) WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); - RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file"); - RNA_def_boolean(ot->srna, "relative_remap", 0, "Remap Relative", "Remap relative paths when saving in a different directory"); + RNA_def_boolean(ot->srna, "compress", false, "Compress", "Write compressed .blend file"); + RNA_def_boolean(ot->srna, "relative_remap", false, "Remap Relative", + "Remap relative paths when saving in a different directory"); } static void WM_OT_window_fullscreen_toggle(wmOperatorType *ot) { - ot->name = "Toggle Fullscreen"; + ot->name = "Toggle Window Fullscreen"; ot->idname = "WM_OT_window_fullscreen_toggle"; ot->description = "Toggle the current window fullscreen"; @@ -3712,6 +3804,7 @@ void WM_OT_straightline_gesture(wmOperatorType *ot) #define WM_RADIAL_CONTROL_DISPLAY_SIZE 200 #define WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE 35 #define WM_RADIAL_CONTROL_DISPLAY_WIDTH (WM_RADIAL_CONTROL_DISPLAY_SIZE - WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE) +#define WM_RADIAL_CONTROL_HEADER_LENGTH 180 #define WM_RADIAL_MAX_STR 6 typedef struct { @@ -3729,8 +3822,24 @@ typedef struct { ListBase orig_paintcursors; bool use_secondary_tex; void *cursor; + NumInput num_input; } RadialControl; +static void radial_control_update_header(wmOperator *op, bContext *C) +{ + RadialControl *rc = op->customdata; + char msg[WM_RADIAL_CONTROL_HEADER_LENGTH]; + ScrArea *sa = CTX_wm_area(C); + Scene *scene = CTX_data_scene(C); + + if (sa && hasNumInput(&rc->num_input)) { + char num_str[NUM_STR_REP_LEN]; + outputNumInput(&rc->num_input, num_str, &scene->unit); + BLI_snprintf(msg, WM_RADIAL_CONTROL_HEADER_LENGTH, "%s: %s", RNA_property_ui_name(rc->prop), num_str); + ED_area_headerprint(sa, msg); + } +} + static void radial_control_set_initial_mouse(RadialControl *rc, const wmEvent *event) { float d[2] = {0, 0}; @@ -3742,6 +3851,7 @@ static void radial_control_set_initial_mouse(RadialControl *rc, const wmEvent *e switch (rc->subtype) { case PROP_NONE: case PROP_DISTANCE: + case PROP_PERCENTAGE: case PROP_PIXEL: d[0] = rc->initial_value; break; @@ -3837,7 +3947,7 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd { RadialControl *rc = customdata; ARegion *ar = CTX_wm_region(C); - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_style_get(); const uiFontStyle *fstyle = &style->widget; const int fontid = fstyle->uifont_id; short fstyle_points = fstyle->points; @@ -3850,6 +3960,7 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd switch (rc->subtype) { case PROP_NONE: case PROP_DISTANCE: + case PROP_PERCENTAGE: case PROP_PIXEL: r1 = rc->current_value; r2 = rc->initial_value; @@ -3989,7 +4100,7 @@ static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op, PropertyType prop_type = RNA_property_type(*r_prop); if (((flags & RC_PROP_REQUIRE_BOOL) && (prop_type != PROP_BOOLEAN)) || - ((flags & RC_PROP_REQUIRE_FLOAT) && prop_type != PROP_FLOAT)) + ((flags & RC_PROP_REQUIRE_FLOAT) && (prop_type != PROP_FLOAT))) { MEM_freeN(str); BKE_reportf(op->reports, RPT_ERROR, "Property from path '%s' is not a float", name); @@ -4113,14 +4224,21 @@ static int radial_control_invoke(bContext *C, wmOperator *op, const wmEvent *eve return OPERATOR_CANCELLED; } + /* initialize numerical input */ + initNumInput(&rc->num_input); + rc->num_input.idx_max = 0; + rc->num_input.val_flag[0] |= NUM_NO_NEGATIVE; + rc->num_input.unit_sys = USER_UNIT_NONE; + rc->num_input.unit_type[0] = B_UNIT_LENGTH; + /* get subtype of property */ rc->subtype = RNA_property_subtype(rc->prop); - if (!ELEM(rc->subtype, PROP_NONE, PROP_DISTANCE, PROP_FACTOR, PROP_ANGLE, PROP_PIXEL)) { - BKE_report(op->reports, RPT_ERROR, "Property must be a none, distance, a factor, or an angle"); + if (!ELEM(rc->subtype, PROP_NONE, PROP_DISTANCE, PROP_FACTOR, PROP_PERCENTAGE, PROP_ANGLE, PROP_PIXEL)) { + BKE_report(op->reports, RPT_ERROR, "Property must be a none, distance, factor, percentage, angle, or pixel"); MEM_freeN(rc); return OPERATOR_CANCELLED; } - + rc->current_value = rc->initial_value; radial_control_set_initial_mouse(rc, event); radial_control_set_tex(rc); @@ -4157,11 +4275,16 @@ static void radial_control_cancel(bContext *C, wmOperator *op) { RadialControl *rc = op->customdata; wmWindowManager *wm = CTX_wm_manager(C); + ScrArea *sa = CTX_wm_area(C); if (rc->dial) { MEM_freeN(rc->dial); rc->dial = NULL; } + + if (sa) { + ED_area_headerprint(sa, NULL); + } WM_paint_cursor_end(wm, rc->cursor); @@ -4185,125 +4308,165 @@ static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *even float delta[2], ret = OPERATOR_RUNNING_MODAL; bool snap; float angle_precision = 0.0f; + const bool has_numInput = hasNumInput(&rc->num_input); + bool handled = false; + float numValue; /* TODO: fix hardcoded events */ snap = event->ctrl != 0; - switch (event->type) { - case MOUSEMOVE: - if (rc->slow_mode) { - if (rc->subtype == PROP_ANGLE) { - float position[2] = {event->x, event->y}; - - /* calculate the initial angle here first */ - delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0]; - delta[1] = rc->initial_mouse[1] - rc->slow_mouse[1]; - - /* precision angle gets calculated from dial and gets added later */ - angle_precision = -0.1f * BLI_dial_angle(rc->dial, position); - } - else { - delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0]; - delta[1] = rc->initial_mouse[1] - rc->slow_mouse[1]; - - if (rc->zoom_prop) { - RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom); - delta[0] /= zoom[0]; - delta[1] /= zoom[1]; + /* Modal numinput active, try to handle numeric inputs first... */ + if (event->val == KM_PRESS && has_numInput && handleNumInput(C, &rc->num_input, event)) { + handled = true; + applyNumInput(&rc->num_input, &numValue); + CLAMP(numValue, rc->min_value, rc->max_value); + new_value = numValue; + + radial_control_set_value(rc, new_value); + rc->current_value = new_value; + radial_control_update_header(op, C); + return OPERATOR_RUNNING_MODAL; + } + else { + handled = false; + switch (event->type) { + case ESCKEY: + case RIGHTMOUSE: + /* canceled; restore original value */ + radial_control_set_value(rc, rc->initial_value); + ret = OPERATOR_CANCELLED; + break; + + case LEFTMOUSE: + case PADENTER: + case RETKEY: + /* done; value already set */ + RNA_property_update(C, &rc->ptr, rc->prop); + ret = OPERATOR_FINISHED; + break; + + case MOUSEMOVE: + if (!has_numInput) { + if (rc->slow_mode) { + if (rc->subtype == PROP_ANGLE) { + float position[2] = {event->x, event->y}; + + /* calculate the initial angle here first */ + delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0]; + delta[1] = rc->initial_mouse[1] - rc->slow_mouse[1]; + + /* precision angle gets calculated from dial and gets added later */ + angle_precision = -0.1f * BLI_dial_angle(rc->dial, position); + } + else { + delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0]; + delta[1] = rc->initial_mouse[1] - rc->slow_mouse[1]; + + if (rc->zoom_prop) { + RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom); + delta[0] /= zoom[0]; + delta[1] /= zoom[1]; + } + + dist = len_v2(delta); + + delta[0] = event->x - rc->slow_mouse[0]; + delta[1] = event->y - rc->slow_mouse[1]; + + if (rc->zoom_prop) { + delta[0] /= zoom[0]; + delta[1] /= zoom[1]; + } + + dist = dist + 0.1f * (delta[0] + delta[1]); + } } - - dist = len_v2(delta); - - delta[0] = event->x - rc->slow_mouse[0]; - delta[1] = event->y - rc->slow_mouse[1]; - - if (rc->zoom_prop) { - delta[0] /= zoom[0]; - delta[1] /= zoom[1]; + else { + delta[0] = rc->initial_mouse[0] - event->x; + delta[1] = rc->initial_mouse[1] - event->y; + + if (rc->zoom_prop) { + RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom); + delta[0] /= zoom[0]; + delta[1] /= zoom[1]; + } + + dist = len_v2(delta); + } + + /* calculate new value and apply snapping */ + switch (rc->subtype) { + case PROP_NONE: + case PROP_DISTANCE: + case PROP_PERCENTAGE: + case PROP_PIXEL: + new_value = dist; + if (snap) new_value = ((int)new_value + 5) / 10 * 10; + break; + case PROP_FACTOR: + new_value = (WM_RADIAL_CONTROL_DISPLAY_SIZE - dist) / WM_RADIAL_CONTROL_DISPLAY_WIDTH; + if (snap) new_value = ((int)ceil(new_value * 10.f) * 10.0f) / 100.f; + break; + case PROP_ANGLE: + new_value = atan2f(delta[1], delta[0]) + M_PI + angle_precision; + new_value = fmod(new_value, 2.0f * (float)M_PI); + if (new_value < 0.0f) + new_value += 2.0f * (float)M_PI; + if (snap) new_value = DEG2RADF(((int)RAD2DEGF(new_value) + 5) / 10 * 10); + break; + default: + new_value = dist; /* dummy value, should this ever happen? - campbell */ + break; } - - dist = dist + 0.1f * (delta[0] + delta[1]); + + /* clamp and update */ + CLAMP(new_value, rc->min_value, rc->max_value); + radial_control_set_value(rc, new_value); + rc->current_value = new_value; + handled = true; + break; } - } - else { - delta[0] = rc->initial_mouse[0] - event->x; - delta[1] = rc->initial_mouse[1] - event->y; + break; - if (rc->zoom_prop) { - RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom); - delta[0] /= zoom[0]; - delta[1] /= zoom[1]; + case LEFTSHIFTKEY: + case RIGHTSHIFTKEY: + { + if (event->val == KM_PRESS) { + rc->slow_mouse[0] = event->x; + rc->slow_mouse[1] = event->y; + rc->slow_mode = true; + if (rc->subtype == PROP_ANGLE) { + float initial_position[2] = {UNPACK2(rc->initial_mouse)}; + float current_position[2] = {UNPACK2(rc->slow_mouse)}; + rc->dial = BLI_dial_initialize(initial_position, 0.0f); + /* immediately set the position to get a an initial direction */ + BLI_dial_angle(rc->dial, current_position); + } + handled = true; } - - dist = len_v2(delta); + if (event->val == KM_RELEASE) { + rc->slow_mode = false; + handled = true; + if (rc->dial) { + MEM_freeN(rc->dial); + rc->dial = NULL; + } + } + break; } + } - /* calculate new value and apply snapping */ - switch (rc->subtype) { - case PROP_NONE: - case PROP_DISTANCE: - case PROP_PIXEL: - new_value = dist; - if (snap) new_value = ((int)new_value + 5) / 10 * 10; - break; - case PROP_FACTOR: - new_value = (WM_RADIAL_CONTROL_DISPLAY_SIZE - dist) / WM_RADIAL_CONTROL_DISPLAY_WIDTH; - if (snap) new_value = ((int)ceil(new_value * 10.f) * 10.0f) / 100.f; - break; - case PROP_ANGLE: - new_value = atan2f(delta[1], delta[0]) + M_PI + angle_precision; - new_value = fmod(new_value, 2.0f * (float)M_PI); - if (new_value < 0.0f) - new_value += 2.0f * (float)M_PI; - if (snap) new_value = DEG2RADF(((int)RAD2DEGF(new_value) + 5) / 10 * 10); - break; - default: - new_value = dist; /* dummy value, should this ever happen? - campbell */ - break; - } + /* Modal numinput inactive, try to handle numeric inputs last... */ + if (!handled && event->val == KM_PRESS && handleNumInput(C, &rc->num_input, event)) { + applyNumInput(&rc->num_input, &numValue); + CLAMP(numValue, rc->min_value, rc->max_value); + new_value = numValue; - /* clamp and update */ - CLAMP(new_value, rc->min_value, rc->max_value); radial_control_set_value(rc, new_value); rc->current_value = new_value; - break; - - case ESCKEY: - case RIGHTMOUSE: - /* canceled; restore original value */ - radial_control_set_value(rc, rc->initial_value); - ret = OPERATOR_CANCELLED; - break; - - case LEFTMOUSE: - case PADENTER: - /* done; value already set */ - RNA_property_update(C, &rc->ptr, rc->prop); - ret = OPERATOR_FINISHED; - break; - - case LEFTSHIFTKEY: - case RIGHTSHIFTKEY: - if (event->val == KM_PRESS) { - rc->slow_mouse[0] = event->x; - rc->slow_mouse[1] = event->y; - rc->slow_mode = true; - if (rc->subtype == PROP_ANGLE) { - float initial_position[2] = {UNPACK2(rc->initial_mouse)}; - float current_position[2] = {UNPACK2(rc->slow_mouse)}; - rc->dial = BLI_dial_initialize(initial_position, 0.0f); - /* immediately set the position to get a an initial direction */ - BLI_dial_angle(rc->dial, current_position); - } - } - if (event->val == KM_RELEASE) { - rc->slow_mode = false; - if (rc->dial) { - MEM_freeN(rc->dial); - rc->dial = NULL; - } - } - break; + radial_control_update_header(op, C); + return OPERATOR_RUNNING_MODAL; + } } ED_region_tag_redraw(CTX_wm_region(C)); @@ -4343,7 +4506,7 @@ static void WM_OT_radial_control(wmOperatorType *ot) RNA_def_string(ot->srna, "image_id", NULL, 0, "Image ID", "Path of ID that is used to generate an image for the control"); - RNA_def_boolean(ot->srna, "secondary_tex", 0, "Secondary Texture", "Tweak brush secondary/mask texture"); + RNA_def_boolean(ot->srna, "secondary_tex", false, "Secondary Texture", "Tweak brush secondary/mask texture"); } /* ************************** timer for testing ***************** */ @@ -4645,6 +4808,8 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "CLIP_OT_select_circle"); WM_modalkeymap_assign(keymap, "MASK_OT_select_circle"); WM_modalkeymap_assign(keymap, "NODE_OT_select_circle"); + WM_modalkeymap_assign(keymap, "GPENCIL_OT_select_circle"); + WM_modalkeymap_assign(keymap, "GRAPH_OT_select_circle"); } @@ -4741,6 +4906,7 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "VIEW3D_OT_select_border"); WM_modalkeymap_assign(keymap, "VIEW3D_OT_zoom_border"); /* XXX TODO: zoom border should perhaps map rightmouse to zoom out instead of in+cancel */ WM_modalkeymap_assign(keymap, "IMAGE_OT_render_border"); + WM_modalkeymap_assign(keymap, "GPENCIL_OT_select_border"); } /* zoom to border modal operators */ diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index 76add2f9aac..232c9ad2e4d 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -69,8 +69,6 @@ #include "GHOST_C-api.h" #include "BLF_api.h" -#include "wm_event_types.h" - #include "WM_api.h" /* only for WM_main_playanim */ struct PlayState; @@ -298,8 +296,8 @@ static void playanim_toscreen(PlayState *ps, PlayAnimPict *picture, struct ImBuf glRasterPos2f(offs_x + (ps->draw_flip[0] ? span_x : 0.0f), offs_y + (ps->draw_flip[1] ? span_y : 0.0f)); - glPixelZoom(ps->zoom * ps->draw_flip[0] ? -1.0f : 1.0f, - ps->zoom * ps->draw_flip[1] ? -1.0f : 1.0f); + glPixelZoom(ps->zoom * (ps->draw_flip[0] ? -1.0f : 1.0f), + ps->zoom * (ps->draw_flip[1] ? -1.0f : 1.0f)); glDrawPixels(ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index e26bcac9b1a..d2df020600a 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -53,7 +53,6 @@ #include "WM_api.h" #include "wm_subwindow.h" -#include "wm_window.h" /* wmSubWindow stored in wmWindow... but not exposed outside this C file */ /* it seems a bit redundant (area regions can store it too, but we keep it diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 46a20d3bf88..52fcdd797cb 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1524,3 +1524,21 @@ bool WM_window_is_fullscreen(wmWindow *win) return win->windowstate == GHOST_kWindowStateFullScreen; } + +#ifdef WITH_INPUT_IME +/* note: keep in mind wm_window_IME_begin is also used to reposition the IME window */ +void wm_window_IME_begin(wmWindow *win, int x, int y, int w, int h, bool complete) +{ + BLI_assert(win); + + GHOST_BeginIME(win->ghostwin, x, win->sizey - y, w, h, complete); +} + +void wm_window_IME_end(wmWindow *win) +{ + BLI_assert(win && win->ime_data); + + GHOST_EndIME(win->ghostwin); + win->ime_data = NULL; +} +#endif /* WITH_INPUT_IME */ diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index f50f98ed40c..2301405a8ea 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -86,10 +86,19 @@ enum { * paint and drawing tools however will want to handle these. */ INBETWEEN_MOUSEMOVE = 0x0011, +/* IME event, GHOST_kEventImeCompositionStart in ghost */ + WM_IME_COMPOSITE_START = 0x0014, +/* IME event, GHOST_kEventImeComposition in ghost */ + WM_IME_COMPOSITE_EVENT = 0x0015, +/* IME event, GHOST_kEventImeCompositionEnd in ghost */ + WM_IME_COMPOSITE_END = 0x0016, + /* *** Start of keyboard codes. *** */ /* standard keyboard. * XXX from 0x0020 to 0x00ff, and 0x012c to 0x013f for function keys! */ + + /* NOTE: these values are saved in keymap files, do not change them but just add new ones */ AKEY = 0x0061, /* 'a' */ BKEY = 0x0062, /* 'b' */ CKEY = 0x0063, /* 'c' */ @@ -299,6 +308,10 @@ enum { /* Tweak, gestures: 0x500x, 0x501x */ EVT_ACTIONZONE_AREA = 0x5000, EVT_ACTIONZONE_REGION = 0x5001, + EVT_ACTIONZONE_FULLSCREEN = 0x5011, + + /* NOTE: these values are saved in keymap files, do not change them but just add new ones */ + /* tweak events, for L M R mousebuttons */ EVT_TWEAK_L = 0x5002, EVT_TWEAK_M = 0x5003, @@ -308,6 +321,8 @@ enum { EVT_TWEAK_S = 0x5006, EVT_GESTURE = 0x5010, + /* 0x5011 is taken, see EVT_ACTIONZONE_FULLSCREEN */ + /* Misc Blender internals: 0x502x */ EVT_FILESELECT = 0x5020, EVT_BUT_OPEN = 0x5021, @@ -358,6 +373,7 @@ enum { /* ********** wmEvent.val ********** */ /* Gestures */ +/* NOTE: these values are saved in keymap files, do not change them but just add new ones */ enum { /* value of tweaks and line gestures, note, KM_ANY (-1) works for this case too */ EVT_GESTURE_N = 1, diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h index 9c9c79d2f54..833234b0f13 100644 --- a/source/blender/windowmanager/wm_window.h +++ b/source/blender/windowmanager/wm_window.h @@ -69,6 +69,11 @@ wmWindow *wm_window_copy (bContext *C, wmWindow *winorig); void wm_window_testbreak (void); +#ifdef WITH_INPUT_IME +void wm_window_IME_begin (wmWindow *win, int x, int y, int w, int h, bool complete); +void wm_window_IME_end (wmWindow *win); +#endif + /* *************** window operators ************** */ int wm_window_duplicate_exec(bContext *C, struct wmOperator *op); int wm_window_fullscreen_toggle_exec(bContext *C, struct wmOperator *op); |