diff options
Diffstat (limited to 'source/blender/blenkernel')
78 files changed, 1070 insertions, 1142 deletions
diff --git a/source/blender/blenkernel/BKE_appdir.h b/source/blender/blenkernel/BKE_appdir.h index 7ff8514f675..e55cb69a5c6 100644 --- a/source/blender/blenkernel/BKE_appdir.h +++ b/source/blender/blenkernel/BKE_appdir.h @@ -36,6 +36,7 @@ const char *BKE_appdir_folder_id_version(const int folder_id, const int ver, con bool BKE_appdir_app_is_portable_install(void); bool BKE_appdir_app_template_any(void); bool BKE_appdir_app_template_id_search(const char *app_template, char *path, size_t path_len); +bool BKE_appdir_app_template_has_userpref(const char *app_template); void BKE_appdir_app_templates(struct ListBase *templates); /* Initialize path to program executable */ @@ -44,6 +45,9 @@ void BKE_appdir_program_path_init(const char *argv0); const char *BKE_appdir_program_path(void); const char *BKE_appdir_program_dir(void); +/* Return OS fonts directory. */ +bool BKE_appdir_font_folder_default(char *dir); + /* find python executable */ bool BKE_appdir_program_python_search(char *fullpath, const size_t fullpath_len, diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index b5da30e725d..6839e13ffe1 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -84,7 +84,9 @@ bool BKE_pose_minmax( int bone_autoside_name(char name[64], int strip_number, short axis, float head, float tail); struct Bone *BKE_armature_find_bone_name(struct bArmature *arm, const char *name); -struct GHash *BKE_armature_bone_from_name_map(struct bArmature *arm); + +void BKE_armature_bone_hash_make(struct bArmature *arm); +void BKE_armature_bone_hash_free(struct bArmature *arm); bool BKE_armature_bone_flag_test_recursive(const struct Bone *bone, int flag); diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index e01f6a6b751..3fae40d6c7b 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -27,7 +27,7 @@ * \note Use #STRINGIFY() rather than defining with quotes. */ #define BLENDER_VERSION 280 -#define BLENDER_SUBVERSION 60 +#define BLENDER_SUBVERSION 71 /** Several breakages with 280, e.g. collections vs layers. */ #define BLENDER_MINVERSION 280 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenkernel/BKE_blendfile.h b/source/blender/blenkernel/BKE_blendfile.h index 216bef0d1e3..76c05b0411a 100644 --- a/source/blender/blenkernel/BKE_blendfile.h +++ b/source/blender/blenkernel/BKE_blendfile.h @@ -62,6 +62,8 @@ struct UserDef *BKE_blendfile_userdef_read_from_memory(const void *filebuf, bool BKE_blendfile_userdef_write(const char *filepath, struct ReportList *reports); bool BKE_blendfile_userdef_write_app_template(const char *filepath, struct ReportList *reports); +bool BKE_blendfile_userdef_write_all(struct ReportList *reports); + struct WorkspaceConfigFileData *BKE_blendfile_workspace_config_read(const char *filepath, const void *filebuf, int filelength, diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h index 10cd129fbf9..caed4959eff 100644 --- a/source/blender/blenkernel/BKE_camera.h +++ b/source/blender/blenkernel/BKE_camera.h @@ -139,8 +139,6 @@ bool BKE_camera_view_frame_fit_to_coords(const struct Depsgraph *depsgraph, float r_co[3], float *r_scale); -void BKE_camera_to_gpu_dof(struct Object *camera, struct GPUFXSettings *r_fx_settings); - /* Camera multi-view API */ struct Object *BKE_camera_multiview_render(struct Scene *scene, diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h index 47786629aed..0e093bb086b 100644 --- a/source/blender/blenkernel/BKE_collection.h +++ b/source/blender/blenkernel/BKE_collection.h @@ -161,6 +161,8 @@ bool BKE_collection_move(struct Main *bmain, bool BKE_collection_find_cycle(struct Collection *new_ancestor, struct Collection *collection); +bool BKE_collection_has_collection(struct Collection *parent, struct Collection *collection); + /* Iteration callbacks. */ typedef void (*BKE_scene_objects_Cb)(struct Object *ob, void *data); diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index 8be43a50be6..0d2998cc51e 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -311,8 +311,23 @@ 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); +/* Gets pointer to the dependency graph. + * If it doesn't exist yet, it will be allocated. + * + * The result dependency graph is NOT guaranteed to be up-to-date neither from relation nor from + * evaluated data points of view. + * + * NOTE: Can not be used if access to a fully evaluated datablock is needed. */ struct Depsgraph *CTX_data_depsgraph(const bContext *C); +/* Gets fully updated and evaluated dependency graph. + * + * All the relations and evaluated objects are guaranteed to be up to date. + * + * NOTE: Will be expensive if there are relations or objects tagged for update. + * NOTE: If there are pending updates depsgraph hooks will be invoked. */ +struct Depsgraph *CTX_data_evaluated_depsgraph(const bContext *C); + /* Will Return NULL if depsgraph is not allocated yet. * Only used by handful of operators which are run on file load. */ diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 4eaa0fbe057..df1e7a7baea 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -134,21 +134,11 @@ void BKE_curve_editNurb_keyIndex_free(struct GHash **keyindex); void BKE_curve_editNurb_free(struct Curve *cu); struct ListBase *BKE_curve_editNurbs_get(struct Curve *cu); -float *BKE_curve_make_orco(struct Depsgraph *depsgraph, - struct Scene *scene, - struct Object *ob, - int *r_numVerts); float *BKE_curve_surf_make_orco(struct Object *ob); void BKE_curve_bevelList_free(struct ListBase *bev); void BKE_curve_bevelList_make(struct Object *ob, struct ListBase *nurbs, bool for_render); -void BKE_curve_bevel_make(struct Depsgraph *depsgraph, - struct Scene *scene, - struct Object *ob, - struct ListBase *disp, - const bool for_render, - const bool use_render_resolution, - struct LinkNode *ob_cyclic_list); +void BKE_curve_bevel_make(struct Object *ob, struct ListBase *disp); void BKE_curve_forward_diff_bezier( float q0, float q1, float q2, float q3, float *p, int it, int stride); @@ -212,9 +202,9 @@ void BKE_nurb_knot_calc_u(struct Nurb *nu); void BKE_nurb_knot_calc_v(struct Nurb *nu); /* nurb checks if they can be drawn, also clamp order func */ -bool BKE_nurb_check_valid_u(struct Nurb *nu); -bool BKE_nurb_check_valid_v(struct Nurb *nu); -bool BKE_nurb_check_valid_uv(struct Nurb *nu); +bool BKE_nurb_check_valid_u(const struct Nurb *nu); +bool BKE_nurb_check_valid_v(const struct Nurb *nu); +bool BKE_nurb_check_valid_uv(const struct Nurb *nu); bool BKE_nurb_order_clamp_u(struct Nurb *nu); bool BKE_nurb_order_clamp_v(struct Nurb *nu); diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h index 9bf5a2f9971..c57639a8193 100644 --- a/source/blender/blenkernel/BKE_displist.h +++ b/source/blender/blenkernel/BKE_displist.h @@ -85,27 +85,18 @@ void BKE_displist_make_surf(struct Depsgraph *depsgraph, struct ListBase *dispbase, struct Mesh **r_final, const bool for_render, - const bool for_orco, - const bool use_render_resolution); + const bool for_orco); void BKE_displist_make_curveTypes(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, const bool for_render, - const bool for_orco, - struct LinkNode *ob_cyclic_list); + const bool for_orco); void BKE_displist_make_curveTypes_forRender(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct ListBase *dispbase, struct Mesh **r_final, - const bool for_orco, - const bool use_render_resolution, - struct LinkNode *ob_cyclic_list); -void BKE_displist_make_curveTypes_forOrco(struct Depsgraph *depsgraph, - struct Scene *scene, - struct Object *ob, - struct ListBase *dispbase, - struct LinkNode *ob_cyclic_list); + const bool for_orco); void BKE_displist_make_mball(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob); void BKE_displist_make_mball_forRender(struct Depsgraph *depsgraph, struct Scene *scene, diff --git a/source/blender/blenkernel/BKE_editmesh.h b/source/blender/blenkernel/BKE_editmesh.h index 91a558a9ee2..b7280c702d2 100644 --- a/source/blender/blenkernel/BKE_editmesh.h +++ b/source/blender/blenkernel/BKE_editmesh.h @@ -90,6 +90,7 @@ void BKE_editmesh_color_free(BMEditMesh *em); void BKE_editmesh_color_ensure(BMEditMesh *em, const char htype); float (*BKE_editmesh_vertexCos_get_orco(BMEditMesh *em, int *r_numVerts))[3]; void BKE_editmesh_lnorspace_update(BMEditMesh *em); +void BKE_editmesh_ensure_autosmooth(BMEditMesh *em); /* editderivedmesh.c */ /* should really be defined in editmesh.c, but they use 'EditDerivedBMesh' */ diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index c1232addee3..4c1a115eb23 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -340,6 +340,7 @@ float evaluate_fcurve_driver(struct PathResolvedRNA *anim_rna, struct FCurve *fcu, struct ChannelDriver *driver_orig, float evaltime); +bool BKE_fcurve_is_empty(struct FCurve *fcu); /* evaluate fcurve and store value */ float calculate_fcurve(struct PathResolvedRNA *anim_rna, struct FCurve *fcu, float evaltime); diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index 2c19c1e2006..9fe8fc3880f 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -107,10 +107,10 @@ typedef struct Global { /** #Global.f */ enum { G_FLAG_RENDER_VIEWPORT = (1 << 0), - G_FLAG_BACKBUFSEL = (1 << 1), G_FLAG_PICKSEL = (1 << 2), /** Support simulating events (for testing). */ G_FLAG_EVENT_SIMULATE = (1 << 3), + G_FLAG_USERPREF_NO_SAVE_ON_EXIT = (1 << 4), G_FLAG_SCRIPT_AUTOEXEC = (1 << 13), /** When this flag is set ignore the prefs #USER_SCRIPT_AUTOEXEC_DISABLE. */ @@ -121,7 +121,8 @@ enum { /** Don't overwrite these flags when reading a file. */ #define G_FLAG_ALL_RUNTIME \ - (G_FLAG_SCRIPT_AUTOEXEC | G_FLAG_SCRIPT_OVERRIDE_PREF | G_FLAG_EVENT_SIMULATE) + (G_FLAG_SCRIPT_AUTOEXEC | G_FLAG_SCRIPT_OVERRIDE_PREF | G_FLAG_EVENT_SIMULATE | \ + G_FLAG_USERPREF_NO_SAVE_ON_EXIT) /** Flags to read from blend file. */ #define G_FLAG_ALL_READFILE 0 diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h index e6f3d7b4a99..0eb8df1b19d 100644 --- a/source/blender/blenkernel/BKE_idprop.h +++ b/source/blender/blenkernel/BKE_idprop.h @@ -134,7 +134,8 @@ struct IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -void IDP_FreeProperty_ex(struct IDProperty *prop, const bool do_id_user); +void IDP_FreePropertyContent_ex(struct IDProperty *prop, const bool do_id_user); +void IDP_FreePropertyContent(struct IDProperty *prop); void IDP_FreeProperty(struct IDProperty *prop); void IDP_ClearProperty(IDProperty *prop); diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index 28886a5a195..b9f2123b2bd 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -153,29 +153,6 @@ struct RenderData; struct RenderPass; struct RenderResult; -/* ima->source; where image comes from */ -#define IMA_SRC_CHECK 0 -#define IMA_SRC_FILE 1 -#define IMA_SRC_SEQUENCE 2 -#define IMA_SRC_MOVIE 3 -#define IMA_SRC_GENERATED 4 -#define IMA_SRC_VIEWER 5 - -/* ima->type, how to handle/generate it */ -#define IMA_TYPE_IMAGE 0 -#define IMA_TYPE_MULTILAYER 1 -/* generated */ -#define IMA_TYPE_UV_TEST 2 -/* viewers */ -#define IMA_TYPE_R_RESULT 4 -#define IMA_TYPE_COMPOSITE 5 - -enum { - IMA_GENTYPE_BLANK = 0, - IMA_GENTYPE_GRID = 1, - IMA_GENTYPE_GRID_COLOR = 2, -}; - /* ima->ok */ #define IMA_OK 1 #define IMA_OK_LOADED 2 @@ -340,12 +317,16 @@ void BKE_image_buf_fill_checker_color(unsigned char *rect, unsigned char *BKE_image_get_pixels_for_frame(struct Image *image, int frame); float *BKE_image_get_float_pixels_for_frame(struct Image *image, int frame); +/* Image modifications */ +bool BKE_image_is_dirty(struct Image *image); +void BKE_image_mark_dirty(struct Image *image, struct ImBuf *ibuf); + /* Guess offset for the first frame in the sequence */ int BKE_image_sequence_guess_offset(struct Image *image); bool BKE_image_has_anim(struct Image *image); bool BKE_image_has_packedfile(struct Image *image); +bool BKE_image_has_filepath(struct Image *ima); bool BKE_image_is_animated(struct Image *image); -bool BKE_image_is_dirty(struct Image *image); void BKE_image_file_format_set(struct Image *image, int ftype, const struct ImbFormatOptions *options); diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index ecee00b1b3f..c410946f438 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -208,12 +208,13 @@ float (*BKE_mesh_vertexCos_get(const struct Mesh *me, int *r_numVerts))[3]; void BKE_mesh_split_faces(struct Mesh *mesh, bool free_loop_normals); -struct Mesh *BKE_mesh_new_from_object(struct Depsgraph *depsgraph, - struct Main *bmain, - struct Scene *sce, - struct Object *ob, - const bool apply_modifiers, - const bool calc_undeformed); +/* Create new mesh from the given object at its current state. + * The owner of this mesh is unknown, it is up to the caller to decide. */ +struct Mesh *BKE_mesh_new_from_object(struct Object *object); + +/* This is a version of BKE_mesh_new_from_object() which stores mesh in the given main database. */ +struct Mesh *BKE_mesh_new_from_object_to_bmain(struct Main *bmain, struct Object *object); + struct Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob_eval, @@ -671,11 +672,9 @@ void BKE_mesh_eval_geometry(struct Depsgraph *depsgraph, struct Mesh *mesh); /* Draw Cache */ enum { BKE_MESH_BATCH_DIRTY_ALL = 0, - BKE_MESH_BATCH_DIRTY_MAYBE_ALL, BKE_MESH_BATCH_DIRTY_SELECT, BKE_MESH_BATCH_DIRTY_SELECT_PAINT, BKE_MESH_BATCH_DIRTY_SHADING, - BKE_MESH_BATCH_DIRTY_SCULPT_COORDS, BKE_MESH_BATCH_DIRTY_UVEDIT_ALL, BKE_MESH_BATCH_DIRTY_UVEDIT_SELECT, }; diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 49b35bfccc1..aa4d9696527 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -100,6 +100,8 @@ bool BKE_object_is_mode_compat(const struct Object *ob, eObjectMode object_mode) bool BKE_object_data_is_in_editmode(const struct ID *id); +void BKE_object_update_select_id(struct Main *bmain); + typedef enum eObjectVisibilityResult { OB_VISIBLE_SELF = 1, OB_VISIBLE_PARTICLES = 2, @@ -394,6 +396,15 @@ bool BKE_object_empty_image_frame_is_visible_in_view3d(const struct Object *ob, bool BKE_object_empty_image_data_is_visible_in_view3d(const struct Object *ob, const struct RegionView3D *rv3d); +/* This is an utility function for Python's object.to_mesh() (the naming is not very clear though). + * The result is owned by the object. + * + * The mesh will be freed when object is re-evaluated or is destroyed. It is possible to force to + * clear memory sued by this mesh by calling BKE_object_to_mesh_clear(). */ +struct Mesh *BKE_object_to_mesh(struct Object *object); + +void BKE_object_to_mesh_clear(struct Object *object); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index f59288f54bd..315c0224b11 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -34,6 +34,7 @@ struct CCGKey; struct CustomData; struct DMFlagMat; struct GPUBatch; +struct GPU_PBVH_Buffers; struct MLoop; struct MLoopTri; struct MPoly; @@ -48,6 +49,21 @@ typedef struct { float (*co)[3]; } PBVHProxyNode; +typedef enum { + PBVH_Leaf = 1, + + PBVH_UpdateNormals = 2, + PBVH_UpdateBB = 4, + PBVH_UpdateOriginalBB = 8, + PBVH_UpdateDrawBuffers = 16, + PBVH_UpdateRedraw = 32, + + PBVH_RebuildDrawBuffers = 64, + PBVH_FullyHidden = 128, + + PBVH_UpdateTopology = 256, +} PBVHNodeFlags; + /* Callbacks */ /* returns 1 if the search should continue from this node, 0 otherwise */ @@ -151,13 +167,15 @@ bool BKE_pbvh_node_find_nearest_to_ray(PBVH *bvh, void BKE_pbvh_draw_cb(PBVH *bvh, float (*planes)[4], float (*fnors)[3], - bool fast, - bool wires, - bool only_mask, bool show_vcol, - void (*draw_fn)(void *user_data, struct GPUBatch *batch), + void (*draw_fn)(void *user_data, struct GPU_PBVH_Buffers *buffers), void *user_data); +void BKE_pbvh_draw_debug_cb( + PBVH *bvh, + void (*draw_fn)(void *user_data, const float bmin[3], const float bmax[3], PBVHNodeFlags flag), + void *user_data); + /* PBVH Access */ typedef enum { PBVH_FACES, @@ -202,21 +220,6 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *bvh, /* Node Access */ -typedef enum { - PBVH_Leaf = 1, - - PBVH_UpdateNormals = 2, - PBVH_UpdateBB = 4, - PBVH_UpdateOriginalBB = 8, - PBVH_UpdateDrawBuffers = 16, - PBVH_UpdateRedraw = 32, - - PBVH_RebuildDrawBuffers = 64, - PBVH_FullyHidden = 128, - - PBVH_UpdateTopology = 256, -} PBVHNodeFlags; - void BKE_pbvh_node_mark_update(PBVHNode *node); void BKE_pbvh_node_mark_rebuild_draw(PBVHNode *node); void BKE_pbvh_node_mark_redraw(PBVHNode *node); diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 75ff5eace3c..581df648add 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -240,6 +240,11 @@ void BKE_scene_cursor_quat_to_rot(struct View3DCursor *cursor, const float quat[4], bool use_compat); +void BKE_scene_cursor_to_mat4(const struct View3DCursor *cursor, float mat[4][4]); +void BKE_scene_cursor_from_mat4(struct View3DCursor *cursor, + const float mat[4][4], + bool use_compat); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index 93c9c41e482..dcf6d6c3907 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -84,6 +84,9 @@ typedef struct SpaceType { struct wmNotifier *wmn, struct Scene *scene); + /* called when the mouse moves out of the area */ + void (*deactivate)(struct ScrArea *sa); + /* refresh context, called after filereads, ED_area_tag_refresh() */ void (*refresh)(const struct bContext *C, struct ScrArea *sa); @@ -205,6 +208,7 @@ typedef struct PanelType { short region_type; /* For popovers, 0 for default. */ int ui_units_x; + int order; int flag; diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 017c15ebe41..170ab657388 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -100,8 +100,8 @@ typedef struct SeqRenderData { /* special case for OpenGL render */ struct GPUOffScreen *gpu_offscreen; - int gpu_samples; - bool gpu_full_samples; + // int gpu_samples; + // bool gpu_full_samples; } SeqRenderData; void BKE_sequencer_new_render_data(struct Main *bmain, diff --git a/source/blender/blenkernel/BKE_workspace.h b/source/blender/blenkernel/BKE_workspace.h index 0a4ad4cd994..133cf2d6cf5 100644 --- a/source/blender/blenkernel/BKE_workspace.h +++ b/source/blender/blenkernel/BKE_workspace.h @@ -110,6 +110,8 @@ void BKE_workspace_hook_layout_for_workspace_set(struct WorkSpaceInstanceHook *h bool BKE_workspace_owner_id_check(const struct WorkSpace *workspace, const char *owner_id) ATTR_NONNULL(); +void BKE_workspace_id_tag_all_visible(struct Main *bmain, int tag) ATTR_NONNULL(); + #undef GETTER_ATTRS #undef SETTER_ATTRS diff --git a/source/blender/blenkernel/BKE_writeavi.h b/source/blender/blenkernel/BKE_writeavi.h index 72817217a0a..3212bad75cb 100644 --- a/source/blender/blenkernel/BKE_writeavi.h +++ b/source/blender/blenkernel/BKE_writeavi.h @@ -53,9 +53,6 @@ typedef struct bMovieHandle { const char *suffix, struct ReportList *reports); void (*end_movie)(void *context_v); - int (*get_next_frame)(void *context_v, - struct RenderData *rd, - struct ReportList *reports); /* optional */ void (*get_movie_path)(char *string, struct RenderData *rd, bool preview, diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 9b321ff4e44..65b837048cb 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -822,7 +822,6 @@ void BKE_pose_channel_free_ex(bPoseChannel *pchan, bool do_id_user) if (pchan->prop) { IDP_FreeProperty(pchan->prop); - MEM_freeN(pchan->prop); } /* Cached data, for new draw manager rendering code. */ @@ -964,7 +963,6 @@ void BKE_pose_channel_copy_data(bPoseChannel *pchan, const bPoseChannel *pchan_f if (pchan->prop) { /* unlikely but possible it exists */ IDP_FreeProperty(pchan->prop); - MEM_freeN(pchan->prop); pchan->prop = NULL; } if (pchan_from->prop) { @@ -978,6 +976,7 @@ void BKE_pose_channel_copy_data(bPoseChannel *pchan, const bPoseChannel *pchan_f } pchan->custom_scale = pchan_from->custom_scale; + pchan->drawflag = pchan_from->drawflag; } /* checks for IK constraint, Spline IK, and also for Follow-Path constraint. diff --git a/source/blender/blenkernel/intern/addon.c b/source/blender/blenkernel/intern/addon.c index 486da61fe68..99ef38722f5 100644 --- a/source/blender/blenkernel/intern/addon.c +++ b/source/blender/blenkernel/intern/addon.c @@ -81,7 +81,6 @@ void BKE_addon_free(bAddon *addon) { if (addon->prop) { IDP_FreeProperty(addon->prop); - MEM_freeN(addon->prop); } MEM_freeN(addon); } diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index cc5cd3b03ae..4a939180fb0 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -1893,6 +1893,10 @@ static void animsys_evaluate_fcurves(Depsgraph *depsgraph, if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED))) { continue; } + /* Skip empty curves, as if muted. */ + if (BKE_fcurve_is_empty(fcu)) { + continue; + } PathResolvedRNA anim_rna; if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) { const float curval = calculate_fcurve(&anim_rna, fcu, ctime); @@ -2005,7 +2009,7 @@ void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup * /* calculate then execute each curve */ for (fcu = agrp->channels.first; (fcu) && (fcu->grp == agrp); fcu = fcu->next) { /* check if this curve should be skipped */ - if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) { + if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0 && !BKE_fcurve_is_empty(fcu)) { PathResolvedRNA anim_rna; if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) { const float curval = calculate_fcurve(&anim_rna, fcu, ctime); @@ -3101,6 +3105,9 @@ static void nlastrip_evaluate_actionclip(PointerRNA *ptr, if ((fcu->grp) && (fcu->grp->flag & AGRP_MUTED)) { continue; } + if (BKE_fcurve_is_empty(fcu)) { + continue; + } /* evaluate the F-Curve's value for the time given in the strip * NOTE: we use the modified time here, since strip's F-Curve Modifiers @@ -3327,6 +3334,9 @@ static void nla_eval_domain_action(PointerRNA *ptr, if ((fcu->grp) && (fcu->grp->flag & AGRP_MUTED)) { continue; } + if (BKE_fcurve_is_empty(fcu)) { + continue; + } NlaEvalChannel *nec = nlaevalchan_verify(ptr, channels, fcu->rna_path); @@ -3608,9 +3618,9 @@ static void animsys_calculate_nla(Depsgraph *depsgraph, * Prepare data necessary to compute correct keyframe values for NLA strips * with non-Replace mode or influence different from 1. * - * \param cache List used to cache contexts for reuse when keying + * \param cache: List used to cache contexts for reuse when keying * multiple channels in one operation. - * \param ptr RNA pointer to the Object with the animation. + * \param ptr: RNA pointer to the Object with the animation. * \return Keyframing context, or NULL if not necessary. */ NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(struct ListBase *cache, @@ -3652,12 +3662,12 @@ NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(struct ListBase *ca /** * Apply correction from the NLA context to the values about to be keyframed. * - * \param context Context to use (may be NULL). - * \param prop_ptr Property about to be keyframed. - * \param[in,out] values Array of property values to adjust. - * \param count Number of values in the array. - * \param index Index of the element about to be updated, or -1. - * \param[out] r_force_all Set to true if all channels must be inserted. May be NULL. + * \param context: Context to use (may be NULL). + * \param prop_ptr: Property about to be keyframed. + * \param[in,out] values: Array of property values to adjust. + * \param count: Number of values in the array. + * \param index: Index of the element about to be updated, or -1. + * \param[out] r_force_all: Set to true if all channels must be inserted. May be NULL. * \return False if correction fails due to a division by zero, * or null r_force_all when all channels are required. */ diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c index 2b4123c74e2..14a20689db0 100644 --- a/source/blender/blenkernel/intern/appdir.c +++ b/source/blender/blenkernel/intern/appdir.c @@ -30,6 +30,7 @@ #include "BLI_listbase.h" #include "BLI_path_util.h" #include "BLI_string.h" +#include "BLI_string_utf8.h" #include "BKE_blender_version.h" #include "BKE_appdir.h" /* own include */ @@ -838,6 +839,26 @@ bool BKE_appdir_app_template_id_search(const char *app_template, char *path, siz return false; } +bool BKE_appdir_app_template_has_userpref(const char *app_template) +{ + /* Test if app template provides a userpref.blend. + * If not, we will share user preferences with the rest of Blender. */ + if (!app_template && app_template[0]) { + return false; + } + + char app_template_path[FILE_MAX]; + if (!BKE_appdir_app_template_id_search( + app_template, app_template_path, sizeof(app_template_path))) { + return false; + } + + char userpref_path[FILE_MAX]; + BLI_path_join( + userpref_path, sizeof(userpref_path), app_template_path, BLENDER_USERPREF_FILE, NULL); + return BLI_exists(userpref_path); +} + void BKE_appdir_app_templates(ListBase *templates) { BLI_listbase_clear(templates); @@ -1004,3 +1025,17 @@ void BKE_tempdir_session_purge(void) BLI_delete(btempdir_session, true, true); } } + +/* Gets a good default directory for fonts */ +bool BKE_appdir_font_folder_default(char *dir) +{ + bool success = false; +#ifdef WIN32 + wchar_t wpath[FILE_MAXDIR]; + success = SHGetSpecialFolderPathW(0, wpath, CSIDL_FONTS, 0); + BLI_strncpy_wchar_as_utf8(dir, wpath, FILE_MAXDIR); +#endif + /* TODO: Values for other platforms. */ + UNUSED_VARS(dir); + return success; +} diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 60446bf60b6..df22aa1dcfb 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -112,7 +112,6 @@ void BKE_armature_bonelist_free(ListBase *lb) for (bone = lb->first; bone; bone = bone->next) { if (bone->prop) { IDP_FreeProperty(bone->prop); - MEM_freeN(bone->prop); } BKE_armature_bonelist_free(&bone->childbase); } @@ -125,6 +124,7 @@ void BKE_armature_free(bArmature *arm) { BKE_animdata_free(&arm->id, false); + BKE_armature_bone_hash_free(arm); BKE_armature_bonelist_free(&arm->bonebase); /* free editmode data */ @@ -169,25 +169,20 @@ static void copy_bonechildren(Bone *bone_dst, } } -static void copy_bonechildren_custom_handles(Bone *bone_dst, bArmature *arm_dst, GHash **bone_hash) +static void copy_bonechildren_custom_handles(Bone *bone_dst, bArmature *arm_dst) { Bone *bone_dst_child; - /* Lazily create the name -> bone hashtable. */ - if ((bone_dst->bbone_prev || bone_dst->bbone_next) && *bone_hash == NULL) { - *bone_hash = BKE_armature_bone_from_name_map(arm_dst); - } - if (bone_dst->bbone_prev) { - bone_dst->bbone_prev = BLI_ghash_lookup(*bone_hash, bone_dst->bbone_prev->name); + bone_dst->bbone_prev = BKE_armature_find_bone_name(arm_dst, bone_dst->bbone_prev->name); } if (bone_dst->bbone_next) { - bone_dst->bbone_next = BLI_ghash_lookup(*bone_hash, bone_dst->bbone_next->name); + bone_dst->bbone_next = BKE_armature_find_bone_name(arm_dst, bone_dst->bbone_next->name); } for (bone_dst_child = bone_dst->childbase.first; bone_dst_child; bone_dst_child = bone_dst_child->next) { - copy_bonechildren_custom_handles(bone_dst_child, arm_dst, bone_hash); + copy_bonechildren_custom_handles(bone_dst_child, arm_dst); } } @@ -212,6 +207,8 @@ void BKE_armature_copy_data(Main *UNUSED(bmain), /* We never handle usercount here for own data. */ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT; + arm_dst->bonehash = NULL; + BLI_duplicatelist(&arm_dst->bonebase, &arm_src->bonebase); /* Duplicate the childrens' lists */ @@ -224,15 +221,11 @@ void BKE_armature_copy_data(Main *UNUSED(bmain), arm_dst->act_bone = bone_dst_act; - /* Fix custom handle references. */ - GHash *bone_hash = NULL; /* lazily created */ + BKE_armature_bone_hash_make(arm_dst); + /* Fix custom handle references. */ for (bone_dst = arm_dst->bonebase.first; bone_dst; bone_dst = bone_dst->next) { - copy_bonechildren_custom_handles(bone_dst, arm_dst, &bone_hash); - } - - if (bone_hash) { - BLI_ghash_free(bone_hash, NULL, NULL); + copy_bonechildren_custom_handles(bone_dst, arm_dst); } arm_dst->edbo = NULL; @@ -274,6 +267,10 @@ Bone *BKE_armature_find_bone_name(bArmature *arm, const char *name) return NULL; } + if (arm->bonehash) { + return BLI_ghash_lookup(arm->bonehash, name); + } + return get_named_bone_bonechildren(&arm->bonebase, name); } @@ -291,7 +288,7 @@ static void armature_bone_from_name_insert_recursive(GHash *bone_hash, ListBase * \note typically #bPose.chanhash us used via #BKE_pose_channel_find_name * this is for the cases we can't use pose channels. */ -GHash *BKE_armature_bone_from_name_map(bArmature *arm) +static GHash *armature_bone_from_name_map(bArmature *arm) { const int bones_count = BKE_armature_bonelist_count(&arm->bonebase); GHash *bone_hash = BLI_ghash_str_new_ex(__func__, bones_count); @@ -299,6 +296,21 @@ GHash *BKE_armature_bone_from_name_map(bArmature *arm) return bone_hash; } +void BKE_armature_bone_hash_make(bArmature *arm) +{ + if (!arm->bonehash) { + arm->bonehash = armature_bone_from_name_map(arm); + } +} + +void BKE_armature_bone_hash_free(bArmature *arm) +{ + if (arm->bonehash) { + BLI_ghash_free(arm->bonehash, NULL, NULL); + arm->bonehash = NULL; + } +} + bool BKE_armature_bone_flag_test_recursive(const Bone *bone, int flag) { if (bone->flag & flag) { @@ -2417,7 +2429,6 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected } if (prop_orig) { IDP_FreeProperty(prop_orig); - MEM_freeN(prop_orig); } } } @@ -2458,11 +2469,9 @@ void BKE_pose_clear_pointers(bPose *pose) void BKE_pose_remap_bone_pointers(bArmature *armature, bPose *pose) { - GHash *bone_hash = BKE_armature_bone_from_name_map(armature); for (bPoseChannel *pchan = pose->chanbase.first; pchan; pchan = pchan->next) { - pchan->bone = BLI_ghash_lookup(bone_hash, pchan->name); + pchan->bone = BKE_armature_find_bone_name(armature, pchan->name); } - BLI_ghash_free(bone_hash, NULL, NULL); } /** Find the matching pose channel using the bone name, if not NULL. */ diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c index c71c2dc86cf..bf7d81e5d63 100644 --- a/source/blender/blenkernel/intern/armature_update.c +++ b/source/blender/blenkernel/intern/armature_update.c @@ -273,11 +273,12 @@ static void splineik_evaluate_bone( /* first, adjust the point positions on the curve */ float curveLen = tree->points[index] - tree->points[index + 1]; float pointStart = state->curve_position; + float poseScale = len_v3v3(poseHead, poseTail) / pchan->bone->length; float baseScale = 1.0f; if (ikData->yScaleMode == CONSTRAINT_SPLINEIK_YS_ORIGINAL) { /* Carry over the bone Y scale to the curve range. */ - baseScale = len_v3v3(poseHead, poseTail) / pchan->bone->length; + baseScale = poseScale; } float pointEnd = pointStart + curveLen * baseScale * state->curve_scale; @@ -339,8 +340,8 @@ static void splineik_evaluate_bone( sub_v3_v3v3(splineVec, poseTail, poseHead); scaleFac = len_v3(splineVec) / pchan->bone->length; - /* Adjust the scale factor towards the neutral state when rolling off the curve end. */ - scaleFac = interpf(scaleFac, baseScale, tailBlendFac); + /* Extrapolate the full length of the bone as it rolls off the end of the curve. */ + scaleFac = (tailBlendFac < 1e-5f) ? baseScale : scaleFac / tailBlendFac; /* Step 3: compute the shortest rotation needed * to map from the bone rotation to the current axis. @@ -394,24 +395,31 @@ static void splineik_evaluate_bone( } /* step 4: set the scaling factors for the axes */ - { - /* only multiply the y-axis by the scaling factor to get nice volume-preservation */ - mul_v3_fl(poseMat[1], scaleFac); - /* set the scaling factors of the x and z axes from... */ - switch (ikData->xzScaleMode) { - case CONSTRAINT_SPLINEIK_XZS_ORIGINAL: { - /* original scales get used */ - float scale; + /* Always multiply the y-axis by the scaling factor to get the correct length. */ + mul_v3_fl(poseMat[1], scaleFac); + + /* After that, apply x/z scaling modes. */ + if (ikData->xzScaleMode != CONSTRAINT_SPLINEIK_XZS_NONE) { + /* First, apply the original scale if enabled. */ + if (ikData->xzScaleMode == CONSTRAINT_SPLINEIK_XZS_ORIGINAL || + (ikData->flag & CONSTRAINT_SPLINEIK_USE_ORIGINAL_SCALE) != 0) { + float scale; + + /* x-axis scale */ + scale = len_v3(pchan->pose_mat[0]); + mul_v3_fl(poseMat[0], scale); + /* z-axis scale */ + scale = len_v3(pchan->pose_mat[2]); + mul_v3_fl(poseMat[2], scale); + + /* Adjust the scale factor used for volume preservation + * to consider the pre-IK scaling as the initial volume. */ + scaleFac /= poseScale; + } - /* x-axis scale */ - scale = len_v3(pchan->pose_mat[0]); - mul_v3_fl(poseMat[0], scale); - /* z-axis scale */ - scale = len_v3(pchan->pose_mat[2]); - mul_v3_fl(poseMat[2], scale); - break; - } + /* Apply volume preservation. */ + switch (ikData->xzScaleMode) { case CONSTRAINT_SPLINEIK_XZS_INVERSE: { /* old 'volume preservation' method using the inverse scale */ float scale; @@ -483,14 +491,14 @@ static void splineik_evaluate_bone( break; } } + } - /* finally, multiply the x and z scaling by the radius of the curve too, - * to allow automatic scales to get tweaked still - */ - if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_CURVERAD) == 0) { - mul_v3_fl(poseMat[0], radius); - mul_v3_fl(poseMat[2], radius); - } + /* Finally, multiply the x and z scaling by the radius of the curve too, + * to allow automatic scales to get tweaked still. + */ + if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_CURVERAD) == 0) { + mul_v3_fl(poseMat[0], radius); + mul_v3_fl(poseMat[2], radius); } /* Blend the scaling of the matrix according to the influence. */ diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 48b271cf277..9fd3c24092c 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -155,7 +155,6 @@ static void keymap_item_free(wmKeyMapItem *kmi) { if (kmi->properties) { IDP_FreeProperty(kmi->properties); - MEM_freeN(kmi->properties); } if (kmi->ptr) { MEM_freeN(kmi->ptr); @@ -212,7 +211,6 @@ static void userdef_free_keyconfig_prefs(UserDef *userdef) kpt = kpt_next) { kpt_next = kpt->next; IDP_FreeProperty(kpt->prop); - MEM_freeN(kpt->prop); MEM_freeN(kpt); } BLI_listbase_clear(&userdef->user_keyconfig_prefs); diff --git a/source/blender/blenkernel/intern/blender_user_menu.c b/source/blender/blenkernel/intern/blender_user_menu.c index 911f3fdc7b2..ad34ef03e04 100644 --- a/source/blender/blenkernel/intern/blender_user_menu.c +++ b/source/blender/blenkernel/intern/blender_user_menu.c @@ -97,7 +97,6 @@ void BKE_blender_user_menu_item_free(bUserMenuItem *umi) bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi; if (umi_op->prop) { IDP_FreeProperty(umi_op->prop); - MEM_freeN(umi_op->prop); } } MEM_freeN(umi); diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c index d1a3045a829..570c1b9bd4c 100644 --- a/source/blender/blenkernel/intern/blendfile.c +++ b/source/blender/blenkernel/intern/blendfile.c @@ -98,6 +98,25 @@ static bool wm_scene_is_visible(wmWindowManager *wm, Scene *scene) return false; } +static void setup_app_userdef(BlendFileData *bfd) +{ + if (bfd->user) { + /* only here free userdef themes... */ + BKE_blender_userdef_data_set_and_free(bfd->user); + bfd->user = NULL; + + /* Security issue: any blend file could include a USER block. + * + * Currently we load prefs from BLENDER_STARTUP_FILE and later on load BLENDER_USERPREF_FILE, + * to load the preferences defined in the users home dir. + * + * This means we will never accidentally (or maliciously) + * enable scripts auto-execution by loading a '.blend' file. + */ + U.flag |= USER_SCRIPT_AUTOEXEC_DISABLE; + } +} + /** * Context matching, handle no-ui case * @@ -235,26 +254,10 @@ static void setup_app_data(bContext *C, RNA_property_update_cache_free(); bmain = G_MAIN = bfd->main; + bfd->main = NULL; CTX_data_main_set(C, bmain); - if (bfd->user) { - - /* only here free userdef themes... */ - BKE_blender_userdef_data_set_and_free(bfd->user); - bfd->user = NULL; - - /* Security issue: any blend file could include a USER block. - * - * Currently we load prefs from BLENDER_STARTUP_FILE and later on load BLENDER_USERPREF_FILE, - * to load the preferences defined in the users home dir. - * - * This means we will never accidentally (or maliciously) - * enable scripts auto-execution by loading a '.blend' file. - */ - U.flag |= USER_SCRIPT_AUTOEXEC_DISABLE; - } - /* case G_FILE_NO_UI or no screens in file */ if (mode != LOAD_UI) { /* leave entire context further unaltered? */ @@ -356,8 +359,20 @@ static void setup_app_data(bContext *C, /* TODO(sergey): Can this be also move above? */ RE_FreeAllPersistentData(); } +} - MEM_freeN(bfd); +static void setup_app_blend_file_data(bContext *C, + BlendFileData *bfd, + const char *filepath, + const struct BlendFileReadParams *params, + ReportList *reports) +{ + if ((params->skip_flags & BLO_READ_SKIP_USERDEF) == 0) { + setup_app_userdef(bfd); + } + if ((params->skip_flags & BLO_READ_SKIP_DATA) == 0) { + setup_app_data(C, bfd, filepath, params->is_startup, reports); + } } static int handle_subversion_warning(Main *main, ReportList *reports) @@ -400,7 +415,8 @@ int BKE_blendfile_read(bContext *C, retval = BKE_BLENDFILE_READ_FAIL; } else { - setup_app_data(C, bfd, filepath, params->is_startup, reports); + setup_app_blend_file_data(C, bfd, filepath, params, reports); + BLO_blendfiledata_free(bfd); } } else { @@ -422,9 +438,13 @@ bool BKE_blendfile_read_from_memory(bContext *C, bfd = BLO_read_from_memory(filebuf, filelength, params->skip_flags, reports); if (bfd) { if (update_defaults) { - BLO_update_defaults_startup_blend(bfd->main, NULL); + if ((params->skip_flags & BLO_READ_SKIP_DATA) == 0) { + BLO_update_defaults_startup_blend(bfd->main, NULL); + } } - setup_app_data(C, bfd, "<memory2>", params->is_startup, reports); + + setup_app_blend_file_data(C, bfd, "<memory2>", params, reports); + BLO_blendfiledata_free(bfd); } else { BKE_reports_prepend(reports, "Loading failed: "); @@ -453,7 +473,8 @@ bool BKE_blendfile_read_from_memfile(bContext *C, BKE_id_free(bfd->main, bfd->main->screens.first); } - setup_app_data(C, bfd, "<memory1>", params->is_startup, reports); + setup_app_blend_file_data(C, bfd, "<memory1>", params, reports); + BLO_blendfiledata_free(bfd); } else { BKE_reports_prepend(reports, "Loading failed: "); @@ -566,6 +587,63 @@ bool BKE_blendfile_userdef_write_app_template(const char *filepath, ReportList * return ok; } +bool BKE_blendfile_userdef_write_all(ReportList *reports) +{ + char filepath[FILE_MAX]; + const char *cfgdir; + bool ok = true; + const bool use_template_userpref = BKE_appdir_app_template_has_userpref(U.app_template); + + if ((cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL))) { + bool ok_write; + BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE, NULL); + + printf("Writing userprefs: '%s' ", filepath); + if (use_template_userpref) { + ok_write = BKE_blendfile_userdef_write_app_template(filepath, reports); + } + else { + ok_write = BKE_blendfile_userdef_write(filepath, reports); + } + + if (ok_write) { + printf("ok\n"); + } + else { + printf("fail\n"); + ok = false; + } + } + else { + BKE_report(reports, RPT_ERROR, "Unable to create userpref path"); + } + + if (use_template_userpref) { + if ((cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, U.app_template))) { + /* Also save app-template prefs */ + BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE, NULL); + + printf("Writing userprefs app-template: '%s' ", filepath); + if (BKE_blendfile_userdef_write(filepath, reports) != 0) { + printf("ok\n"); + } + else { + printf("fail\n"); + ok = false; + } + } + else { + BKE_report(reports, RPT_ERROR, "Unable to create app-template userpref path"); + ok = false; + } + } + + if (ok) { + U.runtime.is_dirty = false; + } + return ok; +} + WorkspaceConfigFileData *BKE_blendfile_workspace_config_read(const char *filepath, const void *filebuf, int filelength, diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c index 6f0c1891b05..fa7af53df2d 100644 --- a/source/blender/blenkernel/intern/bpath.c +++ b/source/blender/blenkernel/intern/bpath.c @@ -450,7 +450,10 @@ void BKE_bpath_traverse_id( Image *ima; ima = (Image *)id; if (BKE_image_has_packedfile(ima) == false || (flag & BKE_BPATH_TRAVERSE_SKIP_PACKED) == 0) { - if (ELEM(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { + /* Skip empty file paths, these are typically from generated images and + * don't make sense to add directories to until the image has been saved + * once to give it a meaningful value. */ + if (ELEM(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE) && ima->name[0]) { if (rewrite_path_fixed(ima->name, visit_cb, absbase, bpath_user_data)) { if (flag & BKE_BPATH_TRAVERSE_RELOAD_EDITED) { if (!BKE_image_has_packedfile(ima) && diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index e28f1fc566f..78d965564e6 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -501,9 +501,46 @@ void BKE_brush_gpencil_presets(bContext *C) brush->gpencil_settings->gradient_s[0] = 1.0f; brush->gpencil_settings->gradient_s[1] = 1.0f; + /* Soft brush */ + brush = BKE_brush_add_gpencil(bmain, ts, "Draw Soft"); + deft = brush; /* save default brush */ + brush->size = 300.0f; + brush->gpencil_settings->flag |= (GP_BRUSH_USE_PRESSURE | GP_BRUSH_ENABLE_CURSOR); + brush->gpencil_settings->draw_sensitivity = 1.0f; + + brush->gpencil_settings->draw_strength = 0.4f; + brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE; + + brush->gpencil_settings->draw_random_press = 0.0f; + brush->gpencil_settings->draw_random_strength = 0.0f; + + brush->gpencil_settings->draw_jitter = 0.0f; + brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE; + + brush->gpencil_settings->draw_angle = 0.0f; + brush->gpencil_settings->draw_angle_factor = 0.0f; + + brush->gpencil_settings->input_samples = 10; + brush->gpencil_settings->active_smooth = 0.98f; + brush->gpencil_settings->draw_smoothfac = 0.1f; + brush->gpencil_settings->draw_smoothlvl = 1; + brush->gpencil_settings->draw_subdivide = 1; + brush->gpencil_settings->thick_smoothfac = 1.0f; + brush->gpencil_settings->thick_smoothlvl = 3; + brush->gpencil_settings->draw_random_sub = 0.0f; + brush->gpencil_settings->icon_id = GP_BRUSH_ICON_MARKER; + brush->gpencil_tool = GPAINT_TOOL_DRAW; + + brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS; + brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR; + + brush->gpencil_settings->gradient_f = 0.211f; + brush->gpencil_settings->gradient_s[0] = 1.0f; + brush->gpencil_settings->gradient_s[1] = 0.91f; + /* Fill brush */ brush = BKE_brush_add_gpencil(bmain, ts, "Fill Area"); - brush->size = 1.0f; + brush->size = 20.0f; brush->gpencil_settings->flag |= GP_BRUSH_ENABLE_CURSOR; brush->gpencil_settings->draw_sensitivity = 1.0f; brush->gpencil_settings->fill_leak = 3; diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index 25399d342e1..a8f38c3c4ce 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -66,8 +66,9 @@ void BKE_camera_init(Camera *cam) cam->flag |= CAM_SHOWPASSEPARTOUT; cam->passepartalpha = 0.5f; - cam->gpu_dof.fstop = 128.0f; - cam->gpu_dof.ratio = 1.0f; + cam->dof.aperture_fstop = 2.8f; + cam->dof.aperture_ratio = 1.0f; + cam->dof.focus_distance = 10.0f; /* stereoscopy 3d */ cam->stereo.interocular_distance = 0.065f; @@ -134,13 +135,13 @@ float BKE_camera_object_dof_distance(Object *ob) if (ob->type != OB_CAMERA) { return 0.0f; } - if (cam->dof_ob) { + if (cam->dof.focus_object) { float view_dir[3], dof_dir[3]; normalize_v3_v3(view_dir, ob->obmat[2]); - sub_v3_v3v3(dof_dir, ob->obmat[3], cam->dof_ob->obmat[3]); + sub_v3_v3v3(dof_dir, ob->obmat[3], cam->dof.focus_object->obmat[3]); return fabsf(dot_v3v3(view_dir, dof_dir)); } - return cam->dof_distance; + return cam->dof.focus_distance; } float BKE_camera_sensor_size(int sensor_fit, float sensor_x, float sensor_y) @@ -1016,18 +1017,6 @@ void BKE_camera_multiview_params(RenderData *rd, } } -void BKE_camera_to_gpu_dof(struct Object *camera, struct GPUFXSettings *r_fx_settings) -{ - if (camera->type == OB_CAMERA) { - Camera *cam = camera->data; - r_fx_settings->dof = &cam->gpu_dof; - r_fx_settings->dof->focal_length = cam->lens; - r_fx_settings->dof->sensor = BKE_camera_sensor_size( - cam->sensor_fit, cam->sensor_x, cam->sensor_y); - r_fx_settings->dof->focus_distance = BKE_camera_object_dof_distance(camera); - } -} - CameraBGImage *BKE_camera_background_image_new(Camera *cam) { CameraBGImage *bgpic = MEM_callocN(sizeof(CameraBGImage), "Background Image"); diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index d33d4e344b5..d2ca304e973 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -321,11 +321,11 @@ Collection *BKE_collection_copy(Main *bmain, Collection *parent, Collection *col * \warning If any 'deep copy' behavior is enabled, * this functions will clear all \a bmain id.idnew pointers. * - * \param do_hierarchy If true, it will recursively make shallow copies of children collections. - * \param do_objects If true, it will also make duplicates of objects. - * This one does nothing if \a do_hierarchy is not set. - * \param do_obdata If true, it will also make deep duplicates of objects, - * using behavior defined in user settings (U.dupflag). + * \param do_hierarchy: If true, it will recursively make shallow copies of children collections. + * \param do_objects: If true, it will also make duplicates of objects. + * This one does nothing if \a do_hierarchy is not set. + * \param do_obdata: If true, it will also make deep duplicates of objects, + * using behavior defined in user settings (#U.dupflag). * This one does nothing if \a do_hierarchy and \a do_objects are not set. */ Collection *BKE_collection_duplicate(Main *bmain, @@ -434,8 +434,8 @@ static void collection_object_cache_fill(ListBase *lb, Collection *collection, i int object_restrict = base->object->restrictflag; - if (((child_restrict & COLLECTION_RESTRICT_VIEW) == 0) && - ((object_restrict & OB_RESTRICT_VIEW) == 0)) { + if (((child_restrict & COLLECTION_RESTRICT_VIEWPORT) == 0) && + ((object_restrict & OB_RESTRICT_VIEWPORT) == 0)) { base->flag |= BASE_ENABLED_VIEWPORT; } @@ -705,18 +705,27 @@ bool BKE_collection_object_add(Main *bmain, Collection *collection, Object *ob) } /** - * Add object to all scene collections that reference objects is in - * (used to copy objects) + * Add object to all scene collections that reference object is in + * (used to copy objects). */ void BKE_collection_object_add_from(Main *bmain, Scene *scene, Object *ob_src, Object *ob_dst) { + bool is_instantiated = false; + FOREACH_SCENE_COLLECTION_BEGIN (scene, collection) { - if (BKE_collection_has_object(collection, ob_src)) { + if (!ID_IS_LINKED(collection) && BKE_collection_has_object(collection, ob_src)) { collection_object_add(bmain, collection, ob_dst, 0, true); + is_instantiated = true; } } FOREACH_SCENE_COLLECTION_END; + if (!is_instantiated) { + /* In case we could not find any non-linked collections in which instantiate our ob_dst, + * fallback to scene's master collection... */ + collection_object_add(bmain, BKE_collection_master(scene), ob_dst, 0, true); + } + BKE_main_collection_sync(bmain); } @@ -966,6 +975,11 @@ static bool collection_find_child_recursive(Collection *parent, Collection *coll return false; } +bool BKE_collection_has_collection(Collection *parent, Collection *collection) +{ + return collection_find_child_recursive(parent, collection); +} + static CollectionParent *collection_find_parent(Collection *child, Collection *collection) { return BLI_findptr(&child->parents, collection, offsetof(CollectionParent, collection)); diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 0e29f165992..04789adea2f 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1882,6 +1882,7 @@ static void sizelike_new_data(void *cdata) bSizeLikeConstraint *data = (bSizeLikeConstraint *)cdata; data->flag = SIZELIKE_X | SIZELIKE_Y | SIZELIKE_Z | SIZELIKE_MULTIPLY; + data->power = 1.0f; } static void sizelike_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata) @@ -1929,6 +1930,10 @@ static void sizelike_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *ta mat4_to_size(size, ct->matrix); mat4_to_size(obsize, cob->matrix); + for (int i = 0; i < 3; i++) { + size[i] = powf(size[i], data->power); + } + if (data->flag & SIZELIKE_OFFSET) { /* Scale is a multiplicative quantity, so adding it makes no sense. * However, the additive mode has to stay for backward compatibility. */ @@ -2037,7 +2042,7 @@ static void samevolume_new_data(void *cdata) { bSameVolumeConstraint *data = (bSameVolumeConstraint *)cdata; - data->flag = SAMEVOL_Y; + data->free_axis = SAMEVOL_Y; data->volume = 1.0f; } @@ -2046,19 +2051,30 @@ static void samevolume_evaluate(bConstraint *con, bConstraintOb *cob, ListBase * bSameVolumeConstraint *data = con->data; float volume = data->volume; - float fac = 1.0f, total_scale; + float fac = 1.0f, total_scale = 1.0f; float obsize[3]; mat4_to_size(obsize, cob->matrix); /* calculate normalizing scale factor for non-essential values */ - total_scale = obsize[0] * obsize[1] * obsize[2]; + switch (data->mode) { + case SAMEVOL_STRICT: + total_scale = obsize[0] * obsize[1] * obsize[2]; + break; + case SAMEVOL_UNIFORM: + total_scale = pow3f(obsize[data->free_axis]); + break; + case SAMEVOL_SINGLE_AXIS: + total_scale = obsize[data->free_axis]; + break; + } + if (total_scale != 0) { fac = sqrtf(volume / total_scale); } /* apply scaling factor to the channels not being kept */ - switch (data->flag) { + switch (data->free_axis) { case SAMEVOL_X: mul_v3_fl(cob->matrix[1], fac); mul_v3_fl(cob->matrix[2], fac); @@ -2097,7 +2113,6 @@ static void pycon_free(bConstraint *con) /* id-properties */ IDP_FreeProperty(data->prop); - MEM_freeN(data->prop); /* multiple targets */ BLI_freelistN(&data->targets); @@ -2406,7 +2421,8 @@ static void armdef_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targ copy_v3_v3(input_co, cob->matrix[3]); } - /* Process all targets. */ + /* Process all targets. This can't use ct->matrix, as armdef_get_tarmat is not + * called in solve for efficiency because the constraint needs bone data anyway. */ for (bConstraintTarget *ct = targets->first; ct; ct = ct->next) { if (ct->weight <= 0.0f) { continue; @@ -4224,6 +4240,7 @@ static void splineik_new_data(void *cdata) data->bulge_min = 1.0f; data->yScaleMode = CONSTRAINT_SPLINEIK_YS_FIT_CURVE; + data->flag = CONSTRAINT_SPLINEIK_USE_ORIGINAL_SCALE; } static void splineik_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata) @@ -5600,6 +5617,11 @@ void BKE_constraint_targets_for_solving_get(struct Depsgraph *depsgraph, */ cti->get_constraint_targets(con, targets); + /* The Armature constraint doesn't need ct->matrix for evaluate at all. */ + if (ELEM(cti->type, CONSTRAINT_TYPE_ARMATURE)) { + return; + } + /* set matrices * - calculate if possible, otherwise just initialize as identity matrix */ diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 4383b6a1f9b..9d753319cfa 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -399,6 +399,41 @@ static int ctx_data_collection_get(const bContext *C, const char *member, ListBa return 0; } +static int ctx_data_base_collection_get(const bContext *C, const char *member, ListBase *list) +{ + ListBase ctx_object_list; + bool ok = false; + + if (!ctx_data_collection_get(C, member, &ctx_object_list)) { + return 0; + } + + if (BLI_listbase_is_empty(&ctx_object_list)) { + return 0; + } + + bContextDataResult result; + memset(&result, 0, sizeof(bContextDataResult)); + + Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + + CollectionPointerLink *ctx_object; + for (ctx_object = ctx_object_list.first; ctx_object; ctx_object = ctx_object->next) { + Object *ob = ctx_object->ptr.data; + Base *base = BKE_view_layer_base_find(view_layer, ob); + if (base != NULL) { + CTX_data_list_add(&result, &scene->id, &RNA_ObjectBase, base); + ok = true; + } + } + CTX_data_type_set(&result, CTX_DATA_TYPE_COLLECTION); + BLI_freelistN(&ctx_object_list); + + *list = result.list; + return ok; +} + PointerRNA CTX_data_pointer_get(const bContext *C, const char *member) { bContextDataResult result; @@ -1150,7 +1185,7 @@ int CTX_data_selected_editable_objects(const bContext *C, ListBase *list) int CTX_data_selected_editable_bases(const bContext *C, ListBase *list) { - return ctx_data_collection_get(C, "selected_editable_bases", list); + return ctx_data_base_collection_get(C, "selected_editable_objects", list); } int CTX_data_editable_objects(const bContext *C, ListBase *list) @@ -1160,7 +1195,7 @@ int CTX_data_editable_objects(const bContext *C, ListBase *list) int CTX_data_editable_bases(const bContext *C, ListBase *list) { - return ctx_data_collection_get(C, "editable_bases", list); + return ctx_data_base_collection_get(C, "editable_objects", list); } int CTX_data_selected_objects(const bContext *C, ListBase *list) @@ -1170,7 +1205,7 @@ int CTX_data_selected_objects(const bContext *C, ListBase *list) int CTX_data_selected_bases(const bContext *C, ListBase *list) { - return ctx_data_collection_get(C, "selected_bases", list); + return ctx_data_base_collection_get(C, "selected_objects", list); } int CTX_data_visible_objects(const bContext *C, ListBase *list) @@ -1180,7 +1215,7 @@ int CTX_data_visible_objects(const bContext *C, ListBase *list) int CTX_data_visible_bases(const bContext *C, ListBase *list) { - return ctx_data_collection_get(C, "visible_bases", list); + return ctx_data_base_collection_get(C, "visible_objects", list); } int CTX_data_selectable_objects(const bContext *C, ListBase *list) @@ -1190,7 +1225,7 @@ int CTX_data_selectable_objects(const bContext *C, ListBase *list) int CTX_data_selectable_bases(const bContext *C, ListBase *list) { - return ctx_data_collection_get(C, "selectable_bases", list); + return ctx_data_base_collection_get(C, "selectable_objects", list); } struct Object *CTX_data_active_object(const bContext *C) @@ -1200,7 +1235,14 @@ struct Object *CTX_data_active_object(const bContext *C) struct Base *CTX_data_active_base(const bContext *C) { - return ctx_data_pointer_get(C, "active_base"); + Object *ob = ctx_data_pointer_get(C, "active_object"); + + if (ob == NULL) { + return NULL; + } + + ViewLayer *view_layer = CTX_data_view_layer(C); + return BKE_view_layer_base_find(view_layer, ob); } struct Object *CTX_data_edit_object(const bContext *C) @@ -1312,7 +1354,21 @@ Depsgraph *CTX_data_depsgraph(const bContext *C) { Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - return BKE_scene_get_depsgraph(scene, view_layer, true); + Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true); + /* Dependency graph might have been just allocated, and hence it will not be marked. + * This confuses redo system due to the lack of flushing changes back to the original data. + * In the future we would need to check whether the CTX_wm_window(C) is in editing mode (as an + * opposite of playback-preview-only) and set active flag based on that. */ + DEG_make_active(depsgraph); + return depsgraph; +} + +Depsgraph *CTX_data_evaluated_depsgraph(const bContext *C) +{ + Depsgraph *depsgraph = CTX_data_depsgraph(C); + Main *bmain = CTX_data_main(C); + BKE_scene_graph_update_tagged(depsgraph, bmain); + return depsgraph; } Depsgraph *CTX_data_depsgraph_on_load(const bContext *C) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index dc677449a4c..5945fa4bf33 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1737,241 +1737,9 @@ static void forward_diff_bezier_cotangent(const float p0[3], } } -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -float *BKE_curve_surf_make_orco(Object *ob) -{ - /* Note: this function is used in convertblender only atm, so - * suppose nonzero curve's render resolution should always be used */ - Curve *cu = ob->data; - Nurb *nu; - int a, b, tot = 0; - int sizeu, sizev; - int resolu, resolv; - float *fp, *coord_array; - - /* first calculate the size of the datablock */ - nu = cu->nurb.first; - while (nu) { - /* as we want to avoid the seam in a cyclic nurbs - * texture wrapping, reserve extra orco data space to save these extra needed - * vertex based UV coordinates for the meridian vertices. - * Vertices on the 0/2pi boundary are not duplicated inside the displist but later in - * the renderface/vert construction. - * - * See also convertblender.c: init_render_surf() - */ - - resolu = cu->resolu_ren ? cu->resolu_ren : nu->resolu; - resolv = cu->resolv_ren ? cu->resolv_ren : nu->resolv; - - sizeu = nu->pntsu * resolu; - sizev = nu->pntsv * resolv; - if (nu->flagu & CU_NURB_CYCLIC) { - sizeu++; - } - if (nu->flagv & CU_NURB_CYCLIC) { - sizev++; - } - if (nu->pntsv > 1) { - tot += sizeu * sizev; - } - - nu = nu->next; - } - /* makeNurbfaces wants zeros */ - fp = coord_array = MEM_calloc_arrayN(tot, 3 * sizeof(float), "make_orco"); - - nu = cu->nurb.first; - while (nu) { - resolu = cu->resolu_ren ? cu->resolu_ren : nu->resolu; - resolv = cu->resolv_ren ? cu->resolv_ren : nu->resolv; - - if (nu->pntsv > 1) { - sizeu = nu->pntsu * resolu; - sizev = nu->pntsv * resolv; - - if (nu->flagu & CU_NURB_CYCLIC) { - sizeu++; - } - if (nu->flagv & CU_NURB_CYCLIC) { - sizev++; - } - - if (cu->flag & CU_UV_ORCO) { - for (b = 0; b < sizeu; b++) { - for (a = 0; a < sizev; a++) { - - if (sizev < 2) { - fp[0] = 0.0f; - } - else { - fp[0] = -1.0f + 2.0f * ((float)a) / (sizev - 1); - } - - if (sizeu < 2) { - fp[1] = 0.0f; - } - else { - fp[1] = -1.0f + 2.0f * ((float)b) / (sizeu - 1); - } - - fp[2] = 0.0; - - fp += 3; - } - } - } - else { - int size = (nu->pntsu * resolu) * (nu->pntsv * resolv) * 3 * sizeof(float); - float *_tdata = MEM_mallocN(size, "temp data"); - float *tdata = _tdata; - - BKE_nurb_makeFaces(nu, tdata, 0, resolu, resolv); - - for (b = 0; b < sizeu; b++) { - int use_b = b; - if (b == sizeu - 1 && (nu->flagu & CU_NURB_CYCLIC)) { - use_b = false; - } - - for (a = 0; a < sizev; a++) { - int use_a = a; - if (a == sizev - 1 && (nu->flagv & CU_NURB_CYCLIC)) { - use_a = false; - } - - tdata = _tdata + 3 * (use_b * (nu->pntsv * resolv) + use_a); - - fp[0] = (tdata[0] - cu->loc[0]) / cu->size[0]; - fp[1] = (tdata[1] - cu->loc[1]) / cu->size[1]; - fp[2] = (tdata[2] - cu->loc[2]) / cu->size[2]; - fp += 3; - } - } - - MEM_freeN(_tdata); - } - } - nu = nu->next; - } - - return coord_array; -} - -/* NOTE: This routine is tied to the order of vertex - * built by displist and as passed to the renderer. - */ -float *BKE_curve_make_orco(Depsgraph *depsgraph, Scene *scene, Object *ob, int *r_numVerts) -{ - Curve *cu = ob->data; - DispList *dl; - int u, v, numVerts; - float *fp, *coord_array; - ListBase disp = {NULL, NULL}; - - BKE_displist_make_curveTypes_forOrco(depsgraph, scene, ob, &disp, NULL); - - numVerts = 0; - for (dl = disp.first; dl; dl = dl->next) { - if (dl->type == DL_INDEX3) { - numVerts += dl->nr; - } - else if (dl->type == DL_SURF) { - /* convertblender.c uses the Surface code for creating renderfaces when cyclic U only - * (closed circle beveling) - */ - if (dl->flag & DL_CYCL_U) { - if (dl->flag & DL_CYCL_V) { - numVerts += (dl->parts + 1) * (dl->nr + 1); - } - else { - numVerts += dl->parts * (dl->nr + 1); - } - } - else if (dl->flag & DL_CYCL_V) { - numVerts += (dl->parts + 1) * dl->nr; - } - else { - numVerts += dl->parts * dl->nr; - } - } - } - - if (r_numVerts) { - *r_numVerts = numVerts; - } - - fp = coord_array = MEM_malloc_arrayN(numVerts, 3 * sizeof(float), "cu_orco"); - for (dl = disp.first; dl; dl = dl->next) { - if (dl->type == DL_INDEX3) { - for (u = 0; u < dl->nr; u++, fp += 3) { - if (cu->flag & CU_UV_ORCO) { - fp[0] = 2.0f * u / (dl->nr - 1) - 1.0f; - fp[1] = 0.0; - fp[2] = 0.0; - } - else { - copy_v3_v3(fp, &dl->verts[u * 3]); - - fp[0] = (fp[0] - cu->loc[0]) / cu->size[0]; - fp[1] = (fp[1] - cu->loc[1]) / cu->size[1]; - fp[2] = (fp[2] - cu->loc[2]) / cu->size[2]; - } - } - } - else if (dl->type == DL_SURF) { - int sizeu = dl->nr, sizev = dl->parts; - - /* exception as handled in convertblender.c too */ - if (dl->flag & DL_CYCL_U) { - sizeu++; - if (dl->flag & DL_CYCL_V) { - sizev++; - } - } - else if (dl->flag & DL_CYCL_V) { - sizev++; - } - - for (u = 0; u < sizev; u++) { - for (v = 0; v < sizeu; v++, fp += 3) { - if (cu->flag & CU_UV_ORCO) { - fp[0] = 2.0f * u / (sizev - 1) - 1.0f; - fp[1] = 2.0f * v / (sizeu - 1) - 1.0f; - fp[2] = 0.0; - } - else { - const float *vert; - int realv = v % dl->nr; - int realu = u % dl->parts; - - vert = dl->verts + 3 * (dl->nr * realu + realv); - copy_v3_v3(fp, vert); - - fp[0] = (fp[0] - cu->loc[0]) / cu->size[0]; - fp[1] = (fp[1] - cu->loc[1]) / cu->size[1]; - fp[2] = (fp[2] - cu->loc[2]) / cu->size[2]; - } - } - } - } - } - - BKE_displist_free(&disp); - - return coord_array; -} - /* ***************** BEVEL ****************** */ -void BKE_curve_bevel_make(Depsgraph *depsgraph, - Scene *scene, - Object *ob, - ListBase *disp, - const bool for_render, - const bool use_render_resolution, - LinkNode *ob_cyclic_list) +void BKE_curve_bevel_make(Object *ob, ListBase *disp) { DispList *dl, *dlnew; Curve *bevcu, *cu; @@ -1995,26 +1763,7 @@ void BKE_curve_bevel_make(Depsgraph *depsgraph, facx = cu->bevobj->scale[0]; facy = cu->bevobj->scale[1]; - if (for_render) { - if (BLI_linklist_index(ob_cyclic_list, cu->bevobj) == -1) { - BKE_displist_make_curveTypes_forRender(depsgraph, - scene, - cu->bevobj, - &bevdisp, - NULL, - false, - use_render_resolution, - &(LinkNode){ - .link = ob, - .next = ob_cyclic_list, - }); - dl = bevdisp.first; - } - else { - dl = NULL; - } - } - else if (cu->bevobj->runtime.curve_cache) { + if (cu->bevobj->runtime.curve_cache) { dl = cu->bevobj->runtime.curve_cache->disp.first; } else { @@ -4980,7 +4729,7 @@ void BKE_curve_nurbs_keyVertexTilts_apply(ListBase *lb, float *key) } } -bool BKE_nurb_check_valid_u(struct Nurb *nu) +bool BKE_nurb_check_valid_u(const Nurb *nu) { if (nu->pntsu <= 1) { return false; @@ -5007,7 +4756,7 @@ bool BKE_nurb_check_valid_u(struct Nurb *nu) } return true; } -bool BKE_nurb_check_valid_v(struct Nurb *nu) +bool BKE_nurb_check_valid_v(const Nurb *nu) { if (nu->pntsv <= 1) { return false; @@ -5035,7 +4784,7 @@ bool BKE_nurb_check_valid_v(struct Nurb *nu) return true; } -bool BKE_nurb_check_valid_uv(struct Nurb *nu) +bool BKE_nurb_check_valid_uv(const Nurb *nu) { if (!BKE_nurb_check_valid_u(nu)) { return false; diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c index 5d9ba1bcdc7..98c6d519d17 100644 --- a/source/blender/blenkernel/intern/data_transfer.c +++ b/source/blender/blenkernel/intern/data_transfer.c @@ -585,7 +585,7 @@ static bool data_transfer_layersmapping_cdlayers_multisrc_to_dst(ListBase *r_map /* Find last source actually used! */ while (idx_src-- && !use_layers_src[idx_src]) { - ; + /* pass */ } idx_src++; diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index e83e9560b02..a964cab3fa5 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -1124,7 +1124,7 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map, /* Find last source actually used! */ idx_src = num_layers_src; while (idx_src-- && !use_layers_src[idx_src]) { - ; + /* pass */ } idx_src++; diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index c228595b6e8..c8d6f7ae313 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -315,8 +315,7 @@ bool BKE_displist_surfindex_get(DispList *dl, int a, int *b, int *p1, int *p2, i static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, - const bool for_render, - const bool use_render_resolution) + const bool for_render) { Nurb *nu; DispList *dl; @@ -329,7 +328,7 @@ static void curve_to_displist(Curve *cu, nu = nubase->first; while (nu) { if (nu->hide == 0 || editmode == false) { - if (use_render_resolution && cu->resolu_ren != 0) { + if (for_render && cu->resolu_ren != 0) { resolu = cu->resolu_ren; } else { @@ -724,7 +723,7 @@ static float displist_calc_taper(Depsgraph *depsgraph, Scene *scene, Object *tap dl = taperobj->runtime.curve_cache ? taperobj->runtime.curve_cache->disp.first : NULL; if (dl == NULL) { - BKE_displist_make_curveTypes(depsgraph, scene, taperobj, false, false, NULL); + BKE_displist_make_curveTypes(depsgraph, scene, taperobj, false, false); dl = taperobj->runtime.curve_cache->disp.first; } if (dl) { @@ -801,7 +800,7 @@ void BKE_displist_make_mball_forRender(Depsgraph *depsgraph, static ModifierData *curve_get_tessellate_point(Scene *scene, Object *ob, - const bool use_render_resolution, + const bool for_render, const bool editmode) { VirtualModifierData virtualModifierData; @@ -809,7 +808,7 @@ static ModifierData *curve_get_tessellate_point(Scene *scene, ModifierData *pretessellatePoint; int required_mode; - if (use_render_resolution) { + if (for_render) { required_mode = eModifierMode_Render; } else { @@ -848,12 +847,8 @@ static ModifierData *curve_get_tessellate_point(Scene *scene, return pretessellatePoint; } -static void curve_calc_modifiers_pre(Depsgraph *depsgraph, - Scene *scene, - Object *ob, - ListBase *nurb, - const bool for_render, - const bool use_render_resolution) +static void curve_calc_modifiers_pre( + Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *nurb, const bool for_render) { VirtualModifierData virtualModifierData; ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData); @@ -871,7 +866,7 @@ static void curve_calc_modifiers_pre(Depsgraph *depsgraph, if (editmode) { app_flag |= MOD_APPLY_USECACHE; } - if (use_render_resolution) { + if (for_render) { app_flag |= MOD_APPLY_RENDER; required_mode = eModifierMode_Render; } @@ -881,7 +876,7 @@ static void curve_calc_modifiers_pre(Depsgraph *depsgraph, const ModifierEvalContext mectx = {depsgraph, ob, app_flag}; - pretessellatePoint = curve_get_tessellate_point(scene, ob, use_render_resolution, editmode); + pretessellatePoint = curve_get_tessellate_point(scene, ob, for_render, editmode); if (editmode) { required_mode |= eModifierMode_Editmode; @@ -979,8 +974,7 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph, ListBase *nurb, ListBase *dispbase, Mesh **r_final, - const bool for_render, - const bool use_render_resolution) + const bool for_render) { VirtualModifierData virtualModifierData; ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData); @@ -993,7 +987,7 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph, int useCache = !for_render; ModifierApplyFlag app_flag = 0; - if (use_render_resolution) { + if (for_render) { app_flag |= MOD_APPLY_RENDER; required_mode = eModifierMode_Render; } @@ -1006,7 +1000,7 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph, const ModifierEvalContext mectx_apply = { depsgraph, ob, useCache ? app_flag | MOD_APPLY_USECACHE : app_flag}; - pretessellatePoint = curve_get_tessellate_point(scene, ob, use_render_resolution, editmode); + pretessellatePoint = curve_get_tessellate_point(scene, ob, for_render, editmode); if (editmode) { required_mode |= eModifierMode_Editmode; @@ -1199,144 +1193,13 @@ static void displist_surf_indices(DispList *dl) } } -/* XXX2.8(Sybren): unused function; impossible to test after porting to Mesh */ -#ifdef WITH_DERIVEDMESH_DEPRECATED_FUNCS -static DerivedMesh *create_orco_dm(Depsgraph *depsgraph, Scene *scene, Object *ob) -{ - DerivedMesh *dm; - ListBase disp = {NULL, NULL}; - - /* OrcoDM should be created from underformed disp lists */ - BKE_displist_make_curveTypes_forOrco(depsgraph, scene, ob, &disp); - dm = CDDM_from_curve_displist(ob, &disp); - - BKE_displist_free(&disp); - - return dm; -} - -static void add_orco_dm(Object *ob, DerivedMesh *dm, DerivedMesh *orcodm) -{ - float(*orco)[3], (*layerorco)[3]; - int totvert, a; - Curve *cu = ob->data; - - totvert = dm->getNumVerts(dm); - - orco = MEM_callocN(sizeof(float) * 3 * totvert, "dm orco"); - - if (orcodm->getNumVerts(orcodm) == totvert) { - orcodm->getVertCos(orcodm, orco); - } - else { - dm->getVertCos(dm, orco); - } - - for (a = 0; a < totvert; a++) { - float *co = orco[a]; - co[0] = (co[0] - cu->loc[0]) / cu->size[0]; - co[1] = (co[1] - cu->loc[1]) / cu->size[1]; - co[2] = (co[2] - cu->loc[2]) / cu->size[2]; - } - - if ((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) { - memcpy(layerorco, orco, sizeof(float) * totvert); - MEM_freeN(orco); - } - else { - DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco); - } -} -#endif - -/* XXX2.8(Sybren): unused function; impossible to test after porting to Mesh */ -#ifdef WITH_DERIVEDMESH_DEPRECATED_FUNCS -static void curve_calc_orcodm(Depsgraph *depsgraph, - Scene *scene, - Object *ob, - DerivedMesh *dm_final, - const bool for_render, - const bool use_render_resolution) -{ - /* this function represents logic of mesh's orcodm calculation - * for displist-based objects - */ - VirtualModifierData virtualModifierData; - ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData); - ModifierData *pretessellatePoint; - Curve *cu = ob->data; - int required_mode; - const bool editmode = (!for_render && (cu->editnurb || cu->editfont)); - DerivedMesh *ndm, *orcodm = NULL; - ModifierApplyFlag app_flag = MOD_APPLY_ORCO; - - if (use_render_resolution) { - app_flag |= MOD_APPLY_RENDER; - required_mode = eModifierMode_Render; - } - else { - required_mode = eModifierMode_Realtime; - } - - const ModifierEvalContext mectx = {depsgraph, ob, app_flag}; - - pretessellatePoint = curve_get_tessellate_point(scene, ob, use_render_resolution, editmode); - - if (editmode) { - required_mode |= eModifierMode_Editmode; - } - - if (pretessellatePoint) { - md = pretessellatePoint->next; - } - - /* If modifiers are disabled, we wouldn't be here because - * this function is only called if there're enabled constructive - * modifiers applied on the curve. - * - * This means we can create ORCO DM in advance and assume it's - * never NULL. - */ - orcodm = create_orco_dm(depsgraph, scene, ob); - - for (; md; md = md->next) { - const ModifierTypeInfo *mti = modifierType_getInfo(md->type); - - md->scene = scene; - - if (!modifier_isEnabled(scene, md, required_mode)) { - continue; - } - if (mti->type != eModifierTypeType_Constructive) { - continue; - } - - ndm = modwrap_applyModifier(md, &mectx, orcodm); - - if (ndm) { - /* if the modifier returned a new dm, release the old one */ - if (orcodm && orcodm != ndm) { - orcodm->release(orcodm); - } - orcodm = ndm; - } - } - - /* add an orco layer if needed */ - add_orco_dm(ob, dm_final, orcodm); - - orcodm->release(orcodm); -} -#endif - void BKE_displist_make_surf(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *dispbase, Mesh **r_final, const bool for_render, - const bool for_orco, - const bool use_render_resolution) + const bool for_orco) { ListBase nubase = {NULL, NULL}; Nurb *nu; @@ -1353,14 +1216,14 @@ void BKE_displist_make_surf(Depsgraph *depsgraph, } if (!for_orco) { - curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render, use_render_resolution); + curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render); } for (nu = nubase.first; nu; nu = nu->next) { if ((for_render || nu->hide == 0) && BKE_nurb_check_valid_uv(nu)) { int resolu = nu->resolu, resolv = nu->resolv; - if (use_render_resolution) { + if (for_render) { if (cu->resolu_ren) { resolu = cu->resolu_ren; } @@ -1431,8 +1294,7 @@ void BKE_displist_make_surf(Depsgraph *depsgraph, if (!for_orco) { BKE_nurbList_duplicate(&ob->runtime.curve_cache->deformed_nurbs, &nubase); - curve_calc_modifiers_post( - depsgraph, scene, ob, &nubase, dispbase, r_final, for_render, use_render_resolution); + curve_calc_modifiers_post(depsgraph, scene, ob, &nubase, dispbase, r_final, for_render); } BKE_nurbList_free(&nubase); @@ -1665,8 +1527,6 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph, ListBase *dispbase, const bool for_render, const bool for_orco, - const bool use_render_resolution, - LinkNode *ob_cyclic_list, Mesh **r_final) { Curve *cu = ob->data; @@ -1677,8 +1537,7 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph, } if (ob->type == OB_SURF) { - BKE_displist_make_surf( - depsgraph, scene, ob, dispbase, r_final, for_render, for_orco, use_render_resolution); + BKE_displist_make_surf(depsgraph, scene, ob, dispbase, r_final, for_render, for_orco); } else if (ELEM(ob->type, OB_CURVE, OB_FONT)) { ListBase dlbev; @@ -1705,18 +1564,17 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph, } if (!for_orco) { - curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render, use_render_resolution); + curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render); } - BKE_curve_bevelList_make(ob, &nubase, use_render_resolution); + BKE_curve_bevelList_make(ob, &nubase, for_render); /* If curve has no bevel will return nothing */ - BKE_curve_bevel_make( - depsgraph, scene, ob, &dlbev, for_render, use_render_resolution, ob_cyclic_list); + BKE_curve_bevel_make(ob, &dlbev); /* no bevel or extrude, and no width correction? */ if (!dlbev.first && cu->width == 1.0f) { - curve_to_displist(cu, &nubase, dispbase, for_render, use_render_resolution); + curve_to_displist(cu, &nubase, dispbase, for_render); } else { float widfac = cu->width - 1.0f; @@ -1916,8 +1774,7 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph, if (!for_orco) { BKE_nurbList_duplicate(&ob->runtime.curve_cache->deformed_nurbs, &nubase); - curve_calc_modifiers_post( - depsgraph, scene, ob, &nubase, dispbase, r_final, for_render, use_render_resolution); + curve_calc_modifiers_post(depsgraph, scene, ob, &nubase, dispbase, r_final, for_render); } if (cu->flag & CU_DEFORM_FILL && !ob->runtime.mesh_eval) { @@ -1928,12 +1785,8 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph, } } -void BKE_displist_make_curveTypes(Depsgraph *depsgraph, - Scene *scene, - Object *ob, - const bool for_render, - const bool for_orco, - LinkNode *ob_cyclic_list) +void BKE_displist_make_curveTypes( + Depsgraph *depsgraph, Scene *scene, Object *ob, const bool for_render, const bool for_orco) { ListBase *dispbase; @@ -1952,15 +1805,8 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph, dispbase = &(ob->runtime.curve_cache->disp); - do_makeDispListCurveTypes(depsgraph, - scene, - ob, - dispbase, - for_render, - for_orco, - false, - ob_cyclic_list, - &ob->runtime.mesh_eval); + do_makeDispListCurveTypes( + depsgraph, scene, ob, dispbase, for_render, for_orco, &ob->runtime.mesh_eval); boundbox_displist_object(ob); } @@ -1970,33 +1816,13 @@ void BKE_displist_make_curveTypes_forRender(Depsgraph *depsgraph, Object *ob, ListBase *dispbase, Mesh **r_final, - const bool for_orco, - const bool use_render_resolution, - LinkNode *ob_cyclic_list) -{ - if (ob->runtime.curve_cache == NULL) { - ob->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve"); - } - - do_makeDispListCurveTypes(depsgraph, - scene, - ob, - dispbase, - true, - for_orco, - use_render_resolution, - ob_cyclic_list, - r_final); -} - -void BKE_displist_make_curveTypes_forOrco( - Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *dispbase, LinkNode *ob_cyclic_list) + const bool for_orco) { if (ob->runtime.curve_cache == NULL) { ob->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve"); } - do_makeDispListCurveTypes(depsgraph, scene, ob, dispbase, 1, 1, 1, ob_cyclic_list, NULL); + do_makeDispListCurveTypes(depsgraph, scene, ob, dispbase, true, for_orco, r_final); } void BKE_displist_minmax(ListBase *dispbase, float min[3], float max[3]) diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 0ee32af336d..b5242d00ee0 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -2066,7 +2066,7 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * } if (update_normals) { - // result->dirty |= DM_DIRTY_NORMALS; + result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; } } /* make a copy of mesh to use as brush data */ @@ -5393,7 +5393,7 @@ static void dynamic_paint_effect_drip_cb(void *__restrict userdata, const uint8_t epointlock_bitmask = 1 << (n_trgt & 7); /* 7 == 0b111 */ while (atomic_fetch_and_or_uint8(&point_locks[epointlock_idx], epointlock_bitmask) & epointlock_bitmask) { - ; + /* pass */ } PaintPoint *ePoint = &((PaintPoint *)sData->type_data)[n_trgt]; @@ -5440,7 +5440,7 @@ static void dynamic_paint_effect_drip_cb(void *__restrict userdata, const uint8_t ppointlock_bitmask = 1 << (index & 7); /* 7 == 0b111 */ while (atomic_fetch_and_or_uint8(&point_locks[ppointlock_idx], ppointlock_bitmask) & ppointlock_bitmask) { - ; + /* pass */ } pPoint->wetness -= ppoint_wetness_diff; diff --git a/source/blender/blenkernel/intern/editmesh.c b/source/blender/blenkernel/intern/editmesh.c index 130f4ae88f1..b8234ccc5bb 100644 --- a/source/blender/blenkernel/intern/editmesh.c +++ b/source/blender/blenkernel/intern/editmesh.c @@ -248,3 +248,13 @@ void BKE_editmesh_lnorspace_update(BMEditMesh *em) BM_lnorspace_update(bm); } + +/* If autosmooth not already set, set it */ +void BKE_editmesh_ensure_autosmooth(BMEditMesh *em) +{ + Mesh *me = em->ob->data; + if (!(me->flag & ME_AUTOSMOOTH)) { + me->flag |= ME_AUTOSMOOTH; + BKE_editmesh_lnorspace_update(em); + } +} diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 51715c3a223..7cbd5b6b050 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -172,7 +172,7 @@ static void precalculate_effector(struct Depsgraph *depsgraph, EffectorCache *ef if (cu->flag & CU_PATH) { if (eff->ob->runtime.curve_cache == NULL || eff->ob->runtime.curve_cache->path == NULL || eff->ob->runtime.curve_cache->path->data == NULL) { - BKE_displist_make_curveTypes(depsgraph, eff->scene, eff->ob, false, false, NULL); + BKE_displist_make_curveTypes(depsgraph, eff->scene, eff->ob, false, false); } if (eff->ob->runtime.curve_cache->path && eff->ob->runtime.curve_cache->path->data) { diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 8c95e4c7ff3..3bca77c5b51 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -1707,6 +1707,11 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar) /* not valid channel */ return 0.0f; } + else if (dtar->transChan == DTAR_TRANSCHAN_SCALE_AVG) { + /* Cubic root of the change in volume, equal to the geometric mean + * of scale over all three axes unless the matrix includes shear. */ + return cbrtf(mat4_to_volume_scale(mat)); + } else if (dtar->transChan >= DTAR_TRANSCHAN_SCALEX) { /* Extract scale, and choose the right axis, * inline 'mat4_to_size'. */ @@ -3065,14 +3070,20 @@ float evaluate_fcurve_driver(PathResolvedRNA *anim_rna, return evaluate_fcurve_ex(fcu, evaltime, cvalue); } +/* Checks if the curve has valid keys, drivers or modifiers that produce an actual curve. */ +bool BKE_fcurve_is_empty(FCurve *fcu) +{ + return (fcu->totvert == 0) && (fcu->driver == NULL) && + !list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE); +} + /* Calculate the value of the given F-Curve at the given frame, and set its curval */ float calculate_fcurve(PathResolvedRNA *anim_rna, FCurve *fcu, float evaltime) { /* only calculate + set curval (overriding the existing value) if curve has * any data which warrants this... */ - if ((fcu->totvert) || (fcu->driver && !(fcu->driver->flag & DRIVER_FLAG_INVALID)) || - list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE)) { + if (!BKE_fcurve_is_empty(fcu)) { /* calculate and set curval (evaluates driver too if necessary) */ float curval; if (fcu->driver) { diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index c6188642e41..794d07203af 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -867,7 +867,6 @@ static void fcm_python_free(FModifier *fcm) /* id-properties */ IDP_FreeProperty(data->prop); - MEM_freeN(data->prop); } static void fcm_python_new_data(void *mdata) diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index c82b2c377fa..439005ca1b4 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -1109,7 +1109,8 @@ Material *BKE_gpencil_object_material_new(Main *bmain, Object *ob, const char *n /* Returns the material for a brush with respect to its pinned state. */ Material *BKE_gpencil_object_material_get_from_brush(Object *ob, Brush *brush) { - if ((brush) && (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED)) { + if ((brush) && (brush->gpencil_settings) && + (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED)) { Material *ma = BKE_gpencil_brush_material_get(brush); return ma; } diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index 39e72d7e3a8..016da52252a 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -121,7 +121,7 @@ static void IDP_FreeIDPArray(IDProperty *prop, const bool do_id_user) BLI_assert(prop->type == IDP_IDPARRAY); for (i = 0; i < prop->len; i++) { - IDP_FreeProperty_ex(GETPROP(prop, i), do_id_user); + IDP_FreePropertyContent_ex(GETPROP(prop, i), do_id_user); } if (prop->data.pointer) { @@ -142,7 +142,7 @@ void IDP_SetIndexArray(IDProperty *prop, int index, IDProperty *item) old = GETPROP(prop, index); if (item != old) { - IDP_FreeProperty(old); + IDP_FreePropertyContent(old); memcpy(old, item, sizeof(IDProperty)); } @@ -175,7 +175,7 @@ void IDP_ResizeIDPArray(IDProperty *prop, int newlen) int i; for (i = newlen; i < prop->len; i++) { - IDP_FreeProperty(GETPROP(prop, i)); + IDP_FreePropertyContent(GETPROP(prop, i)); } prop->len = newlen; @@ -192,7 +192,7 @@ void IDP_ResizeIDPArray(IDProperty *prop, int newlen) /* newlen is smaller */ int i; for (i = newlen; i < prop->len; i++) { - IDP_FreeProperty(GETPROP(prop, i)); + IDP_FreePropertyContent(GETPROP(prop, i)); } } @@ -236,7 +236,6 @@ static void idp_resize_group_array(IDProperty *prop, int newlen, void *newarr) for (a = newlen; a < prop->len; a++) { IDP_FreeProperty(array[a]); - MEM_freeN(array[a]); } } } @@ -513,7 +512,6 @@ void IDP_SyncGroupValues(IDProperty *dest, const IDProperty *src) default: { BLI_insertlinkreplace(&dest->data.group, other, IDP_CopyProperty(prop)); IDP_FreeProperty(other); - MEM_freeN(other); break; } } @@ -535,7 +533,6 @@ void IDP_SyncGroupTypes(IDProperty *dst, const IDProperty *src, const bool do_ar (prop_src->len != prop_dst->len))) { BLI_insertlinkreplace(&dst->data.group, prop_dst, IDP_CopyProperty(prop_src)); IDP_FreeProperty(prop_dst); - MEM_freeN(prop_dst); } else if (prop_dst->type == IDP_GROUP) { IDP_SyncGroupTypes(prop_dst, prop_src, do_arraylen); @@ -562,7 +559,6 @@ void IDP_ReplaceGroupInGroup(IDProperty *dest, const IDProperty *src) if (STREQ(loop->name, prop->name)) { BLI_insertlinkreplace(&dest->data.group, loop, IDP_CopyProperty(prop)); IDP_FreeProperty(loop); - MEM_freeN(loop); break; } } @@ -588,7 +584,6 @@ void IDP_ReplaceInGroup_ex(IDProperty *group, IDProperty *prop, IDProperty *prop if (prop_exist != NULL) { BLI_insertlinkreplace(&group->data.group, prop_exist, prop); IDP_FreeProperty(prop_exist); - MEM_freeN(prop_exist); } else { group->len++; @@ -668,12 +663,6 @@ void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overw * (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 - * to free an ID property, you first call #IDP_FreeProperty then #MEM_freeN the struct. - * In the future this will just be #IDP_FreeProperty and the code will - * be reorganized to work properly. */ bool IDP_AddToGroup(IDProperty *group, IDProperty *prop) { @@ -709,8 +698,7 @@ bool IDP_InsertToGroup(IDProperty *group, IDProperty *previous, IDProperty *pnew * \note this does not free the property!! * * To free the property, you have to do: - * IDP_FreeProperty(prop); //free all subdata - * MEM_freeN(prop); //free property struct itself + * IDP_FreeProperty(prop); */ void IDP_RemoveFromGroup(IDProperty *group, IDProperty *prop) { @@ -727,7 +715,6 @@ void IDP_FreeFromGroup(IDProperty *group, IDProperty *prop) { IDP_RemoveFromGroup(group, prop); IDP_FreeProperty(prop); - MEM_freeN(prop); } IDProperty *IDP_GetPropertyFromGroup(IDProperty *prop, const char *name) @@ -753,7 +740,7 @@ static void IDP_FreeGroup(IDProperty *prop, const bool do_id_user) BLI_assert(prop->type == IDP_GROUP); for (loop = prop->data.group.first; loop; loop = loop->next) { - IDP_FreeProperty_ex(loop, do_id_user); + IDP_FreePropertyContent_ex(loop, do_id_user); } BLI_freelistN(&prop->data.group); } @@ -1070,7 +1057,7 @@ IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char * * \note This will free allocated data, all child properties of arrays and groups, and unlink IDs! * But it does not free the actual IDProperty struct itself. */ -void IDP_FreeProperty_ex(IDProperty *prop, const bool do_id_user) +void IDP_FreePropertyContent_ex(IDProperty *prop, const bool do_id_user) { switch (prop->type) { case IDP_ARRAY: @@ -1093,14 +1080,20 @@ void IDP_FreeProperty_ex(IDProperty *prop, const bool do_id_user) } } +void IDP_FreePropertyContent(IDProperty *prop) +{ + IDP_FreePropertyContent_ex(prop, true); +} + void IDP_FreeProperty(IDProperty *prop) { - IDP_FreeProperty_ex(prop, true); + IDP_FreePropertyContent(prop); + MEM_freeN(prop); } void IDP_ClearProperty(IDProperty *prop) { - IDP_FreeProperty(prop); + IDP_FreePropertyContent(prop); prop->data.pointer = NULL; prop->len = prop->totallen = 0; } diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index f23c58befdf..9960994400f 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -470,7 +470,7 @@ bool BKE_image_scale(Image *image, int width, int height) if (ibuf) { IMB_scaleImBuf(ibuf, width, height); - ibuf->userflags |= IB_BITMAPDIRTY; + BKE_image_mark_dirty(image, ibuf); } BKE_image_release_ibuf(image, ibuf, lock); @@ -502,6 +502,12 @@ static void image_init_color_management(Image *ima) if (ibuf->flags & IB_alphamode_premul) { ima->alpha_mode = IMA_ALPHA_PREMUL; } + else if (ibuf->flags & IB_alphamode_channel_packed) { + ima->alpha_mode = IMA_ALPHA_CHANNEL_PACKED; + } + else if (ibuf->flags & IB_alphamode_ignore) { + ima->alpha_mode = IMA_ALPHA_IGNORE; + } else { ima->alpha_mode = IMA_ALPHA_STRAIGHT; } @@ -646,7 +652,6 @@ static ImBuf *add_ibuf_size(unsigned int width, } STRNCPY(ibuf->name, name); - ibuf->userflags |= IB_BITMAPDIRTY; switch (gen_type) { case IMA_GENTYPE_GRID: @@ -3593,16 +3598,18 @@ static void image_initialize_after_load(Image *ima, ImBuf *UNUSED(ibuf)) static int imbuf_alpha_flags_for_image(Image *ima) { - int flag = 0; - - if (ima->flag & IMA_IGNORE_ALPHA) { - flag |= IB_ignore_alpha; - } - else if (ima->alpha_mode == IMA_ALPHA_PREMUL) { - flag |= IB_alphamode_premul; + switch (ima->alpha_mode) { + case IMA_ALPHA_STRAIGHT: + return 0; + case IMA_ALPHA_PREMUL: + return IB_alphamode_premul; + case IMA_ALPHA_CHANNEL_PACKED: + return IB_alphamode_channel_packed; + case IMA_ALPHA_IGNORE: + return IB_alphamode_ignore; } - return flag; + return 0; } /* the number of files will vary according to the stereo format */ @@ -5081,12 +5088,20 @@ bool BKE_image_has_packedfile(Image *ima) return (BLI_listbase_is_empty(&ima->packedfiles) == false); } +bool BKE_image_has_filepath(Image *ima) +{ + /* This could be improved to detect cases like //../../, currently path + * remapping empty file paths empty. */ + return ima->name[0] != '\0'; +} + /* Checks the image buffer changes with time (not keyframed values). */ bool BKE_image_is_animated(Image *image) { return ELEM(image->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE); } +/* Image modifications */ bool BKE_image_is_dirty(Image *image) { bool is_dirty = false; @@ -5110,6 +5125,11 @@ bool BKE_image_is_dirty(Image *image) return is_dirty; } +void BKE_image_mark_dirty(Image *UNUSED(image), ImBuf *ibuf) +{ + ibuf->userflags |= IB_BITMAPDIRTY; +} + void BKE_image_file_format_set(Image *image, int ftype, const ImbFormatOptions *options) { BLI_spin_lock(&image_spin); diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c index fc349e62809..60c00160e6d 100644 --- a/source/blender/blenkernel/intern/layer.c +++ b/source/blender/blenkernel/intern/layer.c @@ -235,7 +235,6 @@ void BKE_view_layer_free_ex(ViewLayer *view_layer, const bool do_id_user) if (view_layer->id_properties) { IDP_FreeProperty(view_layer->id_properties); - MEM_freeN(view_layer->id_properties); } MEM_SAFE_FREE(view_layer->object_bases_array); @@ -693,8 +692,8 @@ static short layer_collection_sync(ViewLayer *view_layer, lc->runtime_flag = child_runtime_flag; } - if (((child_restrict & COLLECTION_RESTRICT_VIEW) == 0) && - ((child_layer_restrict & LAYER_COLLECTION_RESTRICT_VIEW) == 0)) { + if (((child_restrict & COLLECTION_RESTRICT_VIEWPORT) == 0) && + ((child_layer_restrict & LAYER_COLLECTION_HIDE) == 0)) { lc->runtime_flag |= LAYER_COLLECTION_VISIBLE; } @@ -723,9 +722,9 @@ static short layer_collection_sync(ViewLayer *view_layer, BLI_addtail(new_object_bases, base); } - if ((child_restrict & COLLECTION_RESTRICT_VIEW) == 0) { + if ((child_restrict & COLLECTION_RESTRICT_VIEWPORT) == 0) { base->flag_from_collection |= BASE_ENABLED_VIEWPORT; - if ((child_layer_restrict & LAYER_COLLECTION_RESTRICT_VIEW) == 0) { + if ((child_layer_restrict & LAYER_COLLECTION_HIDE) == 0) { base->flag_from_collection |= BASE_VISIBLE; if (((child_restrict & COLLECTION_RESTRICT_SELECT) == 0)) { base->flag_from_collection |= BASE_SELECTABLE; @@ -1014,8 +1013,8 @@ bool BKE_layer_collection_isolate(Scene *scene, bool hide_it = extend && (lc->runtime_flag & LAYER_COLLECTION_VISIBLE); if ((!ID_IS_LINKED(lc->collection) && !hide_it)) { - if (lc->collection->flag & COLLECTION_RESTRICT_VIEW) { - lc->collection->flag &= ~COLLECTION_RESTRICT_VIEW; + if (lc->collection->flag & COLLECTION_RESTRICT_VIEWPORT) { + lc->collection->flag &= ~COLLECTION_RESTRICT_VIEWPORT; depsgraph_need_update = true; } } @@ -1024,13 +1023,13 @@ bool BKE_layer_collection_isolate(Scene *scene, /* Hide all collections . */ for (LayerCollection *lc_iter = lc_master->layer_collections.first; lc_iter; lc_iter = lc_iter->next) { - layer_collection_flag_set_recursive(lc_iter, LAYER_COLLECTION_RESTRICT_VIEW); + layer_collection_flag_set_recursive(lc_iter, LAYER_COLLECTION_HIDE); } } /* Make all the direct parents visible. */ if (hide_it) { - lc->flag |= LAYER_COLLECTION_RESTRICT_VIEW; + lc->flag |= LAYER_COLLECTION_HIDE; } else { LayerCollection *lc_parent = lc; @@ -1044,13 +1043,13 @@ bool BKE_layer_collection_isolate(Scene *scene, while (lc_parent != lc) { if (!ID_IS_LINKED(lc_parent->collection)) { - if (lc_parent->collection->flag & COLLECTION_RESTRICT_VIEW) { - lc_parent->collection->flag &= ~COLLECTION_RESTRICT_VIEW; + if (lc_parent->collection->flag & COLLECTION_RESTRICT_VIEWPORT) { + lc_parent->collection->flag &= ~COLLECTION_RESTRICT_VIEWPORT; depsgraph_need_update = true; } } - lc_parent->flag &= ~LAYER_COLLECTION_RESTRICT_VIEW; + lc_parent->flag &= ~LAYER_COLLECTION_HIDE; for (LayerCollection *lc_iter = lc_parent->layer_collections.first; lc_iter; lc_iter = lc_iter->next) { @@ -1062,7 +1061,7 @@ bool BKE_layer_collection_isolate(Scene *scene, } /* Make all the children visible, but respect their disable state. */ - layer_collection_flag_unset_recursive(lc, LAYER_COLLECTION_RESTRICT_VIEW); + layer_collection_flag_unset_recursive(lc, LAYER_COLLECTION_HIDE); BKE_layer_collection_activate(view_layer, lc); } @@ -1109,27 +1108,27 @@ bool BKE_layer_collection_set_visible(ViewLayer *view_layer, bool depsgraph_changed = false; if (visible && (!ID_IS_LINKED(lc->collection)) && - ((lc->collection->flag & COLLECTION_RESTRICT_VIEW) != 0)) { - lc->collection->flag &= ~COLLECTION_RESTRICT_VIEW; + ((lc->collection->flag & COLLECTION_RESTRICT_VIEWPORT) != 0)) { + lc->collection->flag &= ~COLLECTION_RESTRICT_VIEWPORT; depsgraph_changed = true; } if (hierarchy) { if (visible) { - layer_collection_flag_unset_recursive(lc, LAYER_COLLECTION_RESTRICT_VIEW); + layer_collection_flag_unset_recursive(lc, LAYER_COLLECTION_HIDE); layer_collection_bases_show_recursive(view_layer, lc); } else { - layer_collection_flag_set_recursive(lc, LAYER_COLLECTION_RESTRICT_VIEW); + layer_collection_flag_set_recursive(lc, LAYER_COLLECTION_HIDE); layer_collection_bases_hide_recursive(view_layer, lc); } } else { if (visible) { - lc->flag &= ~LAYER_COLLECTION_RESTRICT_VIEW; + lc->flag &= ~LAYER_COLLECTION_HIDE; } else { - lc->flag |= LAYER_COLLECTION_RESTRICT_VIEW; + lc->flag |= LAYER_COLLECTION_HIDE; } } return depsgraph_changed; @@ -1491,7 +1490,7 @@ void BKE_base_eval_flags(Base *base) /* Apply object restrictions. */ const int object_restrict = base->object->restrictflag; - if (object_restrict & OB_RESTRICT_VIEW) { + if (object_restrict & OB_RESTRICT_VIEWPORT) { base->flag &= ~BASE_ENABLED_VIEWPORT; } if (object_restrict & OB_RESTRICT_RENDER) { diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index ad0c405ab28..8b08c189270 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -873,7 +873,7 @@ bool id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop) /* assign copy */ RNA_id_pointer_create(newid, &idptr); - RNA_property_pointer_set(ptr, prop, idptr); + RNA_property_pointer_set(ptr, prop, idptr, NULL); RNA_property_update(C, ptr, prop); /* tag grease pencil datablock and disable onion */ @@ -1860,7 +1860,7 @@ static void library_make_local_copying_check(ID *id, * (except group and objects ones). */ /* Note: Old (2.77) version was simply making (tagging) data-blocks as local, - * without actually making any check whether * they were also indirectly used or not... + * without actually making any check whether they were also indirectly used or not... * * Current version uses regular id_make_local callback, with advanced pre-processing step to detect * all cases of IDs currently indirectly used, but which will be used by local data only once this diff --git a/source/blender/blenkernel/intern/library_override.c b/source/blender/blenkernel/intern/library_override.c index 5ed6577e90a..231e0b8ee60 100644 --- a/source/blender/blenkernel/intern/library_override.c +++ b/source/blender/blenkernel/intern/library_override.c @@ -81,7 +81,7 @@ IDOverrideStatic *BKE_override_static_init(ID *local_id, ID *reference_id) for (ancestor_id = reference_id; ancestor_id != NULL && ancestor_id->override_static != NULL && ancestor_id->override_static->reference != NULL; ancestor_id = ancestor_id->override_static->reference) { - ; + /* pass */ } if (ancestor_id != NULL && ancestor_id->override_static != NULL) { diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c index d0515d8783d..a95069a2af9 100644 --- a/source/blender/blenkernel/intern/library_query.c +++ b/source/blender/blenkernel/intern/library_query.c @@ -755,7 +755,7 @@ static void library_foreach_ID_link(Main *bmain, case ID_CA: { Camera *camera = (Camera *)id; - CALLBACK_INVOKE(camera->dof_ob, IDWALK_CB_NOP); + CALLBACK_INVOKE(camera->dof.focus_object, IDWALK_CB_NOP); for (CameraBGImage *bgpic = camera->bg_images.first; bgpic; bgpic = bgpic->next) { if (bgpic->source == CAM_BGIMG_SOURCE_IMAGE) { CALLBACK_INVOKE(bgpic->ima, IDWALK_CB_USER); diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c index 3b6f11935d1..4e5eac7924b 100644 --- a/source/blender/blenkernel/intern/library_remap.c +++ b/source/blender/blenkernel/intern/library_remap.c @@ -740,7 +740,7 @@ void BKE_libblock_relink_to_newid(ID *id) void BKE_libblock_free_data(ID *id, const bool do_id_user) { if (id->properties) { - IDP_FreeProperty_ex(id->properties, do_id_user); + IDP_FreePropertyContent_ex(id->properties, do_id_user); MEM_freeN(id->properties); } diff --git a/source/blender/blenkernel/intern/light.c b/source/blender/blenkernel/intern/light.c index 05b2eb82daf..1c3acb6a73a 100644 --- a/source/blender/blenkernel/intern/light.c +++ b/source/blender/blenkernel/intern/light.c @@ -80,6 +80,7 @@ void BKE_light_init(Light *la) la->contact_thickness = 0.2f; la->spec_fac = 1.0f; la->att_dist = 40.0f; + la->sun_angle = DEG2RADF(0.526f); curvemapping_initialize(la->curfalloff); } diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 9a9b3757ef2..43fc8152c7b 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -225,6 +225,16 @@ MaskLayer *BKE_mask_layer_copy(const MaskLayer *masklay) MaskSpline *spline_new = BKE_mask_spline_copy(spline); BLI_addtail(&masklay_new->splines, spline_new); + + if (spline == masklay->act_spline) { + masklay_new->act_spline = spline_new; + } + + if (masklay->act_point >= spline->points && + masklay->act_point < spline->points + spline->tot_point) { + const size_t point_index = masklay->act_point - spline->points; + masklay_new->act_point = spline_new->points + point_index; + } } /* correct animation */ diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c index 3f4e504867c..461adc823b9 100644 --- a/source/blender/blenkernel/intern/mesh_convert.c +++ b/source/blender/blenkernel/intern/mesh_convert.c @@ -34,10 +34,13 @@ #include "BLI_math.h" #include "BLI_listbase.h" #include "BLI_edgehash.h" +#include "BLI_string.h" #include "BKE_main.h" #include "BKE_DerivedMesh.h" +#include "BKE_editmesh.h" #include "BKE_key.h" +#include "BKE_library_query.h" #include "BKE_mesh.h" #include "BKE_mesh_runtime.h" #include "BKE_modifier.h" @@ -612,7 +615,13 @@ void BKE_mesh_from_nurbs_displist(Main *bmain, } /* make mesh */ - me = BKE_mesh_add(bmain, obdata_name); + if (bmain != NULL) { + me = BKE_mesh_add(bmain, obdata_name); + } + else { + me = BKE_id_new_nomain(ID_ME, obdata_name); + } + me->totvert = totvert; me->totedge = totedge; me->totloop = totloop; @@ -632,7 +641,13 @@ void BKE_mesh_from_nurbs_displist(Main *bmain, BKE_mesh_calc_normals(me); } else { - me = BKE_mesh_add(bmain, obdata_name); + if (bmain != NULL) { + me = BKE_mesh_add(bmain, obdata_name); + } + else { + me = BKE_id_new_nomain(ID_ME, obdata_name); + } + ob->runtime.mesh_eval = NULL; BKE_mesh_nomain_to_mesh(me_eval, me, ob, &CD_MASK_MESH, true); } @@ -662,16 +677,18 @@ void BKE_mesh_from_nurbs_displist(Main *bmain, ob->type = OB_MESH; /* other users */ - ob1 = bmain->objects.first; - while (ob1) { - if (ob1->data == cu) { - ob1->type = OB_MESH; - - id_us_min((ID *)ob1->data); - ob1->data = ob->data; - id_us_plus((ID *)ob1->data); + if (bmain != NULL) { + ob1 = bmain->objects.first; + while (ob1) { + if (ob1->data == cu) { + ob1->type = OB_MESH; + + id_us_min((ID *)ob1->data); + ob1->data = ob->data; + id_us_plus((ID *)ob1->data); + } + ob1 = ob1->id.next; } - ob1 = ob1->id.next; } if (temporary) { @@ -892,302 +909,280 @@ void BKE_mesh_to_curve(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(scene), } } -/* settings: 1 - preview, 2 - render - * - * The convention goes as following: - * - * - Passing original object with apply_modifiers=false will give a - * non-modified non-deformed mesh. - * The result mesh will point to datablocks from the original "domain". For - * example, materials will be original. - * - * - Passing original object with apply_modifiers=true will give a mesh which - * has all modifiers applied. - * The result mesh will point to datablocks from the original "domain". For - * example, materials will be original. +/* Create a temporary object to be used for nurbs-to-mesh conversion. * - * - Passing evaluated object will ignore apply_modifiers argument, and the - * result always contains all modifiers applied. - * The result mesh will point to an evaluated datablocks. For example, - * materials will be an evaluated IDs from the dependency graph. - */ -Mesh *BKE_mesh_new_from_object(Depsgraph *depsgraph, - Main *bmain, - Scene *sce, - Object *ob, - const bool apply_modifiers, - const bool calc_undeformed) + * This is more complex that it should be because BKE_mesh_from_nurbs_displist() will do more than + * simply conversion and will attempt to take over ownership of evaluated result and will also + * modify the input object. */ +static Object *object_for_curve_to_mesh_create(Object *object) { - Mesh *tmpmesh; - Curve *tmpcu = NULL, *copycu; - int i; - const bool render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER); - bool effective_apply_modifiers = apply_modifiers; - bool do_mat_id_data_us = true; - - Object *object_input = ob; - Object *object_eval = DEG_get_evaluated_object(depsgraph, object_input); - Object object_for_eval; - - if (object_eval == object_input) { - /* Evaluated mesh contains all modifiers applied already. - * The other types of object has them applied, but are stored in other - * data structures than a mesh. So need to apply modifiers again on a - * temporary copy before converting result to mesh. */ - if (object_input->type == OB_MESH) { - effective_apply_modifiers = false; - } - else { - effective_apply_modifiers = true; - } - object_for_eval = *object_eval; + Curve *curve = (Curve *)object->data; + + /* Create object itself. */ + Object *temp_object; + BKE_id_copy_ex(NULL, &object->id, (ID **)&temp_object, LIB_ID_COPY_LOCALIZE); + + /* Remove all modifiers, since we don't want them to be applied. */ + BKE_object_free_modifiers(temp_object, LIB_ID_CREATE_NO_USER_REFCOUNT); + + /* Copy relevant evaluated fields of curve cache. + * + * Note that there are extra fields in there like bevel and path, but those are not needed during + * conversion, so they are not copied to save unnecessary allocations. */ + if (object->runtime.curve_cache != NULL) { + temp_object->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), + "CurveCache for curve types"); + BKE_displist_copy(&temp_object->runtime.curve_cache->disp, &object->runtime.curve_cache->disp); } - else { - if (apply_modifiers) { - object_for_eval = *object_eval; - if (object_for_eval.runtime.mesh_orig != NULL) { - object_for_eval.data = object_for_eval.runtime.mesh_orig; - } - } - else { - object_for_eval = *object_input; - } + /* Constructive modifiers will use mesh to store result. */ + if (object->runtime.mesh_eval != NULL) { + BKE_id_copy_ex(NULL, + &object->runtime.mesh_eval->id, + (ID **)&temp_object->runtime.mesh_eval, + LIB_ID_COPY_LOCALIZE); } - const bool cage = !effective_apply_modifiers; + /* Need to create copy of curve itself as well, it will be freed by underlying conversion + * functions. + * + * NOTE: Copies the data, but not the shapekeys. */ + BKE_id_copy_ex(NULL, object->data, (ID **)&temp_object->data, LIB_ID_COPY_LOCALIZE); + Curve *temp_curve = (Curve *)temp_object->data; - /* perform the mesh extraction based on type */ - switch (object_for_eval.type) { - case OB_FONT: - case OB_CURVE: - case OB_SURF: { - ListBase dispbase = {NULL, NULL}; - Mesh *me_eval_final = NULL; - int uv_from_orco; - - /* copies object and modifiers (but not the data) */ - Object *tmpobj; - BKE_id_copy_ex(NULL, &object_for_eval.id, (ID **)&tmpobj, LIB_ID_COPY_LOCALIZE); - tmpcu = (Curve *)tmpobj->data; - - /* Copy cached display list, it might be needed by the stack evaluation. - * Ideally stack should be able to use render-time display list, but doing - * so is quite tricky and not safe so close to the release. - * - * TODO(sergey): Look into more proper solution. - */ - if (object_for_eval.runtime.curve_cache != NULL) { - if (tmpobj->runtime.curve_cache == NULL) { - tmpobj->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), - "CurveCache for curve types"); - } - BKE_displist_copy(&tmpobj->runtime.curve_cache->disp, - &object_for_eval.runtime.curve_cache->disp); - } + /* Make sure texture space is calculated for a copy of curve, it will be used for the final + * result. */ + BKE_curve_texspace_calc(temp_curve); - /* if getting the original caged mesh, delete object modifiers */ - if (cage) { - BKE_object_free_modifiers(tmpobj, LIB_ID_CREATE_NO_USER_REFCOUNT); - } + /* Temporarily set edit so we get updates from edit mode, but also because for text datablocks + * copying it while in edit mode gives invalid data structures. */ + temp_curve->editfont = curve->editfont; + temp_curve->editnurb = curve->editnurb; - /* copies the data, but *not* the shapekeys. */ - BKE_id_copy_ex(NULL, object_for_eval.data, (ID **)©cu, LIB_ID_COPY_LOCALIZE); - tmpobj->data = copycu; - - /* make sure texture space is calculated for a copy of curve, - * it will be used for the final result. - */ - BKE_curve_texspace_calc(copycu); - - /* temporarily set edit so we get updates from edit mode, but - * also because for text datablocks copying it while in edit - * mode gives invalid data structures */ - copycu->editfont = tmpcu->editfont; - copycu->editnurb = tmpcu->editnurb; - - /* get updated display list, and convert to a mesh */ - BKE_displist_make_curveTypes_forRender( - depsgraph, sce, tmpobj, &dispbase, &me_eval_final, false, render, NULL); - - copycu->editfont = NULL; - copycu->editnurb = NULL; - - tmpobj->runtime.mesh_eval = me_eval_final; - - /* convert object type to mesh */ - uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0; - BKE_mesh_from_nurbs_displist( - bmain, tmpobj, &dispbase, uv_from_orco, tmpcu->id.name + 2, true); - /* Function above also frees copycu (aka tmpobj->data), make this obvious here. */ - copycu = NULL; - - tmpmesh = tmpobj->data; - id_us_min( - &tmpmesh->id); /* Gets one user from its creation in BKE_mesh_from_nurbs_displist(). */ - - BKE_displist_free(&dispbase); - - /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked. - * if it didn't the curve did not have any segments or otherwise - * would have generated an empty mesh */ - if (tmpobj->type != OB_MESH) { - BKE_id_free(NULL, tmpobj); - return NULL; - } + return temp_object; +} - BKE_id_free(NULL, tmpobj); +static void curve_to_mesh_eval_ensure(Object *object) +{ + if (object->runtime.curve_cache == NULL) { + object->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve"); + } + Curve *curve = (Curve *)object->data; + Curve remapped_curve = *curve; + Object remapped_object = *object; + remapped_object.data = &remapped_curve; - /* XXX The curve to mesh conversion is convoluted... - * But essentially, BKE_mesh_from_nurbs_displist() - * already transfers the ownership of materials from the temp copy of the Curve ID to the - * new Mesh ID, so we do not want to increase materials' usercount later. */ - do_mat_id_data_us = false; + /* Clear all modifiers for the bevel object. + * + * This is because they can not be reliably evaluated for an original object (at least because + * the state of dependencies is not know). + * + * So we create temporary copy of the object which will use same data as the original bevel, but + * will have no modifiers. */ + Object bevel_object = {NULL}; + if (remapped_curve.bevobj != NULL) { + bevel_object = *remapped_curve.bevobj; + BLI_listbase_clear(&bevel_object.modifiers); + remapped_curve.bevobj = &bevel_object; + } - break; - } + /* Same thing for taper. */ + Object taper_object = {NULL}; + if (remapped_curve.taperobj != NULL) { + taper_object = *remapped_curve.taperobj; + BLI_listbase_clear(&taper_object.modifiers); + remapped_curve.taperobj = &taper_object; + } - case OB_MBALL: { - /* metaballs don't have modifiers, so just convert to mesh */ - Object *basis_ob = BKE_mball_basis_find(sce, object_input); - /* todo, re-generatre for render-res */ - /* metaball_polygonize(scene, ob) */ + /* NOTE: We don't have dependency graph or scene here, so we pass NULL. This is all fine since + * they are only used for modifier stack, which we have explicitly disabled for all objects. + * + * TODO(sergey): This is a very fragile logic, but proper solution requires re-writing quite a + * bit of internal functions (BKE_mesh_from_nurbs_displist, BKE_mesh_nomain_to_mesh) and also + * Mesh From Curve operator. + * Brecht says hold off with that. */ + BKE_displist_make_curveTypes_forRender(NULL, + NULL, + &remapped_object, + &remapped_object.runtime.curve_cache->disp, + &remapped_object.runtime.mesh_eval, + false); + + BKE_object_free_curve_cache(&bevel_object); + BKE_object_free_curve_cache(&taper_object); +} - if (basis_ob != object_input) { - /* Only do basis metaball. */ - return NULL; - } +static Mesh *mesh_new_from_curve_type_object(Object *object) +{ + Curve *curve = object->data; + const bool uv_from_orco = (curve->flag & CU_UV_ORCO) != 0; - tmpmesh = BKE_mesh_add(bmain, ((ID *)object_for_eval.data)->name + 2); - /* BKE_mesh_add gives us a user count we don't need */ - id_us_min(&tmpmesh->id); + Object *temp_object = object_for_curve_to_mesh_create(object); + Curve *temp_curve = (Curve *)temp_object->data; - if (render) { - ListBase disp = {NULL, NULL}; - BKE_displist_make_mball_forRender(depsgraph, sce, &object_for_eval, &disp); - BKE_mesh_from_metaball(&disp, tmpmesh); - BKE_displist_free(&disp); - } - else { - ListBase disp = {NULL, NULL}; - if (object_for_eval.runtime.curve_cache) { - disp = object_for_eval.runtime.curve_cache->disp; - } - BKE_mesh_from_metaball(&disp, tmpmesh); - } + /* When input object is an original one, we don't have evaluated curve cache yet, so need to + * create it in the temporary object. */ + if (!DEG_is_evaluated_object(object)) { + curve_to_mesh_eval_ensure(temp_object); + } - BKE_mesh_texspace_copy_from_object(tmpmesh, &object_for_eval); + /* Reset pointers before conversion. */ + temp_curve->editfont = NULL; + temp_curve->editnurb = NULL; + + /* Convert to mesh. */ + BKE_mesh_from_nurbs_displist(NULL, + temp_object, + &temp_object->runtime.curve_cache->disp, + uv_from_orco, + curve->id.name + 2, + true); + + /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked. If it didn't the curve did + * not have any segments or otherwise would have generated an empty mesh. */ + if (temp_object->type != OB_MESH) { + BKE_id_free(NULL, temp_object); + return NULL; + } - break; - } - case OB_MESH: - /* copies object and modifiers (but not the data) */ - if (cage) { - /* copies the data (but *not* the shapekeys). */ - Mesh *mesh = object_for_eval.data; - BKE_id_copy_ex(bmain, &mesh->id, (ID **)&tmpmesh, 0); - /* XXX BKE_mesh_copy() already handles materials usercount. */ - do_mat_id_data_us = false; - } - /* if not getting the original caged mesh, get final derived mesh */ - else { - /* Make a dummy mesh, saves copying */ - Mesh *me_eval; - CustomData_MeshMasks mask = CD_MASK_MESH; /* this seems more suitable, exporter, - * for example, needs CD_MASK_MDEFORMVERT */ + Mesh *mesh_result = temp_object->data; - if (calc_undeformed) { - mask.vmask |= CD_MASK_ORCO; - } + BKE_id_free(NULL, temp_object); - if (render) { - me_eval = mesh_create_eval_final_render(depsgraph, sce, &object_for_eval, &mask); - } - else { - me_eval = mesh_create_eval_final_view(depsgraph, sce, &object_for_eval, &mask); - } + /* NOTE: Materials are copied in BKE_mesh_from_nurbs_displist(). */ - tmpmesh = BKE_mesh_add(bmain, ((ID *)object_for_eval.data)->name + 2); - BKE_mesh_nomain_to_mesh(me_eval, tmpmesh, &object_for_eval, &mask, true); + return mesh_result; +} - /* Copy autosmooth settings from original mesh. */ - Mesh *me = (Mesh *)object_for_eval.data; - tmpmesh->flag |= (me->flag & ME_AUTOSMOOTH); - tmpmesh->smoothresh = me->smoothresh; - } +static Mesh *mesh_new_from_mball_object(Object *object) +{ + MetaBall *mball = (MetaBall *)object->data; - /* BKE_mesh_add/copy gives us a user count we don't need */ - id_us_min(&tmpmesh->id); + /* NOTE: We can only create mesh for a polygonized meta ball. This figures out all original meta + * balls and all evaluated child meta balls (since polygonization is only stored in the mother + * ball). + * + * We create empty mesh so scripters don't run into None objects. */ + if (!DEG_is_evaluated_object(object) || object->runtime.curve_cache == NULL || + BLI_listbase_is_empty(&object->runtime.curve_cache->disp)) { + return BKE_id_new_nomain(ID_ME, ((ID *)object->data)->name + 2); + } - break; - default: - /* "Object does not have geometry data") */ - return NULL; + Mesh *mesh_result = BKE_id_new_nomain(ID_ME, ((ID *)object->data)->name + 2); + BKE_mesh_from_metaball(&object->runtime.curve_cache->disp, mesh_result); + + /* Copy materials. */ + mesh_result->totcol = mball->totcol; + mesh_result->mat = MEM_dupallocN(mball->mat); + if (mball->mat != NULL) { + for (int i = mball->totcol; i-- > 0;) { + mesh_result->mat[i] = give_current_material(object, i + 1); + } } - /* Copy materials to new mesh */ - switch (object_for_eval.type) { - case OB_SURF: - case OB_FONT: - case OB_CURVE: - tmpmesh->totcol = tmpcu->totcol; + return mesh_result; +} - /* free old material list (if it exists) and adjust user counts */ - if (tmpcu->mat) { - for (i = tmpcu->totcol; i-- > 0;) { - /* are we an object material or data based? */ - tmpmesh->mat[i] = give_current_material(object_input, i + 1); +static Mesh *mesh_new_from_mesh_object(Object *object) +{ + Mesh *mesh_input = object->data; + /* If we are in edit mode, use evaluated mesh from edit structure, matching to what + * viewport is using for visualization. */ + if (mesh_input->edit_mesh != NULL && mesh_input->edit_mesh->mesh_eval_final) { + mesh_input = mesh_input->edit_mesh->mesh_eval_final; + } + Mesh *mesh_result = NULL; + BKE_id_copy_ex(NULL, + &mesh_input->id, + (ID **)&mesh_result, + LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT); + /* NOTE: Materials should already be copied. */ + /* Copy original mesh name. This is because edit meshes might not have one properly set name. */ + BLI_strncpy(mesh_result->id.name, ((ID *)object->data)->name, sizeof(mesh_result->id.name)); + return mesh_result; +} - if (((object_for_eval.matbits && object_for_eval.matbits[i]) || do_mat_id_data_us) && - tmpmesh->mat[i]) { - id_us_plus(&tmpmesh->mat[i]->id); - } - } - } +Mesh *BKE_mesh_new_from_object(Object *object) +{ + Mesh *new_mesh = NULL; + switch (object->type) { + case OB_FONT: + case OB_CURVE: + case OB_SURF: + new_mesh = mesh_new_from_curve_type_object(object); + break; + case OB_MBALL: + new_mesh = mesh_new_from_mball_object(object); break; + case OB_MESH: + new_mesh = mesh_new_from_mesh_object(object); + break; + default: + /* Object does not have geometry data. */ + return NULL; + } + if (new_mesh == NULL) { + /* Happens in special cases like request of mesh for non-mother meta ball. */ + return NULL; + } + /* The result must have 0 users, since it's just a mesh which is free-dangling data-block. + * All the conversion functions are supposed to ensure mesh is not counted. */ + BLI_assert(new_mesh->id.us == 0); + return new_mesh; +} - case OB_MBALL: { - MetaBall *tmpmb = (MetaBall *)object_for_eval.data; - tmpmesh->mat = MEM_dupallocN(tmpmb->mat); - tmpmesh->totcol = tmpmb->totcol; +static int foreach_libblock_make_original_and_usercount_callback(void *user_data_v, + ID *id_self, + ID **id_p, + int cb_flag) +{ + UNUSED_VARS(user_data_v, id_self, cb_flag); + if (*id_p == NULL) { + return IDWALK_RET_NOP; + } + *id_p = DEG_get_original_id(*id_p); + id_us_plus(*id_p); + return IDWALK_RET_NOP; +} - /* free old material list (if it exists) and adjust user counts */ - if (tmpmb->mat) { - for (i = tmpmb->totcol; i-- > 0;) { - /* are we an object material or data based? */ - tmpmesh->mat[i] = give_current_material(object_input, i + 1); +Mesh *BKE_mesh_new_from_object_to_bmain(Main *bmain, Object *object) +{ + Mesh *mesh = BKE_mesh_new_from_object(object); - if (((object_for_eval.matbits && object_for_eval.matbits[i]) || do_mat_id_data_us) && - tmpmesh->mat[i]) { - id_us_plus(&tmpmesh->mat[i]->id); - } - } - } - break; - } + /* Make sure mesh only points original datablocks, also increase users of materials and other + * possibly referenced data-blocks. + * + * Going to original data-blocks is required to have bmain in a consistent state, where + * everything is only allowed to reference original data-blocks. + * + * user-count is required is because so far mesh was in a limbo, where library management does + * not perform any user management (i.e. copy of a mesh will not increase users of materials). */ + BKE_library_foreach_ID_link( + NULL, &mesh->id, foreach_libblock_make_original_and_usercount_callback, NULL, IDWALK_NOP); + + /* Append the mesh to bmain. + * We do it a bit longer way since there is no simple and clear way of adding existing datablock + * to the bmain. So we allocate new empty mesh in the bmain (which guarantess all the naming and + * orders and flags) and move the temporary mesh in place there. */ + Mesh *mesh_in_bmain = BKE_mesh_add(bmain, mesh->id.name + 2); + + /* NOTE: BKE_mesh_nomain_to_mesh() does not copy materials and instead it preserves them in the + * destinaion mesh .So we "steal" all related fields before calling it. + * + * TODO(sergey): We really better have a function which gets and ID and accepts it for the bmain. + */ + mesh_in_bmain->mat = mesh->mat; + mesh_in_bmain->totcol = mesh->totcol; + mesh_in_bmain->flag = mesh->flag; + mesh_in_bmain->smoothresh = mesh->smoothresh; + mesh->mat = NULL; - case OB_MESH: - if (!cage) { - Mesh *origmesh = object_for_eval.data; - tmpmesh->flag = origmesh->flag; - tmpmesh->mat = MEM_dupallocN(origmesh->mat); - tmpmesh->totcol = origmesh->totcol; - tmpmesh->smoothresh = origmesh->smoothresh; - if (origmesh->mat) { - for (i = origmesh->totcol; i-- > 0;) { - /* are we an object material or data based? */ - tmpmesh->mat[i] = give_current_material(object_input, i + 1); - - if (((object_for_eval.matbits && object_for_eval.matbits[i]) || do_mat_id_data_us) && - tmpmesh->mat[i]) { - id_us_plus(&tmpmesh->mat[i]->id); - } - } - } - } - break; - } /* end copy materials */ + BKE_mesh_nomain_to_mesh(mesh, mesh_in_bmain, NULL, &CD_MASK_MESH, true); + + /* Make sure user count from BKE_mesh_add() is the one we expect here and bring it down to 0. */ + BLI_assert(mesh_in_bmain->id.us == 1); + id_us_min(&mesh_in_bmain->id); - return tmpmesh; + return mesh_in_bmain; } static void add_shapekey_layers(Mesh *mesh_dest, Mesh *mesh_src) diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index d889fca3a3a..f0fd1203cae 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -2141,8 +2141,8 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const * Higher level functions hiding most of the code needed around call to * #BKE_mesh_normals_loop_custom_set(). * - * \param r_custom_loopnors is not const, since code will replace zero_v3 normals there - * with automatically computed vectors. + * \param r_custom_loopnors: is not const, since code will replace zero_v3 normals there + * with automatically computed vectors. */ void BKE_mesh_set_custom_normals(Mesh *mesh, float (*r_custom_loopnors)[3]) { @@ -2153,8 +2153,8 @@ void BKE_mesh_set_custom_normals(Mesh *mesh, float (*r_custom_loopnors)[3]) * Higher level functions hiding most of the code needed around call to * #BKE_mesh_normals_loop_custom_from_vertices_set(). * - * \param r_custom_loopnors is not const, since code will replace zero_v3 normals there - * with automatically computed vectors. + * \param r_custom_loopnors: is not const, since code will replace zero_v3 normals there + * with automatically computed vectors. */ void BKE_mesh_set_custom_normals_from_vertices(Mesh *mesh, float (*r_custom_vertnors)[3]) { diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 9bc9865631f..43a5e1d6592 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -934,8 +934,8 @@ void modwrap_deformVertsEM(ModifierData *md, * Note that modifiers in stack always get fully evaluated COW ID pointers, * never original ones. Makes things simpler. * - * \param get_cage_mesh Return evaluated mesh with only deforming modifiers applied - * (i.e. mesh topology remains the same as original one, a.k.a. 'cage' mesh). + * \param get_cage_mesh: Return evaluated mesh with only deforming modifiers applied + * (i.e. mesh topology remains the same as original one, a.k.a. 'cage' mesh). */ Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object(Object *ob_eval, const bool get_cage_mesh) diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 3adb6cfe960..b7db434e234 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -787,7 +787,7 @@ static void node_socket_free(bNodeTree *UNUSED(ntree), const bool do_id_user) { if (sock->prop) { - IDP_FreeProperty_ex(sock->prop, do_id_user); + IDP_FreePropertyContent_ex(sock->prop, do_id_user); MEM_freeN(sock->prop); } @@ -1850,7 +1850,7 @@ static void node_free_node(bNodeTree *ntree, bNode *node) if (node->prop) { /* Remember, no ID user refcount management here! */ - IDP_FreeProperty_ex(node->prop, false); + IDP_FreePropertyContent_ex(node->prop, false); MEM_freeN(node->prop); } @@ -1910,7 +1910,6 @@ static void node_socket_interface_free(bNodeTree *UNUSED(ntree), bNodeSocket *so { if (sock->prop) { IDP_FreeProperty(sock->prop); - MEM_freeN(sock->prop); } if (sock->default_value) { diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 38a8ad2769a..85ca9cb26b9 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -469,6 +469,7 @@ void BKE_object_free_derived_caches(Object *ob) ob->runtime.mesh_deform_eval = NULL; } + BKE_object_to_mesh_clear(ob); BKE_object_free_curve_cache(ob); /* clear grease pencil data */ @@ -1467,7 +1468,7 @@ Object *BKE_object_copy(Main *bmain, const Object *ob) /** Perform deep-copy of object and its 'children' data-blocks (obdata, materials, actions, etc.). * - * \param dupflag Controls which sub-data are also duplicated + * \param dupflag: Controls which sub-data are also duplicated * (see #eDupli_ID_Flags in DNA_userdef_types.h). * * \note This function does not do any remapping to new IDs, caller must do it @@ -1951,7 +1952,6 @@ void BKE_object_make_proxy(Main *bmain, Object *ob, Object *target, Object *cob) /* copy IDProperties */ if (ob->id.properties) { IDP_FreeProperty(ob->id.properties); - MEM_freeN(ob->id.properties); ob->id.properties = NULL; } if (target->id.properties) { @@ -4487,3 +4487,32 @@ void BKE_object_type_set_empty_for_versioning(Object *ob) } ob->mode = OB_MODE_OBJECT; } + +/* Updates select_id of all objects in the given bmain. */ +void BKE_object_update_select_id(struct Main *bmain) +{ + Object *ob = bmain->objects.first; + int select_id = 1; + while (ob) { + ob->runtime.select_id = select_id++; + ob = ob->id.next; + } +} + +Mesh *BKE_object_to_mesh(Object *object) +{ + BKE_object_to_mesh_clear(object); + + Mesh *mesh = BKE_mesh_new_from_object(object); + object->runtime.object_as_temp_mesh = mesh; + return mesh; +} + +void BKE_object_to_mesh_clear(Object *object) +{ + if (object->runtime.object_as_temp_mesh == NULL) { + return; + } + BKE_id_free(NULL, object->runtime.object_as_temp_mesh); + object->runtime.object_as_temp_mesh = NULL; +} diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c index 8080834a53a..0dedbb7e934 100644 --- a/source/blender/blenkernel/intern/object_dupli.c +++ b/source/blender/blenkernel/intern/object_dupli.c @@ -1082,7 +1082,7 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx) /* Should the dupli's be generated for this object? - Respect restrict flags */ if (DEG_get_mode(ctx->depsgraph) == DAG_EVAL_RENDER ? (restrictflag & OB_RESTRICT_RENDER) : - (restrictflag & OB_RESTRICT_VIEW)) { + (restrictflag & OB_RESTRICT_VIEWPORT)) { return NULL; } diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index 183bc968897..6dee936ca76 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -202,9 +202,11 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o case OB_CURVE: case OB_SURF: - case OB_FONT: - BKE_displist_make_curveTypes(depsgraph, scene, ob, false, false, NULL); + case OB_FONT: { + bool for_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER); + BKE_displist_make_curveTypes(depsgraph, scene, ob, for_render, false); break; + } case OB_LATTICE: BKE_lattice_modifiers_calc(depsgraph, scene, ob); diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index c55cf18fcea..5849d691b03 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -82,8 +82,11 @@ static eOverlayControlFlags overlay_flags = 0; void BKE_paint_invalidate_overlay_tex(Scene *scene, ViewLayer *view_layer, const Tex *tex) { Paint *p = BKE_paint_get_active(scene, view_layer); - Brush *br = p->brush; + if (!p) { + return; + } + Brush *br = p->brush; if (!br) { return; } @@ -99,8 +102,11 @@ void BKE_paint_invalidate_overlay_tex(Scene *scene, ViewLayer *view_layer, const void BKE_paint_invalidate_cursor_overlay(Scene *scene, ViewLayer *view_layer, CurveMapping *curve) { Paint *p = BKE_paint_get_active(scene, view_layer); - Brush *br = p->brush; + if (p == NULL) { + return; + } + Brush *br = p->brush; if (br && br->curve == curve) { overlay_flags |= PAINT_OVERLAY_INVALID_CURVE; } @@ -1273,9 +1279,6 @@ void BKE_sculpt_update_mesh_elements( } } } - - /* 2.8x - avoid full mesh update! */ - BKE_mesh_batch_cache_dirty_tag(me, BKE_MESH_BATCH_DIRTY_SCULPT_COORDS); } int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index c6cc72ba989..13649eaf096 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -387,8 +387,11 @@ void psys_find_group_weights(ParticleSettings *part) /* Find object pointers based on index. If the collection is linked from * another library linking may not have the object pointers available on * file load, so we have to retrieve them later. See T49273. */ - const ListBase instance_collection_objects = BKE_collection_object_cache_get( - part->instance_collection); + ListBase instance_collection_objects = {NULL, NULL}; + + if (part->instance_collection) { + instance_collection_objects = BKE_collection_object_cache_get(part->instance_collection); + } for (ParticleDupliWeight *dw = part->instance_weights.first; dw; dw = dw->next) { if (dw->ob == NULL) { diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index 8125024585c..070c3c7a566 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -1170,7 +1170,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, int i_mapped = 0; for (i = 0; i < totelem && element_weight[i] == 0.0f; i++) { - ; + /* pass */ } element_sum[i_mapped] = element_weight[i] * inv_totweight; element_map[i_mapped] = i; @@ -1216,7 +1216,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, for (i = 0, p = 0; p < totpart; p++, pos += step) { for (; (i < totmapped - 1) && (pos > (double)element_sum[i]); i++) { - ; + /* pass */ } particle_element[p] = element_map[i]; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index cba15aed55f..27722aab2d9 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -471,14 +471,6 @@ void psys_thread_context_init(ParticleThreadContext *ctx, ParticleSimulationData ctx->ma = give_current_material(sim->ob, sim->psys->part->omat); } -#define MAX_PARTICLES_PER_TASK \ - 256 /* XXX arbitrary - maybe use at least number of points instead for better balancing? */ - -BLI_INLINE int ceil_ii(int a, int b) -{ - return (a + b - 1) / b; -} - void psys_tasks_create(ParticleThreadContext *ctx, int startpart, int endpart, @@ -486,7 +478,7 @@ void psys_tasks_create(ParticleThreadContext *ctx, int *r_numtasks) { ParticleTask *tasks; - int numtasks = ceil_ii((endpart - startpart), MAX_PARTICLES_PER_TASK); + int numtasks = min_ii(BLI_system_thread_count() * 4, endpart - startpart); float particles_per_task = (float)(endpart - startpart) / (float)numtasks, p, pnext; int i; diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index c186394880b..f1d5347c48b 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -181,10 +181,10 @@ static int partition_indices(int *prim_indices, int lo, int hi, int axis, float int i = lo, j = hi; for (;;) { for (; prim_bbc[prim_indices[i]].bcentroid[axis] < mid; i++) { - ; + /* pass */ } for (; mid < prim_bbc[prim_indices[j]].bcentroid[axis]; j--) { - ; + /* pass */ } if (!(i < j)) { @@ -216,18 +216,18 @@ static int partition_indices_material(PBVH *bvh, int lo, int hi) for (;;) { if (bvh->looptri) { for (; face_materials_match(first, &mpoly[looptri[indices[i]].poly]); i++) { - ; + /* pass */ } for (; !face_materials_match(first, &mpoly[looptri[indices[j]].poly]); j--) { - ; + /* pass */ } } else { for (; grid_materials_match(first, &flagmats[indices[i]]); i++) { - ; + /* pass */ } for (; !grid_materials_match(first, &flagmats[indices[j]]); j--) { - ; + /* pass */ } } @@ -2202,26 +2202,17 @@ bool BKE_pbvh_node_planes_exclude_AABB(PBVHNode *node, void *data) return test_planes_aabb(bb_min, bb_max, data) != ISECT_INSIDE; } -struct PBVHNodeDrawCallbackData { - void (*draw_fn)(void *user_data, GPUBatch *batch); +typedef struct PBVHNodeDrawCallbackData { + void (*draw_fn)(void *user_data, GPU_PBVH_Buffers *buffers); void *user_data; - bool fast; - bool only_mask; /* Only draw nodes that have mask data. */ - bool wires; -}; +} PBVHNodeDrawCallbackData; static void pbvh_node_draw_cb(PBVHNode *node, void *data_v) { - struct PBVHNodeDrawCallbackData *data = data_v; + PBVHNodeDrawCallbackData *data = data_v; if (!(node->flag & PBVH_FullyHidden)) { - GPUBatch *batch = GPU_pbvh_buffers_batch_get(node->draw_buffers, data->fast, data->wires); - bool show_mask = GPU_pbvh_buffers_has_mask(node->draw_buffers); - if (!data->only_mask || show_mask) { - if (batch != NULL) { - data->draw_fn(data->user_data, batch); - } - } + data->draw_fn(data->user_data, node->draw_buffers); } } @@ -2231,20 +2222,10 @@ static void pbvh_node_draw_cb(PBVHNode *node, void *data_v) void BKE_pbvh_draw_cb(PBVH *bvh, float (*planes)[4], float (*fnors)[3], - bool fast, - bool wires, - bool only_mask, bool show_vcol, - void (*draw_fn)(void *user_data, GPUBatch *batch), + void (*draw_fn)(void *user_data, GPU_PBVH_Buffers *buffers), void *user_data) { - struct PBVHNodeDrawCallbackData draw_data = { - .only_mask = only_mask, - .fast = fast, - .wires = wires, - .draw_fn = draw_fn, - .user_data = user_data, - }; PBVHNode **nodes; int totnode; @@ -2261,6 +2242,11 @@ void BKE_pbvh_draw_cb(PBVH *bvh, MEM_freeN(nodes); } + PBVHNodeDrawCallbackData draw_data = { + .draw_fn = draw_fn, + .user_data = user_data, + }; + if (planes) { BKE_pbvh_search_callback( bvh, BKE_pbvh_node_planes_contain_AABB, planes, pbvh_node_draw_cb, &draw_data); @@ -2268,10 +2254,18 @@ void BKE_pbvh_draw_cb(PBVH *bvh, else { BKE_pbvh_search_callback(bvh, NULL, NULL, pbvh_node_draw_cb, &draw_data); } -#if 0 - if (G.debug_value == 14) - pbvh_draw_BB(bvh); -#endif +} + +void BKE_pbvh_draw_debug_cb( + PBVH *bvh, + void (*draw_fn)(void *user_data, const float bmin[3], const float bmax[3], PBVHNodeFlags flag), + void *user_data) +{ + for (int a = 0; a < bvh->totnode; a++) { + PBVHNode *node = &bvh->nodes[a]; + + draw_fn(user_data, node->vb.bmin, node->vb.bmax, node->flag); + } } void BKE_pbvh_grids_update( diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 58b36aed24f..872f99ff813 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -497,7 +497,6 @@ void BKE_scene_free_ex(Scene *sce, const bool do_id_user) } if (sce->r.ffcodecdata.properties) { IDP_FreeProperty(sce->r.ffcodecdata.properties); - MEM_freeN(sce->r.ffcodecdata.properties); sce->r.ffcodecdata.properties = NULL; } @@ -566,7 +565,7 @@ void BKE_scene_init(Scene *sce) sce->cursor.rotation_quaternion[0] = 1.0f; sce->cursor.rotation_axis[1] = 1.0f; - sce->r.mode = R_OSA; + sce->r.mode = 0; sce->r.cfra = 1; sce->r.sfra = 1; sce->r.efra = 250; @@ -767,7 +766,6 @@ void BKE_scene_init(Scene *sce) BLI_strncpy(sce->r.pic, U.renderdir, sizeof(sce->r.pic)); BLI_rctf_init(&sce->r.safety, 0.1f, 0.9f, 0.1f, 0.9f); - sce->r.osa = 8; /* Note; in header_info.c the scene copy happens..., * if you add more to renderdata it has to be checked there. */ @@ -905,6 +903,9 @@ void BKE_scene_init(Scene *sce) sce->display.matcap_ssao_attenuation = 1.0f; sce->display.matcap_ssao_samples = 16; + sce->display.render_aa = SCE_DISPLAY_AA_SAMPLES_8; + sce->display.viewport_aa = SCE_DISPLAY_AA_FXAA; + /* OpenGL Render. */ BKE_screen_view3d_shading_init(&sce->display.shading); @@ -2384,4 +2385,20 @@ void BKE_scene_cursor_quat_to_rot(View3DCursor *cursor, const float quat[4], boo } } +void BKE_scene_cursor_to_mat4(const View3DCursor *cursor, float mat[4][4]) +{ + float mat3[3][3]; + BKE_scene_cursor_rot_to_mat3(cursor, mat3); + copy_m4_m3(mat, mat3); + copy_v3_v3(mat[3], cursor->location); +} + +void BKE_scene_cursor_from_mat4(View3DCursor *cursor, const float mat[4][4], bool use_compat) +{ + float mat3[3][3]; + copy_m3_m4(mat3, mat); + BKE_scene_cursor_mat3_to_rot(cursor, mat3, use_compat); + copy_v3_v3(cursor->location, mat[3]); +} + /** \} */ diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 9799f7c2943..222e8ddb724 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -193,18 +193,6 @@ static void panel_list_copy(ListBase *newlb, const ListBase *lb) Panel *pa = lb->first; for (; newpa; newpa = newpa->next, pa = pa->next) { newpa->activedata = NULL; - - Panel *newpatab = newlb->first; - Panel *patab = lb->first; - while (newpatab) { - if (newpa->paneltab == patab) { - newpa->paneltab = newpatab; - break; - } - newpatab = newpatab->next; - patab = patab->next; - } - panel_list_copy(&newpa->children, &pa->children); } } @@ -439,7 +427,6 @@ void BKE_area_region_free(SpaceType *st, ARegion *ar) } if (uilst->properties) { IDP_FreeProperty(uilst->properties); - MEM_freeN(uilst->properties); } } @@ -853,12 +840,13 @@ void BKE_screen_view3d_shading_init(View3DShading *shading) shading->type = OB_SOLID; shading->prev_type = OB_SOLID; shading->flag = V3D_SHADING_SPECULAR_HIGHLIGHT | V3D_SHADING_XRAY_BONE; - shading->light = V3D_LIGHTING_STUDIO; + shading->light = V3D_LIGHTING_MATCAP; shading->shadow_intensity = 0.5f; shading->xray_alpha = 0.5f; shading->xray_alpha_wire = 0.5f; shading->cavity_valley_factor = 1.0f; shading->cavity_ridge_factor = 1.0f; + shading->cavity_type = V3D_SHADING_CAVITY_CURVATURE; shading->curvature_ridge_factor = 1.0f; shading->curvature_valley_factor = 1.0f; copy_v3_fl(shading->single_color, 0.8f); diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c index 1c0aa63f590..f77b3e99e30 100644 --- a/source/blender/blenkernel/intern/seqcache.c +++ b/source/blender/blenkernel/intern/seqcache.c @@ -90,7 +90,6 @@ typedef struct SeqCacheKey { struct SeqCacheKey *link_next; /* Used for linking intermediate items to final frame */ struct Sequence *seq; SeqRenderData context; - float cfra; float nfra; float cost; bool is_temp_cache; @@ -232,14 +231,17 @@ static SeqCacheKey *seq_cache_choose_key(Scene *scene, SeqCacheKey *lkey, SeqCac SeqCacheKey *finalkey = NULL; if (rkey && lkey) { - if (lkey->cfra > rkey->cfra) { + int lkey_cfra = lkey->seq->start + lkey->nfra; + int rkey_cfra = rkey->seq->start + rkey->nfra; + + if (lkey_cfra > rkey_cfra) { SeqCacheKey *swapkey = lkey; lkey = rkey; rkey = swapkey; } - int l_diff = scene->r.cfra - lkey->cfra; - int r_diff = rkey->cfra - scene->r.cfra; + int l_diff = scene->r.cfra - lkey_cfra; + int r_diff = rkey_cfra - scene->r.cfra; if (l_diff > r_diff) { finalkey = lkey; @@ -319,7 +321,7 @@ static SeqCacheKey *seq_cache_get_item_for_removal(Scene *scene) if (key->cost <= scene->ed->recycle_max_cost) { cheap_count++; if (lkey) { - if (key->cfra < lkey->cfra) { + if (key->seq->start + key->nfra < lkey->seq->start + lkey->nfra) { lkey = key; } } @@ -327,7 +329,7 @@ static SeqCacheKey *seq_cache_get_item_for_removal(Scene *scene) lkey = key; } if (rkey) { - if (key->cfra > rkey->cfra) { + if (key->seq->start + key->nfra > rkey->seq->start + rkey->nfra) { rkey = key; } } @@ -425,7 +427,7 @@ void BKE_sequencer_cache_free_temp_cache(Scene *scene, short id, int cfra) SeqCacheKey *key = BLI_ghashIterator_getKey(&gh_iter); BLI_ghashIterator_step(&gh_iter); - if (key->is_temp_cache && key->creator_id == id && key->cfra != cfra) { + if (key->is_temp_cache && key->creator_id == id && key->seq->start + key->nfra != cfra) { BLI_ghash_remove(cache->hash, key, seq_cache_keyfree, seq_cache_valfree); } } @@ -592,7 +594,6 @@ void BKE_sequencer_cache_put( key->cache_owner = cache; key->seq = seq; key->context = *context; - key->cfra = cfra; key->nfra = cfra - seq->start; key->type = type; key->cost = cost; @@ -634,7 +635,7 @@ void BKE_sequencer_cache_put( void BKE_sequencer_cache_iterate( struct Scene *scene, void *userdata, - bool callback(void *userdata, struct Sequence *seq, int cfra, int cache_type, float cost)) + bool callback(void *userdata, struct Sequence *seq, int nfra, int cache_type, float cost)) { SeqCache *cache = seq_cache_get_from_scene(scene); if (!cache) { @@ -650,7 +651,7 @@ void BKE_sequencer_cache_iterate( SeqCacheKey *key = BLI_ghashIterator_getKey(&gh_iter); BLI_ghashIterator_step(&gh_iter); - interrupt = callback(userdata, key->seq, key->cfra, key->type, key->cost); + interrupt = callback(userdata, key->seq, key->nfra, key->type, key->cost); } cache->last_key = NULL; diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index b1a32552878..92f951ec637 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -262,7 +262,7 @@ static void BKE_sequence_free_ex(Scene *scene, } if (seq->prop) { - IDP_FreeProperty_ex(seq->prop, do_id_user); + IDP_FreePropertyContent_ex(seq->prop, do_id_user); MEM_freeN(seq->prop); } @@ -635,8 +635,6 @@ void BKE_sequencer_new_render_data(Main *bmain, r_context->is_proxy_render = false; r_context->view_id = 0; r_context->gpu_offscreen = NULL; - r_context->gpu_samples = (scene->r.mode & R_OSA) ? scene->r.osa : 0; - r_context->gpu_full_samples = (r_context->gpu_samples) && (scene->r.scemode & R_FULL_SAMPLE); } /* ************************* iterator ************************** */ @@ -2792,7 +2790,7 @@ static ImBuf *input_preprocess(const SeqRenderData *context, } if (ibuf->x != context->rectx || ibuf->y != context->recty) { - if (scene->r.mode & R_OSA) { + if (scene->display.render_aa > SCE_DISPLAY_AA_FXAA) { IMB_scaleImBuf(ibuf, (short)context->rectx, (short)context->recty); } else { @@ -3523,7 +3521,6 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, unsigned int draw_flags = V3D_OFSDRAW_NONE; draw_flags |= (use_gpencil) ? V3D_OFSDRAW_SHOW_ANNOTATION : 0; - draw_flags |= (context->gpu_full_samples) ? V3D_OFSDRAW_USE_FULL_SAMPLE : 0; draw_flags |= (context->scene->r.seq_flag & R_SEQ_OVERRIDE_SCENE_SETTINGS) ? V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS : 0; @@ -3549,7 +3546,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, IB_rect, draw_flags, scene->r.alphamode, - context->gpu_samples, + U.ogl_multisamples, viewname, context->gpu_offscreen, err_out); @@ -3578,9 +3575,9 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, re = RE_NewSceneRender(scene); } - RE_BlenderFrame(re, context->bmain, scene, view_layer, camera, frame, false); + RE_RenderFrame(re, context->bmain, scene, view_layer, camera, frame, false); - /* restore previous state after it was toggled on & off by RE_BlenderFrame */ + /* restore previous state after it was toggled on & off by RE_RenderFrame */ G.is_rendering = is_rendering; } @@ -5671,12 +5668,12 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad if (seq_load->flag & SEQ_LOAD_MOVIE_SOUND) { int start_frame_back = seq_load->start_frame; - seq_load->channel++; + seq_load->channel--; seq_load->seq_sound = BKE_sequencer_add_sound_strip(C, seqbasep, seq_load); seq_load->start_frame = start_frame_back; - seq_load->channel--; + seq_load->channel++; } /* can be NULL */ diff --git a/source/blender/blenkernel/intern/tracking_stabilize.c b/source/blender/blenkernel/intern/tracking_stabilize.c index 1fe63e21e78..695f9b21559 100644 --- a/source/blender/blenkernel/intern/tracking_stabilize.c +++ b/source/blender/blenkernel/intern/tracking_stabilize.c @@ -275,10 +275,10 @@ static int search_closest_marker_index(MovieTrackingTrack *track, int ref_frame) i = MAX2(0, i); i = MIN2(i, end - 1); for (; i < end - 1 && markers[i].framenr <= ref_frame; ++i) { - ; + /* pass */ } for (; 0 < i && markers[i].framenr > ref_frame; --i) { - ; + /* pass */ } track->last_marker = i; diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c index d3e0ff56977..caf88eb0fff 100644 --- a/source/blender/blenkernel/intern/undo_system.c +++ b/source/blender/blenkernel/intern/undo_system.c @@ -29,6 +29,8 @@ #include "BLI_listbase.h" #include "BLI_string.h" +#include "BLT_translation.h" + #include "DNA_listBase.h" #include "DNA_windowmanager_types.h" @@ -337,7 +339,7 @@ static bool undosys_stack_push_main(UndoStack *ustack, const char *name, struct void BKE_undosys_stack_init_from_main(UndoStack *ustack, struct Main *bmain) { UNDO_NESTED_ASSERT(false); - undosys_stack_push_main(ustack, "original", bmain); + undosys_stack_push_main(ustack, IFACE_("Original"), bmain); } /* called after 'BKE_undosys_stack_init_from_main' */ @@ -345,7 +347,7 @@ void BKE_undosys_stack_init_from_context(UndoStack *ustack, bContext *C) { const UndoType *ut = BKE_undosys_type_from_context(C); if ((ut != NULL) && (ut != BKE_UNDOSYS_TYPE_MEMFILE)) { - BKE_undosys_step_push_with_type(ustack, C, "original mode", ut); + BKE_undosys_step_push_with_type(ustack, C, IFACE_("Original Mode"), ut); } } diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index 293eed8cfe3..f5b73d88867 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -663,7 +663,7 @@ static const char *unit_find_str(const char *str, const char *substr, bool case_ } /* If str_found is not a valid unit, we have to check further in the string... */ for (str_found++; isalpha_or_utf8(*str_found); str_found++) { - ; + /* pass */ } str = str_found; } diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c index f9584adc6e0..387d4ec5773 100644 --- a/source/blender/blenkernel/intern/workspace.c +++ b/source/blender/blenkernel/intern/workspace.c @@ -36,6 +36,7 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" +#include "DNA_windowmanager_types.h" #include "DNA_workspace_types.h" #include "DEG_depsgraph.h" @@ -43,7 +44,8 @@ #include "MEM_guardedalloc.h" /* -------------------------------------------------------------------- */ -/* Internal utils */ +/** \name Internal Utils + * \{ */ static void workspace_layout_name_set(WorkSpace *workspace, WorkSpaceLayout *layout, @@ -134,8 +136,11 @@ static bool UNUSED_FUNCTION(workspaces_is_screen_used) return false; } +/** \} */ + /* -------------------------------------------------------------------- */ -/* Create, delete, init */ +/** \name Create, Delete, Init + * \{ */ WorkSpace *BKE_workspace_add(Main *bmain, const char *name) { @@ -253,8 +258,11 @@ void BKE_workspace_relations_free(ListBase *relation_list) } } +/** \} */ + /* -------------------------------------------------------------------- */ -/* General Utils */ +/** \name General Utils + * \{ */ WorkSpaceLayout *BKE_workspace_layout_find(const WorkSpace *workspace, const bScreen *screen) { @@ -348,14 +356,37 @@ void BKE_workspace_tool_remove(struct WorkSpace *workspace, struct bToolRef *tre } if (tref->properties) { IDP_FreeProperty(tref->properties); - MEM_freeN(tref->properties); } BLI_remlink(&workspace->tools, tref); MEM_freeN(tref); } +bool BKE_workspace_owner_id_check(const WorkSpace *workspace, const char *owner_id) +{ + if ((*owner_id == '\0') || ((workspace->flags & WORKSPACE_USE_FILTER_BY_ORIGIN) == 0)) { + return true; + } + else { + /* We could use hash lookup, for now this list is highly likely under < ~16 items. */ + return BLI_findstring(&workspace->owner_ids, owner_id, offsetof(wmOwnerID, name)) != NULL; + } +} + +void BKE_workspace_id_tag_all_visible(Main *bmain, int tag) +{ + BKE_main_id_tag_listbase(&bmain->workspaces, tag, false); + wmWindowManager *wm = bmain->wm.first; + for (wmWindow *win = wm->windows.first; win; win = win->next) { + WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); + workspace->id.tag |= tag; + } +} + +/** \} */ + /* -------------------------------------------------------------------- */ -/* Getters/Setters */ +/** \name Getters/Setters + * \{ */ WorkSpace *BKE_workspace_active_get(WorkSpaceInstanceHook *hook) { @@ -433,13 +464,4 @@ void BKE_workspace_hook_layout_for_workspace_set(WorkSpaceInstanceHook *hook, workspace_relation_ensure_updated(&workspace->hook_layout_relations, hook, layout); } -bool BKE_workspace_owner_id_check(const WorkSpace *workspace, const char *owner_id) -{ - if ((*owner_id == '\0') || ((workspace->flags & WORKSPACE_USE_FILTER_BY_ORIGIN) == 0)) { - return true; - } - else { - /* we could use hash lookup, for now this list is highly under < ~16 items. */ - return BLI_findstring(&workspace->owner_ids, owner_id, offsetof(wmOwnerID, name)) != NULL; - } -} +/** \} */ diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c index b72b99e514d..19425a0d80b 100644 --- a/source/blender/blenkernel/intern/writeavi.c +++ b/source/blender/blenkernel/intern/writeavi.c @@ -118,7 +118,6 @@ bMovieHandle *BKE_movie_handle_get(const char imtype) mh.start_movie = start_stub; mh.append_movie = append_stub; mh.end_movie = end_stub; - mh.get_next_frame = NULL; mh.get_movie_path = NULL; mh.context_create = context_create_stub; mh.context_free = context_free_stub; diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index a74d5b241ed..ae41b8f3272 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -1616,7 +1616,7 @@ static void ffmpeg_set_expert_options(RenderData *rd) int codec_id = rd->ffcodecdata.codec; if (rd->ffcodecdata.properties) { - IDP_FreeProperty(rd->ffcodecdata.properties); + IDP_FreePropertyContent(rd->ffcodecdata.properties); } if (codec_id == AV_CODEC_ID_H264) { @@ -1680,7 +1680,7 @@ void BKE_ffmpeg_preset_set(RenderData *rd, int preset) int isntsc = (rd->frs_sec != 25); if (rd->ffcodecdata.properties) { - IDP_FreeProperty(rd->ffcodecdata.properties); + IDP_FreePropertyContent(rd->ffcodecdata.properties); } switch (preset) { |