diff options
Diffstat (limited to 'source')
572 files changed, 8834 insertions, 6360 deletions
diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt index c2fac8fc7d7..316ab531a05 100644 --- a/source/blender/CMakeLists.txt +++ b/source/blender/CMakeLists.txt @@ -65,8 +65,9 @@ set(SRC_DNA_INC ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_modifier_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_nla_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_node_types.h - ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_fluidsim.h - ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_force.h + ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_fluidsim_types.h + ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_force_types.h + ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_enums.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_outliner_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_packedFile_types.h diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc index fa2bbb8dfc3..c2c99e2b11f 100644 --- a/source/blender/alembic/intern/abc_mesh.cc +++ b/source/blender/alembic/intern/abc_mesh.cc @@ -31,7 +31,7 @@ extern "C" { #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_modifier_types.h" -#include "DNA_object_fluidsim.h" +#include "DNA_object_fluidsim_types.h" #include "DNA_object_types.h" #include "BLI_math_geom.h" diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index 24347d57917..0cca1852c91 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -551,7 +551,7 @@ static void blf_draw_gl__start(FontBLF *font) */ glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); gpuPushMatrix(); diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 9bb44a726de..c3cea6c883c 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -100,6 +100,8 @@ struct GPUDrawObject; struct PBVH; struct EvaluationContext; +#include "DNA_object_enums.h" + /* number of sub-elements each mesh element has (for interpolation) */ #define SUB_ELEMS_VERT 0 #define SUB_ELEMS_EDGE 2 @@ -381,7 +383,7 @@ struct DerivedMesh { /** Get the BVH used for paint modes */ - struct PBVH *(*getPBVH)(struct Object *ob, DerivedMesh *dm); + struct PBVH *(*getPBVH)(struct Object *ob, DerivedMesh *dm, eObjectMode object_mode); /* Drawing Operations */ diff --git a/source/blender/blenkernel/BKE_addon.h b/source/blender/blenkernel/BKE_addon.h index 74c1edd1c1b..e631d1d6537 100644 --- a/source/blender/blenkernel/BKE_addon.h +++ b/source/blender/blenkernel/BKE_addon.h @@ -26,8 +26,11 @@ * \ingroup bke */ -#include "RNA_types.h" +struct ListBase; +struct bAddon; + +#ifdef __RNA_TYPES_H__ typedef struct bAddonPrefType { /* type info */ char idname[64]; // best keep the same size as BKE_ST_MAXNAME @@ -36,6 +39,10 @@ typedef struct bAddonPrefType { ExtensionRNA ext; } bAddonPrefType; +#else +typedef struct bAddonPrefType bAddonPrefType; +#endif + bAddonPrefType *BKE_addon_pref_type_find(const char *idname, bool quiet); void BKE_addon_pref_type_add(bAddonPrefType *apt); void BKE_addon_pref_type_remove(const bAddonPrefType *apt); @@ -43,4 +50,8 @@ void BKE_addon_pref_type_remove(const bAddonPrefType *apt); void BKE_addon_pref_type_init(void); void BKE_addon_pref_type_free(void); +struct bAddon *BKE_addon_new(void); +struct bAddon *BKE_addon_ensure(struct ListBase *addons, const char *module); +void BKE_addon_free(struct bAddon *addon); + #endif /* __BKE_ADDON_H__ */ diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h index e7af7400850..f2601f2ca32 100644 --- a/source/blender/blenkernel/BKE_brush.h +++ b/source/blender/blenkernel/BKE_brush.h @@ -36,6 +36,7 @@ struct Scene; struct UnifiedPaintSettings; // enum eCurveMappingPreset; +#include "DNA_object_enums.h" /* globals for brush execution */ void BKE_brush_system_init(void); @@ -43,8 +44,8 @@ void BKE_brush_system_exit(void); /* datablock functions */ void BKE_brush_init(struct Brush *brush); -struct Brush *BKE_brush_add(struct Main *bmain, const char *name, short ob_mode); -struct Brush *BKE_brush_first_search(struct Main *bmain, short ob_mode); +struct Brush *BKE_brush_add(struct Main *bmain, const char *name, const eObjectMode ob_mode); +struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode); void BKE_brush_copy_data(struct Main *bmain, struct Brush *brush_dst, const struct Brush *brush_src, const int flag); struct Brush *BKE_brush_copy(struct Main *bmain, const struct Brush *brush); void BKE_brush_make_local(struct Main *bmain, struct Brush *brush, const bool lib_local); diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 7f7cbd678e2..27b928c1671 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -236,7 +236,9 @@ void bvhtree_update_from_cloth(struct ClothModifierData *clmd, bool moving); void bvhselftree_update_from_cloth(struct ClothModifierData *clmd, bool moving); // needed for button_object.c -void cloth_clear_cache (struct Object *ob, struct ClothModifierData *clmd, float framenr ); +void cloth_clear_cache( + const struct EvaluationContext *eval_ctx, + struct Object *ob, struct ClothModifierData *clmd, float framenr ); void cloth_parallel_transport_hair_frame(float mat[3][3], const float dir_old[3], const float dir_new[3]); diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h index 48b4ff881ae..3bf14346ccb 100644 --- a/source/blender/blenkernel/BKE_collection.h +++ b/source/blender/blenkernel/BKE_collection.h @@ -49,8 +49,9 @@ struct SceneCollection *BKE_collection_add( struct ID *owner_id, struct SceneCollection *sc_parent, const int type, const char *name); bool BKE_collection_remove(struct ID *owner_id, struct SceneCollection *sc); void BKE_collection_copy_data(struct SceneCollection *sc_dst, struct SceneCollection *sc_src, const int flag); +struct SceneCollection *BKE_collection_duplicate(struct ID *owner_id, struct SceneCollection *scene_collection); struct SceneCollection *BKE_collection_master(const struct ID *owner_id); -void BKE_collection_rename(const struct Scene *scene, struct SceneCollection *sc, const char *name); +void BKE_collection_rename(const struct ID *owner_id, struct SceneCollection *sc, const char *name); void BKE_collection_master_free(struct ID *owner_id, const bool do_id_user); bool BKE_collection_object_add(const struct ID *owner_id, struct SceneCollection *sc, struct Object *object); void BKE_collection_object_add_from(struct Scene *scene, struct Object *ob_src, struct Object *ob_dst); diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index 3d53f28c185..8aa253bfc3a 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -77,6 +77,8 @@ struct SpaceClip; struct ID; struct EvaluationContext; +#include "DNA_object_enums.h" + /* Structs */ struct bContext; @@ -261,7 +263,9 @@ struct RenderEngineType *CTX_data_engine_type(const bContext *C); struct ToolSettings *CTX_data_tool_settings(const bContext *C); const char *CTX_data_mode_string(const bContext *C); -int CTX_data_mode_enum_ex(const struct Object *obedit, const struct Object *ob); +int CTX_data_mode_enum_ex( + const struct Object *obedit, const struct Object *ob, + const eObjectMode object_mode); int CTX_data_mode_enum(const bContext *C); void CTX_data_main_set(bContext *C, struct Main *bmain); diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h index b605b208f66..17b854e5bf7 100644 --- a/source/blender/blenkernel/BKE_layer.h +++ b/source/blender/blenkernel/BKE_layer.h @@ -29,6 +29,8 @@ #include "BKE_collection.h" +#include "DNA_scene_types.h" + #ifdef __cplusplus extern "C" { #endif @@ -76,11 +78,18 @@ struct Base *BKE_view_layer_base_find(struct ViewLayer *view_layer, struct Objec void BKE_view_layer_base_deselect_all(struct ViewLayer *view_layer); void BKE_view_layer_base_select(struct ViewLayer *view_layer, struct Base *selbase); +void BKE_layer_collection_sync_flags( + struct ID *owner_id, + struct SceneCollection *scene_collection_dst, + struct SceneCollection *scene_collection_src); + void BKE_view_layer_copy_data( struct ViewLayer *view_layer_dst, struct ViewLayer *view_layer_src, struct SceneCollection *mc_dst, struct SceneCollection *mc_src, const int flag); +struct LayerCollection *BKE_layer_collection_duplicate(struct ID *owner_id, struct LayerCollection *layer_collection); + void BKE_layer_collection_free(struct ViewLayer *view_layer, struct LayerCollection *lc); struct LayerCollection *BKE_layer_collection_get_active(struct ViewLayer *view_layer); @@ -106,6 +115,8 @@ void BKE_collection_enable(struct ViewLayer *view_layer, struct LayerCollection bool BKE_view_layer_has_collection(struct ViewLayer *view_layer, const struct SceneCollection *sc); bool BKE_scene_has_object(struct Scene *scene, struct Object *ob); +void BKE_layer_collection_objects_select(struct LayerCollection *layer_collection); + /* syncing */ void BKE_layer_sync_new_scene_collection(struct ID *owner_id, const struct SceneCollection *sc_parent, struct SceneCollection *sc); @@ -228,9 +239,9 @@ void BKE_visible_bases_iterator_end(BLI_Iterator *iter); #define FOREACH_OBJECT(view_layer, _instance) \ { \ Object *_instance; \ - Base *base; \ - for (base = (view_layer)->object_bases.first; base; base = base->next) { \ - _instance = base->object; + Base *_base; \ + for (_base = (view_layer)->object_bases.first; _base; _base = _base->next) { \ + _instance = _base->object; #define FOREACH_OBJECT_END \ } \ @@ -263,6 +274,8 @@ void BKE_visible_bases_iterator_end(BLI_Iterator *iter); typedef struct ObjectsRenderableIteratorData { struct Scene *scene; + struct Base base_temp; + struct Scene scene_temp; struct { struct ViewLayer *view_layer; diff --git a/source/blender/blenkernel/BKE_mball.h b/source/blender/blenkernel/BKE_mball.h index 9db277f95fb..d4776d890d2 100644 --- a/source/blender/blenkernel/BKE_mball.h +++ b/source/blender/blenkernel/BKE_mball.h @@ -77,9 +77,9 @@ void BKE_mball_eval_geometry(const struct EvaluationContext *eval_ctx, struct MetaBall *mball); /* Draw Cache */ -void BKE_mball_element_calc_display_m3x4(float r_scale_xform[3][4], - const float obmat[4][4], - const float local_pos[3]); +void BKE_mball_element_calc_scale_xform(float r_scale_xform[3][4], + const float obmat[4][4], + const float local_pos[3]); enum { BKE_MBALL_BATCH_DIRTY_ALL = 0, diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 451823aedf5..8ee67850e5f 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -374,7 +374,8 @@ struct Object *modifiers_isDeformedByArmature(struct Object *ob); struct Object *modifiers_isDeformedByLattice(struct Object *ob); struct Object *modifiers_isDeformedByCurve(struct Object *ob); bool modifiers_usesArmature(struct Object *ob, struct bArmature *arm); -bool modifiers_isCorrectableDeformed(struct Scene *scene, struct Object *ob); +bool modifiers_isCorrectableDeformed( + const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); void modifier_freeTemporaryData(struct ModifierData *md); bool modifiers_isPreview(struct Object *ob); diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 761bb7e8acb..22933a093ed 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -48,20 +48,21 @@ struct MVert; struct MPoly; struct MLoopTri; +#include "DNA_object_enums.h" + /* Delete mesh mdisps and grid paint masks */ void multires_customdata_delete(struct Mesh *me); -void multires_set_tot_level(struct Object *ob, - struct MultiresModifierData *mmd, int lvl); +void multires_set_tot_level(struct MultiresModifierData *mmd, int lvl, eObjectMode object_mode); void multires_mark_as_modified(struct Object *ob, enum MultiresModifiedFlags flags); void multires_force_update(struct Object *ob); -void multires_force_render_update(struct Object *ob); +void multires_force_render_update(struct Object *ob, eObjectMode object_mode); void multires_force_external_reload(struct Object *ob); /* internal, only called in subsurf_ccg.c */ -void multires_modifier_update_mdisps(struct DerivedMesh *dm); +void multires_modifier_update_mdisps(struct DerivedMesh *dm, eObjectMode object_mode); void multires_modifier_update_hidden(struct DerivedMesh *dm); void multiresModifier_set_levels_from_disps(struct MultiresModifierData *mmd, struct Object *ob); @@ -73,21 +74,27 @@ typedef enum { MULTIRES_IGNORE_SIMPLIFY = 8 } MultiresFlags; -struct DerivedMesh *multires_make_derived_from_derived(struct DerivedMesh *dm, - struct MultiresModifierData *mmd, - struct Object *ob, - MultiresFlags flags); +struct DerivedMesh *multires_make_derived_from_derived( + struct DerivedMesh *dm, + struct MultiresModifierData *mmd, + struct Object *ob, + MultiresFlags flags, + eObjectMode object_mode); struct MultiresModifierData *find_multires_modifier_before(struct Scene *scene, struct ModifierData *lastmd); struct MultiresModifierData *get_multires_modifier(struct Scene *scene, struct Object *ob, bool use_first); struct DerivedMesh *get_multires_dm(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct MultiresModifierData *mmd, struct Object *ob); -void multiresModifier_del_levels(struct MultiresModifierData *, struct Object *, int direction); -void multiresModifier_base_apply(struct MultiresModifierData *mmd, struct Object *ob); -void multiresModifier_subdivide(struct MultiresModifierData *mmd, struct Object *ob, int updateblock, int simple); +void multiresModifier_del_levels( + struct MultiresModifierData *, struct Object *, int direction, eObjectMode object_mode); +void multiresModifier_base_apply( + struct MultiresModifierData *mmd, struct Object *ob, eObjectMode object_mode); +void multiresModifier_subdivide( + struct MultiresModifierData *mmd, struct Object *ob, int updateblock, int simple, eObjectMode object_mode); void multiresModifier_sync_levels_ex( - struct Object *ob_dst, struct MultiresModifierData *mmd_src, struct MultiresModifierData *mmd_dst); + struct Object *ob_dst, struct MultiresModifierData *mmd_src, struct MultiresModifierData *mmd_dst, + eObjectMode object_mode); int multiresModifier_reshape(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct MultiresModifierData *mmd, struct Object *dst, struct Object *src); int multiresModifier_reshapeFromDM(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct MultiresModifierData *mmd, @@ -103,7 +110,7 @@ enum { MULTIRES_SPACE_OBJECT, MULTIRES_SPACE_ABSOLUTE }; -void multires_set_space(struct DerivedMesh *dm, struct Object *ob, int from, int to); +void multires_set_space(struct DerivedMesh *dm, struct Object *ob, int from, int to, eObjectMode object_mode); /* Related to the old multires */ void multires_free(struct Multires *mr); diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 4e30cb076d4..770b2b4a185 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -801,6 +801,7 @@ struct ShadeResult; #define SH_NODE_EEVEE_SPECULAR 195 #define SH_NODE_BEVEL 197 #define SH_NODE_DISPLACEMENT 198 +#define SH_NODE_VECTOR_DISPLACEMENT 199 /* custom defines options for Material node */ #define SH_NODE_MAT_DIFF 1 diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index d98c52aa91a..536b21e83ce 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -50,6 +50,8 @@ struct RigidBodyWorld; struct HookModifierData; struct ModifierData; +#include "DNA_object_enums.h" + void BKE_object_workob_clear(struct Object *workob); void BKE_object_workob_calc_parent(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct Object *workob); @@ -72,16 +74,18 @@ void BKE_object_modifier_hook_reset(struct Object *ob, struct HookModifierData * bool BKE_object_support_modifier_type_check(struct Object *ob, int modifier_type); -void BKE_object_link_modifiers(struct Object *ob_dst, const struct Object *ob_src); +void BKE_object_link_modifiers( + struct Object *ob_dst, const struct Object *ob_src, + eObjectMode object_mode); void BKE_object_free_modifiers(struct Object *ob); void BKE_object_make_proxy(struct Object *ob, struct Object *target, struct Object *gob); void BKE_object_copy_proxy_drivers(struct Object *ob, struct Object *target); bool BKE_object_exists_check(struct Object *obtest); -bool BKE_object_is_in_editmode(struct Object *ob); +bool BKE_object_is_in_editmode(const struct Object *ob); bool BKE_object_is_in_editmode_vgroup(struct Object *ob); -bool BKE_object_is_in_wpaint_select_vert(struct Object *ob); +bool BKE_object_is_in_wpaint_select_vert(const struct Object *ob, eObjectMode object_mode); typedef enum eObjectVisibilityCheck { OB_VISIBILITY_CHECK_FOR_VIEWPORT, @@ -113,9 +117,12 @@ void BKE_object_lod_add(struct Object *ob); void BKE_object_lod_sort(struct Object *ob); bool BKE_object_lod_remove(struct Object *ob, int level); void BKE_object_lod_update(struct Object *ob, const float camera_position[3]); -bool BKE_object_lod_is_usable(struct Object *ob, struct ViewLayer *view_layer); -struct Object *BKE_object_lod_meshob_get(struct Object *ob, struct ViewLayer *view_layer); -struct Object *BKE_object_lod_matob_get(struct Object *ob, struct ViewLayer *view_layer); +bool BKE_object_lod_is_usable( + struct Object *ob, struct ViewLayer *view_layer, const eObjectMode object_mode); +struct Object *BKE_object_lod_meshob_get( + struct Object *ob, struct ViewLayer *view_layer, const eObjectMode object_mode); +struct Object *BKE_object_lod_matob_get( + struct Object *ob, struct ViewLayer *view_layer, const eObjectMode object_mode); void BKE_object_copy_data(struct Main *bmain, struct Object *ob_dst, const struct Object *ob_src, const int flag); struct Object *BKE_object_copy(struct Main *bmain, const struct Object *ob); @@ -134,8 +141,10 @@ void BKE_object_to_mat4(struct Object *ob, float mat[4][4]); void BKE_object_apply_mat4(struct Object *ob, float mat[4][4], const bool use_compat, const bool use_parent); void BKE_object_matrix_local_get(struct Object *ob, float mat[4][4]); +bool BKE_object_pose_context_check_ex(struct Object *ob, bool selected); bool BKE_object_pose_context_check(struct Object *ob); struct Object *BKE_object_pose_armature_get(struct Object *ob); +struct Object *BKE_object_pose_armature_get_visible(struct Object *ob, struct ViewLayer *view_layer); void BKE_object_get_parent_matrix(struct Scene *scene, struct Object *ob, struct Object *par, float parentmat[4][4]); diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index b952859e508..2840971f157 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -62,6 +62,8 @@ struct EvaluationContext; enum eOverlayFlags; +#include "DNA_object_enums.h" + extern const char PAINT_CURSOR_SCULPT[3]; extern const char PAINT_CURSOR_VERTEX_PAINT[3]; extern const char PAINT_CURSOR_WEIGHT_PAINT[3]; @@ -91,8 +93,10 @@ typedef enum eOverlayControlFlags { PAINT_OVERLAY_OVERRIDE_PRIMARY | \ PAINT_OVERLAY_OVERRIDE_CURSOR) -void BKE_paint_invalidate_overlay_tex(struct Scene *scene, struct ViewLayer *view_layer, const struct Tex *tex); -void BKE_paint_invalidate_cursor_overlay(struct Scene *scene, struct ViewLayer *view_layer, struct CurveMapping *curve); +void BKE_paint_invalidate_overlay_tex( + struct Scene *scene, struct ViewLayer *view_layer, const struct Tex *tex, eObjectMode object_mode); +void BKE_paint_invalidate_cursor_overlay( + struct Scene *scene, struct ViewLayer *view_layer, struct CurveMapping *curve, eObjectMode object_mode); void BKE_paint_invalidate_overlay_all(void); eOverlayControlFlags BKE_paint_get_overlay_flags(void); void BKE_paint_reset_overlay_invalid(eOverlayControlFlags flag); @@ -124,9 +128,10 @@ void BKE_paint_copy(struct Paint *src, struct Paint *tar, const int flag); void BKE_paint_cavity_curve_preset(struct Paint *p, int preset); -short BKE_paint_object_mode_from_paint_mode(ePaintMode mode); +eObjectMode BKE_paint_object_mode_from_paint_mode(ePaintMode mode); struct Paint *BKE_paint_get_active_from_paintmode(struct Scene *sce, ePaintMode mode); -struct Paint *BKE_paint_get_active(struct Scene *sce, struct ViewLayer *view_layer); +struct Paint *BKE_paint_get_active( + struct Scene *sce, struct ViewLayer *view_layer, const eObjectMode object_mode); struct Paint *BKE_paint_get_active_from_context(const struct bContext *C); ePaintMode BKE_paintmode_get_active_from_context(const struct bContext *C); struct Brush *BKE_paint_brush(struct Paint *paint); @@ -142,9 +147,9 @@ bool BKE_paint_proj_mesh_data_check(struct Scene *scene, struct Object *ob, bool /* testing face select mode * Texture paint could be removed since selected faces are not used * however hiding faces is useful */ -bool BKE_paint_select_face_test(struct Object *ob); -bool BKE_paint_select_vert_test(struct Object *ob); -bool BKE_paint_select_elem_test(struct Object *ob); +bool BKE_paint_select_face_test(struct Object *ob, eObjectMode object_mode); +bool BKE_paint_select_vert_test(struct Object *ob, eObjectMode object_mode); +bool BKE_paint_select_elem_test(struct Object *ob, eObjectMode object_mode); /* partial visibility */ bool paint_is_face_hidden(const struct MLoopTri *lt, const struct MVert *mvert, const struct MLoop *mloop); @@ -214,7 +219,6 @@ typedef struct SculptSession { /* Layer brush persistence between strokes */ float (*layer_co)[3]; /* Copy of the mesh vertices' locations */ - struct SculptStroke *stroke; struct StrokeCache *cache; union { @@ -256,6 +260,7 @@ void BKE_sculpt_update_mesh_elements( struct MultiresModifierData *BKE_sculpt_multires_active(struct Scene *scene, struct Object *ob); int BKE_sculpt_mask_layers_ensure(struct Object *ob, struct MultiresModifierData *mmd); +void BKE_sculpt_toolsettings_data_ensure(struct Scene *scene); enum { SCULPT_MASK_LAYER_CALC_VERT = (1 << 0), diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 8bc521c515f..2db4126057a 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -115,6 +115,7 @@ typedef struct ParticleTexture { float damp, gravity, field; /* used in physics */ float length, clump, kink_freq, kink_amp, effector; /* used in path caching */ float rough1, rough2, roughe; /* used in path caching */ + float twist; /* used in path caching */ } ParticleTexture; typedef struct ParticleSeam { @@ -162,9 +163,11 @@ typedef struct ParticleThreadContext { float *vg_length, *vg_clump, *vg_kink; float *vg_rough1, *vg_rough2, *vg_roughe; float *vg_effector; + float *vg_twist; struct CurveMapping *clumpcurve; struct CurveMapping *roughcurve; + struct CurveMapping *twistcurve; } ParticleThreadContext; typedef struct ParticleTask { @@ -298,7 +301,8 @@ void psys_set_current_num(Object *ob, int index); struct LatticeDeformData *psys_create_lattice_deform_data(struct ParticleSimulationData *sim); -bool psys_in_edit_mode(struct ViewLayer *view_layer, struct ParticleSystem *psys); +bool psys_in_edit_mode( + const struct EvaluationContext *eval_ctx, struct ViewLayer *view_layer, struct ParticleSystem *psys); bool psys_check_enabled(struct Object *ob, struct ParticleSystem *psys, const bool use_render_params); bool psys_check_edited(struct ParticleSystem *psys); @@ -352,6 +356,7 @@ int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct Pa /* child paths */ void BKE_particlesettings_clump_curve_init(struct ParticleSettings *part); void BKE_particlesettings_rough_curve_init(struct ParticleSettings *part); +void BKE_particlesettings_twist_curve_init(struct ParticleSettings *part); void psys_apply_child_modifiers(struct ParticleThreadContext *ctx, struct ListBase *modifiers, struct ChildParticle *cpa, struct ParticleTexture *ptex, const float orco[3], const float ornor[3], float hairmat[4][4], struct ParticleCacheKey *keys, struct ParticleCacheKey *parent_keys, const float parent_orco[3]); diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h index 9a5a9e9e56a..e9be6d9f7ca 100644 --- a/source/blender/blenkernel/BKE_pointcache.h +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -34,7 +34,7 @@ #include "DNA_ID.h" #include "DNA_dynamicpaint_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_boid_types.h" #include <stdio.h> /* for FILE */ @@ -141,7 +141,7 @@ typedef struct PTCacheID { unsigned int default_step; unsigned int max_step; - /* flags defined in DNA_object_force.h */ + /* flags defined in DNA_object_force_types.h */ unsigned int data_types, info_types; /* copies point data to cache data */ diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h index d2ab4f3164c..0c4f2bc9c05 100644 --- a/source/blender/blenkernel/BKE_shrinkwrap.h +++ b/source/blender/blenkernel/BKE_shrinkwrap.h @@ -54,6 +54,7 @@ struct ShrinkwrapModifierData; struct MDeformVert; struct BVHTree; struct SpaceTransform; +struct EvaluationContext; typedef struct ShrinkwrapCalcData { @@ -76,8 +77,10 @@ typedef struct ShrinkwrapCalcData { } ShrinkwrapCalcData; -void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Object *ob, struct DerivedMesh *dm, - float (*vertexCos)[3], int numVerts, bool for_render); +void shrinkwrapModifier_deform( + const struct EvaluationContext *eval_ctx, + struct ShrinkwrapModifierData *smd, struct Object *ob, struct DerivedMesh *dm, + float (*vertexCos)[3], int numVerts, bool for_render); /* * This function casts a ray in the given BVHTree.. but it takes into consideration the space_transform, that is: diff --git a/source/blender/blenkernel/BKE_workspace.h b/source/blender/blenkernel/BKE_workspace.h index 9f989f7ae8f..b309ae838d6 100644 --- a/source/blender/blenkernel/BKE_workspace.h +++ b/source/blender/blenkernel/BKE_workspace.h @@ -34,17 +34,6 @@ struct Scene; struct TransformOrientation; struct ViewLayer; -/** - * Plan is to store the object-mode per workspace, not per object anymore. - * However, there's quite some work to be done for that, so for now, there is just a basic - * implementation of an object <-> workspace object-mode syncing for testing, with some known - * problems. Main problem being that the modes can get out of sync when changing object selection. - * Would require a pile of temporary changes to always sync modes when changing selection. So just - * leaving this here for some testing until object-mode is really a workspace level setting. - */ -#define USE_WORKSPACE_MODE - - /* -------------------------------------------------------------------- */ /* Create, delete, init */ @@ -106,15 +95,6 @@ void BKE_workspace_active_layout_set(struct WorkSpaceInstanceHook *h struct bScreen *BKE_workspace_active_screen_get(const struct WorkSpaceInstanceHook *hook) GETTER_ATTRS; void BKE_workspace_active_screen_set( struct WorkSpaceInstanceHook *hook, struct WorkSpace *workspace, struct bScreen *screen) SETTER_ATTRS; -#ifdef USE_WORKSPACE_MODE -enum eObjectMode BKE_workspace_object_mode_get( - const struct WorkSpace *workspace, - const struct Scene *scene) GETTER_ATTRS; -void BKE_workspace_object_mode_set( - struct WorkSpace *workspace, - struct Scene *scene, - const enum eObjectMode mode) SETTER_ATTRS; -#endif struct Base *BKE_workspace_active_base_get(const struct WorkSpace *workspace, const struct Scene *scene); struct ListBase *BKE_workspace_transform_orientations_get(struct WorkSpace *workspace) GETTER_ATTRS; struct ViewLayer *BKE_workspace_view_layer_get( @@ -149,6 +129,13 @@ void BKE_workspace_update_tagged(struct EvaluationContext *eval_ctx, struct WorkSpace *workspace, struct Scene *scene); +void BKE_workspace_update_object_mode( + struct EvaluationContext *eval_ctx, + struct WorkSpace *workspace); + +struct Object *BKE_workspace_edit_object( + struct WorkSpace *workspace, struct Scene *scene); + #undef GETTER_ATTRS #undef SETTER_ATTRS diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 279068c440e..3f6bb5b9954 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -315,6 +315,7 @@ set(SRC nla_private.h tracking_private.h + particle_private.h intern/CCGSubSurf.h intern/CCGSubSurf_inline.h intern/CCGSubSurf_intern.h diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index cfeca50a751..67463ffe915 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -51,6 +51,8 @@ #include "BLI_linklist.h" #include "BLI_task.h" +#include "DEG_depsgraph.h" + #include "BKE_cdderivedmesh.h" #include "BKE_colorband.h" #include "BKE_editmesh.h" @@ -1660,7 +1662,7 @@ static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape cos = CustomData_get_layer_n(&dm->vertData, CD_SHAPEKEY, i); kb->totelem = dm->numVertData; - kb->data = kbcos = MEM_malloc_arrayN(kb->totelem, sizeof(float), "kbcos DerivedMesh.c"); + kb->data = kbcos = MEM_malloc_arrayN(kb->totelem, 3 * sizeof(float), "kbcos DerivedMesh.c"); if (kb->uid == actshape_uid) { MVert *mvert = dm->getVertArray(dm); @@ -1776,17 +1778,19 @@ static void mesh_calc_modifiers( MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); const bool has_multires = (mmd && mmd->sculptlvl != 0); bool multires_applied = false; - const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt && !useRenderParams; + const bool sculpt_mode = eval_ctx->object_mode & OB_MODE_SCULPT && ob->sculpt && !useRenderParams; const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm) && !useRenderParams; const int draw_flag = dm_drawflag_calc(scene->toolsettings, me); /* Generic preview only in object mode! */ - const bool do_mod_mcol = (ob->mode == OB_MODE_OBJECT); + const bool do_mod_mcol = (eval_ctx->object_mode == OB_MODE_OBJECT); #if 0 /* XXX Will re-enable this when we have global mod stack options. */ const bool do_final_wmcol = (scene->toolsettings->weights_preview == WP_WPREVIEW_FINAL) && do_wmcol; #endif const bool do_final_wmcol = false; - const bool do_init_wmcol = ((dataMask & CD_MASK_PREVIEW_MLOOPCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT) && !do_final_wmcol); + const bool do_init_wmcol = ( + (dataMask & CD_MASK_PREVIEW_MLOOPCOL) && + (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) && !do_final_wmcol); /* XXX Same as above... For now, only weights preview in WPaint mode. */ const bool do_mod_wmcol = do_init_wmcol; @@ -2624,7 +2628,7 @@ static bool calc_modifiers_skip_orco(const EvaluationContext *eval_ctx, if (U.opensubdiv_compute_type == USER_OPENSUBDIV_COMPUTE_NONE) { return false; } - else if ((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) != 0) { + else if ((eval_ctx->object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) != 0) { return false; } else if ((DEG_get_eval_flags_for_id(eval_ctx->depsgraph, &ob->id) & DAG_EVAL_NEED_CPU) != 0) { @@ -2665,7 +2669,7 @@ static void mesh_build_data( ob->lastDataMask = dataMask; ob->lastNeedMapping = need_mapping; - if ((ob->mode & OB_MODE_ALL_SCULPT) && ob->sculpt) { + if ((eval_ctx->object_mode & OB_MODE_ALL_SCULPT) && ob->sculpt) { /* create PBVH immediately (would be created on the fly too, * but this avoids waiting on first stroke) */ @@ -2703,7 +2707,9 @@ static void editbmesh_build_data( BLI_assert(!(em->derivedFinal->dirty & DM_DIRTY_NORMALS)); } -static CustomDataMask object_get_datamask(const Scene *scene, Object *ob, bool *r_need_mapping) +static CustomDataMask object_get_datamask( + const EvaluationContext *eval_ctx, + const Scene *scene, Object *ob, bool *r_need_mapping) { /* TODO(sergey): Avoid this linear list lookup. */ ViewLayer *view_layer = BKE_view_layer_context_active_PLACEHOLDER(scene); @@ -2715,28 +2721,28 @@ static CustomDataMask object_get_datamask(const Scene *scene, Object *ob, bool * } if (ob == actob) { - bool editing = BKE_paint_select_face_test(ob); + bool editing = BKE_paint_select_face_test(ob, eval_ctx->object_mode); /* weight paint and face select need original indices because of selection buffer drawing */ if (r_need_mapping) { - *r_need_mapping = (editing || (ob->mode & (OB_MODE_WEIGHT_PAINT | OB_MODE_VERTEX_PAINT))); + *r_need_mapping = (editing || (eval_ctx->object_mode & (OB_MODE_WEIGHT_PAINT | OB_MODE_VERTEX_PAINT))); } /* check if we need tfaces & mcols due to face select or texture paint */ - if ((ob->mode & OB_MODE_TEXTURE_PAINT) || editing) { + if ((eval_ctx->object_mode & OB_MODE_TEXTURE_PAINT) || editing) { mask |= CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL; } /* check if we need mcols due to vertex paint or weightpaint */ - if (ob->mode & OB_MODE_VERTEX_PAINT) { + if (eval_ctx->object_mode & OB_MODE_VERTEX_PAINT) { mask |= CD_MASK_MLOOPCOL; } - if (ob->mode & OB_MODE_WEIGHT_PAINT) { + if (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) { mask |= CD_MASK_PREVIEW_MLOOPCOL; } - if (ob->mode & OB_MODE_EDIT) + if (eval_ctx->object_mode & OB_MODE_EDIT) mask |= CD_MASK_MVERT_SKIN; } @@ -2748,7 +2754,7 @@ void makeDerivedMesh( CustomDataMask dataMask, const bool build_shapekey_layers) { bool need_mapping; - dataMask |= object_get_datamask(scene, ob, &need_mapping); + dataMask |= object_get_datamask(eval_ctx, scene, ob, &need_mapping); if (em) { editbmesh_build_data(eval_ctx, scene, ob, em, dataMask); @@ -2767,7 +2773,7 @@ DerivedMesh *mesh_get_derived_final( * the data we need, rebuild the derived mesh */ bool need_mapping; - dataMask |= object_get_datamask(scene, ob, &need_mapping); + dataMask |= object_get_datamask(eval_ctx, scene, ob, &need_mapping); if (!ob->derivedFinal || ((dataMask & ob->lastDataMask) != dataMask) || @@ -2787,7 +2793,7 @@ DerivedMesh *mesh_get_derived_deform(const struct EvaluationContext *eval_ctx, S */ bool need_mapping; - dataMask |= object_get_datamask(scene, ob, &need_mapping); + dataMask |= object_get_datamask(eval_ctx, scene, ob, &need_mapping); if (!ob->derivedDeform || ((dataMask & ob->lastDataMask) != dataMask) || @@ -2906,7 +2912,7 @@ DerivedMesh *editbmesh_get_derived_cage_and_final( /* if there's no derived mesh or the last data mask used doesn't include * the data we need, rebuild the derived mesh */ - dataMask |= object_get_datamask(scene, obedit, NULL); + dataMask |= object_get_datamask(eval_ctx, scene, obedit, NULL); if (!em->derivedCage || (em->lastDataMask & dataMask) != dataMask) @@ -2926,7 +2932,7 @@ DerivedMesh *editbmesh_get_derived_cage( /* if there's no derived mesh or the last data mask used doesn't include * the data we need, rebuild the derived mesh */ - dataMask |= object_get_datamask(scene, obedit, NULL); + dataMask |= object_get_datamask(eval_ctx, scene, obedit, NULL); if (!em->derivedCage || (em->lastDataMask & dataMask) != dataMask) @@ -3719,7 +3725,7 @@ void DM_init_origspace(DerivedMesh *dm) BKE_mesh_calc_poly_normal(mp, l, mv, p_nor); axis_dominant_v3_to_m3(mat, p_nor); - BLI_array_empty(vcos_2d); + BLI_array_clear(vcos_2d); BLI_array_reserve(vcos_2d, mp->totloop); for (j = 0; j < mp->totloop; j++, l++) { mul_v3_m3v3(co, mat, mv[l->v].co); diff --git a/source/blender/blenkernel/intern/addon.c b/source/blender/blenkernel/intern/addon.c index 0ef12397fe7..689e0fb5ee6 100644 --- a/source/blender/blenkernel/intern/addon.c +++ b/source/blender/blenkernel/intern/addon.c @@ -27,13 +27,58 @@ #include <stddef.h> #include <stdlib.h> +#include "RNA_types.h" + #include "BLI_utildefines.h" #include "BLI_ghash.h" +#include "BLI_string.h" +#include "BLI_listbase.h" #include "BKE_addon.h" /* own include */ +#include "BKE_idprop.h" + +#include "DNA_listBase.h" +#include "DNA_userdef_types.h" + #include "MEM_guardedalloc.h" +/* -------------------------------------------------------------------- */ +/** \name Add-on New/Free + * \{ */ + +bAddon *BKE_addon_new(void) +{ + bAddon *addon = MEM_callocN(sizeof(bAddon), "bAddon"); + return addon; +} + +bAddon *BKE_addon_ensure(ListBase *addon_list, const char *module) +{ + bAddon *addon = BLI_findstring(addon_list, module, offsetof(bAddon, module)); + if (addon == NULL) { + addon = BKE_addon_new(); + BLI_strncpy(addon->module, module, sizeof(addon->module)); + BLI_addtail(addon_list, addon); + } + return addon; +} + +void BKE_addon_free(bAddon *addon) +{ + if (addon->prop) { + IDP_FreeProperty(addon->prop); + MEM_freeN(addon->prop); + } + MEM_freeN(addon); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Add-on Preference API + * \{ */ + static GHash *global_addonpreftype_hash = NULL; @@ -81,3 +126,5 @@ void BKE_addon_pref_type_free(void) BLI_ghash_free(global_addonpreftype_hash, NULL, MEM_freeN); global_addonpreftype_hash = NULL; } + +/** \} */ diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c index 1b8bf3feb10..de0dfe2530d 100644 --- a/source/blender/blenkernel/intern/armature_update.c +++ b/source/blender/blenkernel/intern/armature_update.c @@ -588,13 +588,15 @@ void BKE_pose_eval_init_ik(const struct EvaluationContext *eval_ctx, Object *ob, bPose *UNUSED(pose)) { - float ctime = BKE_scene_frame_get(scene); /* not accurate... */ - DEBUG_PRINT("%s on %s\n", __func__, ob->id.name); - + BLI_assert(ob->type == OB_ARMATURE); + const float ctime = BKE_scene_frame_get(scene); /* not accurate... */ + bArmature *arm = (bArmature *)ob->data; + if (arm->flag & ARM_RESTPOS) { + return; + } /* 2a. construct the IK tree (standard IK) */ BIK_initialize_tree(eval_ctx, scene, ob, ctime); - /* 2b. construct the Spline IK trees * - this is not integrated as an IK plugin, since it should be able * to function in conjunction with standard IK @@ -607,9 +609,9 @@ void BKE_pose_eval_bone(const struct EvaluationContext *eval_ctx, Object *ob, bPoseChannel *pchan) { - bArmature *arm = (bArmature *)ob->data; DEBUG_PRINT("%s on %s pchan %s\n", __func__, ob->id.name, pchan->name); BLI_assert(ob->type == OB_ARMATURE); + bArmature *arm = (bArmature *)ob->data; if (arm->edbo || (arm->flag & ARM_RESTPOS)) { Bone *bone = pchan->bone; if (bone) { @@ -674,8 +676,13 @@ void BKE_pose_iktree_evaluate(const struct EvaluationContext *eval_ctx, Object *ob, bPoseChannel *rootchan) { - float ctime = BKE_scene_frame_get(scene); /* not accurate... */ DEBUG_PRINT("%s on %s pchan %s\n", __func__, ob->id.name, rootchan->name); + BLI_assert(ob->type == OB_ARMATURE); + const float ctime = BKE_scene_frame_get(scene); /* not accurate... */ + bArmature *arm = (bArmature *)ob->data; + if (arm->flag & ARM_RESTPOS) { + return; + } BIK_execute_tree(eval_ctx, scene, ob, rootchan, ctime); } @@ -684,8 +691,13 @@ void BKE_pose_splineik_evaluate(const struct EvaluationContext *eval_ctx, Object *ob, bPoseChannel *rootchan) { - float ctime = BKE_scene_frame_get(scene); /* not accurate... */ DEBUG_PRINT("%s on %s pchan %s\n", __func__, ob->id.name, rootchan->name); + BLI_assert(ob->type == OB_ARMATURE); + const float ctime = BKE_scene_frame_get(scene); /* not accurate... */ + bArmature *arm = (bArmature *)ob->data; + if (arm->flag & ARM_RESTPOS) { + return; + } BKE_splineik_execute_tree(eval_ctx, scene, ob, rootchan, ctime); } diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 182b88c1c57..e9a6d0fe5a5 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -45,6 +45,7 @@ #include "IMB_imbuf.h" #include "IMB_moviecache.h" +#include "BKE_addon.h" #include "BKE_blender.h" /* own include */ #include "BKE_blender_version.h" /* own include */ #include "BKE_blendfile.h" @@ -202,11 +203,7 @@ static void userdef_free_addons(UserDef *userdef) { for (bAddon *addon = userdef->addons.first, *addon_next; addon; addon = addon_next) { addon_next = addon->next; - if (addon->prop) { - IDP_FreeProperty(addon->prop); - MEM_freeN(addon->prop); - } - MEM_freeN(addon); + BKE_addon_free(addon); } BLI_listbase_clear(&userdef->addons); } diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index 8c78787c259..f440ce711ff 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -35,7 +35,7 @@ #include "MEM_guardedalloc.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_scene_types.h" #include "BLI_rand.h" diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c index 158c6c31432..e9a8de4469d 100644 --- a/source/blender/blenkernel/intern/bpath.c +++ b/source/blender/blenkernel/intern/bpath.c @@ -53,8 +53,8 @@ #include "DNA_mesh_types.h" #include "DNA_modifier_types.h" #include "DNA_movieclip_types.h" -#include "DNA_object_fluidsim.h" -#include "DNA_object_force.h" +#include "DNA_object_fluidsim_types.h" +#include "DNA_object_force_types.h" #include "DNA_object_types.h" #include "DNA_particle_types.h" #include "DNA_sequence_types.h" diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 8d63c1cfb44..d82c1ca56fe 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -151,7 +151,7 @@ void BKE_brush_init(Brush *brush) /** * \note Resulting brush will have two users: one as a fake user, another is assumed to be used by the caller. */ -Brush *BKE_brush_add(Main *bmain, const char *name, short ob_mode) +Brush *BKE_brush_add(Main *bmain, const char *name, const eObjectMode ob_mode) { Brush *brush; @@ -164,7 +164,7 @@ Brush *BKE_brush_add(Main *bmain, const char *name, short ob_mode) return brush; } -struct Brush *BKE_brush_first_search(struct Main *bmain, short ob_mode) +struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode) { Brush *brush; diff --git a/source/blender/blenkernel/intern/bullet.c b/source/blender/blenkernel/intern/bullet.c index 088031e16a7..c16c0f7af31 100644 --- a/source/blender/blenkernel/intern/bullet.c +++ b/source/blender/blenkernel/intern/bullet.c @@ -33,7 +33,7 @@ #include "MEM_guardedalloc.h" /* types */ -#include "DNA_object_force.h" /* here is the softbody struct */ +#include "DNA_object_force_types.h" /* here is the softbody struct */ #include "BKE_bullet.h" diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c index 775499304d4..cd2c7194237 100644 --- a/source/blender/blenkernel/intern/bvhutils.c +++ b/source/blender/blenkernel/intern/bvhutils.c @@ -411,7 +411,7 @@ static BVHTree *bvhtree_from_editmesh_verts_create_tree( BMVert *eve = BM_vert_at_index(em->bm, i); BLI_bvhtree_insert(tree, i, eve->co, 1); } - BLI_assert(BLI_bvhtree_get_size(tree) == verts_num_active); + BLI_assert(BLI_bvhtree_get_len(tree) == verts_num_active); BLI_bvhtree_balance(tree); } @@ -440,7 +440,7 @@ static BVHTree *bvhtree_from_mesh_verts_create_tree( } BLI_bvhtree_insert(tree, i, vert[i].co, 1); } - BLI_assert(BLI_bvhtree_get_size(tree) == verts_num_active); + BLI_assert(BLI_bvhtree_get_len(tree) == verts_num_active); BLI_bvhtree_balance(tree); } @@ -612,7 +612,7 @@ static BVHTree *bvhtree_from_editmesh_edges_create_tree( BLI_bvhtree_insert(tree, i, co[0], 2); } - BLI_assert(BLI_bvhtree_get_size(tree) == edges_num_active); + BLI_assert(BLI_bvhtree_get_len(tree) == edges_num_active); BLI_bvhtree_balance(tree); } @@ -829,7 +829,7 @@ static BVHTree *bvhtree_from_mesh_faces_create_tree( BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3); } } - BLI_assert(BLI_bvhtree_get_size(tree) == faces_num_active); + BLI_assert(BLI_bvhtree_get_len(tree) == faces_num_active); BLI_bvhtree_balance(tree); } } @@ -990,7 +990,7 @@ static BVHTree *bvhtree_from_editmesh_looptri_create_tree( } } } - BLI_assert(BLI_bvhtree_get_size(tree) == looptri_num_active); + BLI_assert(BLI_bvhtree_get_len(tree) == looptri_num_active); BLI_bvhtree_balance(tree); } } @@ -1032,7 +1032,7 @@ static BVHTree *bvhtree_from_mesh_looptri_create_tree( BLI_bvhtree_insert(tree, i, co[0], 3); } } - BLI_assert(BLI_bvhtree_get_size(tree) == looptri_num_active); + BLI_assert(BLI_bvhtree_get_len(tree) == looptri_num_active); BLI_bvhtree_balance(tree); } } diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index ea54548ab09..fc860817a83 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -64,6 +64,8 @@ #include "GPU_shader.h" #include "GPU_basic_shader.h" +#include "DEG_depsgraph.h" + #include <string.h> #include <limits.h> #include <math.h> @@ -260,7 +262,8 @@ static bool can_pbvh_draw(Object *ob, DerivedMesh *dm) return cddm->mvert == me->mvert || ob->sculpt->kb; } -static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm) +static PBVH *cdDM_getPBVH( + Object *ob, DerivedMesh *dm, eObjectMode UNUSED(object_mode)) { CDDerivedMesh *cddm = (CDDerivedMesh *) dm; @@ -3307,7 +3310,7 @@ void CDDM_calc_edges_tessface(DerivedMesh *dm) } } - numEdges = BLI_edgeset_size(eh); + numEdges = BLI_edgeset_len(eh); /* write new edges into a temporary CustomData */ CustomData_reset(&edgeData); @@ -3376,7 +3379,7 @@ void CDDM_calc_edges(DerivedMesh *dm) } } - numEdges = BLI_edgehash_size(eh); + numEdges = BLI_edgehash_len(eh); /* write new edges into a temporary CustomData */ CustomData_reset(&edgeData); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 09b793629f7..22fd0bbfa9c 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -40,6 +40,8 @@ #include "BLI_edgehash.h" #include "BLI_linklist.h" +#include "DEG_depsgraph.h" + #include "BKE_cdderivedmesh.h" #include "BKE_cloth.h" #include "BKE_effect.h" @@ -304,14 +306,14 @@ void bvhselftree_update_from_cloth(ClothModifierData *clmd, bool moving) } } -void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) +void cloth_clear_cache(const EvaluationContext *eval_ctx, Object *ob, ClothModifierData *clmd, float framenr) { PTCacheID pid; BKE_ptcache_id_from_cloth(&pid, ob, clmd); // don't do anything as long as we're in editmode! - if (pid.cache->edit && ob->mode & OB_MODE_PARTICLE_EDIT) + if (pid.cache->edit && eval_ctx->object_mode & OB_MODE_PARTICLE_EDIT) return; BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_AFTER, framenr); diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index ca77969ccaa..c92096efd07 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -68,10 +68,9 @@ static SceneCollection *collection_master_from_id(const ID *owner_id) } /** - * Add a collection to a collection ListBase and syncronize all render layers - * The ListBase is NULL when the collection is to be added to the master collection + * Add a new collection, but don't handle syncing with layer collections */ -SceneCollection *BKE_collection_add(ID *owner_id, SceneCollection *sc_parent, const int type, const char *name_custom) +static SceneCollection *collection_add(ID *owner_id, SceneCollection *sc_parent, const int type, const char *name_custom) { SceneCollection *sc_master = collection_master_from_id(owner_id); SceneCollection *sc = MEM_callocN(sizeof(SceneCollection), "New Collection"); @@ -89,17 +88,13 @@ SceneCollection *BKE_collection_add(ID *owner_id, SceneCollection *sc_parent, co else { const int number = BLI_listbase_count(&sc_parent->scene_collections) + 1; const int digits = integer_digits_i(number); - const int max_len = sizeof(sc_parent->name) - - 1 /* NULL terminator */ - - (1 + digits) /* " %d" */; + const int max_len = sizeof(sc_parent->name) - 1 /* NULL terminator */ - (1 + digits) /* " %d" */; name = BLI_sprintfN("%.*s %d", max_len, sc_parent->name, number); } } BLI_addtail(&sc_parent->scene_collections, sc); - BKE_collection_rename((Scene *)owner_id, sc, name); - - BKE_layer_sync_new_scene_collection(owner_id, sc_parent, sc); + BKE_collection_rename(owner_id, sc, name); if (name != name_custom) { MEM_freeN((char *)name); @@ -109,6 +104,21 @@ SceneCollection *BKE_collection_add(ID *owner_id, SceneCollection *sc_parent, co } /** + * Add a collection to a collection ListBase and syncronize all render layers + * The ListBase is NULL when the collection is to be added to the master collection + */ +SceneCollection *BKE_collection_add(ID *owner_id, SceneCollection *sc_parent, const int type, const char *name_custom) +{ + if (sc_parent == NULL) { + sc_parent = BKE_collection_master(owner_id); + } + + SceneCollection *scene_collection = collection_add(owner_id, sc_parent, type, name_custom); + BKE_layer_sync_new_scene_collection(owner_id, sc_parent, scene_collection); + return scene_collection; +} + +/** * Free the collection items recursively */ static void collection_free(SceneCollection *sc, const bool do_id_user) @@ -270,6 +280,43 @@ void BKE_collection_copy_data(SceneCollection *sc_dst, SceneCollection *sc_src, } } +/** + * Makes a shallow copy of a SceneCollection + * + * Add a new collection in the same level as the old one, copy any nested collections + * but link the objects to the new collection (as oppose to copy them). + */ +SceneCollection *BKE_collection_duplicate(ID *owner_id, SceneCollection *scene_collection) +{ + SceneCollection *scene_collection_master = BKE_collection_master(owner_id); + SceneCollection *scene_collection_parent = find_collection_parent(scene_collection, scene_collection_master); + + /* It's not allowed to copy the master collection. */ + if (scene_collection_master == scene_collection) { + return NULL; + } + + SceneCollection *scene_collection_new = collection_add( + owner_id, + scene_collection_parent, + scene_collection->type, + scene_collection->name); + + if (scene_collection_new != scene_collection->next) { + BLI_remlink(&scene_collection_parent->scene_collections, scene_collection_new); + BLI_insertlinkafter(&scene_collection_parent->scene_collections, scene_collection, scene_collection_new); + } + + BKE_collection_copy_data(scene_collection_new, scene_collection, 0); + BKE_layer_sync_new_scene_collection(owner_id, scene_collection_parent, scene_collection_new); + + /* Make sure every linked instance of the new collection has the same values (flags, overrides, ...) as the + * corresponding original collection. */ + BKE_layer_collection_sync_flags(owner_id, scene_collection_new, scene_collection); + + return scene_collection_new; +} + static SceneCollection *master_collection_from_id(const ID *owner_id) { switch (GS(owner_id->name)) { @@ -298,9 +345,9 @@ static void collection_rename(const ID *owner_id, SceneCollection *sc, const cha BLI_uniquename(&sc_parent->scene_collections, sc, DATA_("Collection"), '.', offsetof(SceneCollection, name), sizeof(sc->name)); } -void BKE_collection_rename(const Scene *scene, SceneCollection *sc, const char *name) +void BKE_collection_rename(const ID *owner_id, SceneCollection *sc, const char *name) { - collection_rename(&scene->id, sc, name); + collection_rename(owner_id, sc, name); } /** diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 2f80fbbec46..21945f07a10 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -36,7 +36,7 @@ #include "DNA_effect_types.h" #include "DNA_group_types.h" #include "DNA_object_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_scene_types.h" #include "DNA_meshdata_types.h" diff --git a/source/blender/blenkernel/intern/colorband.c b/source/blender/blenkernel/intern/colorband.c index d35e797ddac..f72d4df725a 100644 --- a/source/blender/blenkernel/intern/colorband.c +++ b/source/blender/blenkernel/intern/colorband.c @@ -210,7 +210,7 @@ static void colorband_init_from_table_rgba_resample( while ((carr_len > 1 && !BLI_heap_is_empty(heap)) && ((carr_len >= MAXCOLORBAND) || (BLI_heap_node_value(BLI_heap_top(heap)) <= eps_2x))) { - c = BLI_heap_popmin(heap); + c = BLI_heap_pop_min(heap); struct ColorResampleElem *c_next = c->next, *c_prev = c->prev; c_prev->next = c_next; c_next->prev = c_prev; diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index a92299810ec..3d6080b8db9 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -1005,7 +1005,7 @@ SceneCollection *CTX_data_scene_collection(const bContext *C) return BKE_collection_master(&scene->id); } -int CTX_data_mode_enum_ex(const Object *obedit, const Object *ob) +int CTX_data_mode_enum_ex(const Object *obedit, const Object *ob, const eObjectMode object_mode) { // Object *obedit = CTX_data_edit_object(C); if (obedit) { @@ -1029,12 +1029,12 @@ int CTX_data_mode_enum_ex(const Object *obedit, const Object *ob) else { // Object *ob = CTX_data_active_object(C); if (ob) { - if (ob->mode & OB_MODE_POSE) return CTX_MODE_POSE; - else if (ob->mode & OB_MODE_SCULPT) return CTX_MODE_SCULPT; - else if (ob->mode & OB_MODE_WEIGHT_PAINT) return CTX_MODE_PAINT_WEIGHT; - else if (ob->mode & OB_MODE_VERTEX_PAINT) return CTX_MODE_PAINT_VERTEX; - else if (ob->mode & OB_MODE_TEXTURE_PAINT) return CTX_MODE_PAINT_TEXTURE; - else if (ob->mode & OB_MODE_PARTICLE_EDIT) return CTX_MODE_PARTICLE; + if (object_mode & OB_MODE_POSE) return CTX_MODE_POSE; + else if (object_mode & OB_MODE_SCULPT) return CTX_MODE_SCULPT; + else if (object_mode & OB_MODE_WEIGHT_PAINT) return CTX_MODE_PAINT_WEIGHT; + else if (object_mode & OB_MODE_VERTEX_PAINT) return CTX_MODE_PAINT_VERTEX; + else if (object_mode & OB_MODE_TEXTURE_PAINT) return CTX_MODE_PAINT_TEXTURE; + else if (object_mode & OB_MODE_PARTICLE_EDIT) return CTX_MODE_PARTICLE; } } @@ -1043,9 +1043,10 @@ int CTX_data_mode_enum_ex(const Object *obedit, const Object *ob) int CTX_data_mode_enum(const bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *obedit = CTX_data_edit_object(C); Object *obact = obedit ? NULL : CTX_data_active_object(C); - return CTX_data_mode_enum_ex(obedit, obact); + return CTX_data_mode_enum_ex(obedit, obact, workspace->object_mode); } /* would prefer if we can use the enum version below over this one - Campbell */ @@ -1282,7 +1283,9 @@ void CTX_data_eval_ctx(const bContext *C, EvaluationContext *eval_ctx) Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); RenderEngineType *engine_type = CTX_data_engine_type(C); - DEG_evaluation_context_init_from_scene(eval_ctx, - scene, view_layer, engine_type, - DAG_EVAL_VIEWPORT); + WorkSpace *workspace = CTX_wm_workspace(C); + DEG_evaluation_context_init_from_scene( + eval_ctx, + scene, view_layer, engine_type, + workspace->object_mode, DAG_EVAL_VIEWPORT); } diff --git a/source/blender/blenkernel/intern/curve_decimate.c b/source/blender/blenkernel/intern/curve_decimate.c index 7983c63c99d..1a6c4714afd 100644 --- a/source/blender/blenkernel/intern/curve_decimate.c +++ b/source/blender/blenkernel/intern/curve_decimate.c @@ -159,7 +159,7 @@ static void curve_decimate( struct Knot *k; { - struct Removal *r = BLI_heap_popmin(heap); + struct Removal *r = BLI_heap_pop_min(heap); k = &knots[r->knot_index]; k->heap_node = NULL; k->prev->handles[1] = r->handles[0]; diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 2591c3c3c47..349f995819c 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -4555,7 +4555,7 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface, } /* begin thread safe malloc */ - BLI_begin_threaded_malloc(); + BLI_threaded_malloc_begin(); /* only continue if particle bb is close enough to canvas bb */ if (boundsIntersectDist(&grid->grid_bounds, &part_bb, range)) { @@ -4590,7 +4590,7 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface, &settings); } } - BLI_end_threaded_malloc(); + BLI_threaded_malloc_end(); BLI_kdtree_free(tree); return 1; diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 0491cbd21f0..2018962eb62 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -44,7 +44,7 @@ #include "atomic_ops.h" #include "BLI_math.h" -#include "BLI_jitter.h" +#include "BLI_jitter_2d.h" #include "BLI_bitmap.h" #include "BLI_task.h" diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 16124fb4777..b54093555f5 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -42,7 +42,7 @@ #include "DNA_listBase.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_particle_types.h" #include "DNA_texture_types.h" #include "DNA_scene_types.h" @@ -221,7 +221,8 @@ ListBase *pdInitEffectors( if (weights->group) { view_layer = weights->group->view_layer; } - else if (eval_ctx) { + /* TODO(mai): the check for view_layer shouldnt be needed, remove when render engine api is updated for this */ + else if (eval_ctx && eval_ctx->view_layer) { view_layer = eval_ctx->view_layer; } else { diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c index 12b9abc6d03..a4ed7a9d63f 100644 --- a/source/blender/blenkernel/intern/fluidsim.c +++ b/source/blender/blenkernel/intern/fluidsim.c @@ -40,8 +40,8 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" -#include "DNA_object_fluidsim.h" -#include "DNA_object_force.h" // for pointcache +#include "DNA_object_fluidsim_types.h" +#include "DNA_object_force_types.h" // for pointcache #include "DNA_object_types.h" #include "DNA_particle_types.h" #include "DNA_scene_types.h" diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index a314cc0a131..5545eba8764 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -1080,8 +1080,13 @@ makebreak: float distfac, imat[4][4], imat3[3][3], cmat[3][3]; float minx, maxx, miny, maxy; float timeofs, sizefac; - - invert_m4_m4(imat, ob->obmat); + + if (ob != NULL) { + invert_m4_m4(imat, ob->obmat); + } + else { + unit_m4(imat); + } copy_m3_m4(imat3, imat); copy_m3_m4(cmat, cu->textoncurve->obmat); diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c index ca6d92efa80..c615f67fe42 100644 --- a/source/blender/blenkernel/intern/group.c +++ b/source/blender/blenkernel/intern/group.c @@ -387,7 +387,7 @@ static void group_eval_layer_collections( ListBase *layer_collections, LayerCollection *parent_layer_collection) { - BLI_LISTBASE_FOREACH (LayerCollection *, layer_collection, layer_collections) { + LISTBASE_FOREACH (LayerCollection *, layer_collection, layer_collections) { /* Evaluate layer collection itself. */ BKE_layer_eval_layer_collection(eval_ctx, layer_collection, diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index d720dc41abf..d38987c942f 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2548,7 +2548,7 @@ void BKE_image_verify_viewer_views(const RenderData *rd, Image *ima, ImageUser * bool do_reset; const bool is_multiview = (rd->scemode & R_MULTIVIEW) != 0; - BLI_lock_thread(LOCK_DRAW_IMAGE); + BLI_thread_lock(LOCK_DRAW_IMAGE); if (!BKE_scene_multiview_is_stereo3d(rd)) iuser->flag &= ~IMA_SHOW_STEREO; @@ -2582,7 +2582,7 @@ void BKE_image_verify_viewer_views(const RenderData *rd, Image *ima, ImageUser * BLI_spin_unlock(&image_spin); } - BLI_unlock_thread(LOCK_DRAW_IMAGE); + BLI_thread_unlock(LOCK_DRAW_IMAGE); } void BKE_image_walk_all_users(const Main *mainp, void *customdata, @@ -3663,7 +3663,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc /* release is done in BKE_image_release_ibuf using r_lock */ if (from_render) { - BLI_lock_thread(LOCK_VIEWER); + BLI_thread_lock(LOCK_VIEWER); *r_lock = re; rv = NULL; } @@ -3756,7 +3756,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc } /* invalidate color managed buffers if render result changed */ - BLI_lock_thread(LOCK_COLORMANAGE); + BLI_thread_lock(LOCK_COLORMANAGE); if (ibuf->x != rres.rectx || ibuf->y != rres.recty || ibuf->rect_float != rectf) { ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; } @@ -3797,7 +3797,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc ibuf->flags &= ~IB_zbuffloat; } - BLI_unlock_thread(LOCK_COLORMANAGE); + BLI_thread_unlock(LOCK_COLORMANAGE); ibuf->dither = dither; @@ -3999,7 +3999,7 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock) /* requires lock/unlock, otherwise don't return image */ if (r_lock) { /* unlock in BKE_image_release_ibuf */ - BLI_lock_thread(LOCK_VIEWER); + BLI_thread_lock(LOCK_VIEWER); *r_lock = ima; /* XXX anim play for viewer nodes not yet supported */ @@ -4052,11 +4052,11 @@ void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock) if (lock) { /* for getting image during threaded render / compositing, need to release */ if (lock == ima) { - BLI_unlock_thread(LOCK_VIEWER); /* viewer image */ + BLI_thread_unlock(LOCK_VIEWER); /* viewer image */ } else if (lock) { RE_ReleaseResultImage(lock); /* render result */ - BLI_unlock_thread(LOCK_VIEWER); /* view image imbuf */ + BLI_thread_unlock(LOCK_VIEWER); /* view image imbuf */ } } diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c index c6515d0c47a..8e7b7f5456b 100644 --- a/source/blender/blenkernel/intern/layer.c +++ b/source/blender/blenkernel/intern/layer.c @@ -61,6 +61,7 @@ /* prototype */ struct EngineSettingsCB_Type; +static void layer_collections_sync_flags(ListBase *layer_collections_dst, const ListBase *layer_collections_src); static void layer_collection_free(ViewLayer *view_layer, LayerCollection *lc); static void layer_collection_objects_populate(ViewLayer *view_layer, LayerCollection *lc, ListBase *objects); static LayerCollection *layer_collection_add(ViewLayer *view_layer, LayerCollection *parent, SceneCollection *sc); @@ -353,27 +354,95 @@ static SceneCollection *scene_collection_from_new_tree( return NULL; } +static void layer_collection_sync_flags( + LayerCollection *layer_collection_dst, + const LayerCollection *layer_collection_src) +{ + layer_collection_dst->flag = layer_collection_src->flag; + + if (layer_collection_dst->properties != NULL) { + IDP_FreeProperty(layer_collection_dst->properties); + MEM_SAFE_FREE(layer_collection_dst->properties); + } + + if (layer_collection_src->properties != NULL) { + layer_collection_dst->properties = IDP_CopyProperty(layer_collection_src->properties); + } + + layer_collections_sync_flags(&layer_collection_dst->layer_collections, + &layer_collection_src->layer_collections); +} + static void layer_collections_sync_flags(ListBase *layer_collections_dst, const ListBase *layer_collections_src) { + BLI_assert(BLI_listbase_count(layer_collections_dst) == BLI_listbase_count(layer_collections_src)); LayerCollection *layer_collection_dst = (LayerCollection *)layer_collections_dst->first; const LayerCollection *layer_collection_src = (const LayerCollection *)layer_collections_src->first; while (layer_collection_dst != NULL) { - layer_collection_dst->flag = layer_collection_src->flag; + layer_collection_sync_flags(layer_collection_dst, layer_collection_src); + layer_collection_dst = layer_collection_dst->next; + layer_collection_src = layer_collection_src->next; + } +} - if (layer_collection_dst->properties != NULL) { - IDP_FreeProperty(layer_collection_dst->properties); - MEM_SAFE_FREE(layer_collection_dst->properties); +static bool layer_collection_sync_if_match( + ListBase *lb, + const SceneCollection *scene_collection_dst, + const SceneCollection *scene_collection_src) +{ + for (LayerCollection *layer_collection = lb->first; + layer_collection; + layer_collection = layer_collection->next) + { + if (layer_collection->scene_collection == scene_collection_src) { + LayerCollection *layer_collection_dst = + BLI_findptr( + lb, + scene_collection_dst, + offsetof(LayerCollection, scene_collection)); + + if (layer_collection_dst != NULL) { + layer_collection_sync_flags(layer_collection_dst, layer_collection); + } + return true; } - - if (layer_collection_src->properties != NULL) { - layer_collection_dst->properties = IDP_CopyProperty(layer_collection_src->properties); + else { + if (layer_collection_sync_if_match( + &layer_collection->layer_collections, + scene_collection_dst, + scene_collection_src)) + { + return true; + } } + } + return false; +} - layer_collections_sync_flags(&layer_collection_dst->layer_collections, - &layer_collection_src->layer_collections); - - layer_collection_dst = layer_collection_dst->next; - layer_collection_src = layer_collection_src->next; +/** + * Sync sibling collections across all view layers + * + * Make sure every linked instance of \a scene_collection_dst has the same values + * (flags, overrides, ...) as the corresponding scene_collection_src. + * + * \note expect scene_collection_dst to be scene_collection_src->next, and it also + * expects both collections to have the same ammount of sub-collections. + */ +void BKE_layer_collection_sync_flags( + ID *owner_id, + SceneCollection *scene_collection_dst, + SceneCollection *scene_collection_src) +{ + for (ViewLayer *view_layer = BKE_view_layer_first_from_id(owner_id); view_layer; view_layer = view_layer->next) { + for (LayerCollection *layer_collection = view_layer->layer_collections.first; + layer_collection; + layer_collection = layer_collection->next) + { + layer_collection_sync_if_match( + &layer_collection->layer_collections, + scene_collection_dst, + scene_collection_src); + } } } @@ -438,6 +507,78 @@ void BKE_view_layer_copy_data( } } +/** + * Find and return the ListBase of LayerCollection that has \a lc_child as one of its directly + * nested LayerCollection. + * + * \param lb_parent Initial ListBase of LayerCollection to look into recursively + * usually the view layer's collection list + */ +static ListBase *find_layer_collection_parent_list_base(ListBase *lb_parent, const LayerCollection *lc_child) +{ + for (LayerCollection *lc_nested = lb_parent->first; lc_nested; lc_nested = lc_nested->next) { + if (lc_nested == lc_child) { + return lb_parent; + } + + ListBase *found = find_layer_collection_parent_list_base(&lc_nested->layer_collections, lc_child); + if (found != NULL) { + return found; + } + } + + return NULL; +} + +/** + * Makes a shallow copy of a LayerCollection + * + * Add a new collection in the same level as the old one (linking if necessary), + * and copy all the collection data across them. + */ +struct LayerCollection *BKE_layer_collection_duplicate(struct ID *owner_id, struct LayerCollection *layer_collection) +{ + SceneCollection *scene_collection, *scene_collection_new; + + scene_collection = layer_collection->scene_collection; + scene_collection_new = BKE_collection_duplicate(owner_id, scene_collection); + + LayerCollection *layer_collection_new = NULL; + + /* If the original layer_collection was directly linked to the view layer + we need to link the new scene collection here as well. */ + for (ViewLayer *view_layer = BKE_view_layer_first_from_id(owner_id); view_layer; view_layer = view_layer->next) { + if (BLI_findindex(&view_layer->layer_collections, layer_collection) != -1) { + layer_collection_new = BKE_collection_link(view_layer, scene_collection_new); + layer_collection_sync_flags(layer_collection_new, layer_collection); + + if (layer_collection_new != layer_collection->next) { + BLI_remlink(&view_layer->layer_collections, layer_collection_new); + BLI_insertlinkafter(&view_layer->layer_collections, layer_collection, layer_collection_new); + } + break; + } + } + + /* Otherwise just try to find the corresponding layer collection to return it back. */ + if (layer_collection_new == NULL) { + for (ViewLayer *view_layer = BKE_view_layer_first_from_id(owner_id); view_layer; view_layer = view_layer->next) { + ListBase *layer_collections_parent; + layer_collections_parent = find_layer_collection_parent_list_base( + &view_layer->layer_collections, + layer_collection); + if (layer_collections_parent != NULL) { + layer_collection_new = BLI_findptr( + layer_collections_parent, + scene_collection_new, + offsetof(LayerCollection, scene_collection)); + break; + } + } + } + return layer_collection_new; +} + static void view_layer_object_base_unref(ViewLayer *view_layer, Base *base) { base->refcount--; @@ -988,6 +1129,34 @@ void BKE_layer_collection_resync(const ID *owner_id, const SceneCollection *sc) /* ---------------------------------------------------------------------- */ /** + * Select all the objects of this layer collection + * + * It also select the objects that are in nested collections. + * \note Recursive + */ +void BKE_layer_collection_objects_select(struct LayerCollection *layer_collection) +{ + if ((layer_collection->flag & COLLECTION_DISABLED) || + ((layer_collection->flag & COLLECTION_SELECTABLE) == 0)) + { + return; + } + + for (LinkData *link = layer_collection->object_bases.first; link; link = link->next) { + Base *base = link->data; + if (base->flag & BASE_SELECTABLED) { + base->flag |= BASE_SELECTED; + } + } + + for (LayerCollection *iter = layer_collection->layer_collections.first; iter; iter = iter->next) { + BKE_layer_collection_objects_select(iter); + } +} + +/* ---------------------------------------------------------------------- */ + +/** * Link a collection to a renderlayer * The collection needs to be created separately */ @@ -1970,10 +2139,11 @@ void BKE_renderable_objects_iterator_begin(BLI_Iterator *iter, void *data_in) { ObjectsRenderableIteratorData *data = data_in; + /* Tag objects to prevent going over the same object twice. */ for (Scene *scene = data->scene; scene; scene = scene->set) { for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) { for (Base *base = view_layer->object_bases.first; base; base = base->next) { - base->object->id.flag |= LIB_TAG_DOIT; + base->object->id.flag |= LIB_TAG_DOIT; } } } @@ -1981,8 +2151,8 @@ void BKE_renderable_objects_iterator_begin(BLI_Iterator *iter, void *data_in) ViewLayer *view_layer = data->scene->view_layers.first; data->iter.view_layer = view_layer; - Base base = {(Base *)view_layer->object_bases.first, NULL}; - data->iter.base = &base; + data->base_temp.next = view_layer->object_bases.first; + data->iter.base = &data->base_temp; data->iter.set = NULL; @@ -1992,6 +2162,9 @@ void BKE_renderable_objects_iterator_begin(BLI_Iterator *iter, void *data_in) void BKE_renderable_objects_iterator_next(BLI_Iterator *iter) { + /* Set it early in case we need to exit and we are running from within a loop. */ + iter->skip = true; + ObjectsRenderableIteratorData *data = iter->data; Base *base = data->iter.base->next; @@ -1999,11 +2172,17 @@ void BKE_renderable_objects_iterator_next(BLI_Iterator *iter) if (base != NULL) { Object *ob = base->object; - iter->current = ob; + /* We need to set the iter.base even if the rest fail otherwise + * we keep checking the exactly same base over and over again. */ data->iter.base = base; - if ((base->flag & BASE_VISIBLED) == 0) { - BKE_renderable_objects_iterator_next(iter); + if (ob->id.flag & LIB_TAG_DOIT) { + ob->id.flag &= ~LIB_TAG_DOIT; + + if ((base->flag & BASE_VISIBLED) != 0) { + iter->skip = false; + iter->current = ob; + } } return; } @@ -2013,30 +2192,23 @@ void BKE_renderable_objects_iterator_next(BLI_Iterator *iter) while ((data->iter.view_layer = data->iter.view_layer->next)) { ViewLayer *view_layer = data->iter.view_layer; if (view_layer->flag & VIEW_LAYER_RENDER) { - - Base base_iter = {(Base *)view_layer->object_bases.first, NULL}; - data->iter.base = &base_iter; - - BKE_renderable_objects_iterator_next(iter); + data->base_temp.next = view_layer->object_bases.first; + data->iter.base = &data->base_temp; return; } } /* Setup the "set" for the next iteration. */ - Scene scene = {.set = data->scene}; - data->iter.set = &scene; - BKE_renderable_objects_iterator_next(iter); + data->scene_temp.set = data->scene; + data->iter.set = &data->scene_temp; return; } /* Look for an object in the next set. */ while ((data->iter.set = data->iter.set->set)) { ViewLayer *view_layer = BKE_view_layer_from_scene_get(data->iter.set); - - Base base_iter = {(Base *)view_layer->object_bases.first, NULL}; - data->iter.base = &base_iter; - - BKE_renderable_objects_iterator_next(iter); + data->base_temp.next = view_layer->object_bases.first; + data->iter.base = &data->base_temp; return; } diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 066b3e34b0d..e0608efece2 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -2129,7 +2129,7 @@ void BKE_library_make_local( GSet *loop_tags = BLI_gset_ptr_new(__func__); for (LinkNode *it = todo_ids; it; it = it->next) { library_make_local_copying_check(it->link, loop_tags, bmain->relations, done_ids); - BLI_assert(BLI_gset_size(loop_tags) == 0); + BLI_assert(BLI_gset_len(loop_tags) == 0); } BLI_gset_free(loop_tags, NULL); BLI_gset_free(done_ids, NULL); diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c index 6c5931263d8..419ed8246db 100644 --- a/source/blender/blenkernel/intern/library_query.c +++ b/source/blender/blenkernel/intern/library_query.c @@ -51,7 +51,7 @@ #include "DNA_movieclip_types.h" #include "DNA_mask_types.h" #include "DNA_node_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_lightprobe_types.h" #include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" @@ -421,10 +421,6 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */ library_foreach_ID_as_subdata_link((ID **)&scene->nodetree, callback, user_data, flag, &data); } - /* DO NOT handle scene->basact here, it's doubling with the loop over whole scene->base later, - * since basact is just a pointer to one of those items. */ - CALLBACK_INVOKE(scene->obedit, IDWALK_CB_NOP); - if (scene->ed) { Sequence *seq; SEQP_BEGIN(scene->ed, seq) diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 5a0ac86823f..cc801b2d8c3 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -549,9 +549,9 @@ void BKE_mball_eval_geometry(const struct EvaluationContext *UNUSED(eval_ctx), /* Draw Engine */ /* use for draw-manager only. */ -void BKE_mball_element_calc_display_m3x4(float r_scale_xform[3][4], - const float obmat[4][4], - const float local_pos[3]) +void BKE_mball_element_calc_scale_xform(float r_scale_xform[3][4], + const float obmat[4][4], + const float local_pos[3]) { float world_pos[3], scamat[3][3]; mul_v3_m4v3(world_pos, obmat, local_pos); diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 3217c234718..d3c74f71f78 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -1044,7 +1044,7 @@ static void make_edges_mdata_extend(MEdge **r_alledge, int *r_totedge, BKE_mesh_poly_edgehash_insert(eh, mp, mloop + mp->loopstart); } - totedge_new = BLI_edgehash_size(eh); + totedge_new = BLI_edgehash_len(eh); #ifdef DEBUG /* ensure that theres no overlap! */ diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index 00d1b29caf8..c7678be18c7 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -43,7 +43,7 @@ #include "BLI_math.h" #include "BLI_edgehash.h" #include "BLI_bitmap.h" -#include "BLI_polyfill2d.h" +#include "BLI_polyfill_2d.h" #include "BLI_linklist.h" #include "BLI_linklist_stack.h" #include "BLI_alloca.h" @@ -253,16 +253,6 @@ static void mesh_calc_normals_poly_prepare_cb( } } -static void mesh_calc_normals_poly_accum_cb( - void *__restrict userdata, - const int lidx, - const ParallelRangeTLS *__restrict UNUSED(tls)) -{ - MeshCalcNormalsData *data = userdata; - - add_v3_v3(data->vnors[data->mloop[lidx].v], data->lnors_weighted[lidx]); -} - static void mesh_calc_normals_poly_finalize_cb( void *__restrict userdata, const int vidx, @@ -327,7 +317,11 @@ void BKE_mesh_calc_normals_poly( BLI_task_parallel_range(0, numPolys, &data, mesh_calc_normals_poly_prepare_cb, &settings); /* Actually accumulate weighted loop normals into vertex ones. */ - BLI_task_parallel_range(0, numLoops, &data, mesh_calc_normals_poly_accum_cb, &settings); + /* Unfortunately, not possible to thread that (not in a reasonable, totally lock- and barrier-free fashion), + * since several loops will point to the same vertex... */ + for (int lidx = 0; lidx < numLoops; lidx++) { + add_v3_v3(vnors[mloop[lidx].v], data.lnors_weighted[lidx]); + } /* Normalize and validate computed vertex normals. */ BLI_task_parallel_range(0, numVerts, &data, mesh_calc_normals_poly_finalize_cb, &settings); @@ -2798,9 +2792,22 @@ void BKE_mesh_recalc_looptri( } else if (mp_totloop == 4) { ML_TO_MLT(0, 1, 2); + MLoopTri *mlt_a = mlt; mlooptri_index++; ML_TO_MLT(0, 2, 3); + MLoopTri *mlt_b = mlt; mlooptri_index++; + + if (UNLIKELY(is_quad_flip_v3_first_third_fast( + mvert[mloop[mlt_a->tri[0]].v].co, + mvert[mloop[mlt_a->tri[1]].v].co, + mvert[mloop[mlt_a->tri[2]].v].co, + mvert[mloop[mlt_b->tri[2]].v].co))) + { + /* flip out of degenerate 0-2 state. */ + mlt_a->tri[2] = mlt_b->tri[2]; + mlt_b->tri[0] = mlt_a->tri[1]; + } } #endif /* USE_TESSFACE_SPEEDUP */ else { diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c index f321c94bf00..0af4dae4506 100644 --- a/source/blender/blenkernel/intern/mesh_remap.c +++ b/source/blender/blenkernel/intern/mesh_remap.c @@ -36,7 +36,7 @@ #include "BLI_bitmap.h" #include "BLI_math.h" #include "BLI_memarena.h" -#include "BLI_polyfill2d.h" +#include "BLI_polyfill_2d.h" #include "BLI_rand.h" #include "BKE_bvhutils.h" diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index 54de843bc64..f7509d07ca4 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -1412,7 +1412,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool update, const bool select) } } - totedge = BLI_edgehash_size(eh); + totedge = BLI_edgehash_len(eh); /* write new edges into a temporary CustomData */ CustomData_reset(&edata); diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 8bfeacd256c..1604a017054 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -69,6 +69,8 @@ #include "BKE_main.h" /* end */ +#include "DEG_depsgraph.h" + #include "MOD_modifiertypes.h" static ModifierTypeInfo *modifier_types[NUM_MODIFIER_TYPES] = {NULL}; @@ -660,15 +662,15 @@ bool modifier_isCorrectableDeformed(ModifierData *md) return (mti->deformMatricesEM != NULL); } -bool modifiers_isCorrectableDeformed(struct Scene *scene, Object *ob) +bool modifiers_isCorrectableDeformed(const EvaluationContext *eval_ctx, struct Scene *scene, Object *ob) { VirtualModifierData virtualModifierData; ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData); int required_mode = eModifierMode_Realtime; - if (ob->mode == OB_MODE_EDIT) + if (eval_ctx->object_mode == OB_MODE_EDIT) { required_mode |= eModifierMode_Editmode; - + } for (; md; md = md->next) { if (!modifier_isEnabled(scene, md, required_mode)) { /* pass */ diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 08df976941b..a416de07c6d 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -926,7 +926,7 @@ static ImBuf *movieclip_get_postprocessed_ibuf(MovieClip *clip, /* cache isn't threadsafe itself and also loading of movies * can't happen from concurrent threads that's why we use lock here */ - BLI_lock_thread(LOCK_MOVIECLIP); + BLI_thread_lock(LOCK_MOVIECLIP); /* try to obtain cached postprocessed frame first */ if (need_postprocessed_frame(user, postprocess_flag)) { @@ -976,7 +976,7 @@ static ImBuf *movieclip_get_postprocessed_ibuf(MovieClip *clip, } } - BLI_unlock_thread(LOCK_MOVIECLIP); + BLI_thread_unlock(LOCK_MOVIECLIP); return ibuf; } @@ -1410,13 +1410,13 @@ static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, i * could be solved in a way that thread only prepares memory * buffer and write to disk happens separately */ - BLI_lock_thread(LOCK_MOVIECLIP); + BLI_thread_lock(LOCK_MOVIECLIP); BLI_make_existing_file(name); if (IMB_saveiff(scaleibuf, name, IB_rect) == 0) perror(name); - BLI_unlock_thread(LOCK_MOVIECLIP); + BLI_thread_unlock(LOCK_MOVIECLIP); IMB_freeImBuf(scaleibuf); } @@ -1560,9 +1560,9 @@ ImBuf *BKE_movieclip_anim_ibuf_for_frame(MovieClip *clip, MovieClipUser *user) ImBuf *ibuf = NULL; if (clip->source == MCLIP_SRC_MOVIE) { - BLI_lock_thread(LOCK_MOVIECLIP); + BLI_thread_lock(LOCK_MOVIECLIP); ibuf = movieclip_load_movie_file(clip, user, user->framenr, clip->flag); - BLI_unlock_thread(LOCK_MOVIECLIP); + BLI_thread_unlock(LOCK_MOVIECLIP); } return ibuf; @@ -1572,9 +1572,9 @@ bool BKE_movieclip_has_cached_frame(MovieClip *clip, MovieClipUser *user) { bool has_frame = false; - BLI_lock_thread(LOCK_MOVIECLIP); + BLI_thread_lock(LOCK_MOVIECLIP); has_frame = has_imbuf_cache(clip, user, clip->flag); - BLI_unlock_thread(LOCK_MOVIECLIP); + BLI_thread_unlock(LOCK_MOVIECLIP); return has_frame; } @@ -1585,9 +1585,9 @@ bool BKE_movieclip_put_frame_if_possible(MovieClip *clip, { bool result; - BLI_lock_thread(LOCK_MOVIECLIP); + BLI_thread_lock(LOCK_MOVIECLIP); result = put_imbuf_cache(clip, user, ibuf, clip->flag, false); - BLI_unlock_thread(LOCK_MOVIECLIP); + BLI_thread_unlock(LOCK_MOVIECLIP); return result; } diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 55f11604710..e7c36685c42 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -60,6 +60,8 @@ #include "BKE_object.h" +#include "DEG_depsgraph.h" + #include "CCGSubSurf.h" #include <math.h> @@ -336,12 +338,13 @@ MultiresModifierData *get_multires_modifier(Scene *scene, Object *ob, bool use_f return mmd; } -static int multires_get_level(Object *ob, MultiresModifierData *mmd, - bool render, bool ignore_simplify) +static int multires_get_level( + MultiresModifierData *mmd, + bool render, bool ignore_simplify, eObjectMode object_mode) { if (render) return (mmd->modifier.scene) ? get_render_subsurf_level(&mmd->modifier.scene->r, mmd->renderlvl, true) : mmd->renderlvl; - else if (ob->mode == OB_MODE_SCULPT) + else if (object_mode == OB_MODE_SCULPT) return mmd->sculptlvl; else if (ignore_simplify) return mmd->lvl; @@ -349,12 +352,13 @@ static int multires_get_level(Object *ob, MultiresModifierData *mmd, return (mmd->modifier.scene) ? get_render_subsurf_level(&mmd->modifier.scene->r, mmd->lvl, false) : mmd->lvl; } -void multires_set_tot_level(Object *ob, MultiresModifierData *mmd, int lvl) +void multires_set_tot_level(MultiresModifierData *mmd, int lvl, eObjectMode object_mode) { mmd->totlvl = lvl; - if (ob->mode != OB_MODE_SCULPT) + if (object_mode != OB_MODE_SCULPT) { mmd->lvl = CLAMPIS(MAX2(mmd->lvl, lvl), 0, mmd->totlvl); + } mmd->sculptlvl = CLAMPIS(MAX2(mmd->sculptlvl, lvl), 0, mmd->totlvl); mmd->renderlvl = CLAMPIS(MAX2(mmd->renderlvl, lvl), 0, mmd->totlvl); @@ -392,9 +396,9 @@ void multires_force_external_reload(Object *ob) multires_force_update(ob); } -void multires_force_render_update(Object *ob) +void multires_force_render_update(Object *ob, eObjectMode object_mode) { - if (ob && (ob->mode & OB_MODE_SCULPT) && modifiers_findByType(ob, eModifierType_Multires)) + if (ob && (object_mode & OB_MODE_SCULPT) && modifiers_findByType(ob, eModifierType_Multires)) multires_force_update(ob); } @@ -434,7 +438,7 @@ int multiresModifier_reshapeFromDeformMod(const struct EvaluationContext *eval_c int numVerts, result; float (*deformedVerts)[3]; - if (multires_get_level(ob, mmd, false, true) == 0) + if (multires_get_level(mmd, false, true, eval_ctx->object_mode) == 0) return 0; /* Create DerivedMesh for deformation modifier */ @@ -614,7 +618,7 @@ static void multires_grid_paint_mask_downsample(GridPaintMask *gpm, int level) } } -static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl) +static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl, eObjectMode object_mode) { Mesh *me = (Mesh *)ob->data; int levels = mmd->totlvl - lvl; @@ -676,14 +680,14 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl) } } - multires_set_tot_level(ob, mmd, lvl); + multires_set_tot_level(mmd, lvl, object_mode); } /* (direction = 1) for delete higher, (direction = 0) for lower (not implemented yet) */ -void multiresModifier_del_levels(MultiresModifierData *mmd, Object *ob, int direction) +void multiresModifier_del_levels(MultiresModifierData *mmd, Object *ob, int direction, eObjectMode object_mode) { Mesh *me = BKE_mesh_from_object(ob); - int lvl = multires_get_level(ob, mmd, false, true); + int lvl = multires_get_level(mmd, false, true, object_mode); int levels = mmd->totlvl - lvl; MDisps *mdisps; @@ -694,13 +698,14 @@ void multiresModifier_del_levels(MultiresModifierData *mmd, Object *ob, int dire multires_force_update(ob); if (mdisps && levels > 0 && direction == 1) { - multires_del_higher(mmd, ob, lvl); + multires_del_higher(mmd, ob, lvl, object_mode); } - multires_set_tot_level(ob, mmd, lvl); + multires_set_tot_level(mmd, lvl, object_mode); } -static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int totlvl, int simple, bool alloc_paint_mask) +static DerivedMesh *multires_dm_create_local( + Object *ob, DerivedMesh *dm, int lvl, int totlvl, int simple, bool alloc_paint_mask, eObjectMode object_mode) { MultiresModifierData mmd = {{NULL}}; MultiresFlags flags = MULTIRES_USE_LOCAL_MMD; @@ -714,10 +719,12 @@ static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lv if (alloc_paint_mask) flags |= MULTIRES_ALLOC_PAINT_MASK; - return multires_make_derived_from_derived(dm, &mmd, ob, flags); + return multires_make_derived_from_derived(dm, &mmd, ob, flags, object_mode); } -static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int simple, int optimal, int plain_uv, int alloc_paint_mask) +static DerivedMesh *subsurf_dm_create_local( + DerivedMesh *dm, int lvl, int simple, + int optimal, int plain_uv, int alloc_paint_mask, eObjectMode object_mode) { SubsurfModifierData smd = {{NULL}}; SubsurfFlags flags = 0; @@ -730,7 +737,7 @@ static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl if (optimal) smd.flags |= eSubsurfModifierFlag_ControlEdges; - if (ob->mode & OB_MODE_EDIT) + if (object_mode & OB_MODE_EDIT) flags |= SUBSURF_IN_EDIT_MODE; if (alloc_paint_mask) @@ -750,7 +757,7 @@ static float v3_dist_from_plane(float v[3], float center[3], float no[3]) return dot_v3v3(s, no); } -void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob) +void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob, eObjectMode object_mode) { DerivedMesh *cddm, *dispdm, *origdm; Mesh *me; @@ -772,7 +779,7 @@ void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob) /* generate highest level with displacements */ cddm = CDDM_from_mesh(me); DM_set_only_copy(cddm, CD_MASK_BAREMESH); - dispdm = multires_dm_create_local(ob, cddm, totlvl, totlvl, 0, 0); + dispdm = multires_dm_create_local(ob, cddm, totlvl, totlvl, 0, 0, object_mode); cddm->release(cddm); /* copy the new locations of the base verts into the mesh */ @@ -868,7 +875,9 @@ void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob) /* subdivide the mesh to highest level without displacements */ cddm = CDDM_from_mesh(me); DM_set_only_copy(cddm, CD_MASK_BAREMESH); - origdm = subsurf_dm_create_local(ob, cddm, totlvl, 0, 0, mmd->flags & eMultiresModifierFlag_PlainUv, 0); + origdm = subsurf_dm_create_local( + cddm, totlvl, 0, + 0, mmd->flags & eMultiresModifierFlag_PlainUv, 0, object_mode); cddm->release(cddm); /* calc disps */ @@ -878,7 +887,8 @@ void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob) dispdm->release(dispdm); } -static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl, int updateblock, int simple) +static void multires_subdivide( + MultiresModifierData *mmd, Object *ob, int totlvl, int updateblock, int simple, eObjectMode object_mode) { Mesh *me = ob->data; MDisps *mdisps; @@ -907,11 +917,13 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl /* create subsurf DM from original mesh at high level */ cddm = CDDM_from_mesh(me); DM_set_only_copy(cddm, CD_MASK_BAREMESH); - highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask); + highdm = subsurf_dm_create_local( + cddm, totlvl, simple, + 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask, object_mode); ss = ((CCGDerivedMesh *)highdm)->ss; /* create multires DM from original mesh at low level */ - lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple, has_mask); + lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple, has_mask, object_mode); BLI_assert(lowdm != cddm); cddm->release(cddm); @@ -958,12 +970,13 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl multires_reallocate_mdisps(me->totloop, mdisps, totlvl); } - multires_set_tot_level(ob, mmd, totlvl); + multires_set_tot_level(mmd, totlvl, object_mode); } -void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int updateblock, int simple) +void multiresModifier_subdivide( + MultiresModifierData *mmd, Object *ob, int updateblock, int simple, eObjectMode object_mode) { - multires_subdivide(mmd, ob, mmd->totlvl + 1, updateblock, simple); + multires_subdivide(mmd, ob, mmd->totlvl + 1, updateblock, simple, object_mode); } static void grid_tangent(const CCGKey *key, int x, int y, int axis, CCGElem *grid, float t[3]) @@ -1196,7 +1209,7 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm } } -void multires_modifier_update_mdisps(struct DerivedMesh *dm) +void multires_modifier_update_mdisps(struct DerivedMesh *dm, eObjectMode object_mode) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; Object *ob; @@ -1228,11 +1241,13 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm) else cddm = CDDM_from_mesh(me); DM_set_only_copy(cddm, CD_MASK_BAREMESH); - highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask); + highdm = subsurf_dm_create_local( + cddm, totlvl, mmd->simple, + 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask, object_mode); ss = ((CCGDerivedMesh *)highdm)->ss; /* create multires DM from original mesh and displacements */ - lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple, has_mask); + lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple, has_mask, object_mode); cddm->release(cddm); /* gather grid data */ @@ -1290,7 +1305,9 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm) else cddm = CDDM_from_mesh(me); DM_set_only_copy(cddm, CD_MASK_BAREMESH); - subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask); + subdm = subsurf_dm_create_local( + cddm, mmd->totlvl, mmd->simple, + 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask, object_mode); cddm->release(cddm); multiresModifier_disp_run(dm, me, NULL, CALC_DISPLACEMENTS, subdm->getGridData(subdm), mmd->totlvl); @@ -1332,7 +1349,7 @@ void multires_modifier_update_hidden(DerivedMesh *dm) } } -void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to) +void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to, eObjectMode object_mode) { DerivedMesh *ccgdm = NULL, *subsurf = NULL; CCGElem **gridData, **subGridData = NULL; @@ -1353,10 +1370,11 @@ void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to) } totlvl = mmd->totlvl; - ccgdm = multires_dm_create_local(ob, dm, totlvl, totlvl, mmd->simple, false); + ccgdm = multires_dm_create_local(ob, dm, totlvl, totlvl, mmd->simple, false, object_mode); - subsurf = subsurf_dm_create_local(ob, dm, totlvl, - mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges, mmd->flags & eMultiresModifierFlag_PlainUv, 0); + subsurf = subsurf_dm_create_local( + dm, totlvl, mmd->simple, + mmd->flags & eMultiresModifierFlag_ControlEdges, mmd->flags & eMultiresModifierFlag_PlainUv, 0, object_mode); numGrids = subsurf->getNumGrids(subsurf); gridSize = subsurf->getGridSize(subsurf); @@ -1471,10 +1489,12 @@ void multires_stitch_grids(Object *ob) } } -DerivedMesh *multires_make_derived_from_derived(DerivedMesh *dm, - MultiresModifierData *mmd, - Object *ob, - MultiresFlags flags) +DerivedMesh *multires_make_derived_from_derived( + DerivedMesh *dm, + MultiresModifierData *mmd, + Object *ob, + MultiresFlags flags, + eObjectMode object_mode) { Mesh *me = ob->data; DerivedMesh *result; @@ -1483,16 +1503,18 @@ DerivedMesh *multires_make_derived_from_derived(DerivedMesh *dm, CCGKey key; const bool render = (flags & MULTIRES_USE_RENDER_PARAMS) != 0; const bool ignore_simplify = (flags & MULTIRES_IGNORE_SIMPLIFY) != 0; - int lvl = multires_get_level(ob, mmd, render, ignore_simplify); + int lvl = multires_get_level(mmd, render, ignore_simplify, object_mode); int i, gridSize, numGrids; if (lvl == 0) return dm; - result = subsurf_dm_create_local(ob, dm, lvl, - mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges, - mmd->flags & eMultiresModifierFlag_PlainUv, - flags & MULTIRES_ALLOC_PAINT_MASK); + result = subsurf_dm_create_local( + dm, lvl, mmd->simple, + mmd->flags & eMultiresModifierFlag_ControlEdges, + mmd->flags & eMultiresModifierFlag_PlainUv, + flags & MULTIRES_ALLOC_PAINT_MASK, + object_mode); if (!(flags & MULTIRES_USE_LOCAL_MMD)) { ccgdm = (CCGDerivedMesh *)result; @@ -2120,6 +2142,7 @@ void multires_load_old(Object *ob, Mesh *me) DerivedMesh *dm, *orig; CustomDataLayer *l; int i; + const eObjectMode object_mode = OB_MODE_OBJECT; /* Load original level into the mesh */ lvl = me->mr->levels.first; @@ -2168,7 +2191,7 @@ void multires_load_old(Object *ob, Mesh *me) BLI_insertlinkbefore(&ob->modifiers, md, mmd); for (i = 0; i < me->mr->level_count - 1; ++i) - multiresModifier_subdivide(mmd, ob, 1, 0); + multiresModifier_subdivide(mmd, ob, 1, 0, object_mode); mmd->lvl = mmd->totlvl; orig = CDDM_from_mesh(me); @@ -2177,7 +2200,7 @@ void multires_load_old(Object *ob, Mesh *me) * reference subsurfed dm with this option, before calling multiresModifier_disp_run(), * which implicitly expects both subsurfs from its first dm and oldGridData parameters to * be of the same "format"! */ - dm = multires_make_derived_from_derived(orig, mmd, ob, 0); + dm = multires_make_derived_from_derived(orig, mmd, ob, 0, object_mode); multires_load_old_dm(dm, me, mmd->totlvl + 1); @@ -2192,21 +2215,22 @@ void multires_load_old(Object *ob, Mesh *me) /* If 'ob_src' and 'ob_dst' both have multires modifiers, synchronize them * such that 'ob_dst' has the same total number of levels as 'ob_src'. */ -void multiresModifier_sync_levels_ex(Object *ob_dst, MultiresModifierData *mmd_src, MultiresModifierData *mmd_dst) +void multiresModifier_sync_levels_ex( + Object *ob_dst, MultiresModifierData *mmd_src, MultiresModifierData *mmd_dst, eObjectMode object_mode) { if (mmd_src->totlvl == mmd_dst->totlvl) { return; } if (mmd_src->totlvl > mmd_dst->totlvl) { - multires_subdivide(mmd_dst, ob_dst, mmd_src->totlvl, false, mmd_dst->simple); + multires_subdivide(mmd_dst, ob_dst, mmd_src->totlvl, false, mmd_dst->simple, object_mode); } else { - multires_del_higher(mmd_dst, ob_dst, mmd_src->totlvl); + multires_del_higher(mmd_dst, ob_dst, mmd_src->totlvl, object_mode); } } -static void multires_sync_levels(Scene *scene, Object *ob_src, Object *ob_dst) +static void multires_sync_levels(Scene *scene, Object *ob_src, Object *ob_dst, eObjectMode object_mode) { MultiresModifierData *mmd_src = get_multires_modifier(scene, ob_src, true); MultiresModifierData *mmd_dst = get_multires_modifier(scene, ob_dst, true); @@ -2221,7 +2245,7 @@ static void multires_sync_levels(Scene *scene, Object *ob_src, Object *ob_dst) } if (mmd_src && mmd_dst) { - multiresModifier_sync_levels_ex(ob_dst, mmd_src, mmd_dst); + multiresModifier_sync_levels_ex(ob_dst, mmd_src, mmd_dst, object_mode); } } @@ -2314,7 +2338,9 @@ static void multires_apply_smat(const struct EvaluationContext *eval_ctx, Scene MEM_freeN(vertCos); /* scaled ccgDM for tangent space of object with applied scale */ - dm = subsurf_dm_create_local(ob, cddm, high_mmd.totlvl, high_mmd.simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, 0); + dm = subsurf_dm_create_local( + cddm, high_mmd.totlvl, high_mmd.simple, + 0, mmd->flags & eMultiresModifierFlag_PlainUv, 0, eval_ctx->object_mode); cddm->release(cddm); gridSize = dm->getGridSize(dm); @@ -2377,7 +2403,7 @@ void multiresModifier_scale_disp(const struct EvaluationContext *eval_ctx, Scene void multiresModifier_prepare_join(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, Object *to_ob) { float smat[3][3], tmat[3][3], mat[3][3]; - multires_sync_levels(scene, to_ob, ob); + multires_sync_levels(scene, to_ob, ob, eval_ctx->object_mode); /* construct scale matrix for displacement */ BKE_object_scale_to_mat3(to_ob, tmat); diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index cac2aab26dd..c2d74739beb 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -2787,7 +2787,7 @@ int BKE_node_instance_hash_haskey(bNodeInstanceHash *hash, bNodeInstanceKey key) int BKE_node_instance_hash_size(bNodeInstanceHash *hash) { - return BLI_ghash_size(hash->ghash); + return BLI_ghash_len(hash->ghash); } void BKE_node_instance_hash_clear_tags(bNodeInstanceHash *hash) @@ -3590,6 +3590,7 @@ static void registerShaderNodes(void) register_node_type_sh_attribute(); register_node_type_sh_bevel(); register_node_type_sh_displacement(); + register_node_type_sh_vector_displacement(); register_node_type_sh_geometry(); register_node_type_sh_light_path(); register_node_type_sh_light_falloff(); @@ -3819,6 +3820,7 @@ bool BKE_node_tree_iter_step(struct NodeTreeIterStore *ntreeiter, void BKE_nodetree_remove_layer_n(bNodeTree *ntree, Scene *scene, const int layer_index) { + BLI_assert(layer_index != -1); for (bNode *node = ntree->nodes.first; node; node = node->next) { if (node->type == CMP_NODE_R_LAYERS && (Scene *)node->id == scene) { if (node->custom1 == layer_index) { diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 8c85a0413b8..a0d2e7d76c8 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -262,7 +262,9 @@ bool BKE_object_support_modifier_type_check(Object *ob, int modifier_type) return true; } -void BKE_object_link_modifiers(struct Object *ob_dst, const struct Object *ob_src) +void BKE_object_link_modifiers( + struct Object *ob_dst, const struct Object *ob_src, + eObjectMode object_mode) { ModifierData *md; BKE_object_free_modifiers(ob_dst); @@ -301,7 +303,8 @@ void BKE_object_link_modifiers(struct Object *ob_dst, const struct Object *ob_sr if (md->type == eModifierType_Multires) { /* Has to be done after mod creation, but *before* we actually copy its settings! */ - multiresModifier_sync_levels_ex(ob_dst, (MultiresModifierData *)md, (MultiresModifierData *)nmd); + multiresModifier_sync_levels_ex( + ob_dst, (MultiresModifierData *)md, (MultiresModifierData *)nmd, object_mode); } modifier_copyData(md, nmd); @@ -486,7 +489,7 @@ void BKE_object_free(Object *ob) } /* actual check for internal data, not context or flags */ -bool BKE_object_is_in_editmode(Object *ob) +bool BKE_object_is_in_editmode(const Object *ob) { if (ob->data == NULL) return false; @@ -535,11 +538,11 @@ bool BKE_object_is_in_editmode_vgroup(Object *ob) BKE_object_is_in_editmode(ob)); } -bool BKE_object_is_in_wpaint_select_vert(Object *ob) +bool BKE_object_is_in_wpaint_select_vert(const Object *ob, eObjectMode object_mode) { if (ob->type == OB_MESH) { - Mesh *me = ob->data; - return ((ob->mode & OB_MODE_WEIGHT_PAINT) && + const Mesh *me = ob->data; + return ((object_mode & OB_MODE_WEIGHT_PAINT) && (me->edit_btmesh == NULL) && (ME_EDIT_PAINT_SEL_MODE(me) == SCE_SELECT_VERTEX)); } @@ -884,10 +887,10 @@ static LodLevel *lod_level_select(Object *ob, const float camera_position[3]) return current; } -bool BKE_object_lod_is_usable(Object *ob, ViewLayer *view_layer) +bool BKE_object_lod_is_usable(Object *ob, ViewLayer *view_layer, const eObjectMode object_mode) { bool active = (view_layer) ? ob == OBACT(view_layer) : false; - return (ob->mode == OB_MODE_OBJECT || !active); + return (object_mode == OB_MODE_OBJECT || !active); } void BKE_object_lod_update(Object *ob, const float camera_position[3]) @@ -900,11 +903,11 @@ void BKE_object_lod_update(Object *ob, const float camera_position[3]) } } -static Object *lod_ob_get(Object *ob, ViewLayer *view_layer, int flag) +static Object *lod_ob_get(Object *ob, ViewLayer *view_layer, int flag, const eObjectMode object_mode) { LodLevel *current = ob->currentlod; - if (!current || !BKE_object_lod_is_usable(ob, view_layer)) + if (!current || !BKE_object_lod_is_usable(ob, view_layer, object_mode)) return ob; while (current->prev && (!(current->flags & flag) || !current->source || current->source->type != OB_MESH)) { @@ -914,14 +917,14 @@ static Object *lod_ob_get(Object *ob, ViewLayer *view_layer, int flag) return current->source; } -struct Object *BKE_object_lod_meshob_get(Object *ob, ViewLayer *view_layer) +struct Object *BKE_object_lod_meshob_get(Object *ob, ViewLayer *view_layer, const eObjectMode object_mode) { - return lod_ob_get(ob, view_layer, OB_LOD_USE_MESH); + return lod_ob_get(ob, view_layer, OB_LOD_USE_MESH, object_mode); } -struct Object *BKE_object_lod_matob_get(Object *ob, ViewLayer *view_layer) +struct Object *BKE_object_lod_matob_get(Object *ob, ViewLayer *view_layer, const eObjectMode object_mode) { - return lod_ob_get(ob, view_layer, OB_LOD_USE_MAT); + return lod_ob_get(ob, view_layer, OB_LOD_USE_MAT, object_mode); } #endif /* WITH_GAMEENGINE */ @@ -1150,12 +1153,13 @@ static void copy_object_lod(Object *obn, const Object *ob, const int UNUSED(flag obn->currentlod = (LodLevel *)obn->lodlevels.first; } -bool BKE_object_pose_context_check(Object *ob) +bool BKE_object_pose_context_check_ex(Object *ob, bool selected) { if ((ob) && (ob->type == OB_ARMATURE) && (ob->pose) && - (ob->mode & OB_MODE_POSE)) + /* Currently using selection when the object isn't active. */ + ((selected == false) || (ob->flag & SELECT))) { return true; } @@ -1164,22 +1168,41 @@ bool BKE_object_pose_context_check(Object *ob) } } +bool BKE_object_pose_context_check(Object *ob) +{ + return BKE_object_pose_context_check_ex(ob, false); +} + Object *BKE_object_pose_armature_get(Object *ob) { if (ob == NULL) return NULL; - if (BKE_object_pose_context_check(ob)) + if (BKE_object_pose_context_check_ex(ob, false)) return ob; ob = modifiers_isDeformedByArmature(ob); - if (BKE_object_pose_context_check(ob)) + /* Only use selected check when non-active. */ + if (BKE_object_pose_context_check_ex(ob, true)) return ob; return NULL; } +Object *BKE_object_pose_armature_get_visible(Object *ob, ViewLayer *view_layer) +{ + Object *ob_armature = BKE_object_pose_armature_get(ob); + if (ob_armature) { + Base *base = BKE_view_layer_base_find(view_layer, ob_armature); + if (base) { + if (BASE_VISIBLE(base)) { + return ob_armature; + } + } + } + return NULL; +} void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src) { copy_v3_v3(ob_tar->loc, ob_src->loc); @@ -1241,7 +1264,6 @@ void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_ BKE_object_facemap_copy_list(&ob_dst->fmaps, &ob_src->fmaps); BKE_constraints_copy_ex(&ob_dst->constraints, &ob_src->constraints, flag_subdata, true); - ob_dst->mode = OB_MODE_OBJECT; ob_dst->sculpt = NULL; if (ob_src->pd) { diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c index 754434eaef6..ffe45d42677 100644 --- a/source/blender/blenkernel/intern/object_deform.c +++ b/source/blender/blenkernel/intern/object_deform.c @@ -42,7 +42,7 @@ #include "DNA_mesh_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_particle_types.h" #include "DNA_scene_types.h" @@ -542,7 +542,7 @@ bool *BKE_object_defgroup_validmap_get(Object *ob, const int defbase_tot) BLI_ghash_insert(gh, dg->name, NULL); } - BLI_assert(BLI_ghash_size(gh) == defbase_tot); + BLI_assert(BLI_ghash_len(gh) == defbase_tot); /* now loop through the armature modifiers and identify deform bones */ for (md = ob->modifiers.first; md; md = !md->next && step1 ? (step1 = 0), modifiers_getVirtualModifierList(ob, &virtualModifierData) : md->next) { @@ -577,7 +577,7 @@ bool *BKE_object_defgroup_validmap_get(Object *ob, const int defbase_tot) defgroup_validmap[i] = (BLI_ghash_lookup(gh, dg->name) != NULL); } - BLI_assert(i == BLI_ghash_size(gh)); + BLI_assert(i == BLI_ghash_len(gh)); BLI_ghash_free(gh, NULL, NULL); diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c index 13589866e48..2d655913b3e 100644 --- a/source/blender/blenkernel/intern/object_dupli.c +++ b/source/blender/blenkernel/intern/object_dupli.c @@ -74,6 +74,7 @@ typedef struct DupliContext { bool do_update; bool animated; Group *group; /* XXX child objects are selected from this group if set, could be nicer */ + Object *obedit; /* Only to check if the object is in edit-mode. */ Scene *scene; ViewLayer *view_layer; @@ -107,6 +108,7 @@ static void init_context(DupliContext *r_ctx, const EvaluationContext *eval_ctx, r_ctx->animated = false; r_ctx->group = NULL; + r_ctx->obedit = OBEDIT_FROM_EVAL_CTX(eval_ctx); r_ctx->object = ob; if (space_mat) copy_m4_m4(r_ctx->space_mat, space_mat); @@ -241,14 +243,13 @@ static bool is_child(const Object *ob, const Object *parent) static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChildDuplisFunc make_child_duplis_cb) { Object *parent = ctx->object; - Object *obedit = ctx->scene->obedit; if (ctx->group) { int groupid = 0; FOREACH_GROUP_BASE(ctx->group, base) { Object *ob = base->object; - if ((base->flag & BASE_VISIBLED) && ob != obedit && is_child(ob, parent)) { + if ((base->flag & BASE_VISIBLED) && ob != ctx->obedit && is_child(ob, parent)) { DupliContext pctx; copy_dupli_context(&pctx, ctx, ctx->object, NULL, groupid, false); @@ -267,7 +268,7 @@ static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChild ViewLayer *view_layer = ctx->view_layer; for (Base *base = view_layer->object_bases.first; base; base = base->next, baseid++) { Object *ob = base->object; - if ((base->flag & BASE_VISIBLED) && ob != obedit && is_child(ob, parent)) { + if ((ob != ctx->obedit) && is_child(ob, parent)) { DupliContext pctx; copy_dupli_context(&pctx, ctx, ctx->object, NULL, baseid, false); diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index bc183ba95a6..52c85011b6a 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -173,7 +173,7 @@ void BKE_object_handle_data_update( switch (ob->type) { case OB_MESH: { - BMEditMesh *em = (ob == scene->obedit) ? BKE_editmesh_from_object(ob) : NULL; + BMEditMesh *em = (eval_ctx->object_mode & OB_MODE_EDIT) ? BKE_editmesh_from_object(ob) : NULL; uint64_t data_mask = scene->customdata_mask | CD_MASK_BAREMESH; #ifdef WITH_FREESTYLE /* make sure Freestyle edge/face marks appear in DM for render (see T40315) */ @@ -223,7 +223,7 @@ void BKE_object_handle_data_update( } /* particles */ - if (ob != scene->obedit && ob->particlesystem.first) { + if ((ob != OBEDIT_FROM_EVAL_CTX(eval_ctx)) && ob->particlesystem.first) { ParticleSystem *tpsys, *psys; DerivedMesh *dm; ob->transflag &= ~OB_DUPLIPARTS; diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c index 0b4bc39627e..2d8527f23d6 100644 --- a/source/blender/blenkernel/intern/ocean.c +++ b/source/blender/blenkernel/intern/ocean.c @@ -917,7 +917,7 @@ void BKE_ocean_init(struct Ocean *o, int M, int N, float Lx, float Lz, float V, o->_fft_in = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in"); o->_htilda = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_htilda"); - BLI_lock_thread(LOCK_FFTW); + BLI_thread_lock(LOCK_FFTW); if (o->_do_disp_y) { o->_disp_y = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_y"); @@ -963,7 +963,7 @@ void BKE_ocean_init(struct Ocean *o, int M, int N, float Lx, float Lz, float V, o->_Jxz_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jxz, o->_Jxz, FFTW_ESTIMATE); } - BLI_unlock_thread(LOCK_FFTW); + BLI_thread_unlock(LOCK_FFTW); BLI_rw_mutex_unlock(&o->oceanmutex); @@ -978,7 +978,7 @@ void BKE_ocean_free_data(struct Ocean *oc) BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_WRITE); - BLI_lock_thread(LOCK_FFTW); + BLI_thread_lock(LOCK_FFTW); if (oc->_do_disp_y) { fftw_destroy_plan(oc->_disp_y_plan); @@ -1016,7 +1016,7 @@ void BKE_ocean_free_data(struct Ocean *oc) MEM_freeN(oc->_Jxz); } - BLI_unlock_thread(LOCK_FFTW); + BLI_thread_unlock(LOCK_FFTW); if (oc->_fft_in) MEM_freeN(oc->_fft_in); diff --git a/source/blender/blenkernel/intern/outliner_treehash.c b/source/blender/blenkernel/intern/outliner_treehash.c index d9a602aa41e..9bbde607b80 100644 --- a/source/blender/blenkernel/intern/outliner_treehash.c +++ b/source/blender/blenkernel/intern/outliner_treehash.c @@ -133,7 +133,7 @@ static void fill_treehash(void *treehash, BLI_mempool *treestore) void *BKE_outliner_treehash_create_from_treestore(BLI_mempool *treestore) { - GHash *treehash = BLI_ghash_new_ex(tse_hash, tse_cmp, "treehash", BLI_mempool_count(treestore)); + GHash *treehash = BLI_ghash_new_ex(tse_hash, tse_cmp, "treehash", BLI_mempool_len(treestore)); fill_treehash(treehash, treestore); return treehash; } @@ -147,7 +147,7 @@ void *BKE_outliner_treehash_rebuild_from_treestore(void *treehash, BLI_mempool * { BLI_assert(treehash); - BLI_ghash_clear_ex(treehash, NULL, free_treehash_group, BLI_mempool_count(treestore)); + BLI_ghash_clear_ex(treehash, NULL, free_treehash_group, BLI_mempool_len(treestore)); fill_treehash(treehash, treestore); return treehash; } diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 152a882de97..81943d470dc 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -41,6 +41,7 @@ #include "DNA_scene_types.h" #include "DNA_brush_types.h" #include "DNA_space_types.h" +#include "DNA_workspace_types.h" #include "BLI_bitmap.h" #include "BLI_utildefines.h" @@ -75,27 +76,67 @@ const char PAINT_CURSOR_TEXTURE_PAINT[3] = {255, 255, 255}; static eOverlayControlFlags overlay_flags = 0; -void BKE_paint_invalidate_overlay_tex(Scene *scene, ViewLayer *view_layer, const Tex *tex) +/* Keep in sync with 'BKE_paint_get_active' */ +#define OB_MODE_HAS_PAINT_STRUCT(SEP) \ + OB_MODE_SCULPT SEP \ + OB_MODE_VERTEX_PAINT SEP \ + OB_MODE_WEIGHT_PAINT SEP \ + OB_MODE_TEXTURE_PAINT SEP \ + OB_MODE_EDIT + +#define COMMA , +static const eObjectMode ob_mode_has_paint_struct = OB_MODE_HAS_PAINT_STRUCT(|); +static const eObjectMode ob_mode_has_paint_struct_array[] = {OB_MODE_HAS_PAINT_STRUCT(COMMA)}; +#undef COMMA + +#define FOREACH_OB_MODE_PAINT_ITER_BEGIN(scene, view_layer, object_mode, p) \ +{ \ + eObjectMode object_mode_test = object_mode & ob_mode_has_paint_struct; \ + for (uint _i = 0; _i < ARRAY_SIZE(ob_mode_has_paint_struct_array) && object_mode_test; _i++) { \ + eObjectMode object_mode_single = ob_mode_has_paint_struct_array[_i]; \ + if (object_mode_test & object_mode_single) { \ + object_mode_test &= ~object_mode_single; \ + Paint *p = BKE_paint_get_active(scene, view_layer, object_mode_single); \ + { + +#define FOREACH_OB_MODE_PAINT_ITER_END \ + } \ + } \ + } \ +} ((void)0) + +void BKE_paint_invalidate_overlay_tex( + Scene *scene, ViewLayer *view_layer, const Tex *tex, eObjectMode object_mode) { - Paint *p = BKE_paint_get_active(scene, view_layer); - Brush *br = p->brush; - - if (!br) - return; - - if (br->mtex.tex == tex) - overlay_flags |= PAINT_INVALID_OVERLAY_TEXTURE_PRIMARY; - if (br->mask_mtex.tex == tex) - overlay_flags |= PAINT_INVALID_OVERLAY_TEXTURE_SECONDARY; + FOREACH_OB_MODE_PAINT_ITER_BEGIN(scene, view_layer, object_mode, p) + { + Brush *br = p->brush; + if (br) { + if (br->mtex.tex == tex) { + overlay_flags |= PAINT_INVALID_OVERLAY_TEXTURE_PRIMARY; + } + if (br->mask_mtex.tex == tex) { + overlay_flags |= PAINT_INVALID_OVERLAY_TEXTURE_SECONDARY; + } + } + } + FOREACH_OB_MODE_PAINT_ITER_END; } -void BKE_paint_invalidate_cursor_overlay(Scene *scene, ViewLayer *view_layer, CurveMapping *curve) +void BKE_paint_invalidate_cursor_overlay( + Scene *scene, ViewLayer *view_layer, CurveMapping *curve, eObjectMode object_mode) { - Paint *p = BKE_paint_get_active(scene, view_layer); - Brush *br = p->brush; - - if (br && br->curve == curve) - overlay_flags |= PAINT_INVALID_OVERLAY_CURVE; + FOREACH_OB_MODE_PAINT_ITER_BEGIN(scene, view_layer, object_mode, p) + { + Brush *br = p->brush; + if (br) { + if (br->curve == curve) { + overlay_flags |= PAINT_INVALID_OVERLAY_CURVE; + break; + } + } + } + FOREACH_OB_MODE_PAINT_ITER_END; } void BKE_paint_invalidate_overlay_all(void) @@ -157,13 +198,13 @@ Paint *BKE_paint_get_active_from_paintmode(Scene *sce, ePaintMode mode) return NULL; } -Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer) +Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer, const eObjectMode object_mode) { if (sce && view_layer) { ToolSettings *ts = sce->toolsettings; if (view_layer->basact && view_layer->basact->object) { - switch (view_layer->basact->object->mode) { + switch (object_mode) { case OB_MODE_SCULPT: return &ts->sculpt->paint; case OB_MODE_VERTEX_PAINT: @@ -176,6 +217,8 @@ Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer) if (ts->use_uv_sculpt) return &ts->uvsculpt->paint; return &ts->imapaint.paint; + default: + break; } } @@ -193,6 +236,7 @@ Paint *BKE_paint_get_active_from_context(const bContext *C) SpaceImage *sima; if (sce && view_layer) { + const WorkSpace *workspace = CTX_wm_workspace(C); ToolSettings *ts = sce->toolsettings; Object *obact = NULL; @@ -200,7 +244,7 @@ Paint *BKE_paint_get_active_from_context(const bContext *C) obact = view_layer->basact->object; if ((sima = CTX_wm_space_image(C)) != NULL) { - if (obact && obact->mode == OB_MODE_EDIT) { + if (obact && workspace->object_mode == OB_MODE_EDIT) { if (sima->mode == SI_MODE_PAINT) return &ts->imapaint.paint; else if (ts->use_uv_sculpt) @@ -211,7 +255,7 @@ Paint *BKE_paint_get_active_from_context(const bContext *C) } } else if (obact) { - switch (obact->mode) { + switch (workspace->object_mode) { case OB_MODE_SCULPT: return &ts->sculpt->paint; case OB_MODE_VERTEX_PAINT: @@ -244,6 +288,7 @@ ePaintMode BKE_paintmode_get_active_from_context(const bContext *C) SpaceImage *sima; if (sce && view_layer) { + const WorkSpace *workspace = CTX_wm_workspace(C); ToolSettings *ts = sce->toolsettings; Object *obact = NULL; @@ -251,7 +296,7 @@ ePaintMode BKE_paintmode_get_active_from_context(const bContext *C) obact = view_layer->basact->object; if ((sima = CTX_wm_space_image(C)) != NULL) { - if (obact && obact->mode == OB_MODE_EDIT) { + if (obact && workspace->object_mode == OB_MODE_EDIT) { if (sima->mode == SI_MODE_PAINT) return ePaintTexture2D; else if (ts->use_uv_sculpt) @@ -262,7 +307,7 @@ ePaintMode BKE_paintmode_get_active_from_context(const bContext *C) } } else if (obact) { - switch (obact->mode) { + switch (workspace->object_mode) { case OB_MODE_SCULPT: return ePaintSculpt; case OB_MODE_VERTEX_PAINT: @@ -453,24 +498,24 @@ bool BKE_palette_is_empty(const struct Palette *palette) /* are we in vertex paint or weight pain face select mode? */ -bool BKE_paint_select_face_test(Object *ob) +bool BKE_paint_select_face_test(Object *ob, eObjectMode object_mode) { return ( (ob != NULL) && (ob->type == OB_MESH) && (ob->data != NULL) && (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) && - (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) + (object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) ); } /* are we in weight paint vertex select mode? */ -bool BKE_paint_select_vert_test(Object *ob) +bool BKE_paint_select_vert_test(Object *ob, eObjectMode object_mode) { return ( (ob != NULL) && (ob->type == OB_MESH) && (ob->data != NULL) && (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_VERT_SEL) && - (ob->mode & OB_MODE_WEIGHT_PAINT || ob->mode & OB_MODE_VERTEX_PAINT) + (object_mode & OB_MODE_WEIGHT_PAINT || object_mode & OB_MODE_VERTEX_PAINT) ); } @@ -478,10 +523,10 @@ bool BKE_paint_select_vert_test(Object *ob) * used to check if selection is possible * (when we don't care if its face or vert) */ -bool BKE_paint_select_elem_test(Object *ob) +bool BKE_paint_select_elem_test(Object *ob, eObjectMode object_mode) { - return (BKE_paint_select_vert_test(ob) || - BKE_paint_select_face_test(ob)); + return (BKE_paint_select_vert_test(ob, object_mode) || + BKE_paint_select_face_test(ob, object_mode)); } void BKE_paint_cavity_curve_preset(Paint *p, int preset) @@ -499,7 +544,7 @@ void BKE_paint_cavity_curve_preset(Paint *p, int preset) curvemapping_changed(p->cavity_curve, false); } -short BKE_paint_object_mode_from_paint_mode(ePaintMode mode) +eObjectMode BKE_paint_object_mode_from_paint_mode(ePaintMode mode) { switch (mode) { case ePaintSculpt: @@ -529,7 +574,7 @@ void BKE_paint_init(Scene *sce, ePaintMode mode, const char col[3]) /* If there's no brush, create one */ brush = BKE_paint_brush(paint); if (brush == NULL) { - short ob_mode = BKE_paint_object_mode_from_paint_mode(mode); + eObjectMode ob_mode = BKE_paint_object_mode_from_paint_mode(mode); brush = BKE_brush_first_search(G.main, ob_mode); if (!brush) { @@ -784,7 +829,7 @@ void BKE_sculptsession_free(Object *ob) BM_log_free(ss->bm_log); if (dm && dm->getPBVH) - dm->getPBVH(NULL, dm); /* signal to clear */ + dm->getPBVH(NULL, dm, OB_MODE_OBJECT); /* signal to clear */ if (ss->texcache) MEM_freeN(ss->texcache); @@ -921,7 +966,7 @@ void BKE_sculpt_update_mesh_elements( dm = mesh_get_derived_final(eval_ctx, scene, ob, CD_MASK_BAREMESH); /* VWPaint require mesh info for loop lookup, so require sculpt mode here */ - if (mmd && ob->mode & OB_MODE_SCULPT) { + if (mmd && eval_ctx->object_mode & OB_MODE_SCULPT) { ss->multires = mmd; ss->totvert = dm->getNumVerts(dm); ss->totpoly = dm->getNumPolys(dm); @@ -939,7 +984,7 @@ void BKE_sculpt_update_mesh_elements( ss->vmask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK); } - ss->pbvh = dm->getPBVH(ob, dm); + ss->pbvh = dm->getPBVH(ob, dm, eval_ctx->object_mode); ss->pmap = (need_pmap && dm->getPolyMap) ? dm->getPolyMap(ob, dm) : NULL; pbvh_show_diffuse_color_set(ss->pbvh, ss->show_diffuse_color); @@ -1064,3 +1109,39 @@ int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd) return ret; } + +void BKE_sculpt_toolsettings_data_ensure(struct Scene *scene) +{ + Sculpt *sd = scene->toolsettings->sculpt; + if (sd == NULL) { + sd = scene->toolsettings->sculpt = MEM_callocN(sizeof(Sculpt), __func__); + + /* Turn on X plane mirror symmetry by default */ + sd->paint.symmetry_flags |= PAINT_SYMM_X; + sd->paint.flags |= PAINT_SHOW_BRUSH; + + /* Make sure at least dyntopo subdivision is enabled */ + sd->flags |= SCULPT_DYNTOPO_SUBDIVIDE | SCULPT_DYNTOPO_COLLAPSE; + } + + if (!sd->detail_size) { + sd->detail_size = 12; + } + if (!sd->detail_percent) { + sd->detail_percent = 25; + } + if (sd->constant_detail == 0.0f) { + sd->constant_detail = 3.0f; + } + + /* Set sane default tiling offsets */ + if (!sd->paint.tile_offset[0]) { + sd->paint.tile_offset[0] = 1.0f; + } + if (!sd->paint.tile_offset[1]) { + sd->paint.tile_offset[1] = 1.0f; + } + if (!sd->paint.tile_offset[2]) { + sd->paint.tile_offset[2] = 1.0f; + } +} diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 5e2cd89a750..c9507ac1a36 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -90,6 +90,8 @@ #include "RE_render_ext.h" +#include "particle_private.h" + unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT]; unsigned int PSYS_FRAND_SEED_MULTIPLIER[PSYS_FRAND_COUNT]; float PSYS_FRAND_BASE[PSYS_FRAND_COUNT]; @@ -109,9 +111,6 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex); static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSettings *part, ParticleData *par, int child_index, int face_index, const float fw[4], float *orco, ParticleTexture *ptex, int event, float cfra); -extern void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim, - ParticleTexture *ptex, const float par_co[3], const float par_vel[3], const float par_rot[4], const float par_orco[3], - ChildParticle *cpa, const float orco[3], float mat[4][4], ParticleKey *state, float t); /* few helpers for countall etc. */ int count_particles(ParticleSystem *psys) @@ -252,7 +251,7 @@ struct LatticeDeformData *psys_create_lattice_deform_data(ParticleSimulationData { struct LatticeDeformData *lattice_deform_data = NULL; - if (psys_in_edit_mode(sim->eval_ctx->view_layer, sim->psys) == 0) { + if (psys_in_edit_mode(sim->eval_ctx, sim->eval_ctx->view_layer, sim->psys) == 0) { Object *lattice = NULL; ModifierData *md = (ModifierData *)psys_get_modifier(sim->ob, sim->psys); int mode = G.is_rendering ? eModifierMode_Render : eModifierMode_Realtime; @@ -289,11 +288,12 @@ void psys_enable_all(Object *ob) psys->flag &= ~PSYS_DISABLED; } -bool psys_in_edit_mode(ViewLayer *view_layer, ParticleSystem *psys) +bool psys_in_edit_mode(const EvaluationContext *eval_ctx, ViewLayer *view_layer, ParticleSystem *psys) { - return (view_layer->basact && - (view_layer->basact->object->mode & OB_MODE_PARTICLE_EDIT) && - psys == psys_get_current((view_layer->basact)->object) && + /* TODO(mai): the check for view_layer shouldnt be needed, remove when render engine api is updated for this */ + return (view_layer && view_layer->basact && + (eval_ctx->object_mode & OB_MODE_PARTICLE_EDIT) && + psys == psys_get_current(view_layer->basact->object) && (psys->edit || psys->pointcache->edit) && !psys->renderdata); } @@ -413,6 +413,8 @@ void BKE_particlesettings_free(ParticleSettings *part) curvemapping_free(part->clumpcurve); if (part->roughcurve) curvemapping_free(part->roughcurve); + if (part->twistcurve) + curvemapping_free(part->twistcurve); free_partdeflect(part->pd); free_partdeflect(part->pd2); @@ -1806,11 +1808,6 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int in /* Path Cache */ /************************************************/ -extern void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], const float par_rot[4], float time, float freq, float shape, float amplitude, float flat, - short type, short axis, float obmat[4][4], int smooth_start); -extern float do_clump(ParticleKey *state, const float par_co[3], float time, const float orco_offset[3], float clumpfac, float clumppow, float pa_clump, - bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve); - void precalc_guides(ParticleSimulationData *sim, ListBase *effectors) { EffectedPoint point; @@ -2098,7 +2095,7 @@ static bool psys_thread_context_init_path( psys_thread_context_init(ctx, sim); /*---start figuring out what is actually wanted---*/ - if (psys_in_edit_mode(sim->eval_ctx->view_layer, psys)) { + if (psys_in_edit_mode(sim->eval_ctx, sim->eval_ctx->view_layer, psys)) { ParticleEditSettings *pset = &scene->toolsettings->particle; if ((psys->renderdata == 0 && use_render_params == 0) && (psys->edit == NULL || pset->flag & PE_DRAW_PART) == 0) @@ -2149,6 +2146,7 @@ static bool psys_thread_context_init_path( ctx->vg_rough1 = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_ROUGH1); ctx->vg_rough2 = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_ROUGH2); ctx->vg_roughe = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_ROUGHE); + ctx->vg_twist = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_TWIST); if (psys->part->flag & PART_CHILD_EFFECT) ctx->vg_effector = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_EFFECTOR); @@ -2167,6 +2165,13 @@ static bool psys_thread_context_init_path( else { ctx->roughcurve = NULL; } + if ((part->child_flag & PART_CHILD_USE_TWIST_CURVE) && part->twistcurve) { + ctx->twistcurve = curvemapping_copy(part->twistcurve); + curvemapping_changed_all(ctx->twistcurve); + } + else { + ctx->twistcurve = NULL; + } return true; } @@ -2187,7 +2192,7 @@ static void psys_thread_create_path(ParticleTask *task, struct ChildParticle *cp ParticleSystem *psys = ctx->sim.psys; ParticleSettings *part = psys->part; ParticleCacheKey **cache = psys->childcache; - ParticleCacheKey **pcache = psys_in_edit_mode(ctx->sim.eval_ctx->view_layer, psys) && psys->edit ? psys->edit->pathcache : psys->pathcache; + ParticleCacheKey **pcache = psys_in_edit_mode(ctx->sim.eval_ctx, ctx->sim.eval_ctx->view_layer, psys) && psys->edit ? psys->edit->pathcache : psys->pathcache; ParticleCacheKey *child, *key[4]; ParticleTexture ptex; float *cpa_fuv = 0, *par_rot = 0, rot[4]; @@ -2311,7 +2316,19 @@ static void psys_thread_create_path(ParticleTask *task, struct ChildParticle *cp /* get the original coordinates (orco) for texture usage */ cpa_from = part->from; - cpa_num = pa->num; + + /* + * NOTE: Should in theory be the same as: + cpa_num = psys_particle_dm_face_lookup( + ctx->sim.psmd->dm_final, + ctx->sim.psmd->dm_deformed, + pa->num, pa->fuv, + NULL); + */ + cpa_num = (ELEM(pa->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND)) + ? pa->num + : pa->num_dmcache; + /* XXX hack to avoid messed up particle num and subsequent crash (#40733) */ if (cpa_num > ctx->sim.psmd->dm_final->getNumTessFaces(ctx->sim.psmd->dm_final)) cpa_num = 0; @@ -2564,7 +2581,9 @@ static void cache_key_incremental_rotation(ParticleCacheKey *key0, ParticleCache void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_render_params) { PARTICLE_PSMD; +#if 0 ParticleEditSettings *pset = &sim->scene->toolsettings->particle; +#endif ParticleSystem *psys = sim->psys; ParticleSettings *part = psys->part; ParticleCacheKey *ca, **cache; @@ -2596,9 +2615,11 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re if ((psys->flag & PSYS_HAIR_DONE || psys->flag & PSYS_KEYED || psys->pointcache) == 0) return; - if (psys_in_edit_mode(sim->eval_ctx->view_layer, psys)) +#if 0 /* TODO(mai): something is very wrong with these conditionals, they dont make sense and the cache isnt updating */ + if (psys_in_edit_mode(sim->eval_ctx, sim->eval_ctx->view_layer, psys)) if (psys->renderdata == 0 && (psys->edit == NULL || pset->flag & PE_DRAW_PART) == 0) return; +#endif keyed = psys->flag & PSYS_KEYED; baked = psys->pointcache->mem_cache.first && psys->part->type != PART_HAIR; @@ -3223,8 +3244,6 @@ void object_remove_particle_system(Scene *UNUSED(scene), Object *ob) if (ob->particlesystem.first) ((ParticleSystem *) ob->particlesystem.first)->flag |= PSYS_CURRENT; - else - ob->mode &= ~OB_MODE_PARTICLE_EDIT; DEG_relations_tag_update(G.main); DEG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -3354,6 +3373,18 @@ void BKE_particlesettings_rough_curve_init(ParticleSettings *part) part->roughcurve = cumap; } +void BKE_particlesettings_twist_curve_init(ParticleSettings *part) +{ + CurveMapping *cumap = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); + + cumap->cm[0].curve[0].x = 0.0f; + cumap->cm[0].curve[0].y = 1.0f; + cumap->cm[0].curve[1].x = 1.0f; + cumap->cm[0].curve[1].y = 1.0f; + + part->twistcurve = cumap; +} + /** * Only copy internal data of ParticleSettings ID from source to already allocated/initialized destination. * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs. @@ -3376,6 +3407,9 @@ void BKE_particlesettings_copy_data( if (part_src->roughcurve) { part_dst->roughcurve = curvemapping_copy(part_src->roughcurve); } + if (part_src->twistcurve) { + part_dst->twistcurve = curvemapping_copy(part_src->twistcurve); + } part_dst->boids = boid_copy_settings(part_src->boids); @@ -3495,6 +3529,7 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti ptex->ivel = ptex->life = ptex->exist = ptex->size = ptex->damp = ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink_freq = ptex->kink_amp = ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.0f; + ptex->twist = 1.0f; ptex->length = 1.0f - part->randlength * psys_frand(psys, child_index + 26); ptex->length *= part->clength_thres < psys_frand(psys, child_index + 27) ? part->clength : 1.0f; @@ -3547,6 +3582,7 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti SET_PARTICLE_TEXTURE(PAMAP_KINK_AMP, ptex->kink_amp, mtex->kinkampfac); SET_PARTICLE_TEXTURE(PAMAP_KINK_FREQ, ptex->kink_freq, mtex->kinkfac); SET_PARTICLE_TEXTURE(PAMAP_DENS, ptex->exist, mtex->padensfac); + SET_PARTICLE_TEXTURE(PAMAP_TWIST, ptex->twist, mtex->twistfac); } } @@ -3572,6 +3608,7 @@ void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTex ptex->ivel = ptex->life = ptex->exist = ptex->size = ptex->damp = ptex->gravity = ptex->field = ptex->length = ptex->clump = ptex->kink_freq = ptex->kink_amp = ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.0f; + ptex->twist = 1.0f; ptex->time = (float)(pa - sim->psys->particles) / (float)sim->psys->totpart; @@ -3646,6 +3683,7 @@ void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTex SET_PARTICLE_TEXTURE(PAMAP_GRAVITY, ptex->gravity, mtex->gravityfac); SET_PARTICLE_TEXTURE(PAMAP_DAMP, ptex->damp, mtex->dampfac); SET_PARTICLE_TEXTURE(PAMAP_LENGTH, ptex->length, mtex->lengthfac); + SET_PARTICLE_TEXTURE(PAMAP_TWIST, ptex->twist, mtex->twistfac); } } @@ -3737,6 +3775,8 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread ptex->roughe *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_roughe); if (ctx->vg_effector) ptex->effector *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_effector); + if (ctx->vg_twist) + ptex->twist *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_twist); } /* get's hair (or keyed) particles state at the "path time" specified in state->time */ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *state, const bool vel) @@ -3789,7 +3829,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE); /* pind.dm disabled in editmode means we don't get effectors taken into * account when subdividing for instance */ - pind.dm = psys_in_edit_mode(sim->eval_ctx->view_layer, psys) ? NULL : psys->hair_out_dm; + pind.dm = psys_in_edit_mode(sim->eval_ctx, sim->eval_ctx->view_layer, psys) ? NULL : psys->hair_out_dm; init_particle_interpolation(sim->ob, psys, pa, &pind); do_particle_interpolation(psys, p, pa, t, &pind, state); @@ -3942,7 +3982,18 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * copy_particle_key(&tstate, state, 1); /* apply different deformations to the child path */ - do_child_modifiers(NULL, sim, &ptex, par->co, par->vel, par->rot, par_orco, cpa, orco, hairmat, state, t); + ParticleChildModifierContext modifier_ctx = {NULL}; + modifier_ctx.thread_ctx = NULL; + modifier_ctx.sim = sim; + modifier_ctx.ptex = &ptex; + modifier_ctx.cpa = cpa; + modifier_ctx.orco = orco; + modifier_ctx.par_co = par->co; + modifier_ctx.par_vel = par->vel; + modifier_ctx.par_rot = par->rot; + modifier_ctx.par_orco = par_orco; + modifier_ctx.parent_keys = psys->childcache ? psys->childcache[p - totpart] : NULL; + do_child_modifiers(&modifier_ctx, hairmat, state, t); /* try to estimate correct velocity */ if (vel) { @@ -4045,7 +4096,19 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta CLAMP(t, 0.0f, 1.0f); unit_m4(mat); - do_child_modifiers(NULL, sim, NULL, key1->co, key1->vel, key1->rot, par_orco, cpa, cpa->fuv, mat, state, t); + ParticleChildModifierContext modifier_ctx = {NULL}; + modifier_ctx.thread_ctx = NULL; + modifier_ctx.sim = sim; + modifier_ctx.ptex = NULL; + modifier_ctx.cpa = cpa; + modifier_ctx.orco = cpa->fuv; + modifier_ctx.par_co = key1->co; + modifier_ctx.par_vel = key1->vel; + modifier_ctx.par_rot = key1->rot; + modifier_ctx.par_orco = par_orco; + modifier_ctx.parent_keys = psys->childcache ? psys->childcache[p - totpart] : NULL; + + do_child_modifiers(&modifier_ctx, mat, state, t); if (psys->lattice_deform_data) calc_latt_deform(psys->lattice_deform_data, state->co, psys->lattice_strength); diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c index d2ad05c20b7..28bdde4e5f5 100644 --- a/source/blender/blenkernel/intern/particle_child.c +++ b/source/blender/blenkernel/intern/particle_child.c @@ -37,15 +37,9 @@ #include "BKE_colortools.h" #include "BKE_particle.h" -struct Material; +#include "particle_private.h" -void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], const float par_rot[4], float time, float freq, float shape, float amplitude, float flat, - short type, short axis, float obmat[4][4], int smooth_start); -float do_clump(ParticleKey *state, const float par_co[3], float time, const float orco_offset[3], float clumpfac, float clumppow, float pa_clump, - bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve); -void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim, - ParticleTexture *ptex, const float par_co[3], const float par_vel[3], const float par_rot[4], const float par_orco[3], - ChildParticle *cpa, const float orco[3], float mat[4][4], ParticleKey *state, float t); +struct Material; static void get_strand_normal(Material *ma, const float surfnor[3], float surfdist, float nor[3]) { @@ -67,7 +61,7 @@ static void get_strand_normal(Material *ma, const float surfnor[3], float surfdi else { copy_v3_v3(vnor, nor); } - + if (ma->strand_surfnor > 0.0f) { if (ma->strand_surfnor > surfdist) { blend = (ma->strand_surfnor - surfdist) / ma->strand_surfnor; @@ -85,7 +79,7 @@ typedef struct ParticlePathIterator { ParticleCacheKey *key; int index; float time; - + ParticleCacheKey *parent_key; float parent_rotation[4]; } ParticlePathIterator; @@ -94,11 +88,11 @@ static void psys_path_iter_get(ParticlePathIterator *iter, ParticleCacheKey *key ParticleCacheKey *parent, int index) { BLI_assert(index >= 0 && index < totkeys); - + iter->key = keys + index; iter->index = index; iter->time = (float)index / (float)(totkeys - 1); - + if (parent) { iter->parent_key = parent + index; if (index > 0) @@ -114,7 +108,7 @@ static void psys_path_iter_get(ParticlePathIterator *iter, ParticleCacheKey *key typedef struct ParticlePathModifier { struct ParticlePathModifier *next, *prev; - + void (*apply)(ParticleCacheKey *keys, int totkeys, ParticleCacheKey *parent_keys); } ParticlePathModifier; @@ -133,7 +127,7 @@ static void do_kink_spiral_deform(ParticleKey *state, const float dir[3], const { /* Creates a logarithmic spiral: * r(theta) = a * exp(b * theta) - * + * * The "density" parameter b is defined by the shape parameter * and goes up to the Golden Spiral for 1.0 * https://en.wikipedia.org/wiki/Golden_spiral @@ -142,33 +136,33 @@ static void do_kink_spiral_deform(ParticleKey *state, const float dir[3], const /* angle of the spiral against the curve (rotated opposite to make a smooth transition) */ const float start_angle = ((b != 0.0f) ? atanf(1.0f / b) : (float)-M_PI_2) + (b > 0.0f ? -(float)M_PI_2 : (float)M_PI_2); - + float spiral_axis[3], rot[3][3]; float vec[3]; - + float theta = freq * time * 2.0f * (float)M_PI; float radius = amplitude * expf(b * theta); - + /* a bit more intuitive than using negative frequency for this */ if (amplitude < 0.0f) theta = -theta; - + cross_v3_v3v3(spiral_axis, dir, kink); normalize_v3(spiral_axis); - + mul_v3_v3fl(vec, kink, -radius); - + axis_angle_normalized_to_mat3(rot, spiral_axis, theta); mul_m3_v3(rot, vec); - + madd_v3_v3fl(vec, kink, amplitude); - + axis_angle_normalized_to_mat3(rot, spiral_axis, -start_angle); mul_m3_v3(rot, vec); - + add_v3_v3v3(result, spiral_start, vec); } - + copy_v3_v3(state->co, result); } @@ -180,7 +174,7 @@ static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, co const int seed = ctx->sim.psys->child_seed + (int)(cpa - ctx->sim.psys->child); const int totkeys = ctx->segments + 1; const int extrakeys = ctx->extra_segments; - + float kink_amp_random = part->kink_amp_random; float kink_amp = part->kink_amp * (1.0f - kink_amp_random * psys_frand(ctx->sim.psys, 93541 + seed)); float kink_freq = part->kink_freq; @@ -189,11 +183,11 @@ static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, co float rough1 = part->rough1; float rough2 = part->rough2; float rough_end = part->rough_end; - + ParticlePathIterator iter; ParticleCacheKey *key; int k; - + float dir[3]; float spiral_start[3] = {0.0f, 0.0f, 0.0f}; float spiral_start_time = 0.0f; @@ -204,7 +198,7 @@ static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, co float cut_time; int start_index = 0, end_index = 0; float kink_base[3]; - + if (ptex) { kink_amp *= ptex->kink_amp; kink_freq *= ptex->kink_freq; @@ -212,44 +206,53 @@ static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, co rough2 *= ptex->rough2; rough_end *= ptex->roughe; } - + cut_time = (totkeys - 1) * ptex->length; zero_v3(spiral_start); - + for (k = 0, key = keys; k < totkeys-1; k++, key++) { if ((float)(k + 1) >= cut_time) { float fac = cut_time - (float)k; ParticleCacheKey *par = parent_keys + k; - + start_index = k + 1; end_index = start_index + extrakeys; - + spiral_start_time = ((float)k + fac) / (float)(totkeys - 1); interp_v3_v3v3(spiral_start, key->co, (key+1)->co, fac); - + interp_v3_v3v3(spiral_par_co, par->co, (par+1)->co, fac); interp_v3_v3v3(spiral_par_vel, par->vel, (par+1)->vel, fac); interp_qt_qtqt(spiral_par_rot, par->rot, (par+1)->rot, fac); - + break; } } - + zero_v3(dir); - + zero_v3(kink_base); kink_base[part->kink_axis] = 1.0f; mul_mat3_m4_v3(ctx->sim.ob->obmat, kink_base); - + + /* Fill in invariant part of modifier context. */ + ParticleChildModifierContext modifier_ctx = {NULL}; + modifier_ctx.thread_ctx = ctx; + modifier_ctx.sim = &ctx->sim; + modifier_ctx.ptex = ptex; + modifier_ctx.cpa = cpa; + modifier_ctx.orco = orco; + modifier_ctx.parent_keys = parent_keys; + for (k = 0, key = keys; k < end_index; k++, key++) { float par_time; float *par_co, *par_vel, *par_rot; - + psys_path_iter_get(&iter, keys, end_index, NULL, k); if (k < start_index) { sub_v3_v3v3(dir, (key+1)->co, key->co); normalize_v3(dir); - + par_time = (float)k / (float)(totkeys - 1); par_co = parent_keys[k].co; par_vel = parent_keys[k].vel; @@ -258,36 +261,42 @@ static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, co else { float spiral_time = (float)(k - start_index) / (float)(extrakeys-1); float kink[3], tmp[3]; - + /* use same time value for every point on the spiral */ par_time = spiral_start_time; par_co = spiral_par_co; par_vel = spiral_par_vel; par_rot = spiral_par_rot; - + project_v3_v3v3(tmp, kink_base, dir); sub_v3_v3v3(kink, kink_base, tmp); normalize_v3(kink); - + if (kink_axis_random > 0.0f) { float a = kink_axis_random * (psys_frand(ctx->sim.psys, 7112 + seed) * 2.0f - 1.0f) * (float)M_PI; float rot[3][3]; - + axis_angle_normalized_to_mat3(rot, dir, a); mul_m3_v3(rot, kink); } - + do_kink_spiral_deform((ParticleKey *)key, dir, kink, spiral_time, kink_freq, kink_shape, kink_amp, spiral_start); } - - /* apply different deformations to the child path */ - do_child_modifiers(ctx, &ctx->sim, ptex, par_co, par_vel, par_rot, parent_orco, cpa, orco, hairmat, (ParticleKey *)key, par_time); + + /* Fill in variant part of modifier context. */ + modifier_ctx.par_co = par_co; + modifier_ctx.par_vel = par_vel; + modifier_ctx.par_rot = par_rot; + modifier_ctx.par_orco = parent_orco; + + /* Apply different deformations to the child path/ */ + do_child_modifiers(&modifier_ctx, hairmat, (ParticleKey *)key, par_time); } - + totlen = 0.0f; for (k = 0, key = keys; k < end_index-1; k++, key++) totlen += len_v3v3((key+1)->co, key->co); - + *r_totkeys = end_index; *r_max_length = totlen; } @@ -318,12 +327,12 @@ void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *mod struct Material *ma = ctx->ma; const bool draw_col_ma = (part->draw_col == PART_DRAW_COL_MAT); const bool use_length_check = !ELEM(part->kink, PART_KINK_SPIRAL); - + ParticlePathModifier *mod; ParticleCacheKey *key; int totkeys, k; float max_length; - + #if 0 /* TODO for the future: use true particle modifiers that work on the whole curve */ for (mod = modifiers->first; mod; mod = mod->next) { mod->apply(keys, totkeys, parent_keys); @@ -331,25 +340,38 @@ void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *mod #else (void)modifiers; (void)mod; - + if (part->kink == PART_KINK_SPIRAL) { do_kink_spiral(ctx, ptex, parent_orco, cpa, orco, hairmat, keys, parent_keys, &totkeys, &max_length); keys->segments = totkeys - 1; } else { - ParticlePathIterator iter; - + /* Fill in invariant part of modifier context. */ + ParticleChildModifierContext modifier_ctx = {NULL}; + modifier_ctx.thread_ctx = ctx; + modifier_ctx.sim = &ctx->sim; + modifier_ctx.ptex = ptex; + modifier_ctx.cpa = cpa; + modifier_ctx.orco = orco; + modifier_ctx.parent_keys = parent_keys; + totkeys = ctx->segments + 1; max_length = ptex->length; - + for (k = 0, key = keys; k < totkeys; k++, key++) { - ParticleKey *par; - + ParticlePathIterator iter; psys_path_iter_get(&iter, keys, totkeys, parent_keys, k); - par = (ParticleKey *)iter.parent_key; - - /* apply different deformations to the child path */ - do_child_modifiers(ctx, &ctx->sim, ptex, par->co, par->vel, iter.parent_rotation, parent_orco, cpa, orco, hairmat, (ParticleKey *)key, iter.time); + + ParticleKey *par = (ParticleKey *)iter.parent_key; + + /* Fill in variant part of modifier context. */ + modifier_ctx.par_co = par->co; + modifier_ctx.par_vel = par->vel; + modifier_ctx.par_rot = iter.parent_rotation; + modifier_ctx.par_orco = parent_orco; + + /* Apply different deformations to the child path. */ + do_child_modifiers(&modifier_ctx, hairmat, (ParticleKey *)key, iter.time); } } @@ -367,11 +389,11 @@ void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *mod if (k >= 2) { sub_v3_v3v3((key-1)->vel, key->co, (key-2)->co); mul_v3_fl((key-1)->vel, 0.5); - + if (ma && draw_col_ma) get_strand_normal(ma, ornor, cur_length, (key-1)->vel); } - + if (use_length_check && k > 1) { float dvec[3]; /* check if path needs to be cut before actual end of data points */ @@ -388,7 +410,7 @@ void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *mod /* last key */ sub_v3_v3v3(key->vel, key->co, (key-1)->co); } - + if (ma && draw_col_ma) { copy_v3_v3(key->col, &ma->r); get_strand_normal(ma, ornor, cur_length, key->vel); @@ -419,7 +441,7 @@ void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], } t = time * freq * (float)M_PI; - + if (smooth_start) { dt = fabsf(t); /* smooth the beginning of kink */ @@ -434,7 +456,7 @@ void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], if (obmat) mul_mat3_m4_v3(obmat, kink); - + mul_qt_v3(par_rot, kink); /* make sure kink is normal to strand */ @@ -450,12 +472,12 @@ void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], case PART_KINK_CURL: { float curl_offset[3]; - + /* rotate kink vector around strand tangent */ mul_v3_v3fl(curl_offset, kink, amplitude); axis_angle_to_quat(q1, par_vel, t); mul_qt_v3(q1, curl_offset); - + interp_v3_v3v3(par_vec, state->co, par_co, flat); add_v3_v3v3(result, par_vec, curl_offset); break; @@ -494,7 +516,7 @@ void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], float z_vec[3] = {0.f, 0.f, 1.f}; float vec_one[3], state_co[3]; float inp_y, inp_z, length; - + if (par_rot) { mul_qt_v3(par_rot, y_vec); mul_qt_v3(par_rot, z_vec); @@ -563,10 +585,10 @@ static float do_clump_level(float result[3], const float co[3], const float par_ float clumpfac, float clumppow, float pa_clump, CurveMapping *clumpcurve) { float clump = 0.0f; - + if (clumpcurve) { - clump = pa_clump * (1.0f - CLAMPIS(curvemapping_evaluateF(clumpcurve, 0, time), 0.0f, 1.0f)); - + clump = pa_clump * (1.0f - clamp_f(curvemapping_evaluateF(clumpcurve, 0, time), 0.0f, 1.0f)); + interp_v3_v3v3(result, co, par_co, clump); } else if (clumpfac != 0.0f) { @@ -584,7 +606,7 @@ static float do_clump_level(float result[3], const float co[3], const float par_ interp_v3_v3v3(result, co, par_co, clump); } - + return clump; } @@ -592,21 +614,21 @@ float do_clump(ParticleKey *state, const float par_co[3], float time, const floa bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve) { float clump; - + if (use_clump_noise && clump_noise_size != 0.0f) { float center[3], noisevec[3]; float da[4], pa[12]; - + mul_v3_v3fl(noisevec, orco_offset, 1.0f / clump_noise_size); voronoi(noisevec[0], noisevec[1], noisevec[2], da, pa, 1.0f, 0); mul_v3_fl(&pa[0], clump_noise_size); add_v3_v3v3(center, par_co, &pa[0]); - + do_clump_level(state->co, state->co, center, time, clumpfac, clumppow, pa_clump, clumpcurve); } - + clump = do_clump_level(state->co, state->co, par_co, time, clumpfac, clumppow, pa_clump, clumpcurve); - + return clump; } @@ -651,27 +673,117 @@ static void do_rough_curve(const float loc[3], float mat[4][4], float time, floa { float rough[3]; float rco[3]; - + if (!roughcurve) return; - - fac *= CLAMPIS(curvemapping_evaluateF(roughcurve, 0, time), 0.0f, 1.0f); - + + fac *= clamp_f(curvemapping_evaluateF(roughcurve, 0, time), 0.0f, 1.0f); + copy_v3_v3(rco, loc); mul_v3_fl(rco, time); rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2); rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2); rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2); - + madd_v3_v3fl(state->co, mat[0], fac * rough[0]); madd_v3_v3fl(state->co, mat[1], fac * rough[1]); madd_v3_v3fl(state->co, mat[2], fac * rough[2]); } -void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim, ParticleTexture *ptex, - const float par_co[3], const float par_vel[3], const float par_rot[4], const float par_orco[3], - ChildParticle *cpa, const float orco[3], float mat[4][4], ParticleKey *state, float t) +static int twist_num_segments(const ParticleChildModifierContext *modifier_ctx) { + ParticleThreadContext *thread_ctx = modifier_ctx->thread_ctx; + return (thread_ctx != NULL) ? thread_ctx->segments + : modifier_ctx->sim->psys->part->draw_step; +} + +static void twist_get_axis(const ParticleChildModifierContext *modifier_ctx, + const float time, float r_axis[3]) +{ + const int num_segments = twist_num_segments(modifier_ctx); + const int index = clamp_i(time * num_segments, 0, num_segments); + if (index > 0) { + sub_v3_v3v3(r_axis, + modifier_ctx->parent_keys[index].co, + modifier_ctx->parent_keys[index - 1].co); + } + else { + sub_v3_v3v3(r_axis, + modifier_ctx->parent_keys[index + 1].co, + modifier_ctx->parent_keys[index].co); + } +} + +static float curvemapping_integrate_clamped(CurveMapping *curve, + float start, float end, float step) +{ + float integral = 0.0f; + float x = start; + while (x < end) { + float y = curvemapping_evaluateF(curve, 0, x); + y = clamp_f(y, 0.0f, 1.0f); + /* TODO(sergey): Clamp last step to end. */ + integral += y * step; + x += step; + } + return integral; +} + +static void do_twist(const ParticleChildModifierContext *modifier_ctx, + ParticleKey *state, const float time) +{ + ParticleThreadContext *thread_ctx = modifier_ctx->thread_ctx; + ParticleSimulationData *sim = modifier_ctx->sim; + ParticleTexture *ptex = modifier_ctx->ptex; + ParticleSettings *part = sim->psys->part; + /* Early output checks. */ + if (part->childtype != PART_CHILD_PARTICLES) { + /* Interpolated children behave weird with twist. */ + return; + } + if (part->twist == 0.0f) { + /* No twist along the strand. */ + return; + } + /* Dependent on whether it's threaded update or not, curve comes + * from different places. + */ + CurveMapping *twist_curve = NULL; + if (part->child_flag & PART_CHILD_USE_TWIST_CURVE) { + twist_curve = (thread_ctx != NULL) ? thread_ctx->twistcurve + : part->twistcurve; + } + /* Axis of rotation. */ + float axis[3]; + twist_get_axis(modifier_ctx, time, axis); + /* Angle of rotation. */ + float angle = part->twist; + if (ptex != NULL) { + angle *= (ptex->twist - 0.5f) * 2.0f; + } + if (twist_curve != NULL) { + const int num_segments = twist_num_segments(modifier_ctx); + angle *= curvemapping_integrate_clamped(twist_curve, + 0.0f, time, + 1.0f / num_segments); + } + else { + angle *= time; + } + /* Perform rotation around parent curve. */ + float vec[3]; + sub_v3_v3v3(vec, state->co, modifier_ctx->par_co); + rotate_v3_v3v3fl(state->co, vec, axis, angle * 2.0f * M_PI); + add_v3_v3(state->co, modifier_ctx->par_co); +} + +void do_child_modifiers(const ParticleChildModifierContext *modifier_ctx, + float mat[4][4], ParticleKey *state, float t) +{ + ParticleThreadContext *ctx = modifier_ctx->thread_ctx; + ParticleSimulationData *sim = modifier_ctx->sim; + ParticleTexture *ptex = modifier_ctx->ptex; + ChildParticle *cpa = modifier_ctx->cpa; ParticleSettings *part = sim->psys->part; CurveMapping *clumpcurve = NULL, *roughcurve = NULL; int i = cpa - sim->psys->child; @@ -700,6 +812,8 @@ void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim, rough_end *= ptex->roughe; } + do_twist(modifier_ctx, state, t); + if (part->flag & PART_CHILD_EFFECT) /* state is safe to cast, since only co and vel are used */ guided = do_guides(sim->eval_ctx, sim->psys->part, sim->psys->effectors, (ParticleKey *)state, cpa->parent, t); @@ -707,33 +821,51 @@ void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim, if (guided == 0) { float orco_offset[3]; float clump; - - sub_v3_v3v3(orco_offset, orco, par_orco); - clump = do_clump(state, par_co, t, orco_offset, part->clumpfac, part->clumppow, ptex ? ptex->clump : 1.f, - part->child_flag & PART_CHILD_USE_CLUMP_NOISE, part->clump_noise_size, clumpcurve); + + sub_v3_v3v3(orco_offset, modifier_ctx->orco, modifier_ctx->par_orco); + clump = do_clump(state, + modifier_ctx->par_co, + t, + orco_offset, + part->clumpfac, + part->clumppow, + ptex ? ptex->clump : 1.0f, + part->child_flag & PART_CHILD_USE_CLUMP_NOISE, + part->clump_noise_size, + clumpcurve); if (kink_freq != 0.f) { kink_amp *= (1.f - kink_amp_clump * clump); - - do_kink(state, par_co, par_vel, par_rot, t, kink_freq, part->kink_shape, - kink_amp, part->kink_flat, part->kink, part->kink_axis, - sim->ob->obmat, smooth_start); + + do_kink(state, + modifier_ctx->par_co, + modifier_ctx->par_vel, + modifier_ctx->par_rot, + t, + kink_freq, + part->kink_shape, + kink_amp, + part->kink_flat, + part->kink, + part->kink_axis, + sim->ob->obmat, + smooth_start); } } if (roughcurve) { - do_rough_curve(orco, mat, t, rough1, part->rough1_size, roughcurve, state); + do_rough_curve(modifier_ctx->orco, mat, t, rough1, part->rough1_size, roughcurve, state); } else { if (rough1 > 0.f) - do_rough(orco, mat, t, rough1, part->rough1_size, 0.0, state); - + do_rough(modifier_ctx->orco, mat, t, rough1, part->rough1_size, 0.0, state); + if (rough2 > 0.f) { float vec[3]; psys_frand_vec(sim->psys, i + 27, vec); do_rough(vec, mat, t, rough2, part->rough2_size, part->rough2_thres, state); } - + if (rough_end > 0.f) { float vec[3]; psys_frand_vec(sim->psys, i + 27, vec); diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index ff8a638089f..767a17a34e7 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -36,7 +36,7 @@ #include "MEM_guardedalloc.h" #include "BLI_utildefines.h" -#include "BLI_jitter.h" +#include "BLI_jitter_2d.h" #include "BLI_kdtree.h" #include "BLI_math.h" #include "BLI_math_geom.h" diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index ac10ad44bf1..9bc4da6f0d5 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -48,7 +48,7 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_object_types.h" #include "DNA_curve_types.h" #include "DNA_scene_types.h" @@ -58,7 +58,7 @@ #include "BLI_utildefines.h" #include "BLI_edgehash.h" #include "BLI_rand.h" -#include "BLI_jitter.h" +#include "BLI_jitter_2d.h" #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_kdtree.h" @@ -98,7 +98,7 @@ /* fluid sim particle import */ #ifdef WITH_MOD_FLUID -#include "DNA_object_fluidsim.h" +#include "DNA_object_fluidsim_types.h" #include "LBM_fluidsim.h" #include <zlib.h> #include <string.h> @@ -499,6 +499,8 @@ void psys_thread_context_free(ParticleThreadContext *ctx) MEM_freeN(ctx->vg_rough2); if (ctx->vg_roughe) MEM_freeN(ctx->vg_roughe); + if (ctx->vg_twist) + MEM_freeN(ctx->vg_twist); if (ctx->sim.psys->lattice_deform_data) { end_latt_deform(ctx->sim.psys->lattice_deform_data); @@ -521,6 +523,9 @@ void psys_thread_context_free(ParticleThreadContext *ctx) if (ctx->roughcurve != NULL) { curvemapping_free(ctx->roughcurve); } + if (ctx->twistcurve != NULL) { + curvemapping_free(ctx->twistcurve); + } } static void initialize_particle_texture(ParticleSimulationData *sim, ParticleData *pa, int p) @@ -2898,14 +2903,19 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra, cons { ParticleSystem *psys = sim->psys; ParticleSettings *part = psys->part; +#if 0 ParticleEditSettings *pset = &sim->scene->toolsettings->particle; +#endif int distr=0, alloc=0, skip=0; if ((psys->part->childtype && psys->totchild != psys_get_tot_child(sim->scene, psys)) || psys->recalc&PSYS_RECALC_RESET) alloc=1; - if (alloc || psys->recalc&PSYS_RECALC_CHILD || (psys->vgroup[PSYS_VG_DENSITY] && (sim->ob && sim->ob->mode & OB_MODE_WEIGHT_PAINT))) + if (alloc || psys->recalc&PSYS_RECALC_CHILD || + (psys->vgroup[PSYS_VG_DENSITY] && (sim->ob && sim->eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT))) + { distr=1; + } if (distr) { if (alloc) @@ -2933,12 +2943,15 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra, cons skip = 1; /* draw visualization */ else if (psys->pointcache->flag & PTCACHE_BAKING) skip = 1; /* no need to cache paths while baking dynamics */ - else if (psys_in_edit_mode(sim->eval_ctx->view_layer, psys)) { + +#if 0 /* TODO(mai): something is very wrong with these conditionals, they dont make sense and the cache isnt updating */ + else if (psys_in_edit_mode(sim->eval_ctx, sim->eval_ctx->view_layer, psys)) { if ((pset->flag & PE_DRAW_PART)==0) skip = 1; else if (part->childtype==0 && (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED)==0) skip = 1; /* in edit mode paths are needed for child particles and dynamic hair */ } +#endif } diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 63f2c7e5452..14e0cfa75b5 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -1296,7 +1296,7 @@ void BKE_pbvh_get_grid_updates(PBVH *bvh, bool clear, void ***r_gridfaces, int * pbvh_iter_end(&iter); - const int tot = BLI_gset_size(face_set); + const int tot = BLI_gset_len(face_set); if (tot == 0) { *r_totface = 0; *r_gridfaces = NULL; @@ -1435,8 +1435,8 @@ void BKE_pbvh_node_num_verts( if (r_uniquevert) *r_uniquevert = node->uniq_verts; break; case PBVH_BMESH: - tot = BLI_gset_size(node->bm_unique_verts); - if (r_totvert) *r_totvert = tot + BLI_gset_size(node->bm_other_verts); + tot = BLI_gset_len(node->bm_unique_verts); + if (r_totvert) *r_totvert = tot + BLI_gset_len(node->bm_other_verts); if (r_uniquevert) *r_uniquevert = tot; break; } diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c index e77edb21798..6b6f2605dc3 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.c +++ b/source/blender/blenkernel/intern/pbvh_bmesh.c @@ -255,7 +255,7 @@ static void pbvh_bmesh_node_split(PBVH *bvh, const BBC *bbc_array, int node_inde const int cd_face_node_offset = bvh->cd_face_node_offset; PBVHNode *n = &bvh->nodes[node_index]; - if (BLI_gset_size(n->bm_faces) <= bvh->leaf_limit) { + if (BLI_gset_len(n->bm_faces) <= bvh->leaf_limit) { /* Node limit not exceeded */ pbvh_bmesh_node_finalize(bvh, node_index, cd_vert_node_offset, cd_face_node_offset); return; @@ -289,8 +289,8 @@ static void pbvh_bmesh_node_split(PBVH *bvh, const BBC *bbc_array, int node_inde *c2 = &bvh->nodes[children + 1]; c1->flag |= PBVH_Leaf; c2->flag |= PBVH_Leaf; - c1->bm_faces = BLI_gset_ptr_new_ex("bm_faces", BLI_gset_size(n->bm_faces) / 2); - c2->bm_faces = BLI_gset_ptr_new_ex("bm_faces", BLI_gset_size(n->bm_faces) / 2); + c1->bm_faces = BLI_gset_ptr_new_ex("bm_faces", BLI_gset_len(n->bm_faces) / 2); + c2->bm_faces = BLI_gset_ptr_new_ex("bm_faces", BLI_gset_len(n->bm_faces) / 2); /* Partition the parent node's faces between the two children */ GSET_ITER (gs_iter, n->bm_faces) { @@ -305,11 +305,11 @@ static void pbvh_bmesh_node_split(PBVH *bvh, const BBC *bbc_array, int node_inde /* Enforce at least one primitive in each node */ GSet *empty = NULL, *other; - if (BLI_gset_size(c1->bm_faces) == 0) { + if (BLI_gset_len(c1->bm_faces) == 0) { empty = c1->bm_faces; other = c2->bm_faces; } - else if (BLI_gset_size(c2->bm_faces) == 0) { + else if (BLI_gset_len(c2->bm_faces) == 0) { empty = c2->bm_faces; other = c1->bm_faces; } @@ -375,7 +375,7 @@ static void pbvh_bmesh_node_split(PBVH *bvh, const BBC *bbc_array, int node_inde static bool pbvh_bmesh_node_limit_ensure(PBVH *bvh, int node_index) { GSet *bm_faces = bvh->nodes[node_index].bm_faces; - const int bm_faces_size = BLI_gset_size(bm_faces); + const int bm_faces_size = BLI_gset_len(bm_faces); if (bm_faces_size <= bvh->leaf_limit) { /* Node limit not exceeded */ return false; @@ -1238,7 +1238,7 @@ static bool pbvh_bmesh_subdivide_long_edges( bool any_subdivided = false; while (!BLI_heap_is_empty(eq_ctx->q->heap)) { - BMVert **pair = BLI_heap_popmin(eq_ctx->q->heap); + BMVert **pair = BLI_heap_pop_min(eq_ctx->q->heap); BMVert *v1 = pair[0], *v2 = pair[1]; BMEdge *e; @@ -1326,7 +1326,7 @@ static void pbvh_bmesh_collapse_edge( /* Note: this could be done with BM_vert_splice(), but that * requires handling other issues like duplicate edges, so doesn't * really buy anything. */ - BLI_buffer_empty(deleted_faces); + BLI_buffer_clear(deleted_faces); BMLoop *l; @@ -1455,7 +1455,7 @@ static bool pbvh_bmesh_collapse_short_edges( GHash *deleted_verts = BLI_ghash_ptr_new("deleted_verts"); while (!BLI_heap_is_empty(eq_ctx->q->heap)) { - BMVert **pair = BLI_heap_popmin(eq_ctx->q->heap); + BMVert **pair = BLI_heap_pop_min(eq_ctx->q->heap); BMVert *v1 = pair[0], *v2 = pair[1]; BLI_mempool_free(eq_ctx->pool, pair); pair = NULL; @@ -2011,10 +2011,10 @@ void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node) if (node->bm_orco) return; - const int totvert = BLI_gset_size(node->bm_unique_verts) + - BLI_gset_size(node->bm_other_verts); + const int totvert = BLI_gset_len(node->bm_unique_verts) + + BLI_gset_len(node->bm_other_verts); - const int tottri = BLI_gset_size(node->bm_faces); + const int tottri = BLI_gset_len(node->bm_faces); node->bm_orco = MEM_mallocN(sizeof(*node->bm_orco) * totvert, __func__); node->bm_ortri = MEM_mallocN(sizeof(*node->bm_ortri) * tottri, __func__); @@ -2189,12 +2189,12 @@ static void pbvh_bmesh_verify(PBVH *bvh) int totface = 0, totvert = 0; for (int i = 0; i < bvh->totnode; i++) { PBVHNode *n = &bvh->nodes[i]; - totface += n->bm_faces ? BLI_gset_size(n->bm_faces) : 0; - totvert += n->bm_unique_verts ? BLI_gset_size(n->bm_unique_verts) : 0; + totface += n->bm_faces ? BLI_gset_len(n->bm_faces) : 0; + totvert += n->bm_unique_verts ? BLI_gset_len(n->bm_unique_verts) : 0; } - BLI_assert(totface == BLI_gset_size(faces_all)); - BLI_assert(totvert == BLI_gset_size(verts_all)); + BLI_assert(totface == BLI_gset_len(faces_all)); + BLI_assert(totvert == BLI_gset_len(verts_all)); } { diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index b794fcfd929..169b1b10024 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -40,7 +40,7 @@ #include "DNA_dynamicpaint_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_particle_types.h" #include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index bd4b817c8cd..4a52c4f7d14 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -50,7 +50,7 @@ #include "DNA_group_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 16e9844241d..899a911270f 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -166,7 +166,6 @@ void BKE_scene_copy_data(Main *bmain, Scene *sce_dst, const Scene *sce_src, cons sce_dst->ed = NULL; sce_dst->depsgraph_hash = NULL; - sce_dst->obedit = NULL; sce_dst->fps_info = NULL; /* layers and collections */ @@ -618,7 +617,7 @@ void BKE_scene_init(Scene *sce) */ sce->r.color_mgt_flag |= R_COLOR_MANAGEMENT; - sce->r.gauss = 1.0; + sce->r.gauss = 1.5f; /* deprecated but keep for upwards compat */ sce->r.postgamma = 1.0; @@ -982,10 +981,6 @@ void BKE_scene_set_background(Main *bmain, Scene *scene) /* check for cyclic sets, for reading old files but also for definite security (py?) */ BKE_scene_validate_setscene(bmain, scene); - /* can happen when switching modes in other scenes */ - if (scene->obedit && !(scene->obedit->mode & OB_MODE_EDIT)) - scene->obedit = NULL; - /* deselect objects (for dataselect) */ for (ob = bmain->object.first; ob; ob = ob->id.next) ob->flag &= ~(SELECT | OB_FROMGROUP); @@ -1381,7 +1376,7 @@ static bool check_rendered_viewport_visible(Main *bmain) return false; } -static void prepare_mesh_for_viewport_render(Main *bmain, Scene *scene) +static void prepare_mesh_for_viewport_render(Main *bmain, const EvaluationContext *eval_ctx) { /* This is needed to prepare mesh to be used by the render * engine from the viewport rendering. We do loading here @@ -1392,7 +1387,7 @@ static void prepare_mesh_for_viewport_render(Main *bmain, Scene *scene) * call loading of the edit data for the mesh objects. */ - Object *obedit = scene->obedit; + Object *obedit = OBEDIT_FROM_EVAL_CTX(eval_ctx); if (obedit) { Mesh *mesh = obedit->data; if ((obedit->type == OB_MESH) && @@ -1401,7 +1396,11 @@ static void prepare_mesh_for_viewport_render(Main *bmain, Scene *scene) { if (check_rendered_viewport_visible(bmain)) { BMesh *bm = mesh->edit_btmesh->bm; - BM_mesh_bm_to_me(bm, mesh, (&(struct BMeshToMeshParams){0})); + BM_mesh_bm_to_me( + bm, mesh, + (&(struct BMeshToMeshParams){ + .calc_object_remap = true, + })); DEG_id_tag_update(&mesh->id, 0); } } @@ -1430,7 +1429,7 @@ void BKE_scene_graph_update_tagged(EvaluationContext *eval_ctx, /* Uncomment this to check if graph was properly tagged for update. */ // DEG_debug_graph_relations_validate(depsgraph, bmain, scene); /* Flush editing data if needed. */ - prepare_mesh_for_viewport_render(bmain, scene); + prepare_mesh_for_viewport_render(bmain, eval_ctx); /* Flush recalc flags to dependencies. */ DEG_graph_flush_update(bmain, depsgraph); /* Update all objects: drivers, matrices, displists, etc. flags set diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index ef9c22f1661..9f475dbd439 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -182,7 +182,7 @@ ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar) BLI_listbase_clear(&newar->panels_category); BLI_listbase_clear(&newar->panels_category_active); BLI_listbase_clear(&newar->ui_lists); - newar->swinid = 0; + newar->visible = 0; newar->manipulator_map = NULL; newar->regiontimer = NULL; newar->headerstr = NULL; diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 618f495dbf1..e91c3e43b83 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -57,6 +57,8 @@ #include "BLI_strict_flags.h" +#include "DEG_depsgraph.h" + /* for timing... */ #if 0 # include "PIL_time_utildefines.h" @@ -614,8 +616,9 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) } /* Main shrinkwrap function */ -void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm, - float (*vertexCos)[3], int numVerts, bool for_render) +void shrinkwrapModifier_deform( + const EvaluationContext *eval_ctx, ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm, + float (*vertexCos)[3], int numVerts, bool for_render) { DerivedMesh *ss_mesh = NULL; @@ -670,7 +673,8 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedM ssmd.subdivType = ME_CC_SUBSURF; /* catmull clark */ ssmd.levels = smd->subsurfLevels; /* levels */ - ss_mesh = subsurf_make_derived_from_derived(dm, &ssmd, NULL, (ob->mode & OB_MODE_EDIT) ? SUBSURF_IN_EDIT_MODE : 0); + ss_mesh = subsurf_make_derived_from_derived( + dm, &ssmd, NULL, (eval_ctx->object_mode & OB_MODE_EDIT) ? SUBSURF_IN_EDIT_MODE : 0); if (ss_mesh) { calc.vert = ss_mesh->getVertDataArray(ss_mesh, CD_MVERT); diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 9f9818127bc..9b11b66cedd 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -170,11 +170,11 @@ void smoke_reallocate_highres_fluid(SmokeDomainSettings *sds, float dx, int res[ } /* smoke_turbulence_init uses non-threadsafe functions from fftw3 lib (like fftw_plan & co). */ - BLI_lock_thread(LOCK_FFTW); + BLI_thread_lock(LOCK_FFTW); sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, BKE_tempdir_session(), use_fire, use_colors); - BLI_unlock_thread(LOCK_FFTW); + BLI_thread_unlock(LOCK_FFTW); sds->res_wt[0] = res[0] * (sds->amplify + 1); sds->res_wt[1] = res[1] * (sds->amplify + 1); @@ -1287,6 +1287,8 @@ static void emit_from_particles( curvemapping_changed_all(psys->part->clumpcurve); if ((psys->part->child_flag & PART_CHILD_USE_ROUGH_CURVE) && psys->part->roughcurve) curvemapping_changed_all(psys->part->roughcurve); + if ((psys->part->child_flag & PART_CHILD_USE_TWIST_CURVE) && psys->part->twistcurve) + curvemapping_changed_all(psys->part->twistcurve); /* initialize particle cache */ if (psys->part->type == PART_HAIR) { diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 3cfa8787f4b..1fb95bd3115 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -1580,12 +1580,12 @@ static void sb_sfesf_threads_run(const struct EvaluationContext *eval_ctx, Scene sb_threads[i].tot= totthread; } if (totthread > 1) { - BLI_init_threads(&threads, exec_scan_for_ext_spring_forces, totthread); + BLI_threadpool_init(&threads, exec_scan_for_ext_spring_forces, totthread); for (i=0; i<totthread; i++) - BLI_insert_thread(&threads, &sb_threads[i]); + BLI_threadpool_insert(&threads, &sb_threads[i]); - BLI_end_threads(&threads); + BLI_threadpool_end(&threads); } else exec_scan_for_ext_spring_forces(&sb_threads[0]); @@ -2192,12 +2192,12 @@ static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float t if (totthread > 1) { - BLI_init_threads(&threads, exec_softbody_calc_forces, totthread); + BLI_threadpool_init(&threads, exec_softbody_calc_forces, totthread); for (i=0; i<totthread; i++) - BLI_insert_thread(&threads, &sb_threads[i]); + BLI_threadpool_insert(&threads, &sb_threads[i]); - BLI_end_threads(&threads); + BLI_threadpool_end(&threads); } else exec_softbody_calc_forces(&sb_threads[0]); diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 1c3ff352126..10792b7d579 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -85,6 +85,8 @@ #include "CCGSubSurf.h" +#include "DEG_depsgraph.h" + #ifdef WITH_OPENSUBDIV # include "opensubdiv_capi.h" #endif @@ -361,7 +363,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, #ifdef USE_DYNSIZE CCGVertHDL fverts[nverts]; #else - BLI_array_empty(fverts); + BLI_array_clear(fverts); BLI_array_grow_items(fverts, nverts); #endif @@ -400,7 +402,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, #ifdef USE_DYNSIZE CCGVertHDL fverts[nverts]; #else - BLI_array_empty(fverts); + BLI_array_clear(fverts); BLI_array_grow_items(fverts, nverts); #endif @@ -744,7 +746,7 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss, #ifdef USE_DYNSIZE CCGVertHDL fVerts[mp->totloop]; #else - BLI_array_empty(fVerts); + BLI_array_clear(fVerts); BLI_array_grow_items(fVerts, mp->totloop); #endif @@ -3788,12 +3790,14 @@ static void ccgDM_release(DerivedMesh *dm) { ccgdm->multires.mmd = NULL; } - if (ccgdm->multires.mmd) { - if (ccgdm->multires.modified_flags & MULTIRES_COORDS_MODIFIED) - multires_modifier_update_mdisps(dm); - if (ccgdm->multires.modified_flags & MULTIRES_HIDDEN_MODIFIED) + if (ccgdm->multires.modified_flags & MULTIRES_COORDS_MODIFIED) { + /* TODO/OBMODE, pass real mode? */ + multires_modifier_update_mdisps(dm, OB_MODE_OBJECT); + } + if (ccgdm->multires.modified_flags & MULTIRES_HIDDEN_MODIFIED) { multires_modifier_update_hidden(dm); + } } } @@ -4187,7 +4191,8 @@ static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm) return 1; } -static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) +static struct PBVH *ccgDM_getPBVH( + Object *ob, DerivedMesh *dm, eObjectMode object_mode) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; CCGKey key; @@ -4204,7 +4209,7 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) return NULL; bool grid_pbvh = ccgDM_use_grid_pbvh(ccgdm); - if ((ob->mode & OB_MODE_SCULPT) == 0) { + if ((object_mode & OB_MODE_SCULPT) == 0) { /* In vwpaint, we may use a grid_pbvh for multires/subsurf, under certain conditions. * More complex cases break 'history' trail back to original vertices, in that case we fall back to * deformed cage only (i.e. original deformed mesh). */ @@ -4583,7 +4588,7 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, *((int *)ccgSubSurf_getFaceUserData(ss, f)) = vertNum; #ifndef USE_DYNSIZE - BLI_array_empty(loopidx); + BLI_array_clear(loopidx); BLI_array_grow_items(loopidx, numVerts); #endif for (s = 0; s < numVerts; s++) { @@ -4591,7 +4596,7 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, } #ifndef USE_DYNSIZE - BLI_array_empty(vertidx); + BLI_array_clear(vertidx); BLI_array_grow_items(vertidx, numVerts); #endif for (s = 0; s < numVerts; s++) { diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index fcedd880615..71b90641e02 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -412,6 +412,7 @@ void BKE_texture_mtex_default(MTex *mtex) mtex->kinkfac = 1.0f; mtex->kinkampfac = 1.0f; mtex->roughfac = 1.0f; + mtex->twistfac = 1.0f; mtex->padensfac = 1.0f; mtex->lifefac = 1.0f; mtex->sizefac = 1.0f; diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c index d8e98291117..8c1b846db84 100644 --- a/source/blender/blenkernel/intern/tracking_util.c +++ b/source/blender/blenkernel/intern/tracking_util.c @@ -787,9 +787,9 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor, * in the cache which is nice on the one hand (faster re-use of the * frames) but on the other hand it bumps the memory usage up. */ - BLI_lock_thread(LOCK_MOVIECLIP); + BLI_thread_lock(LOCK_MOVIECLIP); IMB_float_from_rect(orig_ibuf); - BLI_unlock_thread(LOCK_MOVIECLIP); + BLI_thread_unlock(LOCK_MOVIECLIP); final_ibuf = orig_ibuf; } /* Downscale if needed. */ diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c index 8554cf0fb28..9251c6630a5 100644 --- a/source/blender/blenkernel/intern/workspace.c +++ b/source/blender/blenkernel/intern/workspace.c @@ -38,6 +38,7 @@ #include "BKE_main.h" #include "BKE_scene.h" #include "BKE_screen.h" +#include "BKE_object.h" #include "BKE_workspace.h" #include "DNA_object_types.h" @@ -45,6 +46,8 @@ #include "DNA_screen_types.h" #include "DNA_workspace_types.h" +#include "DEG_depsgraph.h" + #include "MEM_guardedalloc.h" @@ -353,22 +356,22 @@ WorkSpaceLayout *BKE_workspace_layout_iter_circular( WorkSpaceLayout *iter_layout; if (iter_backward) { - BLI_LISTBASE_CIRCULAR_BACKWARD_BEGIN(&workspace->layouts, iter_layout, start) + LISTBASE_CIRCULAR_BACKWARD_BEGIN(&workspace->layouts, iter_layout, start) { if (!callback(iter_layout, arg)) { return iter_layout; } } - BLI_LISTBASE_CIRCULAR_BACKWARD_END(&workspace->layouts, iter_layout, start); + LISTBASE_CIRCULAR_BACKWARD_END(&workspace->layouts, iter_layout, start); } else { - BLI_LISTBASE_CIRCULAR_FORWARD_BEGIN(&workspace->layouts, iter_layout, start) + LISTBASE_CIRCULAR_FORWARD_BEGIN(&workspace->layouts, iter_layout, start) { if (!callback(iter_layout, arg)) { return iter_layout; } } - BLI_LISTBASE_CIRCULAR_FORWARD_END(&workspace->layouts, iter_layout, start) + LISTBASE_CIRCULAR_FORWARD_END(&workspace->layouts, iter_layout, start) } return NULL; @@ -413,21 +416,6 @@ void BKE_workspace_active_screen_set(WorkSpaceInstanceHook *hook, WorkSpace *wor BKE_workspace_hook_layout_for_workspace_set(hook, workspace, layout); } -#ifdef USE_WORKSPACE_MODE -eObjectMode BKE_workspace_object_mode_get(const WorkSpace *workspace, const Scene *scene) -{ - Base *active_base = BKE_workspace_active_base_get(workspace, scene); - return active_base ? active_base->object->mode : OB_MODE_OBJECT; -} -void BKE_workspace_object_mode_set(WorkSpace *workspace, Scene *scene, const eObjectMode mode) -{ - Base *active_base = BKE_workspace_active_base_get(workspace, scene); - if (active_base) { - active_base->object->mode = mode; - } -} -#endif - Base *BKE_workspace_active_base_get(const WorkSpace *workspace, const Scene *scene) { ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene); @@ -521,3 +509,29 @@ void BKE_workspace_update_tagged(struct EvaluationContext *eval_ctx, true); BKE_scene_graph_update_tagged(eval_ctx, depsgraph, bmain, scene, view_layer); } + +void BKE_workspace_update_object_mode( + struct EvaluationContext *eval_ctx, + WorkSpace *workspace) +{ + /* TODO(campbell): Investigate how this should work exactly, + * for now without this 'bmain->eval_ctx' is never set. */ + + eval_ctx->object_mode = workspace->object_mode; +} + +Object *BKE_workspace_edit_object(WorkSpace *workspace, Scene *scene) +{ + if (workspace->object_mode & OB_MODE_EDIT) { + ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene); + if (view_layer) { + Object *obedit = OBACT(view_layer); + if (obedit) { + BLI_assert(BKE_object_is_in_editmode(obedit)); + return obedit; + } + } + } + return NULL; +} + diff --git a/source/blender/blenkernel/particle_private.h b/source/blender/blenkernel/particle_private.h new file mode 100644 index 00000000000..2189527118b --- /dev/null +++ b/source/blender/blenkernel/particle_private.h @@ -0,0 +1,54 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2018 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/particle_private.h + * \ingroup bke + */ + +#ifndef __PARTICLE_PRIVATE_H__ +#define __PARTICLE_PRIVATE_H__ + +typedef struct ParticleChildModifierContext { + ParticleThreadContext *thread_ctx; + ParticleSimulationData *sim; + ParticleTexture *ptex; + ChildParticle *cpa; + const float *par_co; /* float3 */ + const float *par_vel; /* float3 */ + const float *par_rot; /* float4 */ + const float *par_orco; /* float3 */ + const float *orco; /* float3 */ + ParticleCacheKey *parent_keys; +} ParticleChildModifierContext; + +void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], const float par_rot[4], float time, float freq, float shape, float amplitude, float flat, + short type, short axis, float obmat[4][4], int smooth_start); +float do_clump(ParticleKey *state, const float par_co[3], float time, const float orco_offset[3], float clumpfac, float clumppow, float pa_clump, + bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve); +void do_child_modifiers(const ParticleChildModifierContext *modifier_ctx, + float mat[4][4], ParticleKey *state, float t); + +#endif /* __PARTICLE_PRIVATE_H__ */ diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h index 3ffca818c0d..825acb18e91 100644 --- a/source/blender/blenlib/BLI_array.h +++ b/source/blender/blenlib/BLI_array.h @@ -151,7 +151,7 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static, /** * resets the logical size of an array to zero, but doesn't * free the memory. */ -#define BLI_array_empty(arr) \ +#define BLI_array_clear(arr) \ { _##arr##_count = 0; } (void)0 /** diff --git a/source/blender/blenlib/BLI_boxpack2d.h b/source/blender/blenlib/BLI_boxpack_2d.h index b02e3423f88..80e89bdb04f 100644 --- a/source/blender/blenlib/BLI_boxpack2d.h +++ b/source/blender/blenlib/BLI_boxpack_2d.h @@ -25,10 +25,10 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef __BLI_BOXPACK2D_H__ -#define __BLI_BOXPACK2D_H__ +#ifndef __BLI_BOXPACK_2D_H__ +#define __BLI_BOXPACK_2D_H__ -/** \file BLI_boxpack2d.h +/** \file BLI_boxpack_2d.h * \ingroup bli */ @@ -39,7 +39,7 @@ typedef struct BoxPack { float y; float w; float h; - + /* Verts this box uses * (BL,TR,TL,BR) / 0,1,2,3 */ struct BoxVert *v[4]; @@ -49,5 +49,5 @@ typedef struct BoxPack { void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *tot_width, float *tot_height); -#endif +#endif /* __BLI_BOXPACK_2D_H__ */ diff --git a/source/blender/blenlib/BLI_buffer.h b/source/blender/blenlib/BLI_buffer.h index 0c0845daf19..0d2ef0dc9b3 100644 --- a/source/blender/blenlib/BLI_buffer.h +++ b/source/blender/blenlib/BLI_buffer.h @@ -77,7 +77,7 @@ enum { (BLI_buffer_at(buffer_, type_, (buffer_)->count - 1) = val_) \ ) -#define BLI_buffer_empty(buffer_) { \ +#define BLI_buffer_clear(buffer_) { \ (buffer_)->count = 0; \ } (void)0 diff --git a/source/blender/blenlib/BLI_convexhull2d.h b/source/blender/blenlib/BLI_convexhull_2d.h index 4b82071ede8..000d28acdde 100644 --- a/source/blender/blenlib/BLI_convexhull2d.h +++ b/source/blender/blenlib/BLI_convexhull_2d.h @@ -18,10 +18,10 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef __BLI_CONVEXHULL2D_H__ -#define __BLI_CONVEXHULL2D_H__ +#ifndef __BLI_CONVEXHULL_2D_H__ +#define __BLI_CONVEXHULL_2D_H__ -/** \file BLI_convexhull2d.h +/** \file BLI_convexhull_2d.h * \ingroup bli */ @@ -31,4 +31,4 @@ int BLI_convexhull_2d(const float (*points)[2], const int n, int r_points[]); float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned int n); float BLI_convexhull_aabb_fit_points_2d(const float (*points)[2], unsigned int n); -#endif /* __BLI_CONVEXHULL2D_H__ */ +#endif /* __BLI_CONVEXHULL_2D_H__ */ diff --git a/source/blender/blenlib/BLI_dial.h b/source/blender/blenlib/BLI_dial_2d.h index 71ab57bb61a..dbd71a8ad3f 100644 --- a/source/blender/blenlib/BLI_dial.h +++ b/source/blender/blenlib/BLI_dial_2d.h @@ -18,10 +18,10 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef __BLI_DIAL_H__ -#define __BLI_DIAL_H__ +#ifndef __BLI_DIAL_2D_H__ +#define __BLI_DIAL_2D_H__ -/** \file BLI_dial.h +/** \file BLI_dial_2d.h * \ingroup bli * * \note dials act similar to old rotation based phones and output an angle. @@ -56,4 +56,4 @@ Dial *BLI_dial_initialize(const float start_position[2], float threshold); float BLI_dial_angle(Dial *dial, const float current_position[2]); -#endif /* __BLI_DIAL_H__ */ +#endif /* __BLI_DIAL_2D_H__ */ diff --git a/source/blender/blenlib/BLI_edgehash.h b/source/blender/blenlib/BLI_edgehash.h index 20272dd97cd..41789201265 100644 --- a/source/blender/blenlib/BLI_edgehash.h +++ b/source/blender/blenlib/BLI_edgehash.h @@ -59,7 +59,7 @@ bool BLI_edgehash_remove(EdgeHash *eh, unsigned int v0, unsigned int void *BLI_edgehash_popkey(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT; bool BLI_edgehash_haskey(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT; -int BLI_edgehash_size(EdgeHash *eh) ATTR_WARN_UNUSED_RESULT; +int BLI_edgehash_len(EdgeHash *eh) ATTR_WARN_UNUSED_RESULT; void BLI_edgehash_clear_ex(EdgeHash *eh, EdgeHashFreeFP valfreefp, const unsigned int nentries_reserve); void BLI_edgehash_clear(EdgeHash *eh, EdgeHashFreeFP valfreefp); @@ -104,7 +104,7 @@ typedef struct EdgeSetIterator EdgeSetIterator; EdgeSet *BLI_edgeset_new_ex(const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; EdgeSet *BLI_edgeset_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; -int BLI_edgeset_size(EdgeSet *es) ATTR_WARN_UNUSED_RESULT; +int BLI_edgeset_len(EdgeSet *es) ATTR_WARN_UNUSED_RESULT; bool BLI_edgeset_add(EdgeSet *es, unsigned int v0, unsigned int v1); void BLI_edgeset_insert(EdgeSet *es, unsigned int v0, unsigned int v1); bool BLI_edgeset_haskey(EdgeSet *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT; diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h index 5c1fa57886a..bb23c63bdb3 100644 --- a/source/blender/blenlib/BLI_fileops.h +++ b/source/blender/blenlib/BLI_fileops.h @@ -35,6 +35,7 @@ #include <stdio.h> #include <sys/stat.h> +#include <stdint.h> #ifdef __cplusplus extern "C" { diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h index b4819ff4e55..ec591c6bb48 100644 --- a/source/blender/blenlib/BLI_ghash.h +++ b/source/blender/blenlib/BLI_ghash.h @@ -81,7 +81,10 @@ enum { #endif }; -/* *** */ +/** \name GHash API + * + * Defined in ``BLI_ghash.c`` + * \{ */ GHash *BLI_ghash_new_ex( GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info, @@ -110,11 +113,14 @@ void BLI_ghash_clear_ex( void *BLI_ghash_popkey(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp) ATTR_WARN_UNUSED_RESULT; bool BLI_ghash_haskey(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT; bool BLI_ghash_pop(GHash *gh, GHashIterState *state, void **r_key, void **r_val) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -unsigned int BLI_ghash_size(GHash *gh) ATTR_WARN_UNUSED_RESULT; +unsigned int BLI_ghash_len(GHash *gh) ATTR_WARN_UNUSED_RESULT; void BLI_ghash_flag_set(GHash *gh, unsigned int flag); void BLI_ghash_flag_clear(GHash *gh, unsigned int flag); -/* *** */ +/** \} */ + +/** \name GHash Iterator + * \{ */ GHashIterator *BLI_ghashIterator_new(GHash *gh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; @@ -149,94 +155,15 @@ BLI_INLINE bool BLI_ghashIterator_done(GHashIterator *ghi) { return !ghi BLI_ghashIterator_done(&gh_iter_) == false; \ BLI_ghashIterator_step(&gh_iter_), i_++) -/** \name Callbacks for GHash - * - * \note '_p' suffix denotes void pointer arg, - * so we can have functions that take correctly typed args too. - * \{ */ - -unsigned int BLI_ghashutil_ptrhash(const void *key); -bool BLI_ghashutil_ptrcmp(const void *a, const void *b); - -unsigned int BLI_ghashutil_strhash_n(const char *key, size_t n); -#define BLI_ghashutil_strhash(key) ( \ - CHECK_TYPE_ANY(key, char *, const char *, const char * const), \ - BLI_ghashutil_strhash_p(key)) -unsigned int BLI_ghashutil_strhash_p(const void *key); -unsigned int BLI_ghashutil_strhash_p_murmur(const void *key); -bool BLI_ghashutil_strcmp(const void *a, const void *b); - -#define BLI_ghashutil_inthash(key) ( \ - CHECK_TYPE_ANY(&(key), int *, const int *), \ - BLI_ghashutil_uinthash((unsigned int)key)) -unsigned int BLI_ghashutil_uinthash(unsigned int key); -unsigned int BLI_ghashutil_inthash_p(const void *ptr); -unsigned int BLI_ghashutil_inthash_p_murmur(const void *ptr); -unsigned int BLI_ghashutil_inthash_p_simple(const void *ptr); -bool BLI_ghashutil_intcmp(const void *a, const void *b); - -size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b); - - -unsigned int BLI_ghashutil_uinthash_v4(const unsigned int key[4]); -#define BLI_ghashutil_inthash_v4(key) ( \ - CHECK_TYPE_ANY(key, int *, const int *), \ - BLI_ghashutil_uinthash_v4((const unsigned int *)key)) -#define BLI_ghashutil_inthash_v4_p \ - ((GSetHashFP)BLI_ghashutil_uinthash_v4) -#define BLI_ghashutil_uinthash_v4_p \ - ((GSetHashFP)BLI_ghashutil_uinthash_v4) -unsigned int BLI_ghashutil_uinthash_v4_murmur(const unsigned int key[4]); -#define BLI_ghashutil_inthash_v4_murmur(key) ( \ - CHECK_TYPE_ANY(key, int *, const int *), \ - BLI_ghashutil_uinthash_v4_murmur((const unsigned int *)key)) -#define BLI_ghashutil_inthash_v4_p_murmur \ - ((GSetHashFP)BLI_ghashutil_uinthash_v4_murmur) -#define BLI_ghashutil_uinthash_v4_p_murmur \ - ((GSetHashFP)BLI_ghashutil_uinthash_v4_murmur) -bool BLI_ghashutil_uinthash_v4_cmp(const void *a, const void *b); -#define BLI_ghashutil_inthash_v4_cmp \ - BLI_ghashutil_uinthash_v4_cmp - /** \} */ -GHash *BLI_ghash_ptr_new_ex( - const char *info, - const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; -GHash *BLI_ghash_ptr_new( - const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; -GHash *BLI_ghash_str_new_ex( - const char *info, - const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; -GHash *BLI_ghash_str_new( - const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; -GHash *BLI_ghash_int_new_ex( - const char *info, - const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; -GHash *BLI_ghash_int_new( - const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; -GHash *BLI_ghash_pair_new_ex( - const char *info, - const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; -GHash *BLI_ghash_pair_new( - const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; - -typedef struct GHashPair { - const void *first; - const void *second; -} GHashPair; - -GHashPair *BLI_ghashutil_pairalloc(const void *first, const void *second); -unsigned int BLI_ghashutil_pairhash(const void *ptr); -bool BLI_ghashutil_paircmp(const void *a, const void *b); -void BLI_ghashutil_pairfree(void *ptr); - -/** - * GSet is a 'set' implementation (unordered collection of unique elements). +/** \name GSet API + * A 'set' implementation (unordered collection of unique elements). * * Internally this is a 'GHash' without any keys, * which is why this API's are in the same header & source file. - */ + * + * \{ */ typedef struct GSet GSet; @@ -247,21 +174,12 @@ typedef GHashKeyCopyFP GSetKeyCopyFP; typedef GHashIterState GSetIterState; -/* so we can cast but compiler sees as different */ -typedef struct GSetIterator { - GHashIterator _ghi -#ifdef __GNUC__ - __attribute__ ((deprecated)) -#endif - ; -} GSetIterator; - GSet *BLI_gset_new_ex( GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; GSet *BLI_gset_new(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; GSet *BLI_gset_copy(GSet *gs, GSetKeyCopyFP keycopyfp) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; -unsigned int BLI_gset_size(GSet *gs) ATTR_WARN_UNUSED_RESULT; +unsigned int BLI_gset_len(GSet *gs) ATTR_WARN_UNUSED_RESULT; void BLI_gset_flag_set(GSet *gs, unsigned int flag); void BLI_gset_flag_clear(GSet *gs, unsigned int flag); void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp); @@ -281,14 +199,20 @@ void BLI_gset_clear(GSet *gs, GSetKeyFreeFP keyfreefp); void *BLI_gset_lookup(GSet *gh, const void *key) ATTR_WARN_UNUSED_RESULT; void *BLI_gset_pop_key(GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT; -GSet *BLI_gset_ptr_new_ex(const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; -GSet *BLI_gset_ptr_new(const char *info); -GSet *BLI_gset_str_new_ex(const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; -GSet *BLI_gset_str_new(const char *info); -GSet *BLI_gset_pair_new_ex(const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; -GSet *BLI_gset_pair_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +/** \name GSet Iterator + * \{ */ /* rely on inline api for now */ + +/* so we can cast but compiler sees as different */ +typedef struct GSetIterator { + GHashIterator _ghi +#ifdef __GNUC__ + __attribute__ ((deprecated)) +#endif + ; +} GSetIterator; + BLI_INLINE GSetIterator *BLI_gsetIterator_new(GSet *gs) { return (GSetIterator *)BLI_ghashIterator_new((GHash *)gs); } BLI_INLINE void BLI_gsetIterator_init(GSetIterator *gsi, GSet *gs) { BLI_ghashIterator_init((GHashIterator *)gsi, (GHash *)gs); } BLI_INLINE void BLI_gsetIterator_free(GSetIterator *gsi) { BLI_ghashIterator_free((GHashIterator *)gsi); } @@ -306,11 +230,15 @@ BLI_INLINE bool BLI_gsetIterator_done(GSetIterator *gsi) { return BLI_ghashItera BLI_gsetIterator_done(&gs_iter_) == false; \ BLI_gsetIterator_step(&gs_iter_), i_++) +/** \} */ + +/** \name GHash/GSet Debugging API's + * \{ */ /* For testing, debugging only */ #ifdef GHASH_INTERNAL_API -int BLI_ghash_buckets_size(GHash *gh); -int BLI_gset_buckets_size(GSet *gs); +int BLI_ghash_buckets_len(GHash *gh); +int BLI_gset_buckets_len(GSet *gs); double BLI_ghash_calc_quality_ex( GHash *gh, double *r_load, double *r_variance, @@ -321,6 +249,10 @@ double BLI_gset_calc_quality_ex( double BLI_ghash_calc_quality(GHash *gh); double BLI_gset_calc_quality(GSet *gs); #endif /* GHASH_INTERNAL_API */ +/** \} */ + +/** \name GHash/GSet Macros + * \{ */ #define GHASH_FOREACH_BEGIN(type, var, what) \ do { \ @@ -342,6 +274,113 @@ double BLI_gset_calc_quality(GSet *gs); } \ } while(0) +/** \} */ + +/** \name GHash/GSet Utils + * + * Defined in ``BLI_ghash_utils.c`` + * \{ */ + +/** + * Callbacks for GHash (``BLI_ghashutil_``) + * + * \note '_p' suffix denotes void pointer arg, + * so we can have functions that take correctly typed args too. + * \{ */ + +unsigned int BLI_ghashutil_ptrhash(const void *key); +bool BLI_ghashutil_ptrcmp(const void *a, const void *b); + +unsigned int BLI_ghashutil_strhash_n(const char *key, size_t n); +#define BLI_ghashutil_strhash(key) ( \ + CHECK_TYPE_ANY(key, char *, const char *, const char * const), \ + BLI_ghashutil_strhash_p(key)) +unsigned int BLI_ghashutil_strhash_p(const void *key); +unsigned int BLI_ghashutil_strhash_p_murmur(const void *key); +bool BLI_ghashutil_strcmp(const void *a, const void *b); + +#define BLI_ghashutil_inthash(key) ( \ + CHECK_TYPE_ANY(&(key), int *, const int *), \ + BLI_ghashutil_uinthash((unsigned int)key)) +unsigned int BLI_ghashutil_uinthash(unsigned int key); +unsigned int BLI_ghashutil_inthash_p(const void *ptr); +unsigned int BLI_ghashutil_inthash_p_murmur(const void *ptr); +unsigned int BLI_ghashutil_inthash_p_simple(const void *ptr); +bool BLI_ghashutil_intcmp(const void *a, const void *b); + +size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b); + + +unsigned int BLI_ghashutil_uinthash_v4(const unsigned int key[4]); +#define BLI_ghashutil_inthash_v4(key) ( \ + CHECK_TYPE_ANY(key, int *, const int *), \ + BLI_ghashutil_uinthash_v4((const unsigned int *)key)) +#define BLI_ghashutil_inthash_v4_p \ + ((GSetHashFP)BLI_ghashutil_uinthash_v4) +#define BLI_ghashutil_uinthash_v4_p \ + ((GSetHashFP)BLI_ghashutil_uinthash_v4) +unsigned int BLI_ghashutil_uinthash_v4_murmur(const unsigned int key[4]); +#define BLI_ghashutil_inthash_v4_murmur(key) ( \ + CHECK_TYPE_ANY(key, int *, const int *), \ + BLI_ghashutil_uinthash_v4_murmur((const unsigned int *)key)) +#define BLI_ghashutil_inthash_v4_p_murmur \ + ((GSetHashFP)BLI_ghashutil_uinthash_v4_murmur) +#define BLI_ghashutil_uinthash_v4_p_murmur \ + ((GSetHashFP)BLI_ghashutil_uinthash_v4_murmur) +bool BLI_ghashutil_uinthash_v4_cmp(const void *a, const void *b); +#define BLI_ghashutil_inthash_v4_cmp \ + BLI_ghashutil_uinthash_v4_cmp + +typedef struct GHashPair { + const void *first; + const void *second; +} GHashPair; + +GHashPair *BLI_ghashutil_pairalloc(const void *first, const void *second); +unsigned int BLI_ghashutil_pairhash(const void *ptr); +bool BLI_ghashutil_paircmp(const void *a, const void *b); +void BLI_ghashutil_pairfree(void *ptr); + +/** + * Wrapper GHash Creation Functions + */ + +GHash *BLI_ghash_ptr_new_ex( + const char *info, + const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +GHash *BLI_ghash_ptr_new( + const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +GHash *BLI_ghash_str_new_ex( + const char *info, + const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +GHash *BLI_ghash_str_new( + const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +GHash *BLI_ghash_int_new_ex( + const char *info, + const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +GHash *BLI_ghash_int_new( + const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +GHash *BLI_ghash_pair_new_ex( + const char *info, + const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +GHash *BLI_ghash_pair_new( + const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; + +GSet *BLI_gset_ptr_new_ex( + const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +GSet *BLI_gset_ptr_new( + const char *info); +GSet *BLI_gset_str_new_ex( + const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +GSet *BLI_gset_str_new( + const char *info); +GSet *BLI_gset_pair_new_ex( + const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +GSet *BLI_gset_pair_new( + const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; + +/** \} */ + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_gsqueue.h b/source/blender/blenlib/BLI_gsqueue.h index 4600d6f6325..ef0e0f3ab31 100644 --- a/source/blender/blenlib/BLI_gsqueue.h +++ b/source/blender/blenlib/BLI_gsqueue.h @@ -36,11 +36,11 @@ typedef struct _GSQueue GSQueue; GSQueue *BLI_gsqueue_new(size_t elem_size); bool BLI_gsqueue_is_empty(GSQueue *gq); -int BLI_gsqueue_size(GSQueue *gq); +int BLI_gsqueue_len(GSQueue *gq); void BLI_gsqueue_peek(GSQueue *gq, void *r_item); void BLI_gsqueue_pop(GSQueue *gq, void *r_item); void BLI_gsqueue_push(GSQueue *gq, const void *item); -void BLI_gsqueue_pushback(GSQueue *gq, const void *item); +void BLI_gsqueue_push_back(GSQueue *gq, const void *item); void BLI_gsqueue_free(GSQueue *gq); #endif /* __BLI_GSQUEUE_H__ */ diff --git a/source/blender/blenlib/BLI_hash.h b/source/blender/blenlib/BLI_hash.h index e849e5f8f61..fa79481e25c 100644 --- a/source/blender/blenlib/BLI_hash.h +++ b/source/blender/blenlib/BLI_hash.h @@ -63,4 +63,9 @@ BLI_INLINE unsigned int BLI_hash_int(unsigned int k) return BLI_hash_int_2d(k, 0); } +BLI_INLINE float BLI_hash_int_01(unsigned int k) +{ + return (float)BLI_hash_int(k) * (1.0f / (float)0xFFFFFFFF); +} + #endif // __BLI_HASH_H__ diff --git a/source/blender/blenlib/BLI_heap.h b/source/blender/blenlib/BLI_heap.h index d3f6d44e164..19e162d777f 100644 --- a/source/blender/blenlib/BLI_heap.h +++ b/source/blender/blenlib/BLI_heap.h @@ -41,9 +41,9 @@ HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr) ATTR_NONNULL void BLI_heap_insert_or_update(Heap *heap, HeapNode **node_p, float value, void *ptr) ATTR_NONNULL(1, 2); void BLI_heap_remove(Heap *heap, HeapNode *node) ATTR_NONNULL(1, 2); bool BLI_heap_is_empty(const Heap *heap) ATTR_NONNULL(1); -unsigned int BLI_heap_size(const Heap *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +unsigned int BLI_heap_len(const Heap *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); HeapNode *BLI_heap_top(const Heap *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); -void *BLI_heap_popmin(Heap *heap) ATTR_NONNULL(1); +void *BLI_heap_pop_min(Heap *heap) ATTR_NONNULL(1); void BLI_heap_node_value_update(Heap *heap, HeapNode *node, float value) ATTR_NONNULL(1, 2); void BLI_heap_node_value_update_ptr(Heap *heap, HeapNode *node, float value, void *ptr) ATTR_NONNULL(1, 2); diff --git a/source/blender/blenlib/BLI_jitter.h b/source/blender/blenlib/BLI_jitter_2d.h index 769fb445678..e2b1f21800c 100644 --- a/source/blender/blenlib/BLI_jitter.h +++ b/source/blender/blenlib/BLI_jitter_2d.h @@ -25,10 +25,10 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef __BLI_JITTER_H__ -#define __BLI_JITTER_H__ +#ifndef __BLI_JITTER_2D_H__ +#define __BLI_JITTER_2D_H__ -/** \file BLI_jitter.h +/** \file BLI_jitter_2d.h * \ingroup bli */ @@ -36,5 +36,5 @@ void BLI_jitter_init(float (*jitarr)[2], int num); void BLI_jitterate1(float (*jit1)[2], float (*jit2)[2], int num, float radius1); void BLI_jitterate2(float (*jit1)[2], float (*jit2)[2], int num, float radius2); -#endif +#endif /* __BLI_JITTER_2D_H__ */ diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h index 564659ad21e..db53035dc7b 100644 --- a/source/blender/blenlib/BLI_kdopbvh.h +++ b/source/blender/blenlib/BLI_kdopbvh.h @@ -129,7 +129,7 @@ BVHTreeOverlap *BLI_bvhtree_overlap( const BVHTree *tree1, const BVHTree *tree2, unsigned int *r_overlap_tot, BVHTree_OverlapCallback callback, void *userdata); -int BLI_bvhtree_get_size(const BVHTree *tree); +int BLI_bvhtree_get_len(const BVHTree *tree); float BLI_bvhtree_get_epsilon(const BVHTree *tree); diff --git a/source/blender/blenlib/BLI_lasso.h b/source/blender/blenlib/BLI_lasso_2d.h index 28f21e5bd85..3644224f1d7 100644 --- a/source/blender/blenlib/BLI_lasso.h +++ b/source/blender/blenlib/BLI_lasso_2d.h @@ -25,10 +25,10 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef __BLI_LASSO_H__ -#define __BLI_LASSO_H__ +#ifndef __BLI_LASSO_2D_H__ +#define __BLI_LASSO_2D_H__ -/** \file BLI_lasso.h +/** \file BLI_lasso_2d.h * \ingroup bli */ @@ -38,4 +38,4 @@ void BLI_lasso_boundbox(struct rcti *rect, const int mcords[][2], const unsigned bool BLI_lasso_is_point_inside(const int mcords[][2], const unsigned int moves, const int sx, const int sy, const int error_value); bool BLI_lasso_is_edge_inside(const int mcords[][2], const unsigned int moves, int x0, int y0, int x1, int y1, const int error_value); -#endif +#endif /* __BLI_LASSO_2D_H__ */ diff --git a/source/blender/blenlib/BLI_linklist_stack.h b/source/blender/blenlib/BLI_linklist_stack.h index dd92dcec936..dd6d737f111 100644 --- a/source/blender/blenlib/BLI_linklist_stack.h +++ b/source/blender/blenlib/BLI_linklist_stack.h @@ -60,7 +60,7 @@ } (void)0 #define BLI_LINKSTACK_SIZE(var) \ - BLI_mempool_count(var##_pool_) + BLI_mempool_len(var##_pool_) /* check for typeof() */ #ifdef __GNUC__ diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index 2a0f4e6f814..6be9408ac1e 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -103,32 +103,33 @@ struct LinkData *BLI_genericNodeN(void *data); * * \code{.c} * - * BLI_LISTBASE_CIRCULAR_FORWARD_BEGIN (listbase, item, item_init) { + * LISTBASE_CIRCULAR_FORWARD_BEGIN(listbase, item, item_init) + * { * ...operate on marker... * } - * BLI_LISTBASE_CIRCULAR_FORWARD_END (listbase, item, item_init); + * LISTBASE_CIRCULAR_FORWARD_END (listbase, item, item_init); * * \endcode */ -#define BLI_LISTBASE_CIRCULAR_FORWARD_BEGIN(lb, lb_iter, lb_init) \ +#define LISTBASE_CIRCULAR_FORWARD_BEGIN(lb, lb_iter, lb_init) \ if ((lb)->first && (lb_init || (lb_init = (lb)->first))) { \ lb_iter = lb_init; \ do { -#define BLI_LISTBASE_CIRCULAR_FORWARD_END(lb, lb_iter, lb_init) \ +#define LISTBASE_CIRCULAR_FORWARD_END(lb, lb_iter, lb_init) \ } while ((lb_iter = (lb_iter)->next ? (lb_iter)->next : (lb)->first), \ (lb_iter != lb_init)); \ } -#define BLI_LISTBASE_CIRCULAR_BACKWARD_BEGIN(lb, lb_iter, lb_init) \ +#define LISTBASE_CIRCULAR_BACKWARD_BEGIN(lb, lb_iter, lb_init) \ if ((lb)->last && (lb_init || (lb_init = (lb)->last))) { \ lb_iter = lb_init; \ do { -#define BLI_LISTBASE_CIRCULAR_BACKWARD_END(lb, lb_iter, lb_init) \ +#define LISTBASE_CIRCULAR_BACKWARD_END(lb, lb_iter, lb_init) \ } while ((lb_iter = (lb_iter)->prev ? (lb_iter)->prev : (lb)->last), \ (lb_iter != lb_init)); \ } -#define BLI_LISTBASE_FOREACH(type, var, list) \ +#define LISTBASE_FOREACH(type, var, list) \ for (type var = (type)((list)->first); \ var != NULL; \ var = (type)(((Link*)(var))->next)) diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h index 377b9325717..3b24cae018d 100644 --- a/source/blender/blenlib/BLI_math_base.h +++ b/source/blender/blenlib/BLI_math_base.h @@ -132,6 +132,10 @@ MINLINE int max_iiii(int a, int b, int c, int d); MINLINE size_t min_zz(size_t a, size_t b); MINLINE size_t max_zz(size_t a, size_t b); +MINLINE int clamp_i(int value, int min, int max); +MINLINE float clamp_f(float value, float min, float max); +MINLINE size_t clamp_z(size_t value, size_t min, size_t max); + MINLINE int compare_ff(float a, float b, const float max_diff); MINLINE int compare_ff_relative(float a, float b, const float max_diff, const int max_ulps); diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index 933e31ba84b..ffe0ce11cef 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -85,6 +85,7 @@ bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]); bool is_poly_convex_v2(const float verts[][2], unsigned int nr); int is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]); +bool is_quad_flip_v3_first_third_fast(const float v0[3], const float v1[3], const float v2[3], const float v3[3]); /********************************* Distance **********************************/ diff --git a/source/blender/blenlib/BLI_mempool.h b/source/blender/blenlib/BLI_mempool.h index b68ca6b1f2b..45efb8d7ef1 100644 --- a/source/blender/blenlib/BLI_mempool.h +++ b/source/blender/blenlib/BLI_mempool.h @@ -53,7 +53,7 @@ void BLI_mempool_clear_ex(BLI_mempool *pool, const int totelem_reserve) ATTR_NONNULL(1); void BLI_mempool_clear(BLI_mempool *pool) ATTR_NONNULL(1); void BLI_mempool_destroy(BLI_mempool *pool) ATTR_NONNULL(1); -int BLI_mempool_count(BLI_mempool *pool) ATTR_NONNULL(1); +int BLI_mempool_len(BLI_mempool *pool) ATTR_NONNULL(1); void *BLI_mempool_findelem(BLI_mempool *pool, unsigned int index) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); void BLI_mempool_as_table(BLI_mempool *pool, void **data) ATTR_NONNULL(1, 2); diff --git a/source/blender/blenlib/BLI_polyfill2d.h b/source/blender/blenlib/BLI_polyfill_2d.h index 798055f9240..099f08d4663 100644 --- a/source/blender/blenlib/BLI_polyfill2d.h +++ b/source/blender/blenlib/BLI_polyfill_2d.h @@ -18,8 +18,8 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef __BLI_POLYFILL2D_H__ -#define __BLI_POLYFILL2D_H__ +#ifndef __BLI_POLYFILL_2D_H__ +#define __BLI_POLYFILL_2D_H__ struct MemArena; @@ -40,4 +40,4 @@ void BLI_polyfill_calc( /* default size of polyfill arena */ #define BLI_POLYFILL_ARENA_SIZE MEM_SIZE_OPTIMAL(1 << 14) -#endif /* __BLI_POLYFILL2D_H__ */ +#endif /* __BLI_POLYFILL_2D_H__ */ diff --git a/source/blender/blenlib/BLI_polyfill2d_beautify.h b/source/blender/blenlib/BLI_polyfill_2d_beautify.h index 278771e9611..278771e9611 100644 --- a/source/blender/blenlib/BLI_polyfill2d_beautify.h +++ b/source/blender/blenlib/BLI_polyfill_2d_beautify.h diff --git a/source/blender/blenlib/BLI_smallhash.h b/source/blender/blenlib/BLI_smallhash.h index e096354e5b1..495fc94a53c 100644 --- a/source/blender/blenlib/BLI_smallhash.h +++ b/source/blender/blenlib/BLI_smallhash.h @@ -66,7 +66,7 @@ bool BLI_smallhash_remove(SmallHash *sh, uintptr_t key) ATTR_NONNULL(1); void *BLI_smallhash_lookup(const SmallHash *sh, uintptr_t key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; void **BLI_smallhash_lookup_p(const SmallHash *sh, uintptr_t key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; bool BLI_smallhash_haskey(const SmallHash *sh, uintptr_t key) ATTR_NONNULL(1); -int BLI_smallhash_count(const SmallHash *sh) ATTR_NONNULL(1); +int BLI_smallhash_len(const SmallHash *sh) ATTR_NONNULL(1); void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; void **BLI_smallhash_iternext_p(SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; void *BLI_smallhash_iternew(const SmallHash *sh, SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h index 60da6b39cbe..66eb5cfd22b 100644 --- a/source/blender/blenlib/BLI_threads.h +++ b/source/blender/blenlib/BLI_threads.h @@ -55,19 +55,19 @@ void BLI_threadapi_exit(void); struct TaskScheduler *BLI_task_scheduler_get(void); -void BLI_init_threads(struct ListBase *threadbase, void *(*do_thread)(void *), int tot); +void BLI_threadpool_init(struct ListBase *threadbase, void *(*do_thread)(void *), int tot); int BLI_available_threads(struct ListBase *threadbase); -int BLI_available_thread_index(struct ListBase *threadbase); -void BLI_insert_thread(struct ListBase *threadbase, void *callerdata); -void BLI_remove_thread(struct ListBase *threadbase, void *callerdata); -void BLI_remove_thread_index(struct ListBase *threadbase, int index); -void BLI_remove_threads(struct ListBase *threadbase); -void BLI_end_threads(struct ListBase *threadbase); +int BLI_threadpool_available_thread_index(struct ListBase *threadbase); +void BLI_threadpool_insert(struct ListBase *threadbase, void *callerdata); +void BLI_threadpool_remove(struct ListBase *threadbase, void *callerdata); +void BLI_threadpool_remove_index(struct ListBase *threadbase, int index); +void BLI_threadpool_clear(struct ListBase *threadbase); +void BLI_threadpool_end(struct ListBase *threadbase); int BLI_thread_is_main(void); -void BLI_begin_threaded_malloc(void); -void BLI_end_threaded_malloc(void); +void BLI_threaded_malloc_begin(void); +void BLI_threaded_malloc_end(void); /* System Information */ @@ -91,8 +91,8 @@ int BLI_system_num_threads_override_get(void); #define LOCK_FFTW 9 #define LOCK_VIEW3D 10 -void BLI_lock_thread(int type); -void BLI_unlock_thread(int type); +void BLI_thread_lock(int type); +void BLI_thread_unlock(int type); /* Mutex Lock */ @@ -177,7 +177,7 @@ void BLI_thread_queue_free(ThreadQueue *queue); void BLI_thread_queue_push(ThreadQueue *queue, void *work); void *BLI_thread_queue_pop(ThreadQueue *queue); void *BLI_thread_queue_pop_timeout(ThreadQueue *queue, int ms); -int BLI_thread_queue_size(ThreadQueue *queue); +int BLI_thread_queue_len(ThreadQueue *queue); bool BLI_thread_queue_is_empty(ThreadQueue *queue); void BLI_thread_queue_wait_finish(ThreadQueue *queue); diff --git a/source/blender/blenlib/BLI_voronoi.h b/source/blender/blenlib/BLI_voronoi_2d.h index 9d32061bf97..51d1d5aa88e 100644 --- a/source/blender/blenlib/BLI_voronoi.h +++ b/source/blender/blenlib/BLI_voronoi_2d.h @@ -28,7 +28,7 @@ struct ListBase; -/** \file BLI_voronoi.h +/** \file BLI_voronoi_2d.h * \ingroup bli */ diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 9e7b4ed8b6f..ef36b5ac6bd 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -41,10 +41,11 @@ set(INC_SYS set(SRC intern/BLI_args.c intern/BLI_array.c - intern/BLI_dial.c + intern/BLI_dial_2d.c intern/BLI_dynstr.c intern/BLI_filelist.c intern/BLI_ghash.c + intern/BLI_ghash_utils.c intern/BLI_heap.c intern/BLI_kdopbvh.c intern/BLI_kdtree.c @@ -58,10 +59,10 @@ set(SRC intern/array_utils.c intern/astar.c intern/bitmap_draw_2d.c - intern/boxpack2d.c + intern/boxpack_2d.c intern/buffer.c intern/callbacks.c - intern/convexhull2d.c + intern/convexhull_2d.c intern/dynlib.c intern/easing.c intern/edgehash.c @@ -73,8 +74,8 @@ set(SRC intern/gsqueue.c intern/hash_md5.c intern/hash_mm2a.c - intern/jitter.c - intern/lasso.c + intern/jitter_2d.c + intern/lasso_2d.c intern/list_sort_impl.h intern/listbase.c intern/math_base.c @@ -95,8 +96,8 @@ set(SRC intern/memory_utils.c intern/noise.c intern/path_util.c - intern/polyfill2d.c - intern/polyfill2d_beautify.c + intern/polyfill_2d.c + intern/polyfill_2d_beautify.c intern/quadric.c intern/rand.c intern/rct.c @@ -117,7 +118,7 @@ set(SRC intern/time.c intern/timecode.c intern/uvproject.c - intern/voronoi.c + intern/voronoi_2d.c intern/voxel.c intern/winstuff.c intern/winstuff_dir.c @@ -132,14 +133,14 @@ set(SRC BLI_bitmap.h BLI_bitmap_draw_2d.h BLI_blenlib.h - BLI_boxpack2d.h + BLI_boxpack_2d.h BLI_buffer.h BLI_callbacks.h BLI_compiler_attrs.h BLI_compiler_compat.h BLI_compiler_typecheck.h - BLI_convexhull2d.h - BLI_dial.h + BLI_convexhull_2d.h + BLI_dial_2d.h BLI_dlrbTree.h BLI_dynlib.h BLI_dynstr.h @@ -158,10 +159,10 @@ set(SRC BLI_hash_mm2a.h BLI_heap.h BLI_iterator.h - BLI_jitter.h + BLI_jitter_2d.h BLI_kdopbvh.h BLI_kdtree.h - BLI_lasso.h + BLI_lasso_2d.h BLI_link_utils.h BLI_linklist.h BLI_linklist_stack.h @@ -185,8 +186,8 @@ set(SRC BLI_mempool.h BLI_noise.h BLI_path_util.h - BLI_polyfill2d.h - BLI_polyfill2d_beautify.h + BLI_polyfill_2d.h + BLI_polyfill_2d_beautify.h BLI_quadric.h BLI_rand.h BLI_rect.h @@ -211,7 +212,7 @@ set(SRC BLI_utildefines_variadic.h BLI_uvproject.h BLI_vfontdata.h - BLI_voronoi.h + BLI_voronoi_2d.h BLI_voxel.h BLI_winstuff.h PIL_time.h diff --git a/source/blender/blenlib/intern/BLI_dial.c b/source/blender/blenlib/intern/BLI_dial_2d.c index 89f18fa10b4..d31367c5e87 100644 --- a/source/blender/blenlib/intern/BLI_dial.c +++ b/source/blender/blenlib/intern/BLI_dial_2d.c @@ -18,7 +18,11 @@ * ***** END GPL LICENSE BLOCK ***** */ -#include "BLI_dial.h" +/** \file blender/blenlib/intern/BLI_dial_2d.c + * \ingroup bli + */ + +#include "BLI_dial_2d.h" #include "BLI_math.h" #include "MEM_guardedalloc.h" diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index bf2f25fae69..fc8e786e5ff 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -43,11 +43,12 @@ #include "BLI_sys_types.h" /* for intptr_t support */ #include "BLI_utildefines.h" -#include "BLI_hash_mm2a.h" #include "BLI_mempool.h" #define GHASH_INTERNAL_API -#include "BLI_ghash.h" +#include "BLI_ghash.h" /* own include */ + +/* keep last */ #include "BLI_strict_flags.h" /* -------------------------------------------------------------------- */ @@ -741,7 +742,7 @@ void BLI_ghash_reserve(GHash *gh, const uint nentries_reserve) /** * \return size of the GHash. */ -uint BLI_ghash_size(GHash *gh) +uint BLI_ghash_len(GHash *gh) { return gh->nentries; } @@ -1010,7 +1011,7 @@ void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfree */ void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp) { - BLI_assert((int)gh->nentries == BLI_mempool_count(gh->entrypool)); + BLI_assert((int)gh->nentries == BLI_mempool_len(gh->entrypool)); if (keyfreefp || valfreefp) ghash_free_cb(gh, keyfreefp, valfreefp); @@ -1044,7 +1045,7 @@ void BLI_ghash_flag_clear(GHash *gh, uint flag) /** * Create a new GHashIterator. The hash table must not be mutated * while the iterator is in use, and the iterator will step exactly - * BLI_ghash_size(gh) times before becoming done. + * BLI_ghash_len(gh) times before becoming done. * * \param gh The GHash to iterate over. * \return Pointer to a new DynStr. @@ -1059,7 +1060,7 @@ GHashIterator *BLI_ghashIterator_new(GHash *gh) /** * Init an already allocated GHashIterator. The hash table must not * be mutated while the iterator is in use, and the iterator will - * step exactly BLI_ghash_size(gh) times before becoming done. + * step exactly BLI_ghash_len(gh) times before becoming done. * * \param ghi The GHashIterator to initialize. * \param gh The GHash to iterate over. @@ -1161,219 +1162,6 @@ bool BLI_ghashIterator_done(GHashIterator *ghi) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Generic Key Hash & Comparison Functions - * \{ */ - -/***/ - -#if 0 -/* works but slower */ -uint BLI_ghashutil_ptrhash(const void *key) -{ - return (uint)(intptr_t)key; -} -#else -/* based python3.3's pointer hashing function */ -uint BLI_ghashutil_ptrhash(const void *key) -{ - size_t y = (size_t)key; - /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid - * excessive hash collisions for dicts and sets */ - y = (y >> 4) | (y << (8 * sizeof(void *) - 4)); - return (uint)y; -} -#endif -bool BLI_ghashutil_ptrcmp(const void *a, const void *b) -{ - return (a != b); -} - -uint BLI_ghashutil_uinthash_v4(const uint key[4]) -{ - uint hash; - hash = key[0]; - hash *= 37; - hash += key[1]; - hash *= 37; - hash += key[2]; - hash *= 37; - hash += key[3]; - return hash; -} -uint BLI_ghashutil_uinthash_v4_murmur(const uint key[4]) -{ - return BLI_hash_mm2((const unsigned char *)key, sizeof(int) * 4 /* sizeof(key) */, 0); -} - -bool BLI_ghashutil_uinthash_v4_cmp(const void *a, const void *b) -{ - return (memcmp(a, b, sizeof(uint[4])) != 0); -} - -uint BLI_ghashutil_uinthash(uint key) -{ - key += ~(key << 16); - key ^= (key >> 5); - key += (key << 3); - key ^= (key >> 13); - key += ~(key << 9); - key ^= (key >> 17); - - return key; -} - -uint BLI_ghashutil_inthash_p(const void *ptr) -{ - uintptr_t key = (uintptr_t)ptr; - - key += ~(key << 16); - key ^= (key >> 5); - key += (key << 3); - key ^= (key >> 13); - key += ~(key << 9); - key ^= (key >> 17); - - return (uint)(key & 0xffffffff); -} - -uint BLI_ghashutil_inthash_p_murmur(const void *ptr) -{ - uintptr_t key = (uintptr_t)ptr; - - return BLI_hash_mm2((const unsigned char *)&key, sizeof(key), 0); -} - -uint BLI_ghashutil_inthash_p_simple(const void *ptr) -{ - return GET_UINT_FROM_POINTER(ptr); -} - -bool BLI_ghashutil_intcmp(const void *a, const void *b) -{ - return (a != b); -} - -size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b) -{ - return hash_a ^ (hash_b + 0x9e3779b9 + (hash_a << 6) + (hash_a >> 2)); -} - -/** - * This function implements the widely used "djb" hash apparently posted - * by Daniel Bernstein to comp.lang.c some time ago. The 32 bit - * unsigned hash value starts at 5381 and for each byte 'c' in the - * string, is updated: ``hash = hash * 33 + c``. This - * function uses the signed value of each byte. - * - * note: this is the same hash method that glib 2.34.0 uses. - */ -uint BLI_ghashutil_strhash_n(const char *key, size_t n) -{ - const signed char *p; - uint h = 5381; - - for (p = (const signed char *)key; n-- && *p != '\0'; p++) { - h = (uint)((h << 5) + h) + (uint)*p; - } - - return h; -} -uint BLI_ghashutil_strhash_p(const void *ptr) -{ - const signed char *p; - uint h = 5381; - - for (p = ptr; *p != '\0'; p++) { - h = (uint)((h << 5) + h) + (uint)*p; - } - - return h; -} -uint BLI_ghashutil_strhash_p_murmur(const void *ptr) -{ - const unsigned char *key = ptr; - - return BLI_hash_mm2(key, strlen((const char *)key) + 1, 0); -} -bool BLI_ghashutil_strcmp(const void *a, const void *b) -{ - return (a == b) ? false : !STREQ(a, b); -} - -GHashPair *BLI_ghashutil_pairalloc(const void *first, const void *second) -{ - GHashPair *pair = MEM_mallocN(sizeof(GHashPair), "GHashPair"); - pair->first = first; - pair->second = second; - return pair; -} - -uint BLI_ghashutil_pairhash(const void *ptr) -{ - const GHashPair *pair = ptr; - uint hash = BLI_ghashutil_ptrhash(pair->first); - return hash ^ BLI_ghashutil_ptrhash(pair->second); -} - -bool BLI_ghashutil_paircmp(const void *a, const void *b) -{ - const GHashPair *A = a; - const GHashPair *B = b; - - return (BLI_ghashutil_ptrcmp(A->first, B->first) || - BLI_ghashutil_ptrcmp(A->second, B->second)); -} - -void BLI_ghashutil_pairfree(void *ptr) -{ - MEM_freeN(ptr); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Convenience GHash Creation Functions - * \{ */ - -GHash *BLI_ghash_ptr_new_ex(const char *info, const uint nentries_reserve) -{ - return BLI_ghash_new_ex(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, info, nentries_reserve); -} -GHash *BLI_ghash_ptr_new(const char *info) -{ - return BLI_ghash_ptr_new_ex(info, 0); -} - -GHash *BLI_ghash_str_new_ex(const char *info, const uint nentries_reserve) -{ - return BLI_ghash_new_ex(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, info, nentries_reserve); -} -GHash *BLI_ghash_str_new(const char *info) -{ - return BLI_ghash_str_new_ex(info, 0); -} - -GHash *BLI_ghash_int_new_ex(const char *info, const uint nentries_reserve) -{ - return BLI_ghash_new_ex(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, info, nentries_reserve); -} -GHash *BLI_ghash_int_new(const char *info) -{ - return BLI_ghash_int_new_ex(info, 0); -} - -GHash *BLI_ghash_pair_new_ex(const char *info, const uint nentries_reserve) -{ - return BLI_ghash_new_ex(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, info, nentries_reserve); -} -GHash *BLI_ghash_pair_new(const char *info) -{ - return BLI_ghash_pair_new_ex(info, 0); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ /** \name GSet Public API * * Use ghash API to give 'set' functionality @@ -1398,7 +1186,7 @@ GSet *BLI_gset_copy(GSet *gs, GHashKeyCopyFP keycopyfp) return (GSet *)ghash_copy((GHash *)gs, keycopyfp, NULL); } -uint BLI_gset_size(GSet *gs) +uint BLI_gset_len(GSet *gs) { return ((GHash *)gs)->nentries; } @@ -1577,39 +1365,6 @@ void *BLI_gset_pop_key(GSet *gs, const void *key) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Convenience GSet Creation Functions - * \{ */ - -GSet *BLI_gset_ptr_new_ex(const char *info, const uint nentries_reserve) -{ - return BLI_gset_new_ex(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, info, nentries_reserve); -} -GSet *BLI_gset_ptr_new(const char *info) -{ - return BLI_gset_ptr_new_ex(info, 0); -} - -GSet *BLI_gset_str_new_ex(const char *info, const uint nentries_reserve) -{ - return BLI_gset_new_ex(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, info, nentries_reserve); -} -GSet *BLI_gset_str_new(const char *info) -{ - return BLI_gset_str_new_ex(info, 0); -} - -GSet *BLI_gset_pair_new_ex(const char *info, const uint nentries_reserve) -{ - return BLI_gset_new_ex(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, info, nentries_reserve); -} -GSet *BLI_gset_pair_new(const char *info) -{ - return BLI_gset_pair_new_ex(info, 0); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ /** \name Debugging & Introspection * \{ */ @@ -1618,13 +1373,13 @@ GSet *BLI_gset_pair_new(const char *info) /** * \return number of buckets in the GHash. */ -int BLI_ghash_buckets_size(GHash *gh) +int BLI_ghash_buckets_len(GHash *gh) { return (int)gh->nbuckets; } -int BLI_gset_buckets_size(GSet *gs) +int BLI_gset_buckets_len(GSet *gs) { - return BLI_ghash_buckets_size((GHash *)gs); + return BLI_ghash_buckets_len((GHash *)gs); } /** diff --git a/source/blender/blenlib/intern/BLI_ghash_utils.c b/source/blender/blenlib/intern/BLI_ghash_utils.c new file mode 100644 index 00000000000..6554ee7c92f --- /dev/null +++ b/source/blender/blenlib/intern/BLI_ghash_utils.c @@ -0,0 +1,288 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenlib/intern/BLI_ghash_utils.c + * \ingroup bli + * + * Helper functions and implementations of standard data types for #GHash + * (not it's implementation). + */ + +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_hash_mm2a.h" +#include "BLI_ghash.h" /* own include */ + +/* keep last */ +#include "BLI_strict_flags.h" + +/* -------------------------------------------------------------------- */ +/** \name Generic Key Hash & Comparison Functions + * \{ */ + +#if 0 +/* works but slower */ +uint BLI_ghashutil_ptrhash(const void *key) +{ + return (uint)(intptr_t)key; +} +#else +/* based python3.3's pointer hashing function */ +uint BLI_ghashutil_ptrhash(const void *key) +{ + size_t y = (size_t)key; + /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid + * excessive hash collisions for dicts and sets */ + y = (y >> 4) | (y << (8 * sizeof(void *) - 4)); + return (uint)y; +} +#endif +bool BLI_ghashutil_ptrcmp(const void *a, const void *b) +{ + return (a != b); +} + +uint BLI_ghashutil_uinthash_v4(const uint key[4]) +{ + uint hash; + hash = key[0]; + hash *= 37; + hash += key[1]; + hash *= 37; + hash += key[2]; + hash *= 37; + hash += key[3]; + return hash; +} +uint BLI_ghashutil_uinthash_v4_murmur(const uint key[4]) +{ + return BLI_hash_mm2((const unsigned char *)key, sizeof(int) * 4 /* sizeof(key) */, 0); +} + +bool BLI_ghashutil_uinthash_v4_cmp(const void *a, const void *b) +{ + return (memcmp(a, b, sizeof(uint[4])) != 0); +} + +uint BLI_ghashutil_uinthash(uint key) +{ + key += ~(key << 16); + key ^= (key >> 5); + key += (key << 3); + key ^= (key >> 13); + key += ~(key << 9); + key ^= (key >> 17); + + return key; +} + +uint BLI_ghashutil_inthash_p(const void *ptr) +{ + uintptr_t key = (uintptr_t)ptr; + + key += ~(key << 16); + key ^= (key >> 5); + key += (key << 3); + key ^= (key >> 13); + key += ~(key << 9); + key ^= (key >> 17); + + return (uint)(key & 0xffffffff); +} + +uint BLI_ghashutil_inthash_p_murmur(const void *ptr) +{ + uintptr_t key = (uintptr_t)ptr; + + return BLI_hash_mm2((const unsigned char *)&key, sizeof(key), 0); +} + +uint BLI_ghashutil_inthash_p_simple(const void *ptr) +{ + return GET_UINT_FROM_POINTER(ptr); +} + +bool BLI_ghashutil_intcmp(const void *a, const void *b) +{ + return (a != b); +} + +size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b) +{ + return hash_a ^ (hash_b + 0x9e3779b9 + (hash_a << 6) + (hash_a >> 2)); +} + +/** + * This function implements the widely used "djb" hash apparently posted + * by Daniel Bernstein to comp.lang.c some time ago. The 32 bit + * unsigned hash value starts at 5381 and for each byte 'c' in the + * string, is updated: ``hash = hash * 33 + c``. This + * function uses the signed value of each byte. + * + * note: this is the same hash method that glib 2.34.0 uses. + */ +uint BLI_ghashutil_strhash_n(const char *key, size_t n) +{ + const signed char *p; + uint h = 5381; + + for (p = (const signed char *)key; n-- && *p != '\0'; p++) { + h = (uint)((h << 5) + h) + (uint)*p; + } + + return h; +} +uint BLI_ghashutil_strhash_p(const void *ptr) +{ + const signed char *p; + uint h = 5381; + + for (p = ptr; *p != '\0'; p++) { + h = (uint)((h << 5) + h) + (uint)*p; + } + + return h; +} +uint BLI_ghashutil_strhash_p_murmur(const void *ptr) +{ + const unsigned char *key = ptr; + + return BLI_hash_mm2(key, strlen((const char *)key) + 1, 0); +} +bool BLI_ghashutil_strcmp(const void *a, const void *b) +{ + return (a == b) ? false : !STREQ(a, b); +} + +GHashPair *BLI_ghashutil_pairalloc(const void *first, const void *second) +{ + GHashPair *pair = MEM_mallocN(sizeof(GHashPair), "GHashPair"); + pair->first = first; + pair->second = second; + return pair; +} + +uint BLI_ghashutil_pairhash(const void *ptr) +{ + const GHashPair *pair = ptr; + uint hash = BLI_ghashutil_ptrhash(pair->first); + return hash ^ BLI_ghashutil_ptrhash(pair->second); +} + +bool BLI_ghashutil_paircmp(const void *a, const void *b) +{ + const GHashPair *A = a; + const GHashPair *B = b; + + return (BLI_ghashutil_ptrcmp(A->first, B->first) || + BLI_ghashutil_ptrcmp(A->second, B->second)); +} + +void BLI_ghashutil_pairfree(void *ptr) +{ + MEM_freeN(ptr); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Convenience GHash Creation Functions + * \{ */ + +GHash *BLI_ghash_ptr_new_ex(const char *info, const uint nentries_reserve) +{ + return BLI_ghash_new_ex(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, info, nentries_reserve); +} +GHash *BLI_ghash_ptr_new(const char *info) +{ + return BLI_ghash_ptr_new_ex(info, 0); +} + +GHash *BLI_ghash_str_new_ex(const char *info, const uint nentries_reserve) +{ + return BLI_ghash_new_ex(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, info, nentries_reserve); +} +GHash *BLI_ghash_str_new(const char *info) +{ + return BLI_ghash_str_new_ex(info, 0); +} + +GHash *BLI_ghash_int_new_ex(const char *info, const uint nentries_reserve) +{ + return BLI_ghash_new_ex(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, info, nentries_reserve); +} +GHash *BLI_ghash_int_new(const char *info) +{ + return BLI_ghash_int_new_ex(info, 0); +} + +GHash *BLI_ghash_pair_new_ex(const char *info, const uint nentries_reserve) +{ + return BLI_ghash_new_ex(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, info, nentries_reserve); +} +GHash *BLI_ghash_pair_new(const char *info) +{ + return BLI_ghash_pair_new_ex(info, 0); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Convenience GSet Creation Functions + * \{ */ + +GSet *BLI_gset_ptr_new_ex(const char *info, const uint nentries_reserve) +{ + return BLI_gset_new_ex(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, info, nentries_reserve); +} +GSet *BLI_gset_ptr_new(const char *info) +{ + return BLI_gset_ptr_new_ex(info, 0); +} + +GSet *BLI_gset_str_new_ex(const char *info, const uint nentries_reserve) +{ + return BLI_gset_new_ex(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, info, nentries_reserve); +} +GSet *BLI_gset_str_new(const char *info) +{ + return BLI_gset_str_new_ex(info, 0); +} + +GSet *BLI_gset_pair_new_ex(const char *info, const uint nentries_reserve) +{ + return BLI_gset_new_ex(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, info, nentries_reserve); +} +GSet *BLI_gset_pair_new(const char *info) +{ + return BLI_gset_pair_new_ex(info, 0); +} + +/** \} */ diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c index 7c249344541..0c71e75e40f 100644 --- a/source/blender/blenlib/intern/BLI_heap.c +++ b/source/blender/blenlib/intern/BLI_heap.c @@ -303,7 +303,7 @@ bool BLI_heap_is_empty(const Heap *heap) return (heap->size == 0); } -uint BLI_heap_size(const Heap *heap) +uint BLI_heap_len(const Heap *heap) { return heap->size; } @@ -320,7 +320,7 @@ HeapNode *BLI_heap_top(const Heap *heap) /** * Pop the top node off the heap and return it's pointer. */ -void *BLI_heap_popmin(Heap *heap) +void *BLI_heap_pop_min(Heap *heap) { BLI_assert(heap->size != 0); @@ -348,7 +348,7 @@ void BLI_heap_remove(Heap *heap, HeapNode *node) i = p; } - BLI_heap_popmin(heap); + BLI_heap_pop_min(heap); } /** diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 9c055a227a9..d6c58780603 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -1147,7 +1147,7 @@ void BLI_bvhtree_update_tree(BVHTree *tree) * Number of times #BLI_bvhtree_insert has been called. * mainly useful for asserts functions to check we added the correct number. */ -int BLI_bvhtree_get_size(const BVHTree *tree) +int BLI_bvhtree_get_len(const BVHTree *tree) { return tree->totleaf; } diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c index 5b13f129ad4..3a65e6c42ca 100644 --- a/source/blender/blenlib/intern/BLI_mempool.c +++ b/source/blender/blenlib/intern/BLI_mempool.c @@ -474,7 +474,7 @@ void BLI_mempool_free(BLI_mempool *pool, void *addr) } } -int BLI_mempool_count(BLI_mempool *pool) +int BLI_mempool_len(BLI_mempool *pool) { return (int)pool->totused; } diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c index 5b1715bbb3d..acf15b1c892 100644 --- a/source/blender/blenlib/intern/array_store.c +++ b/source/blender/blenlib/intern/array_store.c @@ -1759,7 +1759,7 @@ bool BLI_array_store_is_valid( goto user_finally; } } - if (!(BLI_mempool_count(bs->memory.chunk_list) == (int)BLI_ghash_size(chunk_list_map))) { + if (!(BLI_mempool_len(bs->memory.chunk_list) == (int)BLI_ghash_len(chunk_list_map))) { ok = false; goto user_finally; } @@ -1772,11 +1772,11 @@ bool BLI_array_store_is_valid( totrefs += 1; } } - if (!(BLI_mempool_count(bs->memory.chunk) == (int)BLI_ghash_size(chunk_map))) { + if (!(BLI_mempool_len(bs->memory.chunk) == (int)BLI_ghash_len(chunk_map))) { ok = false; goto user_finally; } - if (!(BLI_mempool_count(bs->memory.chunk_ref) == totrefs)) { + if (!(BLI_mempool_len(bs->memory.chunk_ref) == totrefs)) { ok = false; goto user_finally; } diff --git a/source/blender/blenlib/intern/astar.c b/source/blender/blenlib/intern/astar.c index 0020dbe4612..1b57dc5a683 100644 --- a/source/blender/blenlib/intern/astar.c +++ b/source/blender/blenlib/intern/astar.c @@ -231,7 +231,7 @@ bool BLI_astar_graph_solve( SET_INT_IN_POINTER(node_index_src)); while (!BLI_heap_is_empty(todo_nodes)) { - const int node_curr_idx = GET_INT_FROM_POINTER(BLI_heap_popmin(todo_nodes)); + const int node_curr_idx = GET_INT_FROM_POINTER(BLI_heap_pop_min(todo_nodes)); BLI_AStarGNode *node_curr = &as_graph->nodes[node_curr_idx]; LinkData *ld; diff --git a/source/blender/blenlib/intern/boxpack2d.c b/source/blender/blenlib/intern/boxpack_2d.c index ff17d2ac28b..b3beff0b78b 100644 --- a/source/blender/blenlib/intern/boxpack2d.c +++ b/source/blender/blenlib/intern/boxpack_2d.c @@ -30,7 +30,7 @@ #include "MEM_guardedalloc.h" #include "BLI_utildefines.h" -#include "BLI_boxpack2d.h" /* own include */ +#include "BLI_boxpack_2d.h" /* own include */ #include "BLI_sort.h" /* qsort_r */ #define qsort_r BLI_qsort_r diff --git a/source/blender/blenlib/intern/convexhull2d.c b/source/blender/blenlib/intern/convexhull_2d.c index 1f1f214ce32..38928dbbaa0 100644 --- a/source/blender/blenlib/intern/convexhull2d.c +++ b/source/blender/blenlib/intern/convexhull_2d.c @@ -18,7 +18,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/blenlib/intern/convexhull2d.c +/** \file blender/blenlib/intern/convexhull_2d.c * \ingroup bli */ @@ -28,7 +28,7 @@ #include "MEM_guardedalloc.h" -#include "BLI_convexhull2d.h" +#include "BLI_convexhull_2d.h" #include "BLI_math.h" #include "BLI_strict_flags.h" #include "BLI_utildefines.h" diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c index 772c8bd6247..7074a776aaf 100644 --- a/source/blender/blenlib/intern/edgehash.c +++ b/source/blender/blenlib/intern/edgehash.c @@ -527,7 +527,7 @@ bool BLI_edgehash_haskey(EdgeHash *eh, uint v0, uint v1) /** * Return number of keys in hash. */ -int BLI_edgehash_size(EdgeHash *eh) +int BLI_edgehash_len(EdgeHash *eh) { return (int)eh->nentries; } @@ -565,7 +565,7 @@ void BLI_edgehash_clear(EdgeHash *eh, EdgeHashFreeFP valfreefp) void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP valfreefp) { - BLI_assert((int)eh->nentries == BLI_mempool_count(eh->epool)); + BLI_assert((int)eh->nentries == BLI_mempool_len(eh->epool)); if (valfreefp) edgehash_free_cb(eh, valfreefp); @@ -599,7 +599,7 @@ void BLI_edgehash_flag_clear(EdgeHash *eh, uint flag) /** * Create a new EdgeHashIterator. The hash table must not be mutated * while the iterator is in use, and the iterator will step exactly - * BLI_edgehash_size(eh) times before becoming done. + * BLI_edgehash_len(eh) times before becoming done. */ EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh) { @@ -611,7 +611,7 @@ EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh) /** * Init an already allocated EdgeHashIterator. The hash table must not * be mutated while the iterator is in use, and the iterator will - * step exactly BLI_edgehash_size(eh) times before becoming done. + * step exactly BLI_edgehash_len(eh) times before becoming done. * * \param ehi The EdgeHashIterator to initialize. * \param eh The EdgeHash to iterate over. @@ -729,7 +729,7 @@ EdgeSet *BLI_edgeset_new(const char *info) return BLI_edgeset_new_ex(info, 0); } -int BLI_edgeset_size(EdgeSet *es) +int BLI_edgeset_len(EdgeSet *es) { return (int)((EdgeHash *)es)->nentries; } diff --git a/source/blender/blenlib/intern/gsqueue.c b/source/blender/blenlib/intern/gsqueue.c index 25da7701924..5c8c43ab92a 100644 --- a/source/blender/blenlib/intern/gsqueue.c +++ b/source/blender/blenlib/intern/gsqueue.c @@ -81,7 +81,7 @@ bool BLI_gsqueue_is_empty(GSQueue *gq) /** * Query number elements in the queue */ -int BLI_gsqueue_size(GSQueue *gq) +int BLI_gsqueue_len(GSQueue *gq) { GSQueueElem *elem; int size = 0; @@ -162,7 +162,7 @@ void BLI_gsqueue_push(GSQueue *gq, const void *item) * \param item A pointer to an appropriately * sized structure (the size passed to BLI_gsqueue_new). */ -void BLI_gsqueue_pushback(GSQueue *gq, const void *item) +void BLI_gsqueue_push_back(GSQueue *gq, const void *item) { GSQueueElem *elem = MEM_mallocN(sizeof(*elem) + gq->elem_size, "gqueue_push"); memcpy(elem->data, item, gq->elem_size); diff --git a/source/blender/blenlib/intern/jitter.c b/source/blender/blenlib/intern/jitter_2d.c index bc2b5677fa5..6c51eeb36d9 100644 --- a/source/blender/blenlib/intern/jitter.c +++ b/source/blender/blenlib/intern/jitter_2d.c @@ -35,7 +35,7 @@ #include "MEM_guardedalloc.h" #include "BLI_rand.h" -#include "BLI_jitter.h" +#include "BLI_jitter_2d.h" #include "BLI_strict_flags.h" diff --git a/source/blender/blenlib/intern/lasso.c b/source/blender/blenlib/intern/lasso_2d.c index 710da09521a..663f3ffea22 100644 --- a/source/blender/blenlib/intern/lasso.c +++ b/source/blender/blenlib/intern/lasso_2d.c @@ -26,7 +26,7 @@ * */ -/** \file blender/blenlib/intern/lasso.c +/** \file blender/blenlib/intern/lasso_2d.c * \ingroup bli */ @@ -35,7 +35,7 @@ #include "BLI_math.h" #include "BLI_strict_flags.h" -#include "BLI_lasso.h" /* own include */ +#include "BLI_lasso_2d.h" /* own include */ void BLI_lasso_boundbox(rcti *rect, const int mcords[][2], const unsigned int moves) { diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c index 2f5b0f420b1..1f517471407 100644 --- a/source/blender/blenlib/intern/math_base_inline.c +++ b/source/blender/blenlib/intern/math_base_inline.c @@ -324,6 +324,27 @@ MINLINE size_t max_zz(size_t a, size_t b) return (b < a) ? a : b; } +MINLINE int clamp_i(int value, int min, int max) +{ + return min_ii(max_ii(value, min), max); +} + +MINLINE float clamp_f(float value, float min, float max) +{ + if (value > max) { + return max; + } + else if (value < min) { + return min; + } + return value; +} + +MINLINE size_t clamp_z(size_t value, size_t min, size_t max) +{ + return min_zz(max_zz(value, min), max); +} + /** * Almost-equal for IEEE floats, using absolute difference method. * diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index d3080e5530f..a3d850f9551 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -4903,6 +4903,18 @@ int is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], con return ret; } +bool is_quad_flip_v3_first_third_fast(const float v1[3], const float v2[3], const float v3[3], const float v4[3]) +{ + float d_12[3], d_13[3], d_14[3]; + float cross_a[3], cross_b[3]; + sub_v3_v3v3(d_12, v2, v1); + sub_v3_v3v3(d_13, v3, v1); + sub_v3_v3v3(d_14, v4, v1); + cross_v3_v3v3(cross_a, d_12, d_13); + cross_v3_v3v3(cross_b, d_14, d_13); + return dot_v3v3(cross_a, cross_b) > 0.0f; +} + /** * Return the value which the distance between points will need to be scaled by, * to define a handle, given both points are on a perfect circle. diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 05562502278..d6e48fa59e7 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -890,6 +890,8 @@ void rotate_normalized_v3_v3v3fl(float out[3], const float p[3], const float axi void rotate_v3_v3v3fl(float r[3], const float p[3], const float axis[3], const float angle) { + BLI_assert(r != p); + float axis_n[3]; normalize_v3_v3(axis_n, axis); diff --git a/source/blender/blenlib/intern/polyfill2d.c b/source/blender/blenlib/intern/polyfill_2d.c index 018e2f9be5a..8c0870f0c07 100644 --- a/source/blender/blenlib/intern/polyfill2d.c +++ b/source/blender/blenlib/intern/polyfill_2d.c @@ -18,7 +18,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/blenlib/intern/polyfill2d.c +/** \file blender/blenlib/intern/polyfill_2d.c * \ingroup bli * * An ear clipping algorithm to triangulate single boundary polygons. @@ -53,7 +53,7 @@ #include "BLI_memarena.h" #include "BLI_alloca.h" -#include "BLI_polyfill2d.h" /* own include */ +#include "BLI_polyfill_2d.h" /* own include */ #include "BLI_strict_flags.h" diff --git a/source/blender/blenlib/intern/polyfill2d_beautify.c b/source/blender/blenlib/intern/polyfill_2d_beautify.c index c0c95da5c63..93bfb02bce4 100644 --- a/source/blender/blenlib/intern/polyfill2d_beautify.c +++ b/source/blender/blenlib/intern/polyfill_2d_beautify.c @@ -44,7 +44,7 @@ #include "BLI_memarena.h" #include "BLI_heap.h" -#include "BLI_polyfill2d_beautify.h" /* own include */ +#include "BLI_polyfill_2d_beautify.h" /* own include */ #include "BLI_strict_flags.h" @@ -401,7 +401,7 @@ void BLI_polyfill_beautify( } while (BLI_heap_is_empty(eheap) == false) { - struct HalfEdge *e = BLI_heap_popmin(eheap); + struct HalfEdge *e = BLI_heap_pop_min(eheap); eheap_table[e->base_index] = NULL; polyedge_rotate(half_edges, e); diff --git a/source/blender/blenlib/intern/smallhash.c b/source/blender/blenlib/intern/smallhash.c index 1b862ffe005..56d77abed24 100644 --- a/source/blender/blenlib/intern/smallhash.c +++ b/source/blender/blenlib/intern/smallhash.c @@ -310,7 +310,7 @@ bool BLI_smallhash_haskey(const SmallHash *sh, uintptr_t key) return (e != NULL); } -int BLI_smallhash_count(const SmallHash *sh) +int BLI_smallhash_len(const SmallHash *sh) { return (int)sh->nentries; } diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c index 05cfe4f3972..53c0c560c0d 100644 --- a/source/blender/blenlib/intern/task.c +++ b/source/blender/blenlib/intern/task.c @@ -696,7 +696,7 @@ static TaskPool *task_pool_create_ex(TaskScheduler *scheduler, * and malloc could be non-thread safe at this point because * no other jobs are running. */ - BLI_begin_threaded_malloc(); + BLI_threaded_malloc_begin(); return pool; } @@ -763,7 +763,7 @@ void BLI_task_pool_free(TaskPool *pool) MEM_freeN(pool); - BLI_end_threaded_malloc(); + BLI_threaded_malloc_end(); } BLI_INLINE bool task_can_use_local_queues(TaskPool *pool, int thread_id) @@ -1329,7 +1329,7 @@ void BLI_task_parallel_mempool( ParallelMempoolState state; int i, num_threads, num_tasks; - if (BLI_mempool_count(mempool) == 0) { + if (BLI_mempool_len(mempool) == 0) { return; } diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c index 2f961701801..761f3982e28 100644 --- a/source/blender/blenlib/intern/threads.c +++ b/source/blender/blenlib/intern/threads.c @@ -83,13 +83,13 @@ static TaskScheduler *task_scheduler = NULL; * int maxthreads = 2; * int cont = 1; * - * BLI_init_threads(&lb, do_something_func, maxthreads); + * BLI_threadpool_init(&lb, do_something_func, maxthreads); * * while (cont) { * if (BLI_available_threads(&lb) && !(escape loop event)) { * // get new job (data pointer) * // tag job 'processed - * BLI_insert_thread(&lb, job); + * BLI_threadpool_insert(&lb, job); * } * else PIL_sleep_ms(50); * @@ -98,7 +98,7 @@ static TaskScheduler *task_scheduler = NULL; * for (go over all jobs) * if (job is ready) { * if (job was not removed) { - * BLI_remove_thread(&lb, job); + * BLI_threadpool_remove(&lb, job); * } * } * else cont = 1; @@ -110,7 +110,7 @@ static TaskScheduler *task_scheduler = NULL; * } * } * - * BLI_end_threads(&lb); + * BLI_threadpool_end(&lb); * ************************************************ */ static SpinLock _malloc_lock; @@ -183,7 +183,7 @@ TaskScheduler *BLI_task_scheduler_get(void) * problem otherwise: scene render will kill of the mutex! */ -void BLI_init_threads(ListBase *threadbase, void *(*do_thread)(void *), int tot) +void BLI_threadpool_init(ListBase *threadbase, void *(*do_thread)(void *), int tot) { int a; @@ -228,7 +228,7 @@ int BLI_available_threads(ListBase *threadbase) } /* returns thread number, for sample patterns or threadsafe tables */ -int BLI_available_thread_index(ListBase *threadbase) +int BLI_threadpool_available_thread_index(ListBase *threadbase) { ThreadSlot *tslot; int counter = 0; @@ -258,7 +258,7 @@ int BLI_thread_is_main(void) return pthread_equal(pthread_self(), mainid); } -void BLI_insert_thread(ListBase *threadbase, void *callerdata) +void BLI_threadpool_insert(ListBase *threadbase, void *callerdata) { ThreadSlot *tslot; @@ -273,7 +273,7 @@ void BLI_insert_thread(ListBase *threadbase, void *callerdata) printf("ERROR: could not insert thread slot\n"); } -void BLI_remove_thread(ListBase *threadbase, void *callerdata) +void BLI_threadpool_remove(ListBase *threadbase, void *callerdata) { ThreadSlot *tslot; @@ -286,7 +286,7 @@ void BLI_remove_thread(ListBase *threadbase, void *callerdata) } } -void BLI_remove_thread_index(ListBase *threadbase, int index) +void BLI_threadpool_remove_index(ListBase *threadbase, int index) { ThreadSlot *tslot; int counter = 0; @@ -301,7 +301,7 @@ void BLI_remove_thread_index(ListBase *threadbase, int index) } } -void BLI_remove_threads(ListBase *threadbase) +void BLI_threadpool_clear(ListBase *threadbase) { ThreadSlot *tslot; @@ -314,7 +314,7 @@ void BLI_remove_threads(ListBase *threadbase) } } -void BLI_end_threads(ListBase *threadbase) +void BLI_threadpool_end(ListBase *threadbase) { ThreadSlot *tslot; @@ -418,12 +418,12 @@ static ThreadMutex *global_mutex_from_type(const int type) } } -void BLI_lock_thread(int type) +void BLI_thread_lock(int type) { pthread_mutex_lock(global_mutex_from_type(type)); } -void BLI_unlock_thread(int type) +void BLI_thread_unlock(int type) { pthread_mutex_unlock(global_mutex_from_type(type)); } @@ -773,12 +773,12 @@ void *BLI_thread_queue_pop_timeout(ThreadQueue *queue, int ms) return work; } -int BLI_thread_queue_size(ThreadQueue *queue) +int BLI_thread_queue_len(ThreadQueue *queue) { int size; pthread_mutex_lock(&queue->mutex); - size = BLI_gsqueue_size(queue->queue); + size = BLI_gsqueue_len(queue->queue); pthread_mutex_unlock(&queue->mutex); return size; @@ -819,7 +819,7 @@ void BLI_thread_queue_wait_finish(ThreadQueue *queue) /* ************************************************ */ -void BLI_begin_threaded_malloc(void) +void BLI_threaded_malloc_begin(void) { unsigned int level = atomic_fetch_and_add_u(&thread_levels, 1); if (level == 0) { @@ -832,7 +832,7 @@ void BLI_begin_threaded_malloc(void) } } -void BLI_end_threaded_malloc(void) +void BLI_threaded_malloc_end(void) { unsigned int level = atomic_sub_and_fetch_u(&thread_levels, 1); if (level == 0) { diff --git a/source/blender/blenlib/intern/voronoi.c b/source/blender/blenlib/intern/voronoi_2d.c index e0cbe278ffb..40e98d5914c 100644 --- a/source/blender/blenlib/intern/voronoi.c +++ b/source/blender/blenlib/intern/voronoi_2d.c @@ -23,20 +23,18 @@ * ***** END GPL LICENSE BLOCK ***** */ -/* +/** \file blender/blenlib/intern/voronoi_2d.c + * \ingroup bli + * * Fortune's algorithm implemented using explanation and some code snippets from * http://blog.ivank.net/fortunes-algorithm-and-implementation.html */ -/** \file blender/blenlib/intern/voronoi.c - * \ingroup bli - */ - #include "MEM_guardedalloc.h" #include "BLI_listbase.h" #include "BLI_math.h" -#include "BLI_voronoi.h" +#include "BLI_voronoi_2d.h" #include "BLI_utildefines.h" #define VORONOI_EPS 1e-2f diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 54444ff5151..e5708ec4df0 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -86,7 +86,7 @@ #include "DNA_meshdata_types.h" #include "DNA_nla_types.h" #include "DNA_node_types.h" -#include "DNA_object_fluidsim.h" // NT +#include "DNA_object_fluidsim_types.h" #include "DNA_object_types.h" #include "DNA_packedFile_types.h" #include "DNA_particle_types.h" @@ -4406,6 +4406,9 @@ static void direct_link_particlesettings(FileData *fd, ParticleSettings *part) part->roughcurve = newdataadr(fd, part->roughcurve); if (part->roughcurve) direct_link_curvemapping(fd, part->roughcurve); + part->twistcurve = newdataadr(fd, part->twistcurve); + if (part->twistcurve) + direct_link_curvemapping(fd, part->twistcurve); part->effector_weights = newdataadr(fd, part->effector_weights); if (!part->effector_weights) @@ -4940,8 +4943,7 @@ static void lib_link_object(FileData *fd, Main *main) #else MEM_freeN(ob->pose); #endif - ob->pose= NULL; - ob->mode &= ~OB_MODE_POSE; + ob->pose = NULL; } } for (a=0; a < ob->totcol; a++) @@ -5548,19 +5550,6 @@ static void direct_link_object(FileData *fd, Object *ob) /* XXX This should not be needed - but seems like it can happen in some cases, so for now play safe... */ ob->proxy_from = NULL; - - /* loading saved files with editmode enabled works, but for undo we like - * to stay in object mode during undo presses so keep editmode disabled. - * - * Also when linking in a file don't allow edit and pose modes. - * See [#34776, #42780] for more information. - */ - if (fd->memfile || (ob->id.tag & (LIB_TAG_EXTERN | LIB_TAG_INDIRECT))) { - ob->mode &= ~(OB_MODE_EDIT | OB_MODE_PARTICLE_EDIT); - if (!fd->memfile) { - ob->mode &= ~OB_MODE_POSE; - } - } ob->adt = newdataadr(fd, ob->adt); direct_link_animdata(fd, ob->adt); @@ -6230,7 +6219,6 @@ static void direct_link_scene(FileData *fd, Scene *sce, Main *bmain) SceneRenderLayer *srl; sce->depsgraph_hash = NULL; - sce->obedit = NULL; sce->fps_info = NULL; sce->customdata_mask_modal = 0; sce->lay_updated = 0; @@ -6618,7 +6606,6 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype) BLI_listbase_clear(&ar->handlers); BLI_listbase_clear(&ar->uiblocks); ar->headerstr = NULL; - ar->swinid = 0; ar->type = NULL; ar->swap = 0; ar->do_draw = 0; @@ -7096,7 +7083,6 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) win->ghostwin = NULL; win->eventstate = NULL; - win->curswin = NULL; win->tweak = NULL; #ifdef WIN32 win->ime_data = NULL; @@ -7105,7 +7091,6 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) BLI_listbase_clear(&win->queue); BLI_listbase_clear(&win->handlers); BLI_listbase_clear(&win->modalhandlers); - BLI_listbase_clear(&win->subwindows); BLI_listbase_clear(&win->gesture); BLI_listbase_clear(&win->drawdata); @@ -7118,7 +7103,6 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) win->modalcursor = 0; win->grabcursor = 0; win->addmousemove = true; - win->multisamples = 0; win->stereo3d_format = newdataadr(fd, win->stereo3d_format); /* multiview always fallback to anaglyph at file opening @@ -7639,8 +7623,7 @@ static bool direct_link_screen(FileData *fd, bScreen *sc) link_list(fd, &(sc->areabase)); sc->regionbase.first = sc->regionbase.last= NULL; sc->context = NULL; - - sc->mainwin = sc->subwinactive= 0; /* indices */ + sc->active_region = NULL; sc->swap = 0; sc->preview = direct_link_preview_image(fd, sc->preview); @@ -7690,12 +7673,20 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main) BLI_remlink(&main->library, lib); MEM_freeN(lib); - - + + /* Now, since Blender always expect **latest** Main pointer from fd->mainlist to be the active library + * Main pointer, where to add all non-library data-blocks found in file next, we have to switch that + * 'dupli' found Main to latest position in the list! + * Otherwise, you get weird disappearing linked data on a rather unconsistant basis. + * See also T53977 for reproducible case. */ + BLI_remlink(fd->mainlist, newmain); + BLI_addtail(fd->mainlist, newmain); + return; } } } + /* make sure we have full path in lib->filepath */ BLI_strncpy(lib->filepath, lib->name, sizeof(lib->name)); BLI_cleanup_path(fd->relabase, lib->filepath); @@ -10481,7 +10472,6 @@ static void link_object_postprocess(ID *id, Scene *scene, ViewLayer *view_layer, SceneCollection *sc; ob = (Object *)id; - ob->mode = OB_MODE_OBJECT; sc = get_scene_collection_active_or_create(scene, view_layer, flag); BKE_collection_object_add(&scene->id, sc, ob); @@ -10524,8 +10514,6 @@ void BLO_library_link_copypaste(Main *mainl, BlendHandle *bh) if (bhead->code == ID_OB) { /* Instead of instancing Base's directly, postpone until after groups are loaded * otherwise the base's flag is set incorrectly when groups are used */ - Object *ob = (Object *)id; - ob->mode = OB_MODE_OBJECT; /* ensure give_base_to_objects runs on this object */ BLI_assert(id->us == 0); } @@ -10822,6 +10810,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) Main *mainl = mainlist->first; Main *mainptr; ListBase *lbarray[MAX_LIBARRAY]; + GHash *loaded_ids = BLI_ghash_str_new(__func__); int a; bool do_it = true; @@ -10835,7 +10824,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) mainptr= mainl->next; while (mainptr) { if (mainvar_id_tag_any_check(mainptr, LIB_TAG_READ)) { - // printf("found LIB_TAG_READ %s\n", mainptr->curlib->name); + // printf("found LIB_TAG_READ %s (%s)\n", mainptr->curlib->id.name, mainptr->curlib->name); FileData *fd = mainptr->curlib->filedata; @@ -10933,25 +10922,38 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) a = set_listbasepointers(mainptr, lbarray); while (a--) { ID *id = lbarray[a]->first; + ListBase pending_free_ids = {NULL}; while (id) { ID *idn = id->next; if (id->tag & LIB_TAG_READ) { - ID *realid = NULL; BLI_remlink(lbarray[a], id); - link_id_part(basefd->reports, fd, mainptr, id, &realid); + /* When playing with lib renaming and such, you may end with cases where you have + * more than one linked ID of the same data-block from same library. + * This is absolutely horrible, hence we use a ghash to ensure we go back to a single + * linked data when loading the file... */ + ID **realid = NULL; + if (!BLI_ghash_ensure_p(loaded_ids, id->name, (void ***)&realid)) { + link_id_part(basefd->reports, fd, mainptr, id, realid); + } /* realid shall never be NULL - unless some source file/lib is broken * (known case: some directly linked shapekey from a missing lib...). */ - /* BLI_assert(realid != NULL); */ + /* BLI_assert(*realid != NULL); */ - change_idid_adr(mainlist, basefd, id, realid); + change_idid_adr(mainlist, basefd, id, *realid); - MEM_freeN(id); + /* We cannot free old lib-ref placeholder ID here anymore, since we use its name + * as key in loaded_ids hass. */ + BLI_addtail(&pending_free_ids, id); } id = idn; } + + /* Clear GHash and free all lib-ref placeholders IDs of that type now. */ + BLI_ghash_clear(loaded_ids, NULL, NULL); + BLI_freelistN(&pending_free_ids); } BLO_expand_main(fd, mainptr); } @@ -10959,7 +10961,10 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) mainptr = mainptr->next; } } - + + BLI_ghash_free(loaded_ids, NULL, NULL); + loaded_ids = NULL; + /* test if there are unread libblocks */ /* XXX This code block is kept for 2.77, until we are sure it never gets reached anymore. Can be removed later. */ for (mainptr = mainl->next; mainptr; mainptr = mainptr->next) { diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index 7036470c8e4..59dc6e9d6b7 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -52,7 +52,7 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_node_types.h" -#include "DNA_object_fluidsim.h" // NT +#include "DNA_object_fluidsim_types.h" #include "DNA_object_types.h" #include "DNA_view3d_types.h" #include "DNA_screen_types.h" @@ -1087,8 +1087,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 2)) { Scene *sce; - Object *ob; - for (sce = main->scene.first; sce; sce = sce->id.next) { if (fd->fileflags & G_FILE_ENABLE_ALL_FRAMES) sce->gm.flag |= GAME_ENABLE_ALL_FRAMES; @@ -1120,11 +1118,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) else sce->gm.matmode = GAME_MAT_TEXFACE; } - - for (ob = main->object.first; ob; ob = ob->id.next) { - if (ob->flag & 8192) // OB_POSEMODE = 8192 - ob->mode |= OB_MODE_POSE; - } } if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 4)) { diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c index 3ac934f7de7..f7301fe4664 100644 --- a/source/blender/blenloader/intern/versioning_260.c +++ b/source/blender/blenloader/intern/versioning_260.c @@ -41,7 +41,7 @@ #include "DNA_linestyle_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" -#include "DNA_object_fluidsim.h" // NT +#include "DNA_object_fluidsim_types.h" #include "DNA_object_types.h" #include "DNA_property_types.h" #include "DNA_text_types.h" diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 0800437c3d2..044c47847be 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -45,7 +45,7 @@ #include "DNA_sequence_types.h" #include "DNA_space_types.h" #include "DNA_screen_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_object_types.h" #include "DNA_mask_types.h" #include "DNA_mesh_types.h" diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index aef1621c93f..224bfc6aefb 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -558,6 +558,18 @@ void do_versions_after_linking_280(Main *main) } } + if (!MAIN_VERSION_ATLEAST(main, 280, 3)) { + /* Due to several changes to particle RNA and draw code particles from older files may no longer + * be visible. Here we correct this by setting a default draw size for those files. */ + for (Object *object = main->object.first; object; object = object->id.next) { + for (ParticleSystem *psys = object->particlesystem.first; psys; psys=psys->next) { + if(psys->part->draw_size == 0.0f) { + psys->part->draw_size = 0.1f; + } + } + } + } + { for (WorkSpace *workspace = main->workspaces.first; workspace; workspace = workspace->id.next) { if (workspace->view_layer) { @@ -623,7 +635,7 @@ void do_versions_after_linking_280(Main *main) #endif if (object->particlesystem.first) { object->duplicator_visibility_flag = OB_DUPLI_FLAG_VIEWPORT; - for (ParticleSystem *psys = object->particlesystem.first; psys; psys=psys->next) { + for (ParticleSystem *psys = object->particlesystem.first; psys; psys = psys->next) { if (psys->part->draw & PART_DRAW_EMITTER) { object->duplicator_visibility_flag |= OB_DUPLI_FLAG_RENDER; #ifndef VERSION_280_SUBVERSION_4 @@ -713,6 +725,10 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main) } } } + + for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { + scene->r.gauss = 1.5f; + } } if (!MAIN_VERSION_ATLEAST(main, 280, 1)) { @@ -910,11 +926,11 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main) SpaceOops *so = (SpaceOops *)sl; if (!ELEM(so->outlinevis, - SO_SCENES, - SO_GROUPS, - SO_LIBRARIES, - SO_SEQUENCE, - SO_DATABLOCKS, + SO_SCENES, + SO_GROUPS, + SO_LIBRARIES, + SO_SEQUENCE, + SO_DATABLOCKS, SO_ID_ORPHANS, SO_VIEW_LAYER, SO_COLLECTIONS)) diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c index 0af1c3951ad..fa2287ff6da 100644 --- a/source/blender/blenloader/intern/versioning_legacy.c +++ b/source/blender/blenloader/intern/versioning_legacy.c @@ -58,7 +58,7 @@ #include "DNA_meshdata_types.h" #include "DNA_nla_types.h" #include "DNA_node_types.h" -#include "DNA_object_fluidsim.h" // NT +#include "DNA_object_fluidsim_types.h" #include "DNA_object_types.h" #include "DNA_property_types.h" #include "DNA_view3d_types.h" diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index c5690376305..f3b6b157413 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -132,7 +132,7 @@ #include "DNA_material_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_packedFile_types.h" #include "DNA_particle_types.h" #include "DNA_lightprobe_types.h" @@ -1176,7 +1176,7 @@ static void write_renderinfo(WriteData *wd, Main *mainvar) } } -static void write_keymapitem(WriteData *wd, wmKeyMapItem *kmi) +static void write_keymapitem(WriteData *wd, const wmKeyMapItem *kmi) { writestruct(wd, DATA, wmKeyMapItem, 1, kmi); if (kmi->properties) { @@ -1184,26 +1184,18 @@ static void write_keymapitem(WriteData *wd, wmKeyMapItem *kmi) } } -static void write_userdef(WriteData *wd) +static void write_userdef(WriteData *wd, const UserDef *userdef) { - bTheme *btheme; - wmKeyMap *keymap; - wmKeyMapItem *kmi; - wmKeyMapDiffItem *kmdi; - bAddon *bext; - bPathCompare *path_cmp; - uiStyle *style; + writestruct(wd, USER, UserDef, 1, userdef); - writestruct(wd, USER, UserDef, 1, &U); - - for (btheme = U.themes.first; btheme; btheme = btheme->next) { + for (const bTheme *btheme = userdef->themes.first; btheme; btheme = btheme->next) { writestruct(wd, DATA, bTheme, 1, btheme); } - for (keymap = U.user_keymaps.first; keymap; keymap = keymap->next) { + for (const wmKeyMap *keymap = userdef->user_keymaps.first; keymap; keymap = keymap->next) { writestruct(wd, DATA, wmKeyMap, 1, keymap); - for (kmdi = keymap->diff_items.first; kmdi; kmdi = kmdi->next) { + for (const wmKeyMapDiffItem *kmdi = keymap->diff_items.first; kmdi; kmdi = kmdi->next) { writestruct(wd, DATA, wmKeyMapDiffItem, 1, kmdi); if (kmdi->remove_item) { write_keymapitem(wd, kmdi->remove_item); @@ -1213,23 +1205,23 @@ static void write_userdef(WriteData *wd) } } - for (kmi = keymap->items.first; kmi; kmi = kmi->next) { + for (const wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) { write_keymapitem(wd, kmi); } } - for (bext = U.addons.first; bext; bext = bext->next) { + for (const bAddon *bext = userdef->addons.first; bext; bext = bext->next) { writestruct(wd, DATA, bAddon, 1, bext); if (bext->prop) { IDP_WriteProperty(bext->prop, wd); } } - for (path_cmp = U.autoexec_paths.first; path_cmp; path_cmp = path_cmp->next) { + for (const bPathCompare *path_cmp = userdef->autoexec_paths.first; path_cmp; path_cmp = path_cmp->next) { writestruct(wd, DATA, bPathCompare, 1, path_cmp); } - for (style = U.uistyles.first; style; style = style->next) { + for (const uiStyle *style = userdef->uistyles.first; style; style = style->next) { writestruct(wd, DATA, uiStyle, 1, style); } } @@ -1345,6 +1337,9 @@ static void write_particlesettings(WriteData *wd, ParticleSettings *part) if (part->roughcurve) { write_curvemapping(wd, part->roughcurve); } + if (part->twistcurve) { + write_curvemapping(wd, part->twistcurve); + } for (ParticleDupliWeight *dw = part->dupliweights.first; dw; dw = dw->next) { /* update indices, but only if dw->ob is set (can be NULL after loading e.g.) */ @@ -2912,7 +2907,7 @@ static void write_soops(WriteData *wd, SpaceOops *so) if (ts) { SpaceOops so_flat = *so; - int elems = BLI_mempool_count(ts); + int elems = BLI_mempool_len(ts); /* linearize mempool to array */ TreeStoreElem *data = elems ? BLI_mempool_as_arrayN(ts, "TreeStoreElem") : NULL; @@ -4134,7 +4129,7 @@ static bool write_file_handle( mywrite_flush(wd); if (write_flags & G_FILE_USERPREFS) { - write_userdef(wd); + write_userdef(wd, &U); } /* Write DNA last, because (to be implemented) test for which structs are written. diff --git a/source/blender/blentranslation/msgfmt/msgfmt.c b/source/blender/blentranslation/msgfmt/msgfmt.c index 49f850f200c..a155cce53a5 100644 --- a/source/blender/blentranslation/msgfmt/msgfmt.c +++ b/source/blender/blentranslation/msgfmt/msgfmt.c @@ -186,7 +186,7 @@ typedef struct Offset { /* Return the generated binary output. */ static char *generate(GHash *messages, size_t *r_output_size) { - const uint32_t num_keys = BLI_ghash_size(messages); + const uint32_t num_keys = BLI_ghash_len(messages); /* Get list of sorted keys. */ char **keys = get_keys_sorted(messages, num_keys); diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 36b2f9cadf7..aba0160622f 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -2423,9 +2423,10 @@ static void bmesh_kernel_vert_separate__cleanup(BMesh *bm, LinkNode *edges_separ /* don't visit again */ n_prev->next = n_step->next; } - } while ((void) - (n_prev = n_step), - (n_step = n_step->next)); + else { + n_prev = n_step; + } + } while ((n_step = n_step->next)); } while ((n_orig = n_orig->next) && n_orig->next); } while ((edges_separate = edges_separate->next)); diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c index 96154f051f9..9fe28561b93 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.c +++ b/source/blender/bmesh/intern/bmesh_iterators.c @@ -430,7 +430,7 @@ int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const void bmiter__elem_of_mesh_begin(struct BMIter__elem_of_mesh *iter) { #ifdef USE_IMMUTABLE_ASSERT - ((BMIter *)iter)->count = BLI_mempool_count(iter->pooliter.pool); + ((BMIter *)iter)->count = BLI_mempool_len(iter->pooliter.pool); #endif BLI_mempool_iternew(iter->pooliter.pool, &iter->pooliter); } @@ -438,7 +438,7 @@ void bmiter__elem_of_mesh_begin(struct BMIter__elem_of_mesh *iter) void *bmiter__elem_of_mesh_step(struct BMIter__elem_of_mesh *iter) { #ifdef USE_IMMUTABLE_ASSERT - BLI_assert(((BMIter *)iter)->count <= BLI_mempool_count(iter->pooliter.pool)); + BLI_assert(((BMIter *)iter)->count <= BLI_mempool_len(iter->pooliter.pool)); #endif return BLI_mempool_iterstep(&iter->pooliter); } diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c index 1d16dbc1836..5ae72851c7e 100644 --- a/source/blender/bmesh/intern/bmesh_log.c +++ b/source/blender/bmesh/intern/bmesh_log.c @@ -990,11 +990,11 @@ void BM_log_all_added(BMesh *bm, BMLog *log) BMFace *f; /* avoid unnecessary resizing on initialization */ - if (BLI_ghash_size(log->current_entry->added_verts) == 0) { + if (BLI_ghash_len(log->current_entry->added_verts) == 0) { BLI_ghash_reserve(log->current_entry->added_verts, (uint)bm->totvert); } - if (BLI_ghash_size(log->current_entry->added_faces) == 0) { + if (BLI_ghash_len(log->current_entry->added_faces) == 0) { BLI_ghash_reserve(log->current_entry->added_faces, (uint)bm->totface); } diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 67db51446df..8533083af22 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -1019,7 +1019,8 @@ void BM_loops_calc_normal_vcos( } } -static void UNUSED_FUNCTION(bm_mdisps_space_set)(Object *ob, BMesh *bm, int from, int to) +static void UNUSED_FUNCTION(bm_mdisps_space_set)( + Object *ob, BMesh *bm, int from, int to, eObjectMode object_mode) { /* switch multires data out of tangent space */ if (CustomData_has_layer(&bm->ldata, CD_MDISPS)) { @@ -1030,7 +1031,7 @@ static void UNUSED_FUNCTION(bm_mdisps_space_set)(Object *ob, BMesh *bm, int from BMIter iter; // int i = 0; // UNUSED - multires_set_space(dm, ob, from, to); + multires_set_space(dm, ob, from, to, object_mode); mdisps = CustomData_get_layer(&dm->loopData, CD_MDISPS); diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index 6cc1f37db43..fd32119cb5f 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -708,7 +708,7 @@ void BM_mesh_bm_to_me( } /* patch hook indices and vertex parents */ - if (ototvert > 0) { + if (params->calc_object_remap && (ototvert > 0)) { Object *ob; ModifierData *md; BMVert **vertMap = NULL; @@ -765,11 +765,7 @@ void BM_mesh_bm_to_me( if (vertMap) MEM_freeN(vertMap); } - if (params->calc_tessface) { - BKE_mesh_tessface_calc(me); - } - - BKE_mesh_update_customdata_pointers(me, params->calc_tessface); + BKE_mesh_update_customdata_pointers(me, false); { BMEditSelection *selected; diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.h b/source/blender/bmesh/intern/bmesh_mesh_conv.h index 1974d364171..6e9d62349ea 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.h +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.h @@ -55,7 +55,8 @@ void BM_mesh_bm_from_me( ATTR_NONNULL(1, 3); struct BMeshToMeshParams { - uint calc_tessface : 1; + /** Update object hook indices & vertex parents. */ + uint calc_object_remap : 1; int64_t cd_mask_extra; }; void BM_mesh_bm_to_me( diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 8e0e905cf88..4847ae4be42 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -843,7 +843,6 @@ static BMOpDefine bmo_bmesh_to_mesh_def = { {"mesh", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_MESH}}, /* pointer to an object structure */ {"object", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}}, - {"skip_tessface", BMO_OP_SLOT_BOOL}, /* don't calculate mfaces */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 0f672a9ff2a..f814767a200 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -673,7 +673,7 @@ int BMO_slot_map_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_na { BMOpSlot *slot = BMO_slot_get(slot_args, slot_name); BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING); - return BLI_ghash_size(slot->data.ghash); + return BLI_ghash_len(slot->data.ghash); } /* inserts a key/value mapping into a mapping slot. note that it copies the diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 66fcd739839..bcb940f8b96 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -36,8 +36,8 @@ #include "BLI_alloca.h" #include "BLI_math.h" #include "BLI_memarena.h" -#include "BLI_polyfill2d.h" -#include "BLI_polyfill2d_beautify.h" +#include "BLI_polyfill_2d.h" +#include "BLI_polyfill_2d_beautify.h" #include "BLI_linklist.h" #include "BLI_edgehash.h" #include "BLI_heap.h" @@ -1426,6 +1426,17 @@ void BM_mesh_calc_tessellation(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptri (l_ptr_a[2] = l_ptr_b[1] = l = l->next); ( l_ptr_b[2] = l->next); #endif + + if (UNLIKELY(is_quad_flip_v3_first_third_fast( + l_ptr_a[0]->v->co, + l_ptr_a[1]->v->co, + l_ptr_a[2]->v->co, + l_ptr_b[2]->v->co))) + { + /* flip out of degenerate 0-2 state. */ + l_ptr_a[2] = l_ptr_b[2]; + l_ptr_b[0] = l_ptr_a[1]; + } } #endif /* USE_TESSFACE_SPEEDUP */ diff --git a/source/blender/bmesh/operators/bmo_connect_concave.c b/source/blender/bmesh/operators/bmo_connect_concave.c index 80774323d31..d1811ac6a83 100644 --- a/source/blender/bmesh/operators/bmo_connect_concave.c +++ b/source/blender/bmesh/operators/bmo_connect_concave.c @@ -39,8 +39,8 @@ #include "BLI_alloca.h" #include "BLI_memarena.h" #include "BLI_heap.h" -#include "BLI_polyfill2d.h" -#include "BLI_polyfill2d_beautify.h" +#include "BLI_polyfill_2d.h" +#include "BLI_polyfill_2d_beautify.h" #include "BLI_linklist.h" #include "bmesh.h" diff --git a/source/blender/bmesh/operators/bmo_connect_pair.c b/source/blender/bmesh/operators/bmo_connect_pair.c index 60fd9808fcb..b9e5cd927c3 100644 --- a/source/blender/bmesh/operators/bmo_connect_pair.c +++ b/source/blender/bmesh/operators/bmo_connect_pair.c @@ -662,11 +662,11 @@ void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op) while (!BLI_heap_is_empty(pc.states)) { #ifdef DEBUG_PRINT - printf("\n%s: stepping %u\n", __func__, BLI_heap_size(pc.states)); + printf("\n%s: stepping %u\n", __func__, BLI_heap_len(pc.states)); #endif while (!BLI_heap_is_empty(pc.states)) { - PathLinkState *state = BLI_heap_popmin(pc.states); + PathLinkState *state = BLI_heap_pop_min(pc.states); /* either we insert this into 'pc.states' or its freed */ bool continue_search; diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c index 2df8e73c2b8..5a2f07be70a 100644 --- a/source/blender/bmesh/operators/bmo_dissolve.c +++ b/source/blender/bmesh/operators/bmo_dissolve.c @@ -166,7 +166,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op) continue; } - BLI_array_empty(faces); + BLI_array_clear(faces); faces = NULL; /* forces different allocatio */ BMW_init(®walker, bm, BMW_ISLAND_MANIFOLD, diff --git a/source/blender/bmesh/operators/bmo_edgenet.c b/source/blender/bmesh/operators/bmo_edgenet.c index 64b092da5c8..744ef866128 100644 --- a/source/blender/bmesh/operators/bmo_edgenet.c +++ b/source/blender/bmesh/operators/bmo_edgenet.c @@ -186,7 +186,7 @@ void bmo_edgenet_prepare_exec(BMesh *bm, BMOperator *op) BLI_array_count_set(edges2, BLI_array_count(edges)); } - BLI_array_empty(edges); + BLI_array_clear(edges); count++; } diff --git a/source/blender/bmesh/operators/bmo_hull.c b/source/blender/bmesh/operators/bmo_hull.c index 81ec2860cf7..d52cb00e172 100644 --- a/source/blender/bmesh/operators/bmo_hull.c +++ b/source/blender/bmesh/operators/bmo_hull.c @@ -521,7 +521,7 @@ static void hull_from_bullet( int j; /* Get face vertex indices */ - BLI_array_empty(fvi); + BLI_array_clear(fvi); BLI_array_grow_items(fvi, len); plConvexHullGetFaceVertices(hull, i, fvi); diff --git a/source/blender/bmesh/operators/bmo_mesh_conv.c b/source/blender/bmesh/operators/bmo_mesh_conv.c index 0eb9bf90ca8..7311ed5ce64 100644 --- a/source/blender/bmesh/operators/bmo_mesh_conv.c +++ b/source/blender/bmesh/operators/bmo_mesh_conv.c @@ -62,15 +62,18 @@ void bmo_object_load_bmesh_exec(BMesh *bm, BMOperator *op) Mesh *me = ob->data; BMO_op_callf(bm, op->flag, - "bmesh_to_mesh mesh=%p object=%p skip_tessface=%b", - me, ob, true); + "bmesh_to_mesh mesh=%p object=%p", + me, ob); } void bmo_bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { Mesh *me = BMO_slot_ptr_get(op->slots_in, "mesh"); /* Object *ob = BMO_slot_ptr_get(op, "object"); */ - const bool dotess = !BMO_slot_bool_get(op->slots_in, "skip_tessface"); - BM_mesh_bm_to_me(bm, me, (&(struct BMeshToMeshParams){ .calc_tessface = dotess, })); + BM_mesh_bm_to_me( + bm, me, + (&(struct BMeshToMeshParams){ + .calc_object_remap = true, + })); } diff --git a/source/blender/bmesh/operators/bmo_rotate_edges.c b/source/blender/bmesh/operators/bmo_rotate_edges.c index 9832fdb57d3..75e31c68dae 100644 --- a/source/blender/bmesh/operators/bmo_rotate_edges.c +++ b/source/blender/bmesh/operators/bmo_rotate_edges.c @@ -180,7 +180,7 @@ static void bm_rotate_edges_shared( const int edges_len_rotate_prev = edges_len_rotate; while (!BLI_heap_is_empty(heap)) { - BMEdge *e_best = BLI_heap_popmin(heap); + BMEdge *e_best = BLI_heap_pop_min(heap); eheap_table[BM_elem_index_get(e_best)] = NULL; /* No problem if this fails, re-evaluate if faces connected to this edge are touched. */ diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index 894129b4a33..7d3419b5910 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -1011,8 +1011,8 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) /* figure out which pattern to use */ - BLI_array_empty(edges); - BLI_array_empty(verts); + BLI_array_clear(edges); + BLI_array_clear(verts); BLI_array_grow_items(edges, face->len); BLI_array_grow_items(verts, face->len); @@ -1140,7 +1140,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) face = fd->face; /* figure out which pattern to use */ - BLI_array_empty(verts); + BLI_array_clear(verts); pat = fd->pat; @@ -1148,8 +1148,8 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) int vlen; /* ok, no pattern. we still may be able to do something */ - BLI_array_empty(loops); - BLI_array_empty(loops_split); + BLI_array_clear(loops); + BLI_array_clear(loops_split); /* for case of two edges, connecting them shouldn't be too hard */ BLI_array_grow_items(loops, face->len); diff --git a/source/blender/bmesh/operators/bmo_subdivide_edgering.c b/source/blender/bmesh/operators/bmo_subdivide_edgering.c index adcc0c71629..e6881f6d8b1 100644 --- a/source/blender/bmesh/operators/bmo_subdivide_edgering.c +++ b/source/blender/bmesh/operators/bmo_subdivide_edgering.c @@ -269,7 +269,7 @@ static GSet *bm_edgering_pair_calc(BMesh *bm, ListBase *eloops_rim) BLI_ghash_free(vert_eloop_gh, NULL, NULL); - if (BLI_gset_size(eloop_pair_gs) == 0) { + if (BLI_gset_len(eloop_pair_gs) == 0) { BLI_gset_free(eloop_pair_gs, NULL); eloop_pair_gs = NULL; } @@ -1193,7 +1193,7 @@ void bmo_subdivide_edgering_exec(BMesh *bm, BMOperator *op) goto cleanup; } - lpair_arr = BLI_array_alloca(lpair_arr, BLI_gset_size(eloop_pairs_gs)); + lpair_arr = BLI_array_alloca(lpair_arr, BLI_gset_len(eloop_pairs_gs)); /* first cache pairs */ GSET_ITER_INDEX (gs_iter, eloop_pairs_gs, i) { diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c index 4e8bace59e0..2cdc2646649 100644 --- a/source/blender/bmesh/operators/bmo_triangulate.c +++ b/source/blender/bmesh/operators/bmo_triangulate.c @@ -106,7 +106,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op) /* sf_edge = */ BLI_scanfill_edge_add(&sf_ctx, UNPACK2(sf_verts)); /* sf_edge->tmp.p = e; */ /* UNUSED */ } - nors_tot = BLI_ghash_size(sf_vert_map); + nors_tot = BLI_ghash_len(sf_vert_map); BLI_ghash_free(sf_vert_map, NULL, NULL); diff --git a/source/blender/bmesh/tools/bmesh_beautify.c b/source/blender/bmesh/tools/bmesh_beautify.c index 6e6242fc9f9..d3972363bb4 100644 --- a/source/blender/bmesh/tools/bmesh_beautify.c +++ b/source/blender/bmesh/tools/bmesh_beautify.c @@ -37,7 +37,7 @@ #include "BLI_math.h" #include "BLI_heap.h" -#include "BLI_polyfill2d_beautify.h" +#include "BLI_polyfill_2d_beautify.h" #include "MEM_guardedalloc.h" @@ -392,7 +392,7 @@ void BM_mesh_beautify_fill( bm->elem_index_dirty |= BM_EDGE; while (BLI_heap_is_empty(eheap) == false) { - BMEdge *e = BLI_heap_popmin(eheap); + BMEdge *e = BLI_heap_pop_min(eheap); i = BM_elem_index_get(e); eheap_table[i] = NULL; diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 35167835646..beee9065ece 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -1879,7 +1879,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct) } } -#if 0 +#ifdef DEBUG_ADJUST static void print_adjust_stats(BoundVert *vstart) { BoundVert *v; @@ -1921,21 +1921,25 @@ static void print_adjust_stats(BoundVert *vstart) if (v->adjchain != NULL) { eright = v->efirst; eleft = v->adjchain->elast; - delta = fabs(eright->offset_r - eright->offset_r_spec); + delta = eright->offset_r - eright->offset_r_spec; delta_pct = 100.0 * delta / eright->offset_r_spec; - printf("e%d r(%f) vs r spec(%f): abs(delta)=%f, delta_pct=%f\n", + printf("e%d r(%f) vs r spec(%f): delta=%f, delta_pct=%f\n", BM_elem_index_get(eright->e), eright->offset_r, eright->offset_r_spec, delta, delta_pct); spec_residual2 += delta * delta; + delta = fabs(delta); + delta_pct = fabs(delta_pct); if (delta > max_spec_r) max_spec_r = delta; if (delta_pct > max_spec_r_pct) max_spec_r_pct = delta_pct; - delta = fabs(eleft->offset_l - eleft->offset_l_spec); + delta = eleft->offset_l - eleft->offset_l_spec; delta_pct = 100.0 * delta / eright->offset_l_spec; - printf("e%d l(%f) vs l spec(%f): abs(delta)=%f, delta_pct=%f\n", + printf("e%d l(%f) vs l spec(%f): delta=%f, delta_pct=%f\n", BM_elem_index_get(eright->e), eleft->offset_l, eleft->offset_l_spec, delta, delta_pct); spec_residual2 += delta * delta; + delta = fabs(delta); + delta_pct = fabs(delta_pct); if (delta > max_spec_r) max_spec_r = delta; if (delta_pct > max_spec_r_pct) @@ -1951,6 +1955,15 @@ static void print_adjust_stats(BoundVert *vstart) } #endif +#ifdef FAST_ADJUST_CODE +/* This code uses a direct solution to the adjustment problem for chains and certain cycles. + * It is a two-step approach: first solve for the exact solution of the 'match widths' constraints + * using the one degree of freedom that allows for expressing all other widths in terms of that. + * And then minimize the spec-matching constraints using the derivative of the least squares + * residual in terms of that one degree of freedom. + * Unfortunately, the results are in some cases worse than the general least squares solution + * for the combined (with weights) problem, so this code is not used. + * But keep it here for a while in case peformance issues demand that it be used sometimes. */ static bool adjust_the_cycle_or_chain_fast(BoundVert *vstart, int np, bool iscycle) { BoundVert *v; @@ -1985,6 +1998,7 @@ static bool adjust_the_cycle_or_chain_fast(BoundVert *vstart, int np, bool iscyc g_prod[i] = gprod; gprod_sum += gprod; } + g_prod[0] = 1.0f; if (iscycle) { gprod *= g[0]; if (fabs(gprod - 1.0f) > BEVEL_EPSILON) { @@ -1993,8 +2007,6 @@ static bool adjust_the_cycle_or_chain_fast(BoundVert *vstart, int np, bool iscyc MEM_freeN(g_prod); return false; } - else - g_prod[0] = 1.0f; } if (gprod_sum == 0.0f) { MEM_freeN(g); @@ -2028,6 +2040,7 @@ static bool adjust_the_cycle_or_chain_fast(BoundVert *vstart, int np, bool iscyc MEM_freeN(g_prod); return true; } +#endif /* Adjust the offsets for a single cycle or chain. * For chains and some cycles, a fast solution exists. @@ -2039,22 +2052,35 @@ static bool adjust_the_cycle_or_chain_fast(BoundVert *vstart, int np, bool iscyc static void adjust_the_cycle_or_chain(BoundVert *vstart, bool iscycle) { BoundVert *v; - EdgeHalf *eleft, *eright; + EdgeHalf *eleft, *eright, *enextleft; LinearSolver *solver; double weight, val; int i, np, nrows, row; np = 0; +#ifdef DEBUG_ADJUST + printf("\nadjust the %s (with eigen)\n", iscycle ? "cycle" : "chain"); +#endif v = vstart; do { +#ifdef DEBUG_ADJUST + eleft = v->elast; + eright = v->efirst; + printf(" (left=e%d, right=e%d)", BM_elem_index_get(eleft->e), BM_elem_index_get(eright->e)); +#endif np++; v = v->adjchain; } while (v && v != vstart); +#ifdef DEBUG_ADJUST + printf(" -> %d parms\n", np); +#endif +#ifdef FAST_ADJUST_CODE if (adjust_the_cycle_or_chain_fast(vstart, np, iscycle)) return; +#endif - nrows = iscycle ? 2 * np : 2 * np - 1; + nrows = iscycle ? 3 * np : 3 * np - 3; solver = EIG_linear_least_squares_solver_new(nrows, np, 1); @@ -2063,9 +2089,15 @@ static void adjust_the_cycle_or_chain(BoundVert *vstart, bool iscycle) weight = BEVEL_MATCH_SPEC_WEIGHT; /* sqrt of factor to weight down importance of spec match */ do { /* except at end of chain, v's indep variable is offset_r of v->efirst */ - if (iscycle || v->adjchain != NULL) { + if (iscycle || i < np - 1) { eright = v->efirst; eleft = v->elast; + enextleft = v->adjchain->elast; +#ifdef DEBUG_ADJUST + printf("p%d: e%d->offset_r = %f\n", i, BM_elem_index_get(eright->e), eright->offset_r); + if (iscycle || v != vstart) + printf(" dependent: e%d->offset_l = %f * p%d\n", BM_elem_index_get(eleft->e), v->sinratio, i); +#endif /* residue i: width difference between eright and eleft of next */ EIG_linear_solver_matrix_add(solver, i, i, 1.0); @@ -2074,53 +2106,87 @@ static void adjust_the_cycle_or_chain(BoundVert *vstart, bool iscycle) EIG_linear_solver_matrix_add(solver, i > 0 ? i - 1 : np - 1, i, -v->sinratio); } else { - if (i > 0) + if (i > 0) { EIG_linear_solver_matrix_add(solver, i - 1, i, -v->sinratio); + } } - /* residue np + i (if cycle) else np - 1 + i: + /* residue np + 2*i (if cycle) else np - 1 + 2*i: * right offset for parm i matches its spec; weighted */ - row = iscycle ? np + i : np - 1 + i; + row = iscycle ? np + 2 * i : np - 1 + 2 * i; EIG_linear_solver_matrix_add(solver, row, i, weight); EIG_linear_solver_right_hand_side_add(solver, 0, row, weight * eright->offset_r); +#ifdef DEBUG_ADJUST + printf("b[%d]=%f * %f, for e%d->offset_r\n", row, weight, eright->offset_r, BM_elem_index_get(eright->e)); +#endif + + /* residue np + 2*i + 1 (if cycle) else np - 1 + 2*i + 1: + * left offset for parm i matches its spec; weighted */ + row = row + 1; + EIG_linear_solver_matrix_add(solver, row, (i == np - 1) ? 0 : i + 1, weight * v->adjchain->sinratio); + EIG_linear_solver_right_hand_side_add(solver, 0, row, weight * enextleft->offset_l); +#ifdef DEBUG_ADJUST + printf("b[%d]=%f * %f, for e%d->offset_l\n", row, weight, enextleft->offset_l, + BM_elem_index_get(enextleft->e)); +#endif } else { /* not a cycle, and last of chain */ eleft = v->elast; +#ifdef DEBUG_ADJUST + printf("p%d: e%d->offset_l = %f\n", i, BM_elem_index_get(eleft->e), eleft->offset_l); +#endif /* second part of residue i for last i */ EIG_linear_solver_matrix_add(solver, i - 1, i, -1.0); - /* residue 2 * np -2 : last spec match residue is for left offset of final parm */ - row = 2 * np - 2; - EIG_linear_solver_matrix_add(solver, row, i, weight); - EIG_linear_solver_right_hand_side_add(solver, 0, row, weight * eleft->offset_l); } i++; v = v->adjchain; } while (v && v != vstart); EIG_linear_solver_solve(solver); +#ifdef DEBUG_ADJUST + /* Note: this print only works after solve, but by that time b has been cleared */ + EIG_linear_solver_print_matrix(solver); + printf("\nSolution:\n"); + for (i = 0; i < np; i++) + printf("p%d = %f\n", i, EIG_linear_solver_variable_get(solver, 0, i)); +#endif /* Use the solution to set new widths */ v = vstart; i = 0; do { val = EIG_linear_solver_variable_get(solver, 0, i); - if (iscycle || v->adjchain != NULL) { + if (iscycle || i < np - 1) { eright = v->efirst; eleft = v->elast; eright->offset_r = (float)val; +#ifdef DEBUG_ADJUST + printf("e%d->offset_r = %f\n", BM_elem_index_get(eright->e), eright->offset_r); +#endif if (iscycle || v != vstart) { eleft->offset_l = (float)(v->sinratio * val); +#ifdef DEBUG_ADJUST + printf("e%d->offset_l = %f\n", BM_elem_index_get(eleft->e), eleft->offset_l); +#endif } } else { /* not a cycle, and last of chain */ eleft = v->elast; eleft->offset_l = (float)val; +#ifdef DEBUG_ADJUST + printf("e%d->offset_l = %f\n", BM_elem_index_get(eleft->e), eleft->offset_l); +#endif } i++; v = v->adjchain; } while (v && v != vstart); +#ifdef DEBUG_ADJUST + print_adjust_stats(vstart); + EIG_linear_solver_print_matrix(solver); +#endif + EIG_linear_solver_delete(solver); } @@ -2163,7 +2229,7 @@ static void adjust_offsets(BevelParams *bp) /* first follow paired edges in left->right direction */ v = vchainstart = vanchor; iscycle = false; - while(v->eon && !v->visited && !iscycle) { + while (v->eon && !v->visited && !iscycle) { enext = find_other_end_edge_half(bp, v->efirst, &bvcur); BLI_assert(enext != NULL); vnext = enext->leftv; @@ -2171,7 +2237,6 @@ static void adjust_offsets(BevelParams *bp) v->visited = true; if (vnext->visited) { if (vnext != vchainstart) { - printf("WHOOPS, adjusting offsets, expected cycle!\n"); break; } adjust_the_cycle_or_chain(vchainstart, true); @@ -2191,7 +2256,7 @@ static void adjust_offsets(BevelParams *bp) vchainstart = vnext; v->visited = true; v = vnext; - } while(!v->visited && v->eon); + } while (!v->visited && v->eon); adjust_the_cycle_or_chain(vchainstart, false); } } while ((vanchor = vanchor->next) != bv->vmesh->boundstart); @@ -3188,6 +3253,173 @@ static void build_square_in_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv, VMesh } } +/* copy whichever of a and b is closer to v into r */ +static void closer_v3_v3v3v3(float r[3], float a[3], float b[3], float v[3]) +{ + if (len_squared_v3v3(a, v) <= len_squared_v3v3(b, v)) + copy_v3_v3(r, a); + else + copy_v3_v3(r, b); +} + +/* Special case of VMesh when profile == 1 and there are 3 or more beveled edges. + * We want the effect of parallel offset lines (n/2 of them) on each side of the center, for even n. + * Wherever they intersect with each other between two successive beveled edges, those intersections + * are part of the vmesh rings. + * We have to move the boundary edges too -- the usual method is to make one profile plane between + * successive BoundVerts, but for the effect we want here, there will be two planes, one on each side + * of the original edge. + */ +static VMesh *square_out_adj_vmesh(BevelParams *bp, BevVert *bv) +{ + int n, ns, ns2, odd, i, j, k, ikind, im1, clstride; + float bndco[3], dir1[3], dir2[3], co1[3], co2[3], meet1[3], meet2[3], v1co[3], v2co[3]; + float *on_edge_cur, *on_edge_prev, *p; + float ns2inv, finalfrac, ang; + BoundVert *bndv; + EdgeHalf *e1, *e2; + VMesh *vm; + float *centerline; + + n = bv->vmesh->count; + ns = bv->vmesh->seg; + ns2 = ns / 2; + odd = ns % 2; + ns2inv = 1.0f / (float) ns2; + vm = new_adj_vmesh(bp->mem_arena, n, ns, bv->vmesh->boundstart); + clstride = 3 * (ns2 + 1); + centerline = MEM_mallocN(clstride * n * sizeof(float), "bevel"); + + /* find on_edge, place on bndv[i]'s elast where offset line would meet, + * averaging with position where next sector's offset line would meet */ + bndv = vm->boundstart; + for (i = 0; i < n; i++) { + copy_v3_v3(bndco, bndv->nv.co); + e1 = bndv->efirst; + e2 = bndv->elast; + sub_v3_v3v3(dir1, e1->e->v1->co, e1->e->v2->co); + sub_v3_v3v3(dir2, e2->e->v1->co, e2->e->v2->co); + add_v3_v3v3(co1, bndco, dir1); + add_v3_v3v3(co2, bndco, dir2); + /* intersect e1 with line through bndv parallel to e2 to get v1co */ + ikind = isect_line_line_v3(e1->e->v1->co, e1->e->v2->co, bndco, co2, meet1, meet2); + + if (ikind == 0) { + /* Placeholder: this should get eliminated by min dist test with adjacent edge */ + mid_v3_v3v3(v1co, e1->e->v1->co, e1->e->v2->co); + } + else { + /* if the lines are skew (ikind == 2), want meet1 which is on e1 */ + copy_v3_v3(v1co, meet1); + } + /* intersect e2 with line through bndv parallel to e1 to get v2co */ + ikind = isect_line_line_v3(e2->e->v1->co, e2->e->v2->co, bndco, co1, meet1, meet2); + if (ikind == 0) { + mid_v3_v3v3(v2co, e2->e->v1->co, e2->e->v2->co); + } + else { + copy_v3_v3(v2co, meet1); + } + + /* want on_edge[i] to be min dist to bv->v of v2co and the v1co of next iteration */ + on_edge_cur = centerline + clstride * i; + on_edge_prev = centerline + clstride * ((i == 0) ? n - 1 : i - 1); + if (i == 0) { + copy_v3_v3(on_edge_cur, v2co); + copy_v3_v3(on_edge_prev, v1co); + } + else if (i == n - 1) { + closer_v3_v3v3v3(on_edge_cur, on_edge_cur, v2co, bv->v->co); + closer_v3_v3v3v3(on_edge_prev, on_edge_prev, v1co, bv->v->co); + } + else { + copy_v3_v3(on_edge_cur, v2co); + closer_v3_v3v3v3(on_edge_prev, on_edge_prev, v1co, bv->v->co); + } + bndv = bndv->next; + } + + /* fill in rest of centerlines by interpolation */ + copy_v3_v3(co2, bv->v->co); + bndv = vm->boundstart; + for (i = 0; i < n; i++) { + if (odd) { + ang = 0.5f * angle_v3v3v3(bndv->nv.co, co1, bndv->next->nv.co); + if (ang > BEVEL_SMALL_ANG) { + /* finalfrac is length along arms of isoceles triangle with top angle 2*ang + * such that the base of the triangle is 1. + * This is used in interpolation along centerline in odd case. + * To avoid too big a drop from bv, cap finalfrac a 0.8 arbitrarily */ + finalfrac = 0.5f / sin(ang); + if (finalfrac > 0.8f) + finalfrac = 0.8f; + } + else { + finalfrac = 0.8f; + } + ns2inv = 1.0f / (ns2 + finalfrac); + } + + p = centerline + clstride * i; + copy_v3_v3(co1, p); + p += 3; + for (j = 1; j <= ns2; j++) { + interp_v3_v3v3(p, co1, co2, j * ns2inv); + p += 3; + } + bndv = bndv->next; + } + + /* coords of edges and mid or near-mid line */ + bndv = vm->boundstart; + for (i = 0; i < n; i++) { + copy_v3_v3(co1, bndv->nv.co); + copy_v3_v3(co2, centerline + clstride * (i == 0 ? n - 1 : i - 1)); + for (j = 0; j < ns2 + odd; j++) { + interp_v3_v3v3(mesh_vert(vm, i, j, 0)->co, co1, co2, j * ns2inv); + } + copy_v3_v3(co2, centerline + clstride * i); + for (k = 1; k <= ns2; k++) { + interp_v3_v3v3(mesh_vert(vm, i, 0, k)->co, co1, co2, k * ns2inv); + } + bndv = bndv->next; + } + if (!odd) + copy_v3_v3(mesh_vert(vm, 0, ns2, ns2)->co, bv->v->co); + vmesh_copy_equiv_verts(vm); + + /* fill in interior points by interpolation from edges to centerlines */ + bndv = vm->boundstart; + for (i = 0; i < n; i++) { + im1 = (i == 0) ? n - 1 : i - 1; + for (j = 1; j < ns2 + odd; j++) { + for (k = 1; k <= ns2; k++) { + ikind = isect_line_line_v3( + mesh_vert(vm, i, 0, k)->co, centerline + clstride * im1 + 3 * k, + mesh_vert(vm, i, j, 0)->co, centerline + clstride * i + 3 * j, + meet1, meet2); + if (ikind == 0) { + /* how can this happen? fall back on interpolation in one direction if it does */ + interp_v3_v3v3(mesh_vert(vm, i, j, k)->co, + mesh_vert(vm, i, 0, k)->co, centerline + clstride * im1 + 3 * k, j * ns2inv); + } + else if (ikind == 1) { + copy_v3_v3(mesh_vert(vm, i, j, k)->co, meet1); + } + else { + mid_v3_v3v3(mesh_vert(vm, i, j, k)->co, meet1, meet2); + } + } + } + bndv = bndv->next; + } + + vmesh_copy_equiv_verts(vm); + + MEM_freeN(centerline); + return vm; +} + /* * Given that the boundary is built and the boundary BMVerts have been made, * calculate the positions of the interior mesh points for the M_ADJ pattern, @@ -3210,9 +3442,13 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv) odd = ns % 2; BLI_assert(n >= 3 && ns > 1); + vpipe = pipe_test(bv); - if (vpipe) { + if (bp->pro_super_r == PRO_SQUARE_R && bv->selcount >= 3 && !odd) { + vm1 = square_out_adj_vmesh(bp, bv); + } + else if (vpipe) { vm1 = pipe_adj_vmesh(bp, bv, vpipe); } else if (tri_corner_test(bp, bv)) { @@ -3737,7 +3973,7 @@ static int bevel_edge_order_extend(BMesh *bm, BevVert *bv, int i) tryj = bevel_edge_order_extend(bm, bv, j + 1); if (tryj > bestj || (tryj == bestj && edges_face_connected_at_vert(bv->edges[tryj].e, bv->edges[0].e))) { bestj = tryj; - BLI_array_empty(save_path); + BLI_array_clear(save_path); for (k = j + 1; k <= bestj; k++) { BLI_array_append(save_path, bv->edges[k].e); } diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c index 0a1271c2aa9..c1b2bc2625b 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c +++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c @@ -38,8 +38,8 @@ #include "BLI_alloca.h" #include "BLI_memarena.h" #include "BLI_edgehash.h" -#include "BLI_polyfill2d.h" -#include "BLI_polyfill2d_beautify.h" +#include "BLI_polyfill_2d.h" +#include "BLI_polyfill_2d_beautify.h" #include "BLI_utildefines_stack.h" @@ -1357,7 +1357,7 @@ void BM_mesh_decimate_collapse( (BLI_heap_node_value(BLI_heap_top(eheap)) != COST_INVALID)) { // const float value = BLI_heap_node_value(BLI_heap_top(eheap)); - BMEdge *e = BLI_heap_popmin(eheap); + BMEdge *e = BLI_heap_pop_min(eheap); float optimize_co[3]; BLI_assert(BM_elem_index_get(e) < tot_edge_orig); /* handy to detect corruptions elsewhere */ @@ -1388,7 +1388,7 @@ void BM_mesh_decimate_collapse( * - edges sharing a vertex are ignored, so the pivot vertex isnt moved to one side. */ - BMEdge *e = BLI_heap_popmin(eheap); + BMEdge *e = BLI_heap_pop_min(eheap); const int e_index = BM_elem_index_get(e); const int e_index_mirr = edge_symmetry_map[e_index]; BMEdge *e_mirr = NULL; diff --git a/source/blender/bmesh/tools/bmesh_edgenet.c b/source/blender/bmesh/tools/bmesh_edgenet.c index 193a032b46e..df9d07036af 100644 --- a/source/blender/bmesh/tools/bmesh_edgenet.c +++ b/source/blender/bmesh/tools/bmesh_edgenet.c @@ -335,7 +335,7 @@ static LinkNode *bm_edgenet_path_calc( BLI_linklist_free_pool(v_ls_next, NULL, path_pool); BLI_linklist_free_pool(v_ls_prev, NULL, path_pool); - // BLI_assert(BLI_mempool_count(path_pool) == 0); + // BLI_assert(BLI_mempool_len(path_pool) == 0); path_len = bm_edgenet_path_from_pass(e_found->v1, &path, vnet_info, path_pool); BLI_linklist_reverse(&path); @@ -505,7 +505,7 @@ void BM_mesh_edgenet( } BLI_linklist_free_pool(path, NULL, path_pool); - BLI_assert(BLI_mempool_count(path_pool) == 0); + BLI_assert(BLI_mempool_len(path_pool) == 0); } bm->elem_index_dirty |= BM_FACE | BM_LOOP; diff --git a/source/blender/bmesh/tools/bmesh_intersect.c b/source/blender/bmesh/tools/bmesh_intersect.c index 82545a5e011..cc8511c65f1 100644 --- a/source/blender/bmesh/tools/bmesh_intersect.c +++ b/source/blender/bmesh/tools/bmesh_intersect.c @@ -1265,8 +1265,8 @@ bool BM_mesh_intersect( } } - splice_ls = MEM_mallocN(BLI_gset_size(s.wire_edges) * sizeof(*splice_ls), __func__); - STACK_INIT(splice_ls, BLI_gset_size(s.wire_edges)); + splice_ls = MEM_mallocN(BLI_gset_len(s.wire_edges) * sizeof(*splice_ls), __func__); + STACK_INIT(splice_ls, BLI_gset_len(s.wire_edges)); for (node = s.vert_dissolve; node; node = node->next) { BMEdge *e_pair[2]; @@ -1669,7 +1669,7 @@ bool BM_mesh_intersect( } } - has_edit_isect = (BLI_ghash_size(s.face_edges) != 0); + has_edit_isect = (BLI_ghash_len(s.face_edges) != 0); /* cleanup */ BLI_ghash_free(s.edgetri_cache, NULL, NULL); diff --git a/source/blender/bmesh/tools/bmesh_path.c b/source/blender/bmesh/tools/bmesh_path.c index 85c591b6684..cc5ac6dd8ce 100644 --- a/source/blender/bmesh/tools/bmesh_path.c +++ b/source/blender/bmesh/tools/bmesh_path.c @@ -174,7 +174,7 @@ LinkNode *BM_mesh_calc_path_vert( cost[BM_elem_index_get(v_src)] = 0.0f; while (!BLI_heap_is_empty(heap)) { - v = BLI_heap_popmin(heap); + v = BLI_heap_pop_min(heap); if (v == v_dst) break; @@ -346,7 +346,7 @@ LinkNode *BM_mesh_calc_path_edge( cost[BM_elem_index_get(e_src)] = 0.0f; while (!BLI_heap_is_empty(heap)) { - e = BLI_heap_popmin(heap); + e = BLI_heap_pop_min(heap); if (e == e_dst) break; @@ -532,7 +532,7 @@ LinkNode *BM_mesh_calc_path_face( cost[BM_elem_index_get(f_src)] = 0.0f; while (!BLI_heap_is_empty(heap)) { - f = BLI_heap_popmin(heap); + f = BLI_heap_pop_min(heap); if (f == f_dst) break; diff --git a/source/blender/bmesh/tools/bmesh_region_match.c b/source/blender/bmesh/tools/bmesh_region_match.c index 2abf8f2c46e..e83ba73ad01 100644 --- a/source/blender/bmesh/tools/bmesh_region_match.c +++ b/source/blender/bmesh/tools/bmesh_region_match.c @@ -421,8 +421,8 @@ static void bm_uuidwalk_rehash( UUID_Int *uuid_store; uint i; - uint rehash_store_len_new = MAX2(BLI_ghash_size(uuidwalk->verts_uuid), - BLI_ghash_size(uuidwalk->faces_uuid)); + uint rehash_store_len_new = MAX2(BLI_ghash_len(uuidwalk->verts_uuid), + BLI_ghash_len(uuidwalk->faces_uuid)); bm_uuidwalk_rehash_reserve(uuidwalk, rehash_store_len_new); uuid_store = uuidwalk->cache.rehash_store; @@ -520,8 +520,8 @@ static void bm_uuidwalk_pass_add( verts_uuid_pass = uuidwalk->cache.verts_uuid; faces_step_next = uuidwalk->cache.faces_step; - BLI_assert(BLI_ghash_size(verts_uuid_pass) == 0); - BLI_assert(BLI_gset_size(faces_step_next) == 0); + BLI_assert(BLI_ghash_len(verts_uuid_pass) == 0); + BLI_assert(BLI_gset_len(faces_step_next) == 0); /* Add the face_step data from connected faces, creating new passes */ fstep = BLI_mempool_alloc(uuidwalk->step_pool); @@ -659,7 +659,7 @@ static bool bm_uuidwalk_facestep_begin( LinkNode *f_link, *f_link_next, **f_link_prev_p; bool ok = false; - BLI_assert(BLI_ghash_size(uuidwalk->cache.faces_from_uuid) == 0); + BLI_assert(BLI_ghash_len(uuidwalk->cache.faces_from_uuid) == 0); BLI_assert(BLI_listbase_is_empty(&fstep->items)); f_link_prev_p = &fstep->faces; @@ -864,7 +864,7 @@ static BMFace **bm_mesh_region_match_pair( break; } - found = (BLI_ghash_size(w_dst->faces_uuid) == faces_src_region_len); + found = (BLI_ghash_len(w_dst->faces_uuid) == faces_src_region_len); if (found) { break; } @@ -877,7 +877,7 @@ static BMFace **bm_mesh_region_match_pair( if (found) { GHashIterator gh_iter; - const uint faces_result_len = BLI_ghash_size(w_dst->faces_uuid); + const uint faces_result_len = BLI_ghash_len(w_dst->faces_uuid); uint i; faces_result = MEM_mallocN(sizeof(*faces_result) * (faces_result_len + 1), __func__); diff --git a/source/blender/bmesh/tools/bmesh_separate.c b/source/blender/bmesh/tools/bmesh_separate.c index 287b4125330..b3d0c339885 100644 --- a/source/blender/bmesh/tools/bmesh_separate.c +++ b/source/blender/bmesh/tools/bmesh_separate.c @@ -122,7 +122,7 @@ void BM_mesh_separate_faces( /* Perform the split */ BM_face_loop_separate_multi(bm, loop_split.data, loop_split.count); - BLI_buffer_empty(&loop_split); + BLI_buffer_clear(&loop_split); } } while ((l_iter = l_iter->next) != l_first); } diff --git a/source/blender/bmesh/tools/bmesh_triangulate.c b/source/blender/bmesh/tools/bmesh_triangulate.c index bd201fa89bf..a3a3355d20f 100644 --- a/source/blender/bmesh/tools/bmesh_triangulate.c +++ b/source/blender/bmesh/tools/bmesh_triangulate.c @@ -38,8 +38,8 @@ #include "BLI_linklist.h" /* only for defines */ -#include "BLI_polyfill2d.h" -#include "BLI_polyfill2d_beautify.h" +#include "BLI_polyfill_2d.h" +#include "BLI_polyfill_2d_beautify.h" #include "bmesh.h" diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp index 6e59a404e47..cc772535e37 100644 --- a/source/blender/collada/AnimationExporter.cpp +++ b/source/blender/collada/AnimationExporter.cpp @@ -178,7 +178,7 @@ void AnimationExporter::export_morph_animation(Object *ob) void AnimationExporter::make_anim_frames_from_targets(Object *ob, std::vector<float> &frames ) { - ListBase *conlist = get_active_constraints(ob); + ListBase *conlist = get_active_constraints(this->eval_ctx, ob); if (conlist == NULL) return; bConstraint *con; for (con = (bConstraint *)conlist->first; con; con = con->next) { @@ -989,6 +989,9 @@ std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Obj double outmat[4][4]; converter.mat4_to_dae_double(outmat, mat); + if (this->export_settings->limit_precision) + bc_sanitize_mat(outmat, 6); + source.appendValues(outmat); j++; @@ -1539,7 +1542,7 @@ bool AnimationExporter::validateConstraints(bConstraint *con) void AnimationExporter::calc_ob_mat_at_time(Object *ob, float ctime , float mat[][4]) { - ListBase *conlist = get_active_constraints(ob); + ListBase *conlist = get_active_constraints(this->eval_ctx, ob); bConstraint *con; for (con = (bConstraint *)conlist->first; con; con = con->next) { ListBase targets = {NULL, NULL}; diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp index 65acce41046..e63b70edcf5 100644 --- a/source/blender/collada/AnimationImporter.cpp +++ b/source/blender/collada/AnimationImporter.cpp @@ -780,6 +780,9 @@ void AnimationImporter::apply_matrix_curves(Object *ob, std::vector<FCurve *>& a std::vector<float>::iterator it; + float qref[4]; + unit_qt(qref); + // sample values at each frame for (it = frames.begin(); it != frames.end(); it++) { float fra = *it; @@ -814,8 +817,11 @@ void AnimationImporter::apply_matrix_curves(Object *ob, std::vector<FCurve *>& a } float rot[4], loc[3], scale[3]; + transpose_m4(mat); + + bc_rotate_from_reference_quat(rot, qref, mat); + copy_qt_qt(qref, rot); - mat4_to_quat(rot, mat); #if 0 for (int i = 0 ; i < 4; i++) { rot[i] = RAD2DEGF(rot[i]); @@ -1190,6 +1196,9 @@ void AnimationImporter::add_bone_animation_sampled(Object *ob, std::vector<FCurv std::sort(frames.begin(), frames.end()); + float qref[4]; + unit_qt(qref); + std::vector<float>::iterator it; // sample values at each frame @@ -1223,7 +1232,9 @@ void AnimationImporter::add_bone_animation_sampled(Object *ob, std::vector<FCurv float rot[4], loc[3], scale[3]; - mat4_to_quat(rot, mat); + bc_rotate_from_reference_quat(rot, qref, mat); + copy_qt_qt(qref, rot); + copy_v3_v3(loc, mat[3]); mat4_to_size(scale, mat); diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index ce0c52cdcd1..1741312af5f 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -299,15 +299,15 @@ int DocumentExporter::exportCurrentScene(const EvaluationContext *eval_ctx, Scen // <library_visual_scenes> SceneExporter se(writer, &arm_exporter, this->export_settings); -#if 0 - /* The following code seems to be an obsolete workaround - Comment out until it proofs correct that we no longer need it. - */ // <library_animations> AnimationExporter ae(writer, this->export_settings); - bool has_animations = ae.exportAnimations(eval_ctx, sce); +#if 0 + bool has_animations = ae.exportAnimations(eval_ctx, sce); + /* The following code seems to be an obsolete workaround + Comment out until it proofs correct that we no longer need it. + */ if (has_animations && this->export_settings->export_transformation_type == BC_TRANSFORMATION_TYPE_MATRIX) { // channels adressing <matrix> objects is not (yet) supported // So we force usage of <location>, <translation> and <scale> @@ -320,6 +320,7 @@ int DocumentExporter::exportCurrentScene(const EvaluationContext *eval_ctx, Scen se.setExportTransformationType(this->export_settings->export_transformation_type); } #else + ae.exportAnimations(eval_ctx, sce); se.setExportTransformationType(this->export_settings->export_transformation_type); #endif se.exportScene(eval_ctx, sce); diff --git a/source/blender/collada/ErrorHandler.cpp b/source/blender/collada/ErrorHandler.cpp index 32aa5636e08..7e18328f000 100644 --- a/source/blender/collada/ErrorHandler.cpp +++ b/source/blender/collada/ErrorHandler.cpp @@ -49,7 +49,10 @@ ErrorHandler::~ErrorHandler() //-------------------------------------------------------------------- bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error) { - bool isError = false; + /* This method must return true when Collada should continue. + See https://github.com/KhronosGroup/OpenCOLLADA/issues/442 + */ + bool isWarning = false; if (error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXPARSER) { COLLADASaxFWL::SaxParserError *saxParserError = (COLLADASaxFWL::SaxParserError *) error; @@ -58,14 +61,14 @@ bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error) // Workaround to avoid wrong error if (parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_VALIDATION_MIN_OCCURS_UNMATCHED) { if (STREQ(parserError.getElement(), "effect")) { - isError = false; + isWarning = true; } } if (parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_VALIDATION_SEQUENCE_PREVIOUS_SIBLING_NOT_PRESENT) { if (!(STREQ(parserError.getElement(), "extra") && STREQ(parserError.getAdditionalText().c_str(), "sibling: fx_profile_abstract"))) { - isError = false; + isWarning = true; } } @@ -81,14 +84,12 @@ bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error) * Accept non critical errors as warnings (i.e. texture not found) * This makes the importer more graceful, so it now imports what makes sense. */ - isError = (saxFWLError->getSeverity() != COLLADASaxFWL::IError::SEVERITY_ERROR_NONCRITICAL); + isWarning = (saxFWLError->getSeverity() == COLLADASaxFWL::IError::SEVERITY_ERROR_NONCRITICAL); std::cout << "Sax FWL Error: " << saxFWLError->getErrorMessage() << std::endl; } else { std::cout << "opencollada error: " << error->getFullErrorMessage() << std::endl; } - mError |= isError; - - return isError; // let OpenCollada decide when to abort + return isWarning; } diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp index a2cb8237d08..24b47f8db3c 100644 --- a/source/blender/collada/SkinInfo.cpp +++ b/source/blender/collada/SkinInfo.cpp @@ -227,7 +227,7 @@ void SkinInfo::link_armature(bContext *C, Object *ob, std::map<COLLADAFW::Unique Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - ModifierData *md = ED_object_modifier_add(NULL, bmain, scene, ob, NULL, eModifierType_Armature); + ModifierData *md = ED_object_modifier_add(NULL, bmain, scene, ob, OB_MODE_OBJECT, NULL, eModifierType_Armature); ArmatureModifierData *amd = (ArmatureModifierData *)md; amd->object = ob_arm; diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index f351ebf7952..117e2ef7f76 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -384,6 +384,35 @@ void bc_decompose(float mat[4][4], float *loc, float eul[3], float quat[4], floa } } +/* +* Create rotation_quaternion from a delta rotation and a reference quat +* +* Input: +* mat_from: The rotation matrix before rotation +* mat_to : The rotation matrix after rotation +* qref : the quat corresponding to mat_from +* +* Output: +* rot : the calculated result (quaternion) +* +*/ +void bc_rotate_from_reference_quat(float quat_to[4], float quat_from[4], float mat_to[4][4]) +{ + float qd[4]; + float matd[4][4]; + float mati[4][4]; + float mat_from[4][4]; + quat_to_mat4(mat_from, quat_from); + + // Calculate the difference matrix matd between mat_from and mat_to + invert_m4_m4(mati, mat_from); + mul_m4_m4m4(matd, mati, mat_to); + + mat4_to_quat(qd, matd); + + mul_qt_qtqt(quat_to, qd, quat_from); // rot is the final rotation corresponding to mat_to +} + void bc_triangulate_mesh(Mesh *me) { bool use_beauty = false; @@ -841,3 +870,11 @@ void bc_sanitize_mat(float mat[4][4], int precision) for (int j = 0; j < 4; j++) mat[i][j] = double_round(mat[i][j], precision); } + +void bc_sanitize_mat(double mat[4][4], int precision) +{ + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + mat[i][j] = double_round(mat[i][j], precision); +} + diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h index 5d6e836b9c3..e3a16105861 100644 --- a/source/blender/collada/collada_utils.h +++ b/source/blender/collada/collada_utils.h @@ -93,6 +93,7 @@ extern void bc_match_scale(Object *ob, UnitConverter &bc_unit, bool scale_to_sce extern void bc_match_scale(std::vector<Object *> *objects_done, UnitConverter &unit_converter, bool scale_to_scene); extern void bc_decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size); +extern void bc_rotate_from_reference_quat(float quat_to[4], float quat_from[4], float mat_to[4][4]); extern void bc_triangulate_mesh(Mesh *me); extern bool bc_is_leaf_bone(Bone *bone); @@ -100,6 +101,7 @@ extern EditBone *bc_get_edit_bone(bArmature * armature, char *name); extern int bc_set_layer(int bitfield, int layer, bool enable); extern int bc_set_layer(int bitfield, int layer); extern void bc_sanitize_mat(float mat[4][4], int precision); +extern void bc_sanitize_mat(double mat[4][4], int precision); extern IDProperty *bc_get_IDProperty(Bone *bone, std::string key); extern void bc_set_IDProperty(EditBone *ebone, const char *key, float value); diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp index 68f934008a4..e2dc289eb1c 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.cpp +++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp @@ -131,18 +131,18 @@ void WorkScheduler::start(CompositorContext &context) #if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE unsigned int index; g_cpuqueue = BLI_thread_queue_init(); - BLI_init_threads(&g_cputhreads, thread_execute_cpu, g_cpudevices.size()); + BLI_threadpool_init(&g_cputhreads, thread_execute_cpu, g_cpudevices.size()); for (index = 0; index < g_cpudevices.size(); index++) { Device *device = g_cpudevices[index]; - BLI_insert_thread(&g_cputhreads, device); + BLI_threadpool_insert(&g_cputhreads, device); } #ifdef COM_OPENCL_ENABLED if (context.getHasActiveOpenCLDevices()) { g_gpuqueue = BLI_thread_queue_init(); - BLI_init_threads(&g_gputhreads, thread_execute_gpu, g_gpudevices.size()); + BLI_threadpool_init(&g_gputhreads, thread_execute_gpu, g_gpudevices.size()); for (index = 0; index < g_gpudevices.size(); index++) { Device *device = g_gpudevices[index]; - BLI_insert_thread(&g_gputhreads, device); + BLI_threadpool_insert(&g_gputhreads, device); } g_openclActive = true; } @@ -172,13 +172,13 @@ void WorkScheduler::stop() { #if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE BLI_thread_queue_nowait(g_cpuqueue); - BLI_end_threads(&g_cputhreads); + BLI_threadpool_end(&g_cputhreads); BLI_thread_queue_free(g_cpuqueue); g_cpuqueue = NULL; #ifdef COM_OPENCL_ENABLED if (g_openclActive) { BLI_thread_queue_nowait(g_gpuqueue); - BLI_end_threads(&g_gputhreads); + BLI_threadpool_end(&g_gputhreads); BLI_thread_queue_free(g_gpuqueue); g_gpuqueue = NULL; } diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cpp b/source/blender/compositor/operations/COM_CompositorOperation.cpp index 15ffff2fc90..fe13f3d60a2 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.cpp +++ b/source/blender/compositor/operations/COM_CompositorOperation.cpp @@ -108,9 +108,9 @@ void CompositorOperation::deinitExecution() re = NULL; } - BLI_lock_thread(LOCK_DRAW_IMAGE); + BLI_thread_lock(LOCK_DRAW_IMAGE); BKE_image_signal(BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"), NULL, IMA_SIGNAL_FREE); - BLI_unlock_thread(LOCK_DRAW_IMAGE); + BLI_thread_unlock(LOCK_DRAW_IMAGE); } else { if (this->m_outputBuffer) { diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.h b/source/blender/compositor/operations/COM_KeyingScreenOperation.h index b1a5c0c39c7..45195b1e98d 100644 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.h +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.h @@ -35,7 +35,7 @@ #include "BLI_string.h" extern "C" { -# include "BLI_voronoi.h" +# include "BLI_voronoi_2d.h" } /** diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp index 1145abd076a..75a85ad7e33 100644 --- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp +++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp @@ -28,7 +28,7 @@ extern "C" { #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_math_color.h" -#include "BLI_jitter.h" +#include "BLI_jitter_2d.h" #include "BKE_movieclip.h" #include "BKE_node.h" diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cpp b/source/blender/compositor/operations/COM_ViewerOperation.cpp index aa47d3427d0..42fe24120dc 100644 --- a/source/blender/compositor/operations/COM_ViewerOperation.cpp +++ b/source/blender/compositor/operations/COM_ViewerOperation.cpp @@ -135,14 +135,14 @@ void ViewerOperation::initImage() BKE_image_verify_viewer_views(this->m_rd, ima, this->m_imageUser); } - BLI_lock_thread(LOCK_DRAW_IMAGE); + BLI_thread_lock(LOCK_DRAW_IMAGE); /* local changes to the original ImageUser */ iuser.multi_index = BKE_scene_multiview_view_id_get(this->m_rd, this->m_viewName); ibuf = BKE_image_acquire_ibuf(ima, &iuser, &lock); if (!ibuf) { - BLI_unlock_thread(LOCK_DRAW_IMAGE); + BLI_thread_unlock(LOCK_DRAW_IMAGE); return; } if (ibuf->x != (int)getWidth() || ibuf->y != (int)getHeight()) { @@ -176,7 +176,7 @@ void ViewerOperation::initImage() BKE_image_release_ibuf(this->m_image, this->m_ibuf, lock); - BLI_unlock_thread(LOCK_DRAW_IMAGE); + BLI_thread_unlock(LOCK_DRAW_IMAGE); } void ViewerOperation::updateImage(rcti *rect) diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h index 4d3f36b5fba..8110899048d 100644 --- a/source/blender/depsgraph/DEG_depsgraph.h +++ b/source/blender/depsgraph/DEG_depsgraph.h @@ -75,6 +75,8 @@ typedef enum eEvaluationMode { DAG_EVAL_RENDER = 2, /* evaluate for render purposes */ } eEvaluationMode; +#include "DNA_object_enums.h" + /* Dependency graph evaluation context * * This structure stores all the local dependency graph data, @@ -83,6 +85,7 @@ typedef enum eEvaluationMode { typedef struct EvaluationContext { eEvaluationMode mode; float ctime; + eObjectMode object_mode; struct Depsgraph *depsgraph; struct ViewLayer *view_layer; @@ -213,11 +216,13 @@ struct EvaluationContext *DEG_evaluation_context_new(eEvaluationMode mode); */ void DEG_evaluation_context_init(struct EvaluationContext *eval_ctx, eEvaluationMode mode); -void DEG_evaluation_context_init_from_scene(struct EvaluationContext *eval_ctx, - struct Scene *scene, - struct ViewLayer *view_layer, - struct RenderEngineType *engine_type, - eEvaluationMode mode); +void DEG_evaluation_context_init_from_scene( + struct EvaluationContext *eval_ctx, + struct Scene *scene, + struct ViewLayer *view_layer, + struct RenderEngineType *engine_type, + const eObjectMode object_mode, + eEvaluationMode mode); /* Free evaluation context. */ void DEG_evaluation_context_free(struct EvaluationContext *eval_ctx); diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h index adfda27117e..fffdccf3efc 100644 --- a/source/blender/depsgraph/DEG_depsgraph_query.h +++ b/source/blender/depsgraph/DEG_depsgraph_query.h @@ -91,6 +91,7 @@ typedef struct DEGObjectIterData { int flag; eDepsObjectIteratorMode mode; + int visibility_check; /* eObjectVisibilityCheck. */ /* **** Iteration over dupli-list. *** */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index ddae761cea0..b65c16591dc 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -90,6 +90,7 @@ extern "C" { #include "BKE_node.h" #include "BKE_object.h" #include "BKE_particle.h" +#include "BKE_pointcache.h" #include "BKE_rigidbody.h" #include "BKE_sound.h" #include "BKE_tracking.h" @@ -196,7 +197,7 @@ IDDepsNode *DepsgraphNodeBuilder::add_id_node(ID *id, bool do_tag) * * NOTE: Zero number of components indicates that ID node was just created. */ - if (BLI_ghash_size(id_node->components) == 0) { + if (BLI_ghash_len(id_node->components) == 0) { ComponentDepsNode *comp_cow = id_node->add_component(DEG_NODE_TYPE_COPY_ON_WRITE); OperationDepsNode *op_cow = comp_cow->add_operation( @@ -429,7 +430,7 @@ void DepsgraphNodeBuilder::build_group(Group *group) } group_id->tag |= LIB_TAG_DOIT; /* Build group objects. */ - BLI_LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) { + LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) { build_object(NULL, base->object, DEG_ID_LINKED_INDIRECTLY); } /* Operation to evaluate the whole view layer. @@ -699,7 +700,7 @@ void DepsgraphNodeBuilder::build_animdata(ID *id) } /* drivers */ - BLI_LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) { + LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) { /* create driver */ build_driver(id, fcu); } @@ -817,7 +818,7 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene) /* objects - simulation participants */ if (rbw->group) { - BLI_LISTBASE_FOREACH (Base *, base, &rbw->group->view_layer->object_bases) { + LISTBASE_FOREACH (Base *, base, &rbw->group->view_layer->object_bases) { Object *object = base->object; if (!object || (object->type != OB_MESH)) @@ -853,8 +854,7 @@ void DepsgraphNodeBuilder::build_particles(Object *object) * blackbox evaluation step for one particle system referenced by * the particle systems stack. All dependencies link to this operation. */ - - /* component for all particle systems */ + /* Component for all particle systems. */ ComponentDepsNode *psys_comp = add_component_node(&object->id, DEG_NODE_TYPE_EVAL_PARTICLES); @@ -868,17 +868,14 @@ void DepsgraphNodeBuilder::build_particles(Object *object) scene_cow, ob_cow), DEG_OPCODE_PARTICLE_SYSTEM_EVAL_INIT); - - /* particle systems */ - BLI_LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) { + /* Build all particle systems. */ + LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) { ParticleSettings *part = psys->part; - /* Build particle settings operations. * * NOTE: The call itself ensures settings are only build once. */ build_particle_settings(part); - /* Update on particle settings change. */ add_operation_node(psys_comp, function_bind(BKE_particle_system_settings_eval, @@ -886,15 +883,36 @@ void DepsgraphNodeBuilder::build_particles(Object *object) psys), DEG_OPCODE_PARTICLE_SETTINGS_EVAL, psys->name); - /* Particle system evaluation. */ add_operation_node(psys_comp, NULL, DEG_OPCODE_PARTICLE_SYSTEM_EVAL, psys->name); + /* Visualization of particle system. */ + switch (part->ren_as) { + case PART_DRAW_OB: + if (part->dup_ob != NULL) { + build_object(NULL, + part->dup_ob, + DEG_ID_LINKED_INDIRECTLY); + } + break; + case PART_DRAW_GR: + if (part->dup_group != NULL) { + build_group(part->dup_group); + } + break; + } } /* TODO(sergey): Do we need a point cache operations here? */ + add_operation_node(&object->id, + DEG_NODE_TYPE_CACHE, + function_bind(BKE_ptcache_object_reset, + scene_cow, + ob_cow, + PTCACHE_RESET_DEPSGRAPH), + DEG_OPCODE_POINT_CACHE_RESET); } void DepsgraphNodeBuilder::build_particle_settings(ParticleSettings *part) { @@ -986,7 +1004,7 @@ void DepsgraphNodeBuilder::build_obdata_geom(Object *object) // TODO: "Done" operation /* Cloth modifier. */ - BLI_LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { + LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { if (md->type == eModifierType_Cloth) { build_cloth(object); } @@ -1231,7 +1249,7 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree) ntree), DEG_OPCODE_MATERIAL_UPDATE); /* nodetree's nodes... */ - BLI_LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) { + LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) { ID *id = bnode->id; if (id == NULL) { continue; diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer_collection.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer_collection.cc index 137a79e7276..2ee526b7128 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer_collection.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer_collection.cc @@ -94,7 +94,7 @@ void DepsgraphNodeBuilder::build_layer_collections(ID *owner_id, ListBase *layer_collections, LayerCollectionState *state) { - BLI_LISTBASE_FOREACH (LayerCollection *, layer_collection, layer_collections) { + LISTBASE_FOREACH (LayerCollection *, layer_collection, layer_collections) { build_layer_collection(owner_id, layer_collection, state); } } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc index 2fc42efa440..c3116db6146 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc @@ -247,7 +247,7 @@ void DepsgraphNodeBuilder::build_rig(Object *object) op_node->set_as_exit(); /* bones */ - BLI_LISTBASE_FOREACH (bPoseChannel *, pchan, &object_cow->pose->chanbase) { + LISTBASE_FOREACH (bPoseChannel *, pchan, &object_cow->pose->chanbase) { /* Node for bone evaluation. */ op_node = add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name, NULL, DEG_OPCODE_BONE_LOCAL); @@ -293,7 +293,7 @@ void DepsgraphNodeBuilder::build_rig(Object *object) * as in ik-tree building * - Animated chain-lengths are a problem. */ - BLI_LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) { + LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) { switch (con->type) { case CONSTRAINT_TYPE_KINEMATIC: build_ik_pose(object, pchan, con); @@ -347,8 +347,8 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *object) object_cow), DEG_OPCODE_POSE_INIT); op_node->set_as_entry(); - BLI_LISTBASE_FOREACH (bPoseChannel *, pchan, &object_cow->pose->chanbase) { - /* Local bone transform. */ + + LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) { op_node = add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name, diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc index 4ca19f4e14f..7a0fc790780 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc @@ -84,7 +84,7 @@ void DepsgraphNodeBuilder::build_view_layer( * otherwise remapping will not replace objects with their CoW versions * for CoW bases. */ - BLI_LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) { + LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) { Object *object = base->object; add_id_node(&object->id, false); } @@ -145,15 +145,15 @@ void DepsgraphNodeBuilder::build_view_layer( build_gpencil(scene->gpd); } /* Cache file. */ - BLI_LISTBASE_FOREACH (CacheFile *, cachefile, &bmain_->cachefiles) { + LISTBASE_FOREACH (CacheFile *, cachefile, &bmain_->cachefiles) { build_cachefile(cachefile); } /* Masks. */ - BLI_LISTBASE_FOREACH (Mask *, mask, &bmain_->mask) { + LISTBASE_FOREACH (Mask *, mask, &bmain_->mask) { build_mask(mask); } /* Movie clips. */ - BLI_LISTBASE_FOREACH (MovieClip *, clip, &bmain_->movieclip) { + LISTBASE_FOREACH (MovieClip *, clip, &bmain_->movieclip) { build_movieclip(clip); } /* Collections. */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index cfb73ecc2ad..cff6c926278 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -67,7 +67,7 @@ extern "C" { #include "DNA_scene_types.h" #include "DNA_texture_types.h" #include "DNA_world_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "BKE_action.h" #include "BKE_armature.h" @@ -194,7 +194,7 @@ static bool particle_system_depends_on_time(ParticleSystem *psys) static bool object_particles_depends_on_time(Object *object) { - BLI_LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) { + LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) { if (particle_system_depends_on_time(psys)) { return true; } @@ -347,7 +347,7 @@ void DepsgraphRelationBuilder::add_forcefield_relations( { ListBase *effectors = pdInitEffectors(NULL, scene, object, psys, eff, false); if (effectors != NULL) { - BLI_LISTBASE_FOREACH (EffectorCache *, eff, effectors) { + LISTBASE_FOREACH (EffectorCache *, eff, effectors) { if (eff->ob != object) { ComponentKey eff_key(&eff->ob->id, DEG_NODE_TYPE_TRANSFORM); add_relation(eff_key, key, name); @@ -423,20 +423,20 @@ void DepsgraphRelationBuilder::build_group(Object *object, Group *group) { ID *group_id = &group->id; bool group_done = (group_id->tag & LIB_TAG_DOIT) != 0; - OperationKey object_local_transform_key(&object->id, + OperationKey object_local_transform_key(object != NULL ? &object->id : NULL, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_LOCAL); - if (!group_done) { - BLI_LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) { + LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) { build_object(NULL, base->object); } group_id->tag |= LIB_TAG_DOIT; } - - BLI_LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) { - ComponentKey dupli_transform_key(&base->object->id, DEG_NODE_TYPE_TRANSFORM); - add_relation(dupli_transform_key, object_local_transform_key, "Dupligroup"); + if (object != NULL) { + LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) { + ComponentKey dupli_transform_key(&base->object->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(dupli_transform_key, object_local_transform_key, "Dupligroup"); + } } } @@ -776,7 +776,7 @@ void DepsgraphRelationBuilder::build_constraints(ID *id, else if (cti->get_constraint_targets) { ListBase targets = {NULL, NULL}; cti->get_constraint_targets(con, &targets); - BLI_LISTBASE_FOREACH (bConstraintTarget *, ct, &targets) { + LISTBASE_FOREACH (bConstraintTarget *, ct, &targets) { if (ct->tar == NULL) { continue; } @@ -939,18 +939,7 @@ void DepsgraphRelationBuilder::build_animdata_curves(ID *id) ComponentKey adt_key(id, DEG_NODE_TYPE_ANIMATION); TimeSourceKey time_src_key; add_relation(time_src_key, adt_key, "TimeSrc -> Animation"); - /* Build relations from animation operation to properties it changes. */ - build_animdata_curves_targets(id); -} - -void DepsgraphRelationBuilder::build_animdata_curves_targets(ID *id) -{ - AnimData *adt = BKE_animdata_from_id(id); - if (adt == NULL || adt->action == NULL) { - return; - } - /* Get source operation. */ - ComponentKey adt_key(id, DEG_NODE_TYPE_ANIMATION); + /* Get source operations. */ DepsNode *node_from = get_node(adt_key); BLI_assert(node_from != NULL); if (node_from == NULL) { @@ -958,10 +947,28 @@ void DepsgraphRelationBuilder::build_animdata_curves_targets(ID *id) } OperationDepsNode *operation_from = node_from->get_exit_operation(); BLI_assert(operation_from != NULL); + /* Build relations from animation operation to properties it changes. */ + if (adt->action != NULL) { + build_animdata_curves_targets(id, adt_key, + operation_from, + &adt->action->curves); + } + LISTBASE_FOREACH(NlaTrack *, nlt, &adt->nla_tracks) { + build_animdata_nlastrip_targets(id, adt_key, + operation_from, + &nlt->strips); + } +} + +void DepsgraphRelationBuilder::build_animdata_curves_targets( + ID *id, ComponentKey &adt_key, + OperationDepsNode *operation_from, + ListBase *curves) +{ /* Iterate over all curves and build relations. */ PointerRNA id_ptr; RNA_id_pointer_create(id, &id_ptr); - BLI_LISTBASE_FOREACH (FCurve *, fcu, &adt->action->curves) { + LISTBASE_FOREACH(FCurve *, fcu, curves) { PointerRNA ptr; PropertyRNA *prop; int index; @@ -1004,6 +1011,25 @@ void DepsgraphRelationBuilder::build_animdata_curves_targets(ID *id) } } +void DepsgraphRelationBuilder::build_animdata_nlastrip_targets( + ID *id, ComponentKey &adt_key, + OperationDepsNode *operation_from, + ListBase *strips) +{ + LISTBASE_FOREACH(NlaStrip *, strip, strips) { + if (strip->act != NULL) { + build_animdata_curves_targets(id, adt_key, + operation_from, + &strip->act->curves); + } + else if (strip->strips.first != NULL) { + build_animdata_nlastrip_targets(id, adt_key, + operation_from, + &strip->strips); + } + } +} + void DepsgraphRelationBuilder::build_animdata_drivers(ID *id) { AnimData *adt = BKE_animdata_from_id(id); @@ -1011,7 +1037,7 @@ void DepsgraphRelationBuilder::build_animdata_drivers(ID *id) return; } ComponentKey adt_key(id, DEG_NODE_TYPE_ANIMATION); - BLI_LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) { + LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) { OperationKey driver_key(id, DEG_NODE_TYPE_PARAMETERS, DEG_OPCODE_DRIVER, @@ -1034,7 +1060,7 @@ void DepsgraphRelationBuilder::build_animdata_drivers(ID *id) */ if (fcu->array_index > 0) { FCurve *fcu_prev = NULL; - BLI_LISTBASE_FOREACH (FCurve *, fcu_candidate, &adt->drivers) { + LISTBASE_FOREACH (FCurve *, fcu_candidate, &adt->drivers) { /* Writing to different RNA paths is */ const char *rna_path = fcu->rna_path ? fcu->rna_path : ""; if (!STREQ(fcu_candidate->rna_path, rna_path)) { @@ -1183,7 +1209,7 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu) const char *rna_path = fcu->rna_path ? fcu->rna_path : ""; const RNAPathKey self_key(id, rna_path); - BLI_LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) { + LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) { /* Only used targets. */ DRIVER_TARGETS_USED_LOOPER(dvar) { @@ -1298,7 +1324,7 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) /* objects - simulation participants */ if (rbw->group) { - BLI_LISTBASE_FOREACH (Base *, base, &rbw->group->view_layer->object_bases) { + LISTBASE_FOREACH (Base *, base, &rbw->group->view_layer->object_bases) { Object *object = base->object; if (object == NULL || object->type != OB_MESH) { continue; @@ -1352,7 +1378,7 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) /* constraints */ if (rbw->constraints) { - BLI_LISTBASE_FOREACH (Base *, base, &rbw->constraints->view_layer->object_bases) { + LISTBASE_FOREACH (Base *, base, &rbw->constraints->view_layer->object_bases) { Object *object = base->object; if (object == NULL || !object->rigidbody_constraint) { continue; @@ -1387,8 +1413,8 @@ void DepsgraphRelationBuilder::build_particles(Object *object) DEG_NODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PARTICLE_SYSTEM_EVAL_INIT); - /* particle systems */ - BLI_LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) { + /* Particle systems. */ + LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) { ParticleSettings *part = psys->part; /* Build particle settings relations. @@ -1420,20 +1446,13 @@ void DepsgraphRelationBuilder::build_particles(Object *object) add_relation(psys_key, particle_settings_recalc_clear_key, "Particle Settings Recalc Clear"); - - /* XXX: if particle system is later re-enabled, we must do full rebuild? */ - if (!psys_check_enabled(object, psys, G.is_rendering)) - continue; - add_relation(eval_init_key, psys_key, "Init -> PSys"); - /* TODO(sergey): Currently particle update is just a placeholder, * hook it to the ubereval node so particle system is getting updated * on playback. */ add_relation(psys_key, obdata_ubereval_key, "PSys -> UberEval"); - - /* collisions */ + /* Collisions */ if (part->type != PART_HAIR) { add_collision_relations(psys_key, scene_, @@ -1453,8 +1472,7 @@ void DepsgraphRelationBuilder::build_particles(Object *object) true, "Hair Collision"); } - - /* effectors */ + /* Effectors. */ add_forcefield_relations(psys_key, scene_, object, @@ -1462,35 +1480,46 @@ void DepsgraphRelationBuilder::build_particles(Object *object) part->effector_weights, part->type == PART_HAIR, "Particle Field"); - - /* boids */ + /* Boids .*/ if (part->boids) { - BLI_LISTBASE_FOREACH (BoidState *, state, &part->boids->states) { - BLI_LISTBASE_FOREACH (BoidRule *, rule, &state->rules) { + LISTBASE_FOREACH (BoidState *, state, &part->boids->states) { + LISTBASE_FOREACH (BoidRule *, rule, &state->rules) { Object *ruleob = NULL; - if (rule->type == eBoidRuleType_Avoid) + if (rule->type == eBoidRuleType_Avoid) { ruleob = ((BoidRuleGoalAvoid *)rule)->ob; - else if (rule->type == eBoidRuleType_FollowLeader) + } + else if (rule->type == eBoidRuleType_FollowLeader) { ruleob = ((BoidRuleFollowLeader *)rule)->ob; - + } if (ruleob) { - ComponentKey ruleob_key(&ruleob->id, DEG_NODE_TYPE_TRANSFORM); + ComponentKey ruleob_key(&ruleob->id, + DEG_NODE_TYPE_TRANSFORM); add_relation(ruleob_key, psys_key, "Boid Rule"); } } } } - - if (part->ren_as == PART_DRAW_OB && part->dup_ob) { - ComponentKey dup_ob_key(&part->dup_ob->id, DEG_NODE_TYPE_TRANSFORM); - add_relation(dup_ob_key, psys_key, "Particle Object Visualization"); - if (part->dup_ob->type == OB_MBALL) { - ComponentKey dup_geometry_key(&part->dup_ob->id, - DEG_NODE_TYPE_GEOMETRY); - add_relation(obdata_ubereval_key, - dup_geometry_key, - "Particle MBall Visualization"); - } + switch (part->ren_as) { + case PART_DRAW_OB: + if (part->dup_ob != NULL) { + /* Make sure object's relations are all built. */ + build_object(NULL, part->dup_ob); + /* Build relation for the particle visualization. */ + build_particles_visualization_object(object, + psys, + part->dup_ob); + } + break; + case PART_DRAW_GR: + if (part->dup_group != NULL) { + build_group(NULL, part->dup_group); + LISTBASE_FOREACH (GroupObject *, go, &part->dup_group->gobject) { + build_particles_visualization_object(object, + psys, + go->ob); + } + } + break; } } @@ -1503,7 +1532,11 @@ void DepsgraphRelationBuilder::build_particles(Object *object) ComponentKey transform_key(&object->id, DEG_NODE_TYPE_TRANSFORM); add_relation(transform_key, obdata_ubereval_key, "Partcile Eval"); - /* TODO(sergey): Do we need a point cache operations here? */ + OperationKey point_cache_reset_key(&object->id, + DEG_NODE_TYPE_CACHE, + DEG_OPCODE_POINT_CACHE_RESET); + add_relation(transform_key, point_cache_reset_key, "Object Transform -> Point Cache Reset"); + add_relation(point_cache_reset_key, obdata_ubereval_key, "Point Cache Reset -> UberEval"); } void DepsgraphRelationBuilder::build_particle_settings(ParticleSettings *part) @@ -1526,6 +1559,28 @@ void DepsgraphRelationBuilder::build_particle_settings(ParticleSettings *part) add_relation(eval_key, recalc_clear_key, "Particle Settings Clear Recalc"); } +void DepsgraphRelationBuilder::build_particles_visualization_object( + Object *object, + ParticleSystem *psys, + Object *draw_object) +{ + OperationKey psys_key(&object->id, + DEG_NODE_TYPE_EVAL_PARTICLES, + DEG_OPCODE_PARTICLE_SYSTEM_EVAL, + psys->name); + OperationKey obdata_ubereval_key(&object->id, + DEG_NODE_TYPE_GEOMETRY, + DEG_OPCODE_GEOMETRY_UBEREVAL); + ComponentKey dup_ob_key(&draw_object->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(dup_ob_key, psys_key, "Particle Object Visualization"); + if (draw_object->type == OB_MBALL) { + ComponentKey dup_geometry_key(&draw_object->id, DEG_NODE_TYPE_GEOMETRY); + add_relation(obdata_ubereval_key, + dup_geometry_key, + "Particle MBall Visualization"); + } +} + void DepsgraphRelationBuilder::build_cloth(Object *object, ModifierData * /*md*/) { @@ -1613,7 +1668,7 @@ void DepsgraphRelationBuilder::build_obdata_geom(Object *object) /* Modifiers */ if (object->modifiers.first != NULL) { - BLI_LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { + LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { const ModifierTypeInfo *mti = modifierType_getInfo((ModifierType)md->type); if (mti->updateDepsgraph) { DepsNodeHandle handle = create_node_handle(obdata_ubereval_key); @@ -1834,7 +1889,7 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree) build_animdata(ntree_id); ComponentKey shading_key(ntree_id, DEG_NODE_TYPE_SHADING); /* nodetree's nodes... */ - BLI_LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) { + LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) { ID *id = bnode->id; if (id == NULL) { continue; @@ -2050,6 +2105,22 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDDepsNode *id_node if (op_node->inlinks.size() == 0) { graph_->add_new_relation(op_cow, op_node, "CoW Dependency"); } + else { + bool has_same_id_dependency = false; + foreach (DepsRelation *rel, op_node->inlinks) { + if (rel->from->type != DEG_NODE_TYPE_OPERATION) { + continue; + } + OperationDepsNode *op_node_from = (OperationDepsNode *)rel->from; + if (op_node_from->owner->owner == op_node->owner->owner) { + has_same_id_dependency = true; + break; + } + } + if (!has_same_id_dependency) { + graph_->add_new_relation(op_cow, op_node, "CoW Dependency"); + } + } } GHASH_FOREACH_END(); /* NOTE: We currently ignore implicit relations to an external diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 30b3219f989..ea7e23eca79 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -67,13 +67,13 @@ struct bNodeTree; struct Object; struct bPoseChannel; struct bConstraint; +struct ParticleSystem; +struct ParticleSettings; struct Scene; struct ViewLayer; struct Tex; struct World; struct EffectorWeights; -struct ParticleSystem; -struct ParticleSettings; struct PropertyRNA; @@ -205,7 +205,14 @@ struct DepsgraphRelationBuilder RootPChanMap *root_map); void build_animdata(ID *id); void build_animdata_curves(ID *id); - void build_animdata_curves_targets(ID *id); + void build_animdata_curves_targets(ID *id, + ComponentKey &adt_key, + OperationDepsNode *operation_from, + ListBase *curves); + void build_animdata_nlastrip_targets(ID *id, + ComponentKey &adt_key, + OperationDepsNode *operation_from, + ListBase *strips); void build_animdata_drivers(ID *id); void build_driver(ID *id, FCurve *fcurve); void build_driver_data(ID *id, FCurve *fcurve); @@ -214,6 +221,9 @@ struct DepsgraphRelationBuilder void build_rigidbody(Scene *scene); void build_particles(Object *object); void build_particle_settings(ParticleSettings *part); + void build_particles_visualization_object(Object *object, + ParticleSystem *psys, + Object *draw_object); void build_cloth(Object *object, ModifierData *md); void build_ik_pose(Object *object, bPoseChannel *pchan, diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_layer_collection.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_layer_collection.cc index 9cf82b5fb47..e2154558ed7 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_layer_collection.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_layer_collection.cc @@ -92,7 +92,7 @@ void DepsgraphRelationBuilder::build_layer_collections( ListBase *layer_collections, LayerCollectionState *state) { - BLI_LISTBASE_FOREACH (LayerCollection *, layer_collection, layer_collections) { + LISTBASE_FOREACH (LayerCollection *, layer_collection, layer_collections) { /* Recurs into the layer. */ build_layer_collection(owner_id, layer_collection, state); } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc index ad812a4b505..f3c3772e512 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc @@ -341,8 +341,8 @@ void DepsgraphRelationBuilder::build_rig(Object *object) */ RootPChanMap root_map; bool pose_depends_on_local_transform = false; - BLI_LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) { - BLI_LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) { + LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) { + LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) { switch (con->type) { case CONSTRAINT_TYPE_KINEMATIC: build_ik_pose(object, pchan, con, &root_map); @@ -382,7 +382,7 @@ void DepsgraphRelationBuilder::build_rig(Object *object) } /* links between operations for each bone */ - BLI_LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) { + LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) { OperationKey bone_local_key(&object->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL); OperationKey bone_pose_key(&object->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_POSE_PARENT); OperationKey bone_ready_key(&object->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY); @@ -443,16 +443,43 @@ void DepsgraphRelationBuilder::build_rig(Object *object) void DepsgraphRelationBuilder::build_proxy_rig(Object *object) { - OperationKey pose_init_key(&object->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_INIT); - OperationKey pose_done_key(&object->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE); - BLI_LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) { - OperationKey bone_local_key(&object->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL); - OperationKey bone_ready_key(&object->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY); - OperationKey bone_done_key(&object->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE); + Object *proxy_from = object->proxy_from; + OperationKey pose_init_key(&object->id, + DEG_NODE_TYPE_EVAL_POSE, + DEG_OPCODE_POSE_INIT); + OperationKey pose_done_key(&object->id, + DEG_NODE_TYPE_EVAL_POSE, + DEG_OPCODE_POSE_DONE); + LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) { + OperationKey bone_local_key(&object->id, + DEG_NODE_TYPE_BONE, pchan->name, + DEG_OPCODE_BONE_LOCAL); + OperationKey bone_ready_key(&object->id, + DEG_NODE_TYPE_BONE, + pchan->name, + DEG_OPCODE_BONE_READY); + OperationKey bone_done_key(&object->id, + DEG_NODE_TYPE_BONE, + pchan->name, + DEG_OPCODE_BONE_DONE); add_relation(pose_init_key, bone_local_key, "Pose Init -> Bone Local"); add_relation(bone_local_key, bone_ready_key, "Local -> Ready"); add_relation(bone_ready_key, bone_done_key, "Ready -> Done"); add_relation(bone_done_key, pose_done_key, "Bone Done -> Pose Done"); + + if (pchan->prop != NULL) { + OperationKey bone_parameters(&object->id, + DEG_NODE_TYPE_PARAMETERS, + DEG_OPCODE_PARAMETERS_EVAL, + pchan->name); + OperationKey from_bone_parameters(&proxy_from->id, + DEG_NODE_TYPE_PARAMETERS, + DEG_OPCODE_PARAMETERS_EVAL, + pchan->name); + add_relation(from_bone_parameters, + bone_parameters, + "Proxy Bone Parameters"); + } } } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc index cfb98fe2f79..074d20bb750 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc @@ -78,7 +78,7 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene, ViewLayer *view_la * passed to the evaluation functions. During relations builder we only * do NULL-pointer check of the base, so it's fine to pass original one. */ - BLI_LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) { + LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) { build_object(base, base->object); } if (scene->camera != NULL) { @@ -105,11 +105,11 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene, ViewLayer *view_la build_gpencil(scene->gpd); } /* Masks. */ - BLI_LISTBASE_FOREACH (Mask *, mask, &bmain_->mask) { + LISTBASE_FOREACH (Mask *, mask, &bmain_->mask) { build_mask(mask); } /* Movie clips. */ - BLI_LISTBASE_FOREACH (MovieClip *, clip, &bmain_->movieclip) { + LISTBASE_FOREACH (MovieClip *, clip, &bmain_->movieclip) { build_movieclip(clip); } /* Collections. */ diff --git a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc index 8fc4c0bcec1..ee40ca50ab5 100644 --- a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc +++ b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc @@ -346,7 +346,7 @@ static void deg_debug_graphviz_node(const DebugContext &ctx, case DEG_NODE_TYPE_ID_REF: { const IDDepsNode *id_node = (const IDDepsNode *)node; - if (BLI_ghash_size(id_node->components) == 0) { + if (BLI_ghash_len(id_node->components) == 0) { deg_debug_graphviz_node_single(ctx, node); } else { @@ -405,7 +405,7 @@ static bool deg_debug_graphviz_is_cluster(const DepsNode *node) case DEG_NODE_TYPE_ID_REF: { const IDDepsNode *id_node = (const IDDepsNode *)node; - return BLI_ghash_size(id_node->components) > 0; + return BLI_ghash_len(id_node->components) > 0; } case DEG_NODE_TYPE_PARAMETERS: case DEG_NODE_TYPE_ANIMATION: @@ -467,7 +467,7 @@ static void deg_debug_graphviz_node_relations(const DebugContext &ctx, deg_debug_fprintf(ctx, "["); /* Note: without label an id seem necessary to avoid bugs in graphviz/dot */ deg_debug_fprintf(ctx, "id=\"%s\"", rel->name); - deg_debug_fprintf(ctx, "label=\"%s\"", rel->name); + // deg_debug_fprintf(ctx, "label=\"%s\"", rel->name); deg_debug_fprintf(ctx, ",color="); deg_debug_graphviz_relation_color(ctx, rel); deg_debug_fprintf(ctx, ",penwidth=\"%f\"", penwidth); /* NOTE: edge from node to own cluster is not possible and gives graphviz diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index 3a78c9050f7..3b5ea2bfc3f 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -167,7 +167,7 @@ static bool pointer_to_component_node_criteria( return true; } else if (object->pose != NULL) { - BLI_LISTBASE_FOREACH(bPoseChannel *, pchan, &object->pose->chanbase) { + LISTBASE_FOREACH(bPoseChannel *, pchan, &object->pose->chanbase) { if (BLI_findindex(&pchan->constraints, con) != -1) { /* bone transforms */ *type = DEG_NODE_TYPE_BONE; @@ -220,6 +220,10 @@ static bool pointer_to_component_node_criteria( *subdata = seq->name; // xxx? return true; } + else if (RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) { + *type = DEG_NODE_TYPE_SHADING; + return true; + } if (prop != NULL) { /* All unknown data effectively falls under "parameter evaluation". */ *type = DEG_NODE_TYPE_PARAMETERS; diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index 902cbe039cd..377f2d3b4c5 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -47,7 +47,7 @@ extern "C" { #include "DNA_cachefile_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "BKE_main.h" #include "BKE_collision.h" @@ -215,7 +215,7 @@ void DEG_graph_build_from_view_layer(Depsgraph *graph, * This now could happen for both visible scene is changed and extra * dependency graph was created for render engine. */ - const bool need_on_visible_update = (deg_graph->scene == NULL); + const bool need_on_visible_update = (deg_graph->id_nodes.size() == 0); /* 1) Generate all the nodes in the graph first */ DEG::DepsgraphNodeBuilder node_builder(bmain, deg_graph); @@ -294,8 +294,8 @@ void DEG_graph_relations_update(Depsgraph *graph, void DEG_relations_tag_update(Main *bmain) { DEG_DEBUG_PRINTF("%s: Tagging relations for update.\n", __func__); - BLI_LISTBASE_FOREACH (Scene *, scene, &bmain->scene) { - BLI_LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scene) { + LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) { Depsgraph *depsgraph = (Depsgraph *)BKE_scene_get_depsgraph(scene, view_layer, diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc index ad1a850a807..4fb5a8ff580 100644 --- a/source/blender/depsgraph/intern/depsgraph_eval.cc +++ b/source/blender/depsgraph/intern/depsgraph_eval.cc @@ -76,17 +76,20 @@ void DEG_evaluation_context_init(EvaluationContext *eval_ctx, eval_ctx->mode = mode; } -void DEG_evaluation_context_init_from_scene(EvaluationContext *eval_ctx, - Scene *scene, - ViewLayer *view_layer, - RenderEngineType *engine_type, - eEvaluationMode mode) +void DEG_evaluation_context_init_from_scene( + EvaluationContext *eval_ctx, + Scene *scene, + ViewLayer *view_layer, + RenderEngineType *engine_type, + eObjectMode object_mode, + eEvaluationMode mode) { DEG_evaluation_context_init(eval_ctx, mode); eval_ctx->depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true); eval_ctx->view_layer = view_layer; eval_ctx->engine_type = engine_type; eval_ctx->ctime = BKE_scene_frame_get(scene); + eval_ctx->object_mode = object_mode; } /* Free evaluation context. */ @@ -125,5 +128,5 @@ void DEG_evaluate_on_framechange(EvaluationContext *eval_ctx, bool DEG_needs_eval(Depsgraph *graph) { DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph); - return BLI_gset_size(deg_graph->entry_tags) != 0; + return BLI_gset_len(deg_graph->entry_tags) != 0; } diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc index 30c9d9f10be..fd54030a4e0 100644 --- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc +++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc @@ -110,10 +110,18 @@ static bool deg_objects_dupli_iterator_next(BLI_Iterator *iter) Object *dupli_parent = data->dupli_parent; Object *temp_dupli_object = &data->temp_dupli_object; *temp_dupli_object = *dob->ob; - temp_dupli_object->transflag &= ~OB_DUPLI; temp_dupli_object->select_color = dupli_parent->select_color; temp_dupli_object->base_flag = dupli_parent->base_flag | BASE_FROMDUPLI; + /* Duplicated elements shouldn't care whether their original collection is visible or not. */ + temp_dupli_object->base_flag |= BASE_VISIBLED; + + if (BKE_object_is_visible(temp_dupli_object, (eObjectVisibilityCheck)data->visibility_check) == false) { + continue; + } + + temp_dupli_object->transflag &= ~OB_DUPLI; + if (dob->collection_properties != NULL) { temp_dupli_object->base_collection_properties = dob->collection_properties; IDP_MergeGroup(temp_dupli_object->base_collection_properties, @@ -181,11 +189,7 @@ static void DEG_iterator_objects_step(BLI_Iterator *iter, DEG::IDDepsNode *id_no data->dupli_parent = object; data->dupli_list = object_duplilist(&data->eval_ctx, data->scene, object); data->dupli_object_next = (DupliObject *)data->dupli_list->first; - const eObjectVisibilityCheck mode = - (data->mode == DEG_ITER_OBJECT_MODE_RENDER) - ? OB_VISIBILITY_CHECK_FOR_RENDER - : OB_VISIBILITY_CHECK_FOR_VIEWPORT; - if (BKE_object_is_visible(object, mode) == false) { + if (BKE_object_is_visible(object, (eObjectVisibilityCheck)data->visibility_check) == false) { return; } } @@ -220,6 +224,9 @@ void DEG_iterator_objects_begin(BLI_Iterator *iter, DEGObjectIterData *data) data->scene = DEG_get_evaluated_scene(depsgraph); data->id_node_index = 0; data->num_id_nodes = num_id_nodes; + data->visibility_check = (data->mode == DEG_ITER_OBJECT_MODE_RENDER) + ? OB_VISIBILITY_CHECK_FOR_RENDER + : OB_VISIBILITY_CHECK_FOR_VIEWPORT; DEG::IDDepsNode *id_node = deg_graph->id_nodes[data->id_node_index]; DEG_iterator_objects_step(iter, id_node); diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index 38f43f5720b..b0b3cbe0f8c 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -40,12 +40,15 @@ #include "BLI_task.h" extern "C" { +#include "DNA_curve_types.h" +#include "DNA_key_types.h" +#include "DNA_lattice_types.h" +#include "DNA_mesh_types.h" #include "DNA_object_types.h" #include "DNA_particle_types.h" #include "DNA_screen_types.h" #include "DNA_windowmanager_types.h" - #include "BKE_idcode.h" #include "BKE_library.h" #include "BKE_main.h" @@ -92,6 +95,7 @@ void depsgraph_geometry_tag_to_component(const ID *id, case OB_CURVE: case OB_SURF: case OB_FONT: + case OB_LATTICE: case OB_MBALL: *component_type = DEG_NODE_TYPE_GEOMETRY; break; @@ -294,11 +298,50 @@ void deg_graph_id_tag_legacy_compat(Main *bmain, ID *id, eDepsgraph_Tag tag) { - if (tag == DEG_TAG_GEOMETRY && GS(id->name) == ID_OB) { - Object *object = (Object *)id; - ID *data_id = (ID *)object->data; - if (data_id != NULL) { - DEG_id_tag_update_ex(bmain, data_id, 0); + if (tag == DEG_TAG_GEOMETRY || tag == 0) { + switch (GS(id->name)) { + case ID_OB: + { + Object *object = (Object *)id; + ID *data_id = (ID *)object->data; + if (data_id != NULL) { + DEG_id_tag_update_ex(bmain, data_id, 0); + } + break; + } + /* TODO(sergey): Shape keys are annoying, maybe we should find a + * way to chain geometry evaluation to them, so we don't need extra + * tagging here. + */ + case ID_ME: + { + Mesh *mesh = (Mesh *)id; + ID *key_id = &mesh->key->id; + if (key_id != NULL) { + DEG_id_tag_update_ex(bmain, key_id, 0); + } + break; + } + case ID_LT: + { + Lattice *lattice = (Lattice *)id; + ID *key_id = &lattice->key->id; + if (key_id != NULL) { + DEG_id_tag_update_ex(bmain, key_id, 0); + } + break; + } + case ID_CU: + { + Curve *curve = (Curve *)id; + ID *key_id = &curve->key->id; + if (key_id != NULL) { + DEG_id_tag_update_ex(bmain, key_id, 0); + } + break; + } + default: + break; } } } @@ -364,6 +407,7 @@ void deg_graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id, int flag) if (id_node != NULL) { id_node->tag_update(graph); } + deg_graph_id_tag_legacy_compat(bmain, id, (eDepsgraph_Tag)0); } int current_flag = flag; while (current_flag != 0) { @@ -396,8 +440,8 @@ void deg_ensure_scene_view_layer(Depsgraph *graph, void deg_id_tag_update(Main *bmain, ID *id, int flag) { deg_graph_id_tag_update(bmain, NULL, id, flag); - BLI_LISTBASE_FOREACH (Scene *, scene, &bmain->scene) { - BLI_LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scene) { + LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) { Depsgraph *depsgraph = (Depsgraph *)BKE_scene_get_depsgraph(scene, view_layer, @@ -437,8 +481,12 @@ void deg_graph_on_visible_update(Main *bmain, Depsgraph *graph) scene_iter = scene_iter->set) { IDDepsNode *scene_id_node = graph->find_id_node(&scene_iter->id); - BLI_assert(scene_id_node != NULL); - scene_id_node->tag_update(graph); + if (scene_id_node != NULL) { + scene_id_node->tag_update(graph); + } + else { + BLI_assert(graph->need_update); + } } } @@ -507,8 +555,8 @@ void DEG_graph_on_visible_update(Main *bmain, Depsgraph *depsgraph) void DEG_on_visible_update(Main *bmain, const bool UNUSED(do_time)) { - BLI_LISTBASE_FOREACH (Scene *, scene, &bmain->scene) { - BLI_LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scene) { + LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) { Depsgraph *depsgraph = (Depsgraph *)BKE_scene_get_depsgraph(scene, view_layer, diff --git a/source/blender/depsgraph/intern/depsgraph_type_defines.cc b/source/blender/depsgraph/intern/depsgraph_type_defines.cc index 22df3161428..886601225c7 100644 --- a/source/blender/depsgraph/intern/depsgraph_type_defines.cc +++ b/source/blender/depsgraph/intern/depsgraph_type_defines.cc @@ -119,6 +119,8 @@ static const char *stringify_opcode(eDepsOperation_Code opcode) STRINGIFY_OPCODE(PARTICLE_SYSTEM_EVAL); STRINGIFY_OPCODE(PARTICLE_SETTINGS_EVAL); STRINGIFY_OPCODE(PARTICLE_SETTINGS_RECALC_CLEAR); + /* Point Cache. */ + STRINGIFY_OPCODE(POINT_CACHE_RESET); /* Batch cache. */ STRINGIFY_OPCODE(GEOMETRY_SELECT_UPDATE); /* Masks. */ diff --git a/source/blender/depsgraph/intern/depsgraph_types.h b/source/blender/depsgraph/intern/depsgraph_types.h index d091f42bf80..3f4df21b8d6 100644 --- a/source/blender/depsgraph/intern/depsgraph_types.h +++ b/source/blender/depsgraph/intern/depsgraph_types.h @@ -240,6 +240,9 @@ typedef enum eDepsOperation_Code { DEG_OPCODE_PARTICLE_SETTINGS_EVAL, DEG_OPCODE_PARTICLE_SETTINGS_RECALC_CLEAR, + /* Point Cache. ------------------------------------- */ + DEG_OPCODE_POINT_CACHE_RESET, + /* Collections. ------------------------------------- */ DEG_OPCODE_VIEW_LAYER_INIT, DEG_OPCODE_VIEW_LAYER_EVAL, diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index a6c6a16a528..c3aa84943d3 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -231,7 +231,7 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx, Depsgraph *graph) { /* Nothing to update, early out. */ - if (BLI_gset_size(graph->entry_tags) == 0) { + if (BLI_gset_len(graph->entry_tags) == 0) { return; } /* Set time for the current graph evaluation context. */ diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc index a6668208574..8bdc68d9351 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc @@ -63,8 +63,10 @@ extern "C" { #include "DNA_object_types.h" #ifdef NESTED_ID_NASTY_WORKAROUND +# include "DNA_curve_types.h" # include "DNA_key_types.h" # include "DNA_lamp_types.h" +# include "DNA_lattice_types.h" # include "DNA_linestyle_types.h" # include "DNA_material_types.h" # include "DNA_node_types.h" @@ -91,8 +93,10 @@ namespace { #ifdef NESTED_ID_NASTY_WORKAROUND union NestedIDHackTempStorage { + Curve curve; FreestyleLineStyle linestyle; Lamp lamp; + Lattice lattice; Material material; Mesh mesh; Scene scene; @@ -118,6 +122,8 @@ void nested_id_hack_discard_pointers(ID *id_cow) SPECIAL_CASE(ID_TE, Tex, nodetree) SPECIAL_CASE(ID_WO, World, nodetree) + SPECIAL_CASE(ID_CU, Curve, key) + SPECIAL_CASE(ID_LT, Lattice, key) SPECIAL_CASE(ID_ME, Mesh, key) # undef SPECIAL_CASE @@ -150,6 +156,8 @@ const ID *nested_id_hack_get_discarded_pointers(NestedIDHackTempStorage *storage SPECIAL_CASE(ID_TE, Tex, nodetree, tex) SPECIAL_CASE(ID_WO, World, nodetree, world) + SPECIAL_CASE(ID_CU, Curve, key, curve) + SPECIAL_CASE(ID_LT, Lattice, key, lattice) SPECIAL_CASE(ID_ME, Mesh, key, mesh) # undef SPECIAL_CASE @@ -182,6 +190,8 @@ void nested_id_hack_restore_pointers(const ID *old_id, ID *new_id) SPECIAL_CASE(ID_TE, Tex, nodetree) SPECIAL_CASE(ID_WO, World, nodetree) + SPECIAL_CASE(ID_CU, Curve, key) + SPECIAL_CASE(ID_LT, Lattice, key) SPECIAL_CASE(ID_ME, Mesh, key) #undef SPECIAL_CASE @@ -218,6 +228,8 @@ void ntree_hack_remap_pointers(const Depsgraph *depsgraph, ID *id_cow) SPECIAL_CASE(ID_TE, Tex, nodetree, bNodeTree) SPECIAL_CASE(ID_WO, World, nodetree, bNodeTree) + SPECIAL_CASE(ID_CU, Curve, key, Key) + SPECIAL_CASE(ID_LT, Lattice, key, Key) SPECIAL_CASE(ID_ME, Mesh, key, Key) #undef SPECIAL_CASE @@ -424,11 +436,9 @@ void update_special_pointers(const Depsgraph *depsgraph, * new copy of the object. */ Object *object_cow = (Object *)id_cow; - const Object *object_orig = (const Object *)id_orig; (void) object_cow; /* Ignored for release builds. */ BLI_assert(object_cow->derivedFinal == NULL); BLI_assert(object_cow->derivedDeform == NULL); - object_cow->mode = object_orig->mode; break; } case ID_ME: @@ -451,18 +461,6 @@ void update_special_pointers(const Depsgraph *depsgraph, } break; } - case ID_SCE: - { - const Scene *scene_orig = (const Scene *)id_orig; - Scene *scene_cow = (Scene *)id_cow; - if (scene_orig->obedit != NULL) { - scene_cow->obedit = (Object *)depsgraph->get_cow_id(&scene_orig->obedit->id); - } - else { - scene_cow->obedit = NULL; - } - break; - } default: break; } @@ -612,13 +610,6 @@ void update_copy_on_write_scene(const Depsgraph *depsgraph, update_copy_on_write_view_layers(depsgraph, scene_cow, scene_orig); update_copy_on_write_scene_collection(scene_cow->collection, scene_orig->collection); - // Update edit object pointer. - if (scene_orig->obedit != NULL) { - scene_cow->obedit = (Object *)depsgraph->get_cow_id(&scene_orig->obedit->id); - } - else { - scene_cow->obedit = NULL; - } /* Synchronize active render engine. */ BLI_strncpy(scene_cow->view_render.engine_id, scene_orig->view_render.engine_id, @@ -640,7 +631,6 @@ void update_copy_on_write_object(const Depsgraph * /*depsgraph*/, extract_pose_from_pose(pose_cow, pose_orig); /* Update object itself. */ BKE_object_transform_copy(object_cow, object_orig); - object_cow->mode = object_orig->mode; } /* Update copy-on-write version of datablock from it's original ID without re-building diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index c0d5e08b80f..b4e1c2f4e1a 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -214,7 +214,7 @@ void flush_engine_data_update(ID *id) return; } Object *object = (Object *)id; - BLI_LISTBASE_FOREACH(ObjectEngineData *, engine_data, &object->drawdata) { + LISTBASE_FOREACH(ObjectEngineData *, engine_data, &object->drawdata) { engine_data->recalc |= id->recalc; } } @@ -271,7 +271,7 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph) BLI_assert(bmain != NULL); BLI_assert(graph != NULL); /* Nothing to update, early out. */ - if (BLI_gset_size(graph->entry_tags) == 0) { + if (BLI_gset_len(graph->entry_tags) == 0) { return; } /* Reset all flags, get ready for the flush. */ diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.cc b/source/blender/depsgraph/intern/nodes/deg_node_component.cc index 1f56edd1f87..6c33856555e 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.cc @@ -301,7 +301,7 @@ OperationDepsNode *ComponentDepsNode::get_entry_operation() if (entry_operation) { return entry_operation; } - else if (operations_map != NULL && BLI_ghash_size(operations_map) == 1) { + else if (operations_map != NULL && BLI_ghash_len(operations_map) == 1) { OperationDepsNode *op_node = NULL; /* TODO(sergey): This is somewhat slow. */ GHASH_FOREACH_BEGIN(OperationDepsNode *, tmp, operations_map) @@ -324,7 +324,7 @@ OperationDepsNode *ComponentDepsNode::get_exit_operation() if (exit_operation) { return exit_operation; } - else if (operations_map != NULL && BLI_ghash_size(operations_map) == 1) { + else if (operations_map != NULL && BLI_ghash_len(operations_map) == 1) { OperationDepsNode *op_node = NULL; /* TODO(sergey): This is somewhat slow. */ GHASH_FOREACH_BEGIN(OperationDepsNode *, tmp, operations_map) @@ -344,7 +344,7 @@ OperationDepsNode *ComponentDepsNode::get_exit_operation() void ComponentDepsNode::finalize_build(Depsgraph * /*graph*/) { - operations.reserve(BLI_ghash_size(operations_map)); + operations.reserve(BLI_ghash_len(operations_map)); GHASH_FOREACH_BEGIN(OperationDepsNode *, op_node, operations_map) { operations.push_back(op_node); diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 1bff4b875ce..51b3db695c2 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -92,6 +92,7 @@ set(SRC engines/eevee/eevee_lightprobes.c engines/eevee/eevee_lights.c engines/eevee/eevee_materials.c + engines/eevee/eevee_mist.c engines/eevee/eevee_motion_blur.c engines/eevee/eevee_occlusion.c engines/eevee/eevee_render.c @@ -161,6 +162,7 @@ data_to_c_simple(engines/eevee/shaders/effect_downsample_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_downsample_cube_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_gtao_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_minmaxz_frag.glsl SRC) +data_to_c_simple(engines/eevee/shaders/effect_mist_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_motion_blur_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_ssr_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_subsurface_frag.glsl SRC) diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index c4946e2a4b8..9baad113c42 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -26,6 +26,8 @@ #ifndef __DRW_ENGINE_H__ #define __DRW_ENGINE_H__ +#include "BLI_sys_types.h" /* for bool */ + struct ARegion; struct CollectionEngineSettings; struct Depsgraph; @@ -50,7 +52,7 @@ struct RenderEngine; struct RenderEngineType; struct WorkSpace; -#include "BLI_sys_types.h" /* for bool */ +#include "DNA_object_enums.h" /* Buffer and textures used by the viewport by default */ typedef struct DefaultFramebufferList { @@ -91,25 +93,25 @@ void DRW_draw_view(const struct bContext *C); void DRW_draw_render_loop_ex( struct Depsgraph *depsgraph, struct RenderEngineType *engine_type, - struct ARegion *ar, struct View3D *v3d, + struct ARegion *ar, struct View3D *v3d, const eObjectMode object_mode, const struct bContext *evil_C); void DRW_draw_render_loop( struct Depsgraph *depsgraph, - struct ARegion *ar, struct View3D *v3d); + struct ARegion *ar, struct View3D *v3d, const eObjectMode object_mode); void DRW_draw_render_loop_offscreen( struct Depsgraph *depsgraph, struct RenderEngineType *engine_type, - struct ARegion *ar, struct View3D *v3d, + struct ARegion *ar, struct View3D *v3d, const eObjectMode object_mode, const bool draw_background, struct GPUOffScreen *ofs, struct GPUViewport *viewport); void DRW_draw_select_loop( struct Depsgraph *depsgraph, - struct ARegion *ar, struct View3D *v3d, + struct ARegion *ar, struct View3D *v3d, const eObjectMode object_mode, bool use_obedit_skip, bool use_nearest, const struct rcti *rect); void DRW_draw_depth_loop( struct Depsgraph *depsgraph, - struct ARegion *ar, struct View3D *v3d); + struct ARegion *ar, struct View3D *v3d, const eObjectMode object_mode); /* This is here because GPUViewport needs it */ void DRW_pass_free(struct DRWPass *pass); diff --git a/source/blender/draw/engines/clay/clay_engine.c b/source/blender/draw/engines/clay/clay_engine.c index d2bf164efdc..4b554f776a6 100644 --- a/source/blender/draw/engines/clay/clay_engine.c +++ b/source/blender/draw/engines/clay/clay_engine.c @@ -116,8 +116,6 @@ typedef struct CLAY_Storage { typedef struct CLAY_StorageList { struct CLAY_Storage *storage; - struct GPUUniformBuffer *mat_ubo; - struct GPUUniformBuffer *hair_mat_ubo; struct CLAY_PrivateData *g_data; } CLAY_StorageList; @@ -146,6 +144,9 @@ typedef struct CLAY_Data { typedef struct CLAY_ViewLayerData { struct GPUTexture *jitter_tx; + struct GPUUniformBuffer *mat_ubo; + struct GPUUniformBuffer *matcaps_ubo; + struct GPUUniformBuffer *hair_mat_ubo; struct GPUUniformBuffer *sampling_ubo; int cached_sample_num; } CLAY_ViewLayerData; @@ -162,7 +163,7 @@ static struct { /* Matcap textures */ struct GPUTexture *matcap_array; - float matcap_colors[24][3]; + float matcap_colors[24][4]; /* Ssao */ float winmat[4][4]; @@ -192,6 +193,9 @@ static void clay_view_layer_data_free(void *storage) { CLAY_ViewLayerData *sldata = (CLAY_ViewLayerData *)storage; + DRW_UBO_FREE_SAFE(sldata->mat_ubo); + DRW_UBO_FREE_SAFE(sldata->matcaps_ubo); + DRW_UBO_FREE_SAFE(sldata->hair_mat_ubo); DRW_UBO_FREE_SAFE(sldata->sampling_ubo); DRW_TEXTURE_FREE_SAFE(sldata->jitter_tx); } @@ -399,12 +403,16 @@ static void clay_engine_init(void *vedata) stl->storage = MEM_callocN(sizeof(CLAY_Storage), "CLAY_Storage"); } - if (!stl->mat_ubo) { - stl->mat_ubo = DRW_uniformbuffer_create(sizeof(CLAY_UBO_Storage), NULL); + if (!sldata->mat_ubo) { + sldata->mat_ubo = DRW_uniformbuffer_create(sizeof(CLAY_UBO_Storage), NULL); + } + + if (!sldata->hair_mat_ubo) { + sldata->hair_mat_ubo = DRW_uniformbuffer_create(sizeof(CLAY_HAIR_UBO_Storage), NULL); } - if (!stl->hair_mat_ubo) { - stl->hair_mat_ubo = DRW_uniformbuffer_create(sizeof(CLAY_HAIR_UBO_Storage), NULL); + if (!sldata->matcaps_ubo) { + sldata->matcaps_ubo = DRW_uniformbuffer_create(sizeof(e_data.matcap_colors), e_data.matcap_colors); } if (e_data.ubo_mat_idxs[1] == 0) { @@ -495,9 +503,8 @@ static void clay_engine_init(void *vedata) } } -static DRWShadingGroup *CLAY_shgroup_create(CLAY_Data *vedata, DRWPass *pass, int *material_id, bool use_flat) +static DRWShadingGroup *CLAY_shgroup_create(CLAY_Data *UNUSED(vedata), DRWPass *pass, int *material_id, bool use_flat) { - CLAY_StorageList *stl = vedata->stl; CLAY_ViewLayerData *sldata = CLAY_view_layer_data_get(); DRWShadingGroup *grp = DRW_shgroup_create(use_flat ? e_data.clay_flat_sh : e_data.clay_sh, pass); @@ -507,25 +514,26 @@ static DRWShadingGroup *CLAY_shgroup_create(CLAY_Data *vedata, DRWPass *pass, in DRW_shgroup_uniform_mat4(grp, "WinMatrix", (float *)e_data.winmat); DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)e_data.viewvecs, 3); DRW_shgroup_uniform_vec4(grp, "ssao_params", e_data.ssao_params, 1); - DRW_shgroup_uniform_vec3(grp, "matcaps_color[0]", (float *)e_data.matcap_colors, 24); DRW_shgroup_uniform_int(grp, "mat_id", material_id, 1); DRW_shgroup_uniform_texture(grp, "ssao_jitter", sldata->jitter_tx); DRW_shgroup_uniform_block(grp, "samples_block", sldata->sampling_ubo); - DRW_shgroup_uniform_block(grp, "material_block", stl->mat_ubo); + DRW_shgroup_uniform_block(grp, "material_block", sldata->mat_ubo); + DRW_shgroup_uniform_block(grp, "matcaps_block", sldata->matcaps_ubo); return grp; } -static DRWShadingGroup *CLAY_hair_shgroup_create(CLAY_Data *vedata, DRWPass *pass, int *material_id) +static DRWShadingGroup *CLAY_hair_shgroup_create(CLAY_Data *UNUSED(vedata), DRWPass *pass, int *material_id) { - CLAY_StorageList *stl = vedata->stl; + CLAY_ViewLayerData *sldata = CLAY_view_layer_data_get(); DRWShadingGroup *grp = DRW_shgroup_create(e_data.hair_sh, pass); DRW_shgroup_uniform_texture(grp, "matcaps", e_data.matcap_array); DRW_shgroup_uniform_int(grp, "mat_id", material_id, 1); - DRW_shgroup_uniform_block(grp, "material_block", stl->mat_ubo); + DRW_shgroup_uniform_block(grp, "material_block", sldata->mat_ubo); + DRW_shgroup_uniform_block(grp, "matcaps_block", sldata->matcaps_ubo); return grp; } @@ -762,11 +770,7 @@ static void clay_cache_populate_particles(void *vedata, Object *ob) CLAY_StorageList *stl = ((CLAY_Data *)vedata)->stl; const DRWContextState *draw_ctx = DRW_context_state_get(); - - Scene *scene = draw_ctx->scene; - Object *obedit = scene->obedit; - - if (ob != obedit) { + if (ob != draw_ctx->object_edit) { for (ParticleSystem *psys = ob->particlesystem.first; psys; psys = psys->next) { if (psys_check_enabled(ob, psys, false)) { ParticleSettings *part = psys->part; @@ -820,7 +824,7 @@ static void clay_cache_populate(void *vedata, Object *ob) if (geom) { IDProperty *ces_mode_ob = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_OBJECT, ""); const bool do_cull = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_backface_culling"); - const bool is_sculpt_mode = is_active && (ob->mode & OB_MODE_SCULPT) != 0; + const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0; const bool is_default_mode_shader = is_sculpt_mode; /* Depth Prepass */ @@ -853,10 +857,11 @@ static void clay_cache_populate(void *vedata, Object *ob) static void clay_cache_finish(void *vedata) { + CLAY_ViewLayerData *sldata = CLAY_view_layer_data_get(); CLAY_StorageList *stl = ((CLAY_Data *)vedata)->stl; - DRW_uniformbuffer_update(stl->mat_ubo, &stl->storage->mat_storage); - DRW_uniformbuffer_update(stl->hair_mat_ubo, &stl->storage->hair_mat_storage); + DRW_uniformbuffer_update(sldata->mat_ubo, &stl->storage->mat_storage); + DRW_uniformbuffer_update(sldata->hair_mat_ubo, &stl->storage->hair_mat_storage); } static void clay_draw_scene(void *vedata) diff --git a/source/blender/draw/engines/clay/shaders/clay_frag.glsl b/source/blender/draw/engines/clay/shaders/clay_frag.glsl index 9c8c90bd5b6..619843e2a02 100644 --- a/source/blender/draw/engines/clay/shaders/clay_frag.glsl +++ b/source/blender/draw/engines/clay/shaders/clay_frag.glsl @@ -4,7 +4,6 @@ uniform mat4 WinMatrix; /* Matcap */ uniform sampler2DArray matcaps; -uniform vec3 matcaps_color[24]; /* Screen Space Occlusion */ /* store the view space vectors for the corners of the view frustum here. @@ -26,6 +25,10 @@ layout(std140) uniform samples_block { vec4 ssao_samples[500]; }; +layout(std140) uniform matcaps_block { + vec4 matcaps_color[24]; +}; + layout(std140) uniform material_block { Material matcaps_param[MAX_MATERIAL]; }; @@ -185,7 +188,7 @@ void main() { float cavity, edges; ssao_factors(depth, normal, position, screenco, cavity, edges); - col *= mix(vec3(1.0), matcaps_color[int(matcap_index)], cavity); + col *= mix(vec3(1.0), matcaps_color[int(matcap_index)].rgb, cavity); #endif #ifdef USE_HSV diff --git a/source/blender/draw/engines/eevee/eevee_bloom.c b/source/blender/draw/engines/eevee/eevee_bloom.c index 63c030a574f..1b015a51f6a 100644 --- a/source/blender/draw/engines/eevee/eevee_bloom.c +++ b/source/blender/draw/engines/eevee/eevee_bloom.c @@ -145,14 +145,8 @@ int EEVEE_bloom_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) for (int i = 0; i < effects->bloom_iteration_ct; ++i) { texsize[0] /= 2; texsize[1] /= 2; - if (GPU_type_matches(GPU_DEVICE_AMD_VEGA, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE)) { - texsize[0] = MAX2(texsize[0], 17); - texsize[1] = MAX2(texsize[1], 17); - } - else { - texsize[0] = MAX2(texsize[0], 2); - texsize[1] = MAX2(texsize[1], 2); - } + texsize[0] = MAX2(texsize[0], 2); + texsize[1] = MAX2(texsize[1], 2); effects->downsamp_texel_size[i][0] = 1.0f / (float)texsize[0]; effects->downsamp_texel_size[i][1] = 1.0f / (float)texsize[1]; @@ -168,14 +162,8 @@ int EEVEE_bloom_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) for (int i = 0; i < effects->bloom_iteration_ct - 1; ++i) { texsize[0] /= 2; texsize[1] /= 2; - if (GPU_type_matches(GPU_DEVICE_AMD_VEGA, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE)) { - texsize[0] = MAX2(texsize[0], 17); - texsize[1] = MAX2(texsize[1], 17); - } - else { - texsize[0] = MAX2(texsize[0], 2); - texsize[1] = MAX2(texsize[1], 2); - } + texsize[0] = MAX2(texsize[0], 2); + texsize[1] = MAX2(texsize[1], 2); DRWFboTexture tex_bloom = {&txl->bloom_upsample[i], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER}; DRW_framebuffer_init(&fbl->bloom_accum_fb[i], &draw_engine_eevee_type, diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c index c6e5f645f10..449668d8590 100644 --- a/source/blender/draw/engines/eevee/eevee_data.c +++ b/source/blender/draw/engines/eevee/eevee_data.c @@ -143,8 +143,8 @@ EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_ensure(Object *ob) ob, &draw_engine_eevee_type, sizeof(EEVEE_LightProbeEngineData), - &eevee_lightprobe_data_init, - &eevee_lightprobe_data_free); + eevee_lightprobe_data_init, + eevee_lightprobe_data_free); } /* Lamp data. */ diff --git a/source/blender/draw/engines/eevee/eevee_depth_of_field.c b/source/blender/draw/engines/eevee/eevee_depth_of_field.c index f5fc79aba4f..dcd45e27337 100644 --- a/source/blender/draw/engines/eevee/eevee_depth_of_field.c +++ b/source/blender/draw/engines/eevee/eevee_depth_of_field.c @@ -32,7 +32,7 @@ #include "DNA_anim_types.h" #include "DNA_camera_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_screen_types.h" #include "DNA_view3d_types.h" #include "DNA_world_types.h" diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c index c1ac085230e..751b9a0f7d6 100644 --- a/source/blender/draw/engines/eevee/eevee_effects.c +++ b/source/blender/draw/engines/eevee/eevee_effects.c @@ -105,9 +105,10 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_TextureList *txl = vedata->txl; EEVEE_EffectsInfo *effects; + const DRWContextState *draw_ctx = DRW_context_state_get(); + ViewLayer *view_layer = draw_ctx->view_layer; const float *viewport_size = DRW_viewport_size_get(); - /* Shaders */ if (!e_data.downsample_sh) { eevee_create_shader_downsample(); @@ -129,6 +130,13 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object effects->enabled_effects |= EEVEE_screen_raytrace_init(sldata, vedata); effects->enabled_effects |= EEVEE_volumes_init(sldata, vedata); + /* Force normal buffer creation. */ + if (DRW_state_is_image_render() && + (view_layer->passflag & SCE_PASS_NORMAL) != 0) + { + effects->enabled_effects |= EFFECT_NORMAL_BUFFER; + } + /** * Ping Pong buffer */ @@ -233,7 +241,8 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) { static int zero = 0; psl->color_downsample_cube_ps = DRW_pass_create("Downsample Cube", DRW_STATE_WRITE_COLOR); - DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.downsample_cube_sh, psl->color_downsample_cube_ps, quad); + DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.downsample_cube_sh, psl->color_downsample_cube_ps, + quad, NULL); DRW_shgroup_uniform_buffer(grp, "source", &e_data.color_src); DRW_shgroup_uniform_float(grp, "texelSize", &e_data.cube_texel_size, 1); DRW_shgroup_uniform_int(grp, "Layer", &zero, 1); diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index 8e74f3344dd..4a7258d6525 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -177,6 +177,9 @@ static void eevee_draw_background(void *vedata) DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + /* Sort transparents before the loop. */ + DRW_pass_sort_shgroup_z(psl->transparent_pass); + /* Number of iteration: needed for all temporal effect (SSR, TAA) * when using opengl render. */ int loop_ct = DRW_state_is_image_render() ? 4 : 1; @@ -187,15 +190,18 @@ static void eevee_draw_background(void *vedata) double r[3]; if (DRW_state_is_image_render() || - ((stl->effects->enabled_effects & EFFECT_TAA) != 0)) + ((stl->effects->enabled_effects & EFFECT_TAA) != 0)) { BLI_halton_3D(primes, offset, stl->effects->taa_current_sample, r); EEVEE_update_noise(psl, fbl, r); + EEVEE_volumes_set_jitter(sldata, stl->effects->taa_current_sample - 1); + EEVEE_materials_init(sldata, stl, fbl); } /* Refresh Probes */ DRW_stats_group_start("Probes Refresh"); EEVEE_lightprobes_refresh(sldata, vedata); + EEVEE_lightprobes_refresh_planar(sldata, vedata); DRW_stats_group_end(); /* Update common buffer after probe rendering. */ @@ -220,8 +226,8 @@ static void eevee_draw_background(void *vedata) } if (((stl->effects->enabled_effects & EFFECT_TAA) != 0) && - (stl->effects->taa_current_sample > 1) && - !DRW_state_is_image_render()) + (stl->effects->taa_current_sample > 1) && + !DRW_state_is_image_render()) { DRW_viewport_matrix_override_set(stl->effects->overide_persmat, DRW_MAT_PERS); DRW_viewport_matrix_override_set(stl->effects->overide_persinv, DRW_MAT_PERSINV); @@ -271,7 +277,6 @@ static void eevee_draw_background(void *vedata) EEVEE_volumes_resolve(sldata, vedata); /* Transparent */ - DRW_pass_sort_shgroup_z(psl->transparent_pass); DRW_draw_pass(psl->transparent_pass); /* Post Process */ @@ -372,15 +377,15 @@ static void eevee_id_update(void *vedata, ID *id) } } -static void eevee_render_to_image(void *vedata, struct RenderEngine *engine, struct Depsgraph *depsgraph) +static void eevee_render_to_image(void *vedata, RenderEngine *engine, struct RenderResult *render_result, struct RenderLayer *render_layer) { - EEVEE_render_init(vedata, engine, depsgraph); + const DRWContextState *draw_ctx = DRW_context_state_get(); + EEVEE_render_init(vedata, engine, draw_ctx->depsgraph); + + DRW_render_object_iter(vedata, engine, draw_ctx->depsgraph, EEVEE_render_cache); - DRW_render_object_iter(vedata, engine, depsgraph, EEVEE_render_cache); /* Actually do the rendering. */ - EEVEE_render_draw(vedata, engine, depsgraph); - /* Write outputs to RenderResult. */ - EEVEE_render_output(vedata, engine, depsgraph); + EEVEE_render_draw(vedata, engine, render_result, render_layer); } static void eevee_engine_free(void) @@ -391,6 +396,7 @@ static void eevee_engine_free(void) EEVEE_lightprobes_free(); EEVEE_lights_free(); EEVEE_materials_free(); + EEVEE_mist_free(); EEVEE_motion_blur_free(); EEVEE_occlusion_free(); EEVEE_screen_raytrace_free(); @@ -497,7 +503,8 @@ DrawEngineType draw_engine_eevee_type = { RenderEngineType DRW_engine_viewport_eevee_type = { NULL, NULL, EEVEE_ENGINE, N_("Eevee"), RE_INTERNAL | RE_USE_SHADING_NODES, - NULL, &DRW_render_to_image, NULL, NULL, NULL, NULL, NULL, + NULL, &DRW_render_to_image, NULL, NULL, NULL, NULL, + &EEVEE_render_update_passes, &eevee_layer_collection_settings_create, &eevee_view_layer_settings_create, &draw_engine_eevee_type, diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index 7403da737dd..b4de6081457 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -36,6 +36,7 @@ #include "DNA_view3d_types.h" #include "BKE_object.h" +#include "MEM_guardedalloc.h" #include "GPU_material.h" #include "GPU_texture.h" @@ -82,6 +83,9 @@ static struct { struct GPUTexture *depth_array_placeholder; struct GPUTexture *cube_face_minmaxz; + struct Gwn_VertFormat *format_probe_display_cube; + struct Gwn_VertFormat *format_probe_display_planar; + int update_world; } e_data = {NULL}; /* Engine data */ @@ -433,9 +437,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat { psl->probe_glossy_compute = DRW_pass_create("LightProbe Glossy Compute", DRW_STATE_WRITE_COLOR); - struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get(); - - DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.probe_filter_glossy_sh, psl->probe_glossy_compute, geom); + DRWShadingGroup *grp = DRW_shgroup_create(e_data.probe_filter_glossy_sh, psl->probe_glossy_compute); DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1); DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_ct, 1); DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->invsamples_ct, 1); @@ -448,8 +450,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley); // DRW_shgroup_uniform_texture(grp, "texJitter", e_data.jitter); DRW_shgroup_uniform_texture(grp, "probeHdr", sldata->probe_rt); - - DRW_shgroup_set_instance_count(grp, 1); + DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL); } { @@ -505,18 +506,32 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK; psl->probe_display = DRW_pass_create("LightProbe Display", state); - struct Gwn_Batch *geom = DRW_cache_sphere_get(); - DRWShadingGroup *grp = stl->g_data->cube_display_shgrp = DRW_shgroup_instance_create(e_data.probe_cube_display_sh, psl->probe_display, geom); - DRW_shgroup_attrib_float(grp, "probe_id", 1); /* XXX this works because we are still uploading 4bytes and using the right stride */ - DRW_shgroup_attrib_float(grp, "probe_location", 3); - DRW_shgroup_attrib_float(grp, "sphere_size", 1); + DRW_shgroup_instance_format(e_data.format_probe_display_cube, { + {"probe_id", DRW_ATTRIB_INT, 1}, + {"probe_location", DRW_ATTRIB_FLOAT, 3}, + {"sphere_size", DRW_ATTRIB_FLOAT, 1}, + }); + + DRWShadingGroup *grp = DRW_shgroup_instance_create( + e_data.probe_cube_display_sh, + psl->probe_display, + DRW_cache_sphere_get(), + e_data.format_probe_display_cube); + stl->g_data->cube_display_shgrp = grp; DRW_shgroup_uniform_buffer(grp, "probeCubes", &sldata->probe_pool); DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); - geom = DRW_cache_quad_get(); - grp = stl->g_data->planar_display_shgrp = DRW_shgroup_instance_create(e_data.probe_planar_display_sh, psl->probe_display, geom); - DRW_shgroup_attrib_float(grp, "probe_id", 1); /* XXX this works because we are still uploading 4bytes and using the right stride */ - DRW_shgroup_attrib_float(grp, "probe_mat", 16); + DRW_shgroup_instance_format(e_data.format_probe_display_planar, { + {"probe_id", DRW_ATTRIB_INT, 1}, + {"probe_mat", DRW_ATTRIB_FLOAT, 16}, + }); + + grp = DRW_shgroup_instance_create( + e_data.probe_planar_display_sh, + psl->probe_display, + DRW_cache_quad_get(), + e_data.format_probe_display_planar); + stl->g_data->planar_display_shgrp = grp; DRW_shgroup_uniform_buffer(grp, "probePlanars", &txl->planar_pool); } @@ -524,7 +539,11 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat psl->probe_planar_downsample_ps = DRW_pass_create("LightProbe Planar Downsample", DRW_STATE_WRITE_COLOR); struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get(); - DRWShadingGroup *grp = stl->g_data->planar_downsample = DRW_shgroup_instance_create(e_data.probe_planar_downsample_sh, psl->probe_planar_downsample_ps, geom); + DRWShadingGroup *grp = DRW_shgroup_instance_create( + e_data.probe_planar_downsample_sh, + psl->probe_planar_downsample_ps, + geom, NULL); + stl->g_data->planar_downsample = grp; DRW_shgroup_uniform_buffer(grp, "source", &txl->planar_pool); DRW_shgroup_uniform_float(grp, "fireflyFactor", &sldata->common_data.ssr_firefly_fac, 1); } @@ -548,7 +567,7 @@ void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, Object *ob) ped->num_cell = probe->grid_resolution_x * probe->grid_resolution_y * probe->grid_resolution_z; if ((probe->type == LIGHTPROBE_TYPE_GRID) && - ((pinfo->total_irradiance_samples + ped->num_cell) >= MAX_IRRADIANCE_SAMPLES)) + ((pinfo->total_irradiance_samples + ped->num_cell) >= MAX_IRRADIANCE_SAMPLES)) { printf("Too much grid samples !!!\n"); return; @@ -818,16 +837,20 @@ static void EEVEE_lightprobes_updates(EEVEE_ViewLayerData *sldata, EEVEE_PassLis /* Visibility bias */ egrid->visibility_bias = 0.05f * probe->vis_bias; egrid->visibility_bleed = probe->vis_bleedbias; - egrid->visibility_range = max_ff(max_ff(len_v3(egrid->increment_x), - len_v3(egrid->increment_y)), - len_v3(egrid->increment_z)) + 1.0f; + egrid->visibility_range = ( + sqrtf(max_fff(len_squared_v3(egrid->increment_x), + len_squared_v3(egrid->increment_y), + len_squared_v3(egrid->increment_z))) + 1.0f); /* Debug Display */ if (DRW_state_draw_support() && (probe->flag & LIGHTPROBE_FLAG_SHOW_DATA)) { struct Gwn_Batch *geom = DRW_cache_sphere_get(); - DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.probe_grid_display_sh, psl->probe_display, geom); + DRWShadingGroup *grp = DRW_shgroup_instance_create( + e_data.probe_grid_display_sh, + psl->probe_display, + geom, NULL); DRW_shgroup_set_instance_count(grp, ped->num_cell); DRW_shgroup_uniform_int(grp, "offset", &egrid->offset, 1); DRW_shgroup_uniform_ivec3(grp, "grid_resolution", egrid->resolution, 1); @@ -1420,7 +1443,7 @@ static void lightprobes_refresh_initialize_grid(EEVEE_ViewLayerData *sldata, EEV pinfo->grid_initialized = true; } -static void lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) +void EEVEE_lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) { EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; EEVEE_TextureList *txl = vedata->txl; @@ -1428,6 +1451,8 @@ static void lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data * EEVEE_LightProbesInfo *pinfo = sldata->probes; if (pinfo->num_planar == 0) { + /* Disable SSR if we cannot read previous frame */ + common_data->ssr_toggle = vedata->stl->g_data->valid_double_buffer; return; } @@ -1464,6 +1489,9 @@ static void lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data * common_data->prb_lod_planar_max = (float)(max_lod); DRW_stats_group_end(); } + + /* Disable SSR if we cannot read previous frame */ + common_data->ssr_toggle = vedata->stl->g_data->valid_double_buffer; } static void lightprobes_refresh_cube(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) @@ -1497,6 +1525,8 @@ static void lightprobes_refresh_cube(EEVEE_ViewLayerData *sldata, EEVEE_Data *ve /* Only do one probe per frame */ return; } + + pinfo->do_cube_update = false; } static void lightprobes_refresh_all_no_world(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) @@ -1645,11 +1675,20 @@ static void lightprobes_refresh_all_no_world(EEVEE_ViewLayerData *sldata, EEVEE_ lightprobes_refresh_cube(sldata, vedata); } -void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) +bool EEVEE_lightprobes_all_probes_ready(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(vedata)) { EEVEE_LightProbesInfo *pinfo = sldata->probes; EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; + return ((pinfo->do_cube_update == false) && + (pinfo->updated_bounce == pinfo->num_bounce) && + (common_data->prb_num_render_cube == pinfo->num_cube)); +} + +void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) +{ + EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; + /* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */ common_data->spec_toggle = false; common_data->ssr_toggle = false; @@ -1665,7 +1704,7 @@ void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) if (e_data.update_world) { lightprobes_refresh_world(sldata, vedata); } - else if (pinfo->do_cube_update || (pinfo->updated_bounce < pinfo->num_bounce)) { + else if (EEVEE_lightprobes_all_probes_ready(sldata, vedata) == false) { lightprobes_refresh_all_no_world(sldata, vedata); } @@ -1675,15 +1714,12 @@ void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) common_data->sss_toggle = true; common_data->ao_dist = tmp_ao_dist; common_data->ao_settings = tmp_ao_settings; - - lightprobes_refresh_planar(sldata, vedata); - - /* Disable SSR if we cannot read previous frame */ - common_data->ssr_toggle = vedata->stl->g_data->valid_double_buffer; } void EEVEE_lightprobes_free(void) { + MEM_SAFE_FREE(e_data.format_probe_display_cube); + MEM_SAFE_FREE(e_data.format_probe_display_planar); DRW_SHADER_FREE_SAFE(e_data.probe_default_sh); DRW_SHADER_FREE_SAFE(e_data.probe_filter_glossy_sh); DRW_SHADER_FREE_SAFE(e_data.probe_filter_diffuse_sh); diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c index 69b58bf9670..582f7ea747a 100644 --- a/source/blender/draw/engines/eevee/eevee_lights.c +++ b/source/blender/draw/engines/eevee/eevee_lights.c @@ -343,7 +343,7 @@ void EEVEE_lights_cache_add(EEVEE_ViewLayerData *sldata, Object *ob) /* For light update tracking. */ if ((prev_cube_sh_id >= 0) && - (prev_cube_sh_id < linfo->shcaster_backbuffer->count)) + (prev_cube_sh_id < linfo->shcaster_backbuffer->count)) { linfo->new_shadow_id[prev_cube_sh_id] = linfo->cpu_cube_ct; } @@ -380,12 +380,12 @@ void EEVEE_lights_cache_add(EEVEE_ViewLayerData *sldata, Object *ob) void EEVEE_lights_cache_shcaster_add( EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl, struct Gwn_Batch *geom, float (*obmat)[4]) { - DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.shadow_sh, psl->shadow_cube_pass, geom); + DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.shadow_sh, psl->shadow_cube_pass, geom, NULL); DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo); DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat); DRW_shgroup_set_instance_count(grp, 6); - grp = DRW_shgroup_instance_create(e_data.shadow_sh, psl->shadow_cascade_pass, geom); + grp = DRW_shgroup_instance_create(e_data.shadow_sh, psl->shadow_cascade_pass, geom, NULL); DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo); DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat); DRW_shgroup_set_instance_count(grp, MAX_CASCADE_NUM); @@ -395,7 +395,7 @@ void EEVEE_lights_cache_shcaster_material_add( EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl, struct GPUMaterial *gpumat, struct Gwn_Batch *geom, struct Object *ob, float (*obmat)[4], float *alpha_threshold) { - DRWShadingGroup *grp = DRW_shgroup_material_instance_create(gpumat, psl->shadow_cube_pass, geom, ob); + DRWShadingGroup *grp = DRW_shgroup_material_instance_create(gpumat, psl->shadow_cube_pass, geom, ob, NULL); if (grp == NULL) return; @@ -407,7 +407,7 @@ void EEVEE_lights_cache_shcaster_material_add( DRW_shgroup_set_instance_count(grp, 6); - grp = DRW_shgroup_material_instance_create(gpumat, psl->shadow_cascade_pass, geom, ob); + grp = DRW_shgroup_material_instance_create(gpumat, psl->shadow_cascade_pass, geom, ob, NULL); DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo); DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat); diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 84627e03137..0e444039573 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -471,7 +471,7 @@ static void eevee_init_util_texture(void) MEM_freeN(texels); } -void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, double offsets[3]) +void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const double offsets[3]) { e_data.noise_offsets[0] = offsets[0]; e_data.noise_offsets[1] = offsets[1]; @@ -485,6 +485,46 @@ void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, double DRW_framebuffer_texture_detach(e_data.util_tex); } +static void EEVEE_update_viewvecs(float invproj[4][4], float winmat[4][4], float (*r_viewvecs)[4]) +{ + /* view vectors for the corners of the view frustum. + * Can be used to recreate the world space position easily */ + float view_vecs[4][4] = { + {-1.0f, -1.0f, -1.0f, 1.0f}, + { 1.0f, -1.0f, -1.0f, 1.0f}, + {-1.0f, 1.0f, -1.0f, 1.0f}, + {-1.0f, -1.0f, 1.0f, 1.0f} + }; + + /* convert the view vectors to view space */ + const bool is_persp = (winmat[3][3] == 0.0f); + for (int i = 0; i < 4; i++) { + mul_project_m4_v3(invproj, view_vecs[i]); + /* normalized trick see: + * http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */ + if (is_persp) { + /* Divide XY by Z. */ + mul_v2_fl(view_vecs[i], 1.0f / view_vecs[i][2]); + } + } + + /** + * If ortho : view_vecs[0] is the near-bottom-left corner of the frustum and + * view_vecs[1] is the vector going from the near-bottom-left corner to + * the far-top-right corner. + * If Persp : view_vecs[0].xy and view_vecs[1].xy are respectively the bottom-left corner + * when Z = 1, and top-left corner if Z = 1. + * view_vecs[0].z the near clip distance and view_vecs[1].z is the (signed) + * distance from the near plane to the far clip plane. + **/ + copy_v4_v4(r_viewvecs[0], view_vecs[0]); + + /* we need to store the differences */ + r_viewvecs[1][0] = view_vecs[1][0] - view_vecs[0][0]; + r_viewvecs[1][1] = view_vecs[2][1] - view_vecs[0][1]; + r_viewvecs[1][2] = view_vecs[3][2] - view_vecs[0][2]; +} + void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, EEVEE_FramebufferList *fbl) { if (!e_data.frag_shader_lib) { @@ -553,60 +593,24 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, E eevee_init_noise_texture(); } - /* Alpha hash scale: Non-flickering size if we are not refining the render. */ if (!DRW_state_is_image_render() && - (((stl->effects->enabled_effects & EFFECT_TAA) == 0) || - (stl->effects->taa_current_sample == 1))) + ((stl->effects->enabled_effects & EFFECT_TAA) == 0)) { e_data.alpha_hash_offset = 0.0f; } else { double r; - BLI_halton_1D(5, 0.0, stl->effects->taa_current_sample, &r); + BLI_halton_1D(5, 0.0, stl->effects->taa_current_sample - 1, &r); e_data.alpha_hash_offset = (float)r; } { /* Update view_vecs */ float invproj[4][4], winmat[4][4]; - /* view vectors for the corners of the view frustum. - * Can be used to recreate the world space position easily */ - float view_vecs[3][4] = { - {-1.0f, -1.0f, -1.0f, 1.0f}, - {1.0f, -1.0f, -1.0f, 1.0f}, - {-1.0f, 1.0f, -1.0f, 1.0f} - }; - - /* invert the view matrix */ DRW_viewport_matrix_get(winmat, DRW_MAT_WIN); - invert_m4_m4(invproj, winmat); - const bool is_persp = (winmat[3][3] == 0.0f); - - /* convert the view vectors to view space */ - for (int i = 0; i < 3; i++) { - mul_m4_v4(invproj, view_vecs[i]); - /* normalized trick see: - * http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */ - mul_v3_fl(view_vecs[i], 1.0f / view_vecs[i][3]); - if (is_persp) - mul_v3_fl(view_vecs[i], 1.0f / view_vecs[i][2]); - view_vecs[i][3] = 1.0; - } - - copy_v4_v4(sldata->common_data.view_vecs[0], view_vecs[0]); - copy_v4_v4(sldata->common_data.view_vecs[1], view_vecs[1]); - - /* we need to store the differences */ - sldata->common_data.view_vecs[1][0] -= view_vecs[0][0]; - sldata->common_data.view_vecs[1][1] = view_vecs[2][1] - view_vecs[0][1]; + DRW_viewport_matrix_get(invproj, DRW_MAT_WININV); - /* calculate a depth offset as well */ - if (!is_persp) { - float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f}; - mul_m4_v4(invproj, vec_far); - mul_v3_fl(vec_far, 1.0f / vec_far[3]); - sldata->common_data.view_vecs[1][2] = vec_far[2] - view_vecs[0][2]; - } + EEVEE_update_viewvecs(invproj, winmat, sldata->common_data.view_vecs); } { @@ -1056,9 +1060,16 @@ static void material_opaque( DRW_shgroup_uniform_texture(*shgrp, "sssTexProfile", sss_tex_profile); } - DRW_shgroup_stencil_mask(*shgrp, e_data.sss_count + 1); - EEVEE_subsurface_add_pass(sldata, vedata, e_data.sss_count + 1, sss_profile); - e_data.sss_count++; + /* Limit of 8 bit stencil buffer. ID 255 is refraction. */ + if (e_data.sss_count < 254) { + DRW_shgroup_stencil_mask(*shgrp, e_data.sss_count + 1); + EEVEE_subsurface_add_pass(sldata, vedata, e_data.sss_count + 1, sss_profile); + e_data.sss_count++; + } + else { + /* TODO : display message. */ + printf("Error: Too many different Subsurface shader in the scene.\n"); + } } } } @@ -1230,7 +1241,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld IDProperty *ces_mode_ob = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_OBJECT, ""); const bool do_cull = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_backface_culling"); const bool is_active = (ob == draw_ctx->obact); - const bool is_sculpt_mode = is_active && (ob->mode & OB_MODE_SCULPT) != 0; + const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0; #if 0 const bool is_sculpt_mode_draw = is_sculpt_mode && (draw_ctx->v3d->flag2 & V3D_SHOW_MODE_SHADE_OVERRIDE) == 0; #else @@ -1366,7 +1377,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld } if (ob->type == OB_MESH) { - if (ob != draw_ctx->scene->obedit) { + if (ob != draw_ctx->object_edit) { material_hash = stl->g_data->hair_material_hash; for (ModifierData *md = ob->modifiers.first; md; md = md->next) { diff --git a/source/blender/draw/engines/eevee/eevee_mist.c b/source/blender/draw/engines/eevee/eevee_mist.c new file mode 100644 index 00000000000..ba9157a7f91 --- /dev/null +++ b/source/blender/draw/engines/eevee/eevee_mist.c @@ -0,0 +1,135 @@ +/* + * Copyright 2016, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Blender Institute + * + */ + +/** \file eevee_mist.c + * \ingroup draw_engine + * + * Implementation of Blender Mist pass. + * IMPORTANT: This is a "post process" of the Z depth so it will lack any transparent objects. + */ + +#include "DRW_engine.h" +#include "DRW_render.h" + +#include "DNA_world_types.h" + +#include "BLI_string_utils.h" + +#include "eevee_private.h" + +extern char datatoc_common_uniforms_lib_glsl[]; +extern char datatoc_bsdf_common_lib_glsl[]; +extern char datatoc_effect_mist_frag_glsl[]; + +static struct { + struct GPUShader *mist_sh; +} e_data = {NULL}; /* Engine data */ + +void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + EEVEE_FramebufferList *fbl = vedata->fbl; + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + EEVEE_TextureList *txl = vedata->txl; + EEVEE_StorageList *stl = vedata->stl; + EEVEE_PassList *psl = vedata->psl; + EEVEE_PrivateData *g_data = stl->g_data; + Scene *scene = draw_ctx->scene; + + const float *viewport_size = DRW_viewport_size_get(); + float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + + if (e_data.mist_sh == NULL) { + char *frag_str = BLI_string_joinN( + datatoc_common_uniforms_lib_glsl, + datatoc_bsdf_common_lib_glsl, + datatoc_effect_mist_frag_glsl); + + e_data.mist_sh = DRW_shader_create_fullscreen(frag_str, "#define FIRST_PASS\n"); + + MEM_freeN(frag_str); + } + + /* Create FrameBuffer. */ + DRWFboTexture tex_data = {&txl->mist_accum, DRW_TEX_R_32, 0}; /* Should be enough precision for many samples. */ + DRW_framebuffer_init(&fbl->mist_accum_fb, &draw_engine_eevee_type, (int)viewport_size[0], (int)viewport_size[1], + &tex_data, 1); + + /* Clear texture. */ + DRW_framebuffer_bind(fbl->mist_accum_fb); + DRW_framebuffer_clear(true, false, false, clear, 0.0f); + + /* Mist settings. */ + if (scene && scene->world) { + g_data->mist_start = scene->world->miststa; + g_data->mist_inv_dist = (scene->world->mistdist > 0.0f) ? 1.0f / scene->world->mistdist : 0.0f; + + switch (scene->world->mistype) { + case WO_MIST_QUADRATIC: + g_data->mist_falloff = 2.0f; + break; + case WO_MIST_LINEAR: + g_data->mist_falloff = 1.0f; + break; + case WO_MIST_INVERSE_QUADRATIC: + g_data->mist_falloff = 0.5f; + break; + } + } + else { + float near = -sldata->common_data.view_vecs[0][2]; + float range = sldata->common_data.view_vecs[1][2]; + /* Fallback */ + g_data->mist_start = near; + g_data->mist_inv_dist = 1.0f / fabsf(range); + g_data->mist_falloff = 1.0f; + } + + /* XXX ??!! WHY? If not it does not match cycles. */ + g_data->mist_falloff *= 0.5f; + + /* Create Pass and shgroup. */ + psl->mist_accum_ps = DRW_pass_create("Mist Accum", DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE); + DRWShadingGroup *grp = DRW_shgroup_create(e_data.mist_sh, psl->mist_accum_ps); + DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth); + DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); + DRW_shgroup_uniform_vec3(grp, "mistSettings", &g_data->mist_start, 1); + DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL); +} + +void EEVEE_mist_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) +{ + EEVEE_FramebufferList *fbl = vedata->fbl; + EEVEE_PassList *psl = vedata->psl; + + if (fbl->mist_accum_fb != NULL) { + DRW_framebuffer_bind(fbl->mist_accum_fb); + DRW_draw_pass(psl->mist_accum_ps); + + /* Restore */ + DRW_framebuffer_bind(fbl->main); + } +} + +void EEVEE_mist_free(void) +{ + DRW_SHADER_FREE_SAFE(e_data.mist_sh); +} diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c index 037bbe3b6c9..53fff5de50e 100644 --- a/source/blender/draw/engines/eevee/eevee_motion_blur.c +++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c @@ -79,6 +79,7 @@ static void eevee_motion_blur_camera_get_matrix_at_time( scene, draw_ctx->view_layer, draw_ctx->engine_type, + draw_ctx->object_mode, DAG_EVAL_VIEWPORT); eval_ctx.ctime = time; diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c index 9da438e825f..944003d7d1f 100644 --- a/source/blender/draw/engines/eevee/eevee_occlusion.c +++ b/source/blender/draw/engines/eevee/eevee_occlusion.c @@ -123,6 +123,48 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) return 0; } +void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) +{ + EEVEE_FramebufferList *fbl = vedata->fbl; + EEVEE_TextureList *txl = vedata->txl; + EEVEE_PassList *psl = vedata->psl; + const float *viewport_size = DRW_viewport_size_get(); + + const DRWContextState *draw_ctx = DRW_context_state_get(); + ViewLayer *view_layer = draw_ctx->view_layer; + IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE); + + if (BKE_collection_engine_property_value_get_bool(props, "gtao_enable")) { + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + + DRWFboTexture tex_data = {&txl->ao_accum, DRW_TEX_R_32, 0}; + DRW_framebuffer_init(&fbl->ao_accum_fb, &draw_engine_eevee_type, (int)viewport_size[0], (int)viewport_size[1], + &tex_data, 1); + + /* Clear texture. */ + DRW_framebuffer_bind(fbl->ao_accum_fb); + DRW_framebuffer_clear(true, false, false, clear, 0.0f); + + /* Accumulation pass */ + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE; + psl->ao_accum_ps = DRW_pass_create("AO Accum", state); + DRWShadingGroup *grp = DRW_shgroup_create(e_data.gtao_debug_sh, psl->ao_accum_ps); + DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex()); + DRW_shgroup_uniform_buffer(grp, "maxzBuffer", &txl->maxzbuffer); + DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth); + DRW_shgroup_uniform_buffer(grp, "normalBuffer", &txl->ssr_normal_input); + DRW_shgroup_uniform_buffer(grp, "horizonBuffer", &txl->gtao_horizons); + DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); + DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL); + } + else { + /* Cleanup to release memory */ + DRW_TEXTURE_FREE_SAFE(txl->ao_accum); + DRW_FRAMEBUFFER_FREE_SAFE(fbl->ao_accum_fb); + } +} + void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) { EEVEE_PassList *psl = vedata->psl; @@ -228,6 +270,26 @@ void EEVEE_occlusion_draw_debug(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data } } +void EEVEE_occlusion_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) +{ + EEVEE_FramebufferList *fbl = vedata->fbl; + EEVEE_PassList *psl = vedata->psl; + + if (fbl->ao_accum_fb != NULL) { + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + + /* Update the min_max/horizon buffers so the refracion materials appear in it. */ + EEVEE_create_minmax_buffer(vedata, dtxl->depth, -1); + EEVEE_occlusion_compute(sldata, vedata, dtxl->depth, -1); + + DRW_framebuffer_bind(fbl->ao_accum_fb); + DRW_draw_pass(psl->ao_accum_ps); + + /* Restore */ + DRW_framebuffer_bind(fbl->main); + } +} + void EEVEE_occlusion_free(void) { DRW_SHADER_FREE_SAFE(e_data.gtao_sh); diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 218de6ddd88..85d6dd8b448 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -29,6 +29,8 @@ struct Object; struct EEVEE_BoundSphere; struct EEVEE_ShadowCasterBuffer; +struct RenderLayer; +struct RenderResult; extern struct DrawEngineType draw_engine_eevee_type; @@ -160,6 +162,8 @@ typedef struct EEVEE_PassList { struct DRWPass *ao_horizon_search; struct DRWPass *ao_horizon_search_layer; struct DRWPass *ao_horizon_debug; + struct DRWPass *ao_accum_ps; + struct DRWPass *mist_accum_ps; struct DRWPass *motion_blur; struct DRWPass *bloom_blit; struct DRWPass *bloom_downsample_first; @@ -178,6 +182,7 @@ typedef struct EEVEE_PassList { struct DRWPass *ssr_resolve; struct DRWPass *sss_blur_ps; struct DRWPass *sss_resolve_ps; + struct DRWPass *sss_accum_ps; struct DRWPass *color_downsample_ps; struct DRWPass *color_downsample_cube_ps; struct DRWPass *taa_resolve; @@ -220,6 +225,7 @@ typedef struct EEVEE_FramebufferList { struct GPUFrameBuffer *bloom_accum_fb[MAX_BLOOM_STEP - 1]; struct GPUFrameBuffer *sss_blur_fb; struct GPUFrameBuffer *sss_clear_fb; + struct GPUFrameBuffer *sss_accum_fb; struct GPUFrameBuffer *dof_down_fb; struct GPUFrameBuffer *dof_scatter_far_fb; struct GPUFrameBuffer *dof_scatter_near_fb; @@ -228,6 +234,8 @@ typedef struct EEVEE_FramebufferList { struct GPUFrameBuffer *volumetric_integ_fb; struct GPUFrameBuffer *screen_tracing_fb; struct GPUFrameBuffer *refract_fb; + struct GPUFrameBuffer *mist_accum_fb; + struct GPUFrameBuffer *ao_accum_fb; struct GPUFrameBuffer *update_noise_fb; @@ -249,6 +257,10 @@ typedef struct EEVEE_TextureList { struct GPUTexture *bloom_blit; /* R16_G16_B16 */ struct GPUTexture *bloom_downsample[MAX_BLOOM_STEP]; /* R16_G16_B16 */ struct GPUTexture *bloom_upsample[MAX_BLOOM_STEP - 1]; /* R16_G16_B16 */ + struct GPUTexture *mist_accum; + struct GPUTexture *ao_accum; + struct GPUTexture *sss_dir_accum; + struct GPUTexture *sss_col_accum; struct GPUTexture *ssr_normal_input; struct GPUTexture *ssr_specrough_input; struct GPUTexture *ssr_hit_output; @@ -736,6 +748,8 @@ typedef struct EEVEE_PrivateData { float persmat[4][4], persinv[4][4]; float viewmat[4][4], viewinv[4][4]; float winmat[4][4], wininv[4][4]; + /* Mist Settings */ + float mist_start, mist_inv_dist, mist_falloff; } EEVEE_PrivateData; /* Transient data */ /* eevee_data.c */ @@ -765,7 +779,7 @@ struct GPUMaterial *EEVEE_material_mesh_depth_get(struct Scene *scene, Material struct GPUMaterial *EEVEE_material_hair_get(struct Scene *scene, Material *ma, int shadow_method); void EEVEE_materials_free(void); void EEVEE_draw_default_passes(EEVEE_PassList *psl); -void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, double offsets[3]); +void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const double offsets[3]); /* eevee_lights.c */ void EEVEE_lights_init(EEVEE_ViewLayerData *sldata); @@ -784,11 +798,13 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl); void EEVEE_lights_free(void); /* eevee_lightprobes.c */ +bool EEVEE_lightprobes_all_probes_ready(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, Object *ob); void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); +void EEVEE_lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_lightprobes_free(void); /* eevee_depth_of_field.c */ @@ -805,6 +821,8 @@ void EEVEE_bloom_free(void); /* eevee_occlusion.c */ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); +void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); +void EEVEE_occlusion_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_occlusion_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct GPUTexture *depth_src, int layer); void EEVEE_occlusion_draw_debug(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); @@ -820,10 +838,12 @@ void EEVEE_screen_raytrace_free(void); /* eevee_subsurface.c */ int EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); +void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_subsurface_add_pass( EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, unsigned int sss_id, struct GPUUniformBuffer *sss_profile); void EEVEE_subsurface_data_render(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_subsurface_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); +void EEVEE_subsurface_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_subsurface_free(void); /* eevee_motion_blur.c */ @@ -832,16 +852,22 @@ void EEVEE_motion_blur_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat void EEVEE_motion_blur_draw(EEVEE_Data *vedata); void EEVEE_motion_blur_free(void); +/* eevee_mist.c */ +void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); +void EEVEE_mist_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);; +void EEVEE_mist_free(void); + /* eevee_temporal_sampling.c */ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_temporal_sampling_matrices_calc( - EEVEE_EffectsInfo *effects, float viewmat[4][4], float persmat[4][4], double ht_point[2]); + EEVEE_EffectsInfo *effects, float viewmat[4][4], float persmat[4][4], const double ht_point[2]); void EEVEE_temporal_sampling_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_temporal_sampling_draw(EEVEE_Data *vedata); void EEVEE_temporal_sampling_free(void); /* eevee_volumes.c */ int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); +void EEVEE_volumes_set_jitter(EEVEE_ViewLayerData *sldata, unsigned int current_sample); void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct Scene *scene, Object *ob); void EEVEE_volumes_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); @@ -859,11 +885,11 @@ void EEVEE_effects_do_gtao(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_draw_effects(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_effects_free(void); -/* eevee_ */ +/* eevee_render.c */ void EEVEE_render_init(EEVEE_Data *vedata, struct RenderEngine *engine, struct Depsgraph *depsgraph); void EEVEE_render_cache(void *vedata, struct Object *ob, struct RenderEngine *engine, struct Depsgraph *depsgraph); -void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *engine, struct Depsgraph *depsgraph); -void EEVEE_render_output(EEVEE_Data *vedata, struct RenderEngine *engine, struct Depsgraph *depsgraph); +void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *engine, struct RenderResult *render_result, struct RenderLayer *render_layer); +void EEVEE_render_update_passes(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer); /* Shadow Matrix */ static const float texcomat[4][4] = { /* From NDC to TexCo */ diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c index a020887e420..f2db27f812f 100644 --- a/source/blender/draw/engines/eevee/eevee_render.c +++ b/source/blender/draw/engines/eevee/eevee_render.c @@ -30,6 +30,8 @@ #include "DRW_engine.h" #include "DRW_render.h" +#include "DNA_node_types.h" + #include "BLI_rand.h" #include "DEG_depsgraph_query.h" @@ -75,7 +77,7 @@ void EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph * stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__); } EEVEE_PrivateData *g_data = stl->g_data; - g_data->background_alpha = 1.0f; /* TODO option */ + g_data->background_alpha = DRW_state_draw_background() ? 1.0f : 0.0f; g_data->valid_double_buffer = 0; /* Alloc common ubo data. */ @@ -149,8 +151,228 @@ void EEVEE_render_cache( } } -void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *UNUSED(engine), struct Depsgraph *UNUSED(depsgraph)) +static void eevee_render_result_combined( + RenderResult *rr, RenderLayer *rl, const char *viewname, + EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata)) +{ + RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, viewname); + + DRW_framebuffer_bind(vedata->stl->effects->final_fb); + DRW_framebuffer_read_data(rr->xof, rr->yof, rr->rectx, rr->recty, 4, 0, rp->rect); +} + +static void eevee_render_result_subsurface( + RenderResult *rr, RenderLayer *rl, const char *viewname, + EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata)) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + ViewLayer *view_layer = draw_ctx->view_layer; + + if (vedata->fbl->sss_accum_fb == NULL) { + /* SSS is not enabled. */ + return; + } + + if ((view_layer->passflag & SCE_PASS_SUBSURFACE_COLOR) != 0) { + RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_SUBSURFACE_COLOR, viewname); + + IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE); + float render_samples = (float)BKE_collection_engine_property_value_get_int(props, "taa_render_samples"); + + DRW_framebuffer_bind(vedata->fbl->sss_accum_fb); + DRW_framebuffer_read_data(rr->xof, rr->yof, rr->rectx, rr->recty, 3, 1, rp->rect); + + /* This is the accumulated color. Divide by the number of samples. */ + for (int i = 0; i < rr->rectx * rr->recty * 3; i++) { + rp->rect[i] /= render_samples; + } + } + + if ((view_layer->passflag & SCE_PASS_SUBSURFACE_DIRECT) != 0) { + RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_SUBSURFACE_DIRECT, viewname); + + IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE); + float render_samples = (float)BKE_collection_engine_property_value_get_int(props, "taa_render_samples"); + + DRW_framebuffer_bind(vedata->fbl->sss_accum_fb); + DRW_framebuffer_read_data(rr->xof, rr->yof, rr->rectx, rr->recty, 3, 0, rp->rect); + + /* This is the accumulated color. Divide by the number of samples. */ + for (int i = 0; i < rr->rectx * rr->recty * 3; i++) { + rp->rect[i] /= render_samples; + } + } + + if ((view_layer->passflag & SCE_PASS_SUBSURFACE_INDIRECT) != 0) { + /* Do nothing as all the lighting is in the direct pass. + * TODO : Separate Direct from indirect lighting. */ + } +} + +static void eevee_render_result_normal( + RenderResult *rr, RenderLayer *rl, const char *viewname, + EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata)) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + ViewLayer *view_layer = draw_ctx->view_layer; + EEVEE_StorageList *stl = vedata->stl; + EEVEE_PrivateData *g_data = stl->g_data; + + /* Only read the center texel. */ + if (stl->effects->taa_current_sample > 1) + return; + + if ((view_layer->passflag & SCE_PASS_NORMAL) != 0) { + RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_NORMAL, viewname); + + DRW_framebuffer_read_data(rr->xof, rr->yof, rr->rectx, rr->recty, 3, 1, rp->rect); + + /* Convert Eevee encoded normals to Blender normals. */ + for (int i = 0; i < rr->rectx * rr->recty * 3; i += 3) { + if (rp->rect[i] == 0.0f && rp->rect[i + 1] == 0.0f) { + /* If normal is not correct then do not produce NANs. */ + continue; + } + + float fenc[2]; + fenc[0] = rp->rect[i+0] * 4.0f - 2.0f; + fenc[1] = rp->rect[i+1] * 4.0f - 2.0f; + + float f = dot_v2v2(fenc, fenc); + float g = sqrtf(1.0f - f / 4.0f); + + rp->rect[i + 0] = fenc[0] * g; + rp->rect[i + 1] = fenc[1] * g; + rp->rect[i + 2] = 1.0f - f / 2.0f; + + mul_mat3_m4_v3(g_data->viewinv, &rp->rect[i]); + } + } +} + +static void eevee_render_result_z( + RenderResult *rr, RenderLayer *rl, const char *viewname, + EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + ViewLayer *view_layer = draw_ctx->view_layer; + EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; + EEVEE_StorageList *stl = vedata->stl; + EEVEE_PrivateData *g_data = stl->g_data; + + /* Only read the center texel. */ + if (stl->effects->taa_current_sample > 1) + return; + + if ((view_layer->passflag & SCE_PASS_Z) != 0) { + RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_Z, viewname); + + DRW_framebuffer_read_depth(rr->xof, rr->yof, rr->rectx, rr->recty, rp->rect); + + bool is_persp = DRW_viewport_is_persp_get(); + + /* Convert ogl depth [0..1] to view Z [near..far] */ + for (int i = 0; i < rr->rectx * rr->recty; ++i) { + if (rp->rect[i] == 1.0f ) { + rp->rect[i] = 1e10f; /* Background */ + } + else { + if (is_persp) { + rp->rect[i] = rp->rect[i] * 2.0f - 1.0f; + rp->rect[i] = g_data->winmat[3][2] / (rp->rect[i] + g_data->winmat[2][2]); + } + else { + rp->rect[i] = -common_data->view_vecs[0][2] + rp->rect[i] * -common_data->view_vecs[1][2]; + } + } + } + } +} + +static void eevee_render_result_mist( + RenderResult *rr, RenderLayer *rl, const char *viewname, + EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata)) { + const DRWContextState *draw_ctx = DRW_context_state_get(); + ViewLayer *view_layer = draw_ctx->view_layer; + + if ((view_layer->passflag & SCE_PASS_MIST) != 0) { + RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_MIST, viewname); + + IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE); + float render_samples = (float)BKE_collection_engine_property_value_get_int(props, "taa_render_samples"); + + DRW_framebuffer_bind(vedata->fbl->mist_accum_fb); + DRW_framebuffer_read_data(rr->xof, rr->yof, rr->rectx, rr->recty, 1, 0, rp->rect); + + /* This is the accumulated color. Divide by the number of samples. */ + for (int i = 0; i < rr->rectx * rr->recty; i++) { + rp->rect[i] /= render_samples; + } + } +} + +static void eevee_render_result_occlusion( + RenderResult *rr, RenderLayer *rl, const char *viewname, + EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata)) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + ViewLayer *view_layer = draw_ctx->view_layer; + + if (vedata->fbl->ao_accum_fb == NULL) { + /* AO is not enabled. */ + return; + } + + if ((view_layer->passflag & SCE_PASS_AO) != 0) { + RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_AO, viewname); + + IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE); + float render_samples = (float)BKE_collection_engine_property_value_get_int(props, "taa_render_samples"); + + DRW_framebuffer_bind(vedata->fbl->ao_accum_fb); + DRW_framebuffer_read_data(rr->xof, rr->yof, rr->rectx, rr->recty, 3, 0, rp->rect); + + /* This is the accumulated color. Divide by the number of samples. */ + for (int i = 0; i < rr->rectx * rr->recty * 3; i += 3) { + rp->rect[i] = rp->rect[i + 1] = rp->rect[i+2] = min_ff(1.0f, rp->rect[i] / render_samples); + } + } +} + +static void eevee_render_draw_background(EEVEE_Data *vedata) +{ + EEVEE_TextureList *txl = vedata->txl; + EEVEE_FramebufferList *fbl = vedata->fbl; + EEVEE_PassList *psl = vedata->psl; + + /* Prevent background to write to data buffers. + * NOTE : This also make sure the textures are bound + * to the right double buffer. */ + if (txl->ssr_normal_input != NULL) { + DRW_framebuffer_texture_detach(txl->ssr_normal_input); + } + if (txl->ssr_specrough_input != NULL) { + DRW_framebuffer_texture_detach(txl->ssr_specrough_input); + } + DRW_framebuffer_bind(fbl->main); + + DRW_draw_pass(psl->background_pass); + + if (txl->ssr_normal_input != NULL) { + DRW_framebuffer_texture_attach(fbl->main, txl->ssr_normal_input, 1, 0); + } + if (txl->ssr_specrough_input != NULL) { + DRW_framebuffer_texture_attach(fbl->main, txl->ssr_specrough_input, 2, 0); + } + DRW_framebuffer_bind(fbl->main); +} + +void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderResult *rr, RenderLayer *rl) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + ViewLayer *view_layer = draw_ctx->view_layer; + const char *viewname = RE_GetActiveRenderView(engine->re); EEVEE_PassList *psl = vedata->psl; EEVEE_StorageList *stl = vedata->stl; EEVEE_FramebufferList *fbl = vedata->fbl; @@ -163,32 +385,60 @@ void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *UNUSED(engine), EEVEE_lights_cache_finish(sldata); EEVEE_lightprobes_cache_finish(sldata, vedata); - const DRWContextState *draw_ctx = DRW_context_state_get(); - ViewLayer *view_layer = draw_ctx->view_layer; + /* Sort transparents before the loop. */ + DRW_pass_sort_shgroup_z(psl->transparent_pass); + + /* Push instances attribs to the GPU. */ + DRW_render_instance_buffer_finish(); + + if ((view_layer->passflag & (SCE_PASS_SUBSURFACE_COLOR | + SCE_PASS_SUBSURFACE_DIRECT | + SCE_PASS_SUBSURFACE_INDIRECT)) != 0) + { + EEVEE_subsurface_output_init(sldata, vedata); + } + + if ((view_layer->passflag & SCE_PASS_MIST) != 0) { + EEVEE_mist_output_init(sldata, vedata); + } + + if ((view_layer->passflag & SCE_PASS_AO) != 0) { + EEVEE_occlusion_output_init(sldata, vedata); + } + IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE); unsigned int render_samples = BKE_collection_engine_property_value_get_int(props, "taa_render_samples"); while (render_samples-- > 0) { - float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.6f}; + float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; unsigned int primes[3] = {2, 3, 7}; double offset[3] = {0.0, 0.0, 0.0}; double r[3]; + /* Restore winmat before jittering again. */ + copy_m4_m4(stl->effects->overide_winmat, g_data->winmat); + BLI_halton_3D(primes, offset, stl->effects->taa_current_sample, r); EEVEE_update_noise(psl, fbl, r); EEVEE_temporal_sampling_matrices_calc(stl->effects, g_data->viewmat, g_data->persmat, r); + EEVEE_volumes_set_jitter(sldata, stl->effects->taa_current_sample - 1); + EEVEE_materials_init(sldata, stl, fbl); - /* Refresh Probes & shadows */ - EEVEE_lightprobes_refresh(sldata, vedata); + /* Refresh Probes */ + while (EEVEE_lightprobes_all_probes_ready(sldata, vedata) == false) { + EEVEE_lightprobes_refresh(sldata, vedata); + } + EEVEE_lightprobes_refresh_planar(sldata, vedata); DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data); - EEVEE_draw_shadows(sldata, psl); - + /* Set matrices. */ DRW_viewport_matrix_override_set(stl->effects->overide_persmat, DRW_MAT_PERS); DRW_viewport_matrix_override_set(stl->effects->overide_persinv, DRW_MAT_PERSINV); DRW_viewport_matrix_override_set(stl->effects->overide_winmat, DRW_MAT_WIN); DRW_viewport_matrix_override_set(stl->effects->overide_wininv, DRW_MAT_WININV); DRW_viewport_matrix_override_set(g_data->viewmat, DRW_MAT_VIEW); DRW_viewport_matrix_override_set(g_data->viewinv, DRW_MAT_VIEWINV); + /* Refresh Shadows */ + EEVEE_draw_shadows(sldata, psl); DRW_framebuffer_texture_detach(dtxl->depth); DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0, 0); @@ -202,77 +452,63 @@ void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *UNUSED(engine), EEVEE_occlusion_compute(sldata, vedata, dtxl->depth, -1); EEVEE_volumes_compute(sldata, vedata); /* Shading pass */ - DRW_draw_pass(psl->background_pass); + eevee_render_draw_background(vedata); + DRW_framebuffer_bind(fbl->main); EEVEE_draw_default_passes(psl); DRW_draw_pass(psl->material_pass); EEVEE_subsurface_data_render(sldata, vedata); /* Effects pre-transparency */ EEVEE_subsurface_compute(sldata, vedata); EEVEE_reflection_compute(sldata, vedata); - EEVEE_occlusion_draw_debug(sldata, vedata); - DRW_draw_pass(psl->probe_display); EEVEE_refraction_compute(sldata, vedata); /* Opaque refraction */ DRW_draw_pass(psl->refract_depth_pass); DRW_draw_pass(psl->refract_depth_pass_cull); DRW_draw_pass(psl->refract_pass); + /* Subsurface output */ + EEVEE_subsurface_output_accumulate(sldata, vedata); + /* Occlusion output */ + EEVEE_occlusion_output_accumulate(sldata, vedata); + /* Result NORMAL */ + eevee_render_result_normal(rr, rl, viewname, vedata, sldata); /* Volumetrics Resolve Opaque */ EEVEE_volumes_resolve(sldata, vedata); + /* Mist output */ + EEVEE_mist_output_accumulate(sldata, vedata); /* Transparent */ - DRW_pass_sort_shgroup_z(psl->transparent_pass); DRW_draw_pass(psl->transparent_pass); + /* Result Z */ + eevee_render_result_z(rr, rl, viewname, vedata, sldata); /* Post Process */ EEVEE_draw_effects(sldata, vedata); } + + eevee_render_result_combined(rr, rl, viewname, vedata, sldata); + eevee_render_result_subsurface(rr, rl, viewname, vedata, sldata); + eevee_render_result_mist(rr, rl, viewname, vedata, sldata); + eevee_render_result_occlusion(rr, rl, viewname, vedata, sldata); } -void EEVEE_render_output(EEVEE_Data *vedata, RenderEngine *engine, struct Depsgraph *UNUSED(depsgraph)) +void EEVEE_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer) { - const DRWContextState *draw_ctx = DRW_context_state_get(); - ViewLayer *view_layer = draw_ctx->view_layer; - DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure(); - EEVEE_FramebufferList *fbl = vedata->fbl; - EEVEE_StorageList *stl = vedata->stl; - EEVEE_PrivateData *g_data = stl->g_data; - EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; + int type; - const char *viewname = NULL; - const float *render_size = DRW_viewport_size_get(); + RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA); - /* Combined */ - RenderResult *rr = RE_engine_begin_result(engine, 0, 0, (int)render_size[0], (int)render_size[1], NULL, viewname); - RenderLayer *rl = rr->layers.first; - RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, viewname); - - DRW_framebuffer_bind(stl->effects->final_fb); - DRW_framebuffer_read_data(0, 0, (int)render_size[0], (int)render_size[1], 4, 0, rp->rect); - - if (view_layer->passflag & SCE_PASS_Z) { - rp = RE_pass_find_by_name(rl, RE_PASSNAME_Z, viewname); - - DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0, 0); - DRW_framebuffer_bind(fbl->main); - DRW_framebuffer_read_depth(0, 0, (int)render_size[0], (int)render_size[1], rp->rect); - - bool is_persp = DRW_viewport_is_persp_get(); - - /* Convert ogl depth [0..1] to view Z [near..far] */ - for (int i = 0; i < (int)render_size[0] * (int)render_size[1]; ++i) { - if (rp->rect[i] == 1.0f ) { - rp->rect[i] = 1e10f; /* Background */ - } - else { - if (is_persp) { - rp->rect[i] = rp->rect[i] * 2.0f - 1.0f; - rp->rect[i] = g_data->winmat[3][2] / (rp->rect[i] + g_data->winmat[2][2]); - } - else { - rp->rect[i] = -common_data->view_vecs[0][2] + rp->rect[i] * -common_data->view_vecs[1][2]; - } - } - } +#define CHECK_PASS(name, channels, chanid) \ + if (view_layer->passflag & (SCE_PASS_ ## name)) { \ + if (channels == 4) type = SOCK_RGBA; \ + else if (channels == 3) type = SOCK_VECTOR; \ + else type = SOCK_FLOAT; \ + RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_ ## name, channels, chanid, type); \ } - RE_engine_end_result(engine, rr, false, false, false); -}
\ No newline at end of file + CHECK_PASS(Z, 1, "Z"); + CHECK_PASS(MIST, 1, "Z"); + CHECK_PASS(NORMAL, 3, "XYZ"); + CHECK_PASS(AO, 3, "RGB"); + CHECK_PASS(SUBSURFACE_COLOR, 3, "RGB"); + CHECK_PASS(SUBSURFACE_DIRECT, 3, "RGB"); + +#undef CHECK_PASS +} diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c index 17da4a18b78..c3079d931fb 100644 --- a/source/blender/draw/engines/eevee/eevee_subsurface.c +++ b/source/blender/draw/engines/eevee/eevee_subsurface.c @@ -33,7 +33,7 @@ #include "GPU_texture.h" static struct { - struct GPUShader *sss_sh[3]; + struct GPUShader *sss_sh[4]; } e_data = {NULL}; /* Engine data */ extern char datatoc_common_uniforms_lib_glsl[]; @@ -49,6 +49,9 @@ static void eevee_create_shader_subsurface(void) e_data.sss_sh[1] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n"); e_data.sss_sh[2] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n" "#define USE_SEP_ALBEDO\n"); + e_data.sss_sh[3] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n" + "#define USE_SEP_ALBEDO\n" + "#define RESULT_ACCUM\n"); MEM_freeN(frag_str); } @@ -71,6 +74,11 @@ int EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) effects->sss_separate_albedo = BKE_collection_engine_property_value_get_bool(props, "sss_separate_albedo"); common_data->sss_jitter_threshold = BKE_collection_engine_property_value_get_float(props, "sss_jitter_threshold"); + /* Force separate albedo for final render */ + if (DRW_state_is_image_render()) { + effects->sss_separate_albedo = true; + } + /* Shaders */ if (!e_data.sss_sh[0]) { eevee_create_shader_subsurface(); @@ -90,11 +98,16 @@ int EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) DRW_framebuffer_init(&fbl->sss_clear_fb, &draw_engine_eevee_type, (int)viewport_size[0], (int)viewport_size[1], &tex_data, 1); - if (effects->sss_separate_albedo && (txl->sss_albedo == NULL)) { - txl->sss_albedo = DRW_texture_create_2D((int)viewport_size[0], (int)viewport_size[1], - DRW_TEX_RGB_11_11_10, 0, NULL); + if (effects->sss_separate_albedo) { + if (txl->sss_albedo == NULL) { + txl->sss_albedo = DRW_texture_create_2D((int)viewport_size[0], (int)viewport_size[1], + DRW_TEX_RGB_11_11_10, 0, NULL); + } + } + else { + /* Cleanup to release memory */ + DRW_TEXTURE_FREE_SAFE(txl->sss_albedo); } - return EFFECT_SSS; } @@ -109,6 +122,47 @@ int EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) return 0; } +static void set_shgrp_stencil(void *UNUSED(userData), DRWShadingGroup *shgrp) +{ + DRW_shgroup_stencil_mask(shgrp, 255); +} + +void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) +{ + EEVEE_FramebufferList *fbl = vedata->fbl; + EEVEE_TextureList *txl = vedata->txl; + const float *viewport_size = DRW_viewport_size_get(); + + const DRWContextState *draw_ctx = DRW_context_state_get(); + ViewLayer *view_layer = draw_ctx->view_layer; + IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE); + + if (BKE_collection_engine_property_value_get_bool(props, "sss_enable")) { + float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + + DRWFboTexture tex_data[2] = {{&txl->sss_dir_accum, DRW_TEX_RGBA_16, 0}, + {&txl->sss_col_accum, DRW_TEX_RGBA_16, 0}}; + DRW_framebuffer_init(&fbl->sss_accum_fb, &draw_engine_eevee_type, (int)viewport_size[0], (int)viewport_size[1], + tex_data, 2); + + /* Clear texture. */ + DRW_framebuffer_bind(fbl->sss_accum_fb); + DRW_framebuffer_clear(true, false, false, clear, 0.0f); + + /* Make the opaque refraction pass mask the sss. */ + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_CLIP_PLANES | + DRW_STATE_WIRE | DRW_STATE_WRITE_STENCIL; + DRW_pass_state_set(vedata->psl->refract_pass, state); + DRW_pass_foreach_shgroup(vedata->psl->refract_pass, &set_shgrp_stencil, NULL); + } + else { + /* Cleanup to release memory */ + DRW_TEXTURE_FREE_SAFE(txl->sss_dir_accum); + DRW_TEXTURE_FREE_SAFE(txl->sss_col_accum); + DRW_FRAMEBUFFER_FREE_SAFE(fbl->sss_accum_fb); + } +} + void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) { EEVEE_PassList *psl = vedata->psl; @@ -121,7 +175,9 @@ void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data */ psl->sss_blur_ps = DRW_pass_create("Blur Horiz", DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL); - psl->sss_resolve_ps = DRW_pass_create("Blur Vert", DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE | DRW_STATE_STENCIL_EQUAL); + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE | DRW_STATE_STENCIL_EQUAL; + psl->sss_resolve_ps = DRW_pass_create("Blur Vert", state); + psl->sss_accum_ps = DRW_pass_create("Resolve Accum", state); } } @@ -157,6 +213,18 @@ void EEVEE_subsurface_add_pass( if (effects->sss_separate_albedo) { DRW_shgroup_uniform_buffer(grp, "sssAlbedo", &txl->sss_albedo); } + + if (DRW_state_is_image_render()) { + grp = DRW_shgroup_create(e_data.sss_sh[3], psl->sss_accum_ps); + DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex()); + DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth); + DRW_shgroup_uniform_buffer(grp, "sssData", &txl->sss_blur); + DRW_shgroup_uniform_buffer(grp, "sssAlbedo", &txl->sss_albedo); + DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile); + DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); + DRW_shgroup_stencil_mask(grp, sss_id); + DRW_shgroup_call_add(grp, quad, NULL); + } } void EEVEE_subsurface_data_render(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) @@ -239,13 +307,19 @@ void EEVEE_subsurface_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v DRW_framebuffer_texture_detach(dtxl->depth); - /* First horizontal pass */ + /* 1. horizontal pass */ DRW_framebuffer_bind(fbl->sss_blur_fb); DRW_framebuffer_clear(true, false, false, clear, 0.0f); DRW_draw_pass(psl->sss_blur_ps); - /* First vertical pass + Resolve */ + /* 2. vertical pass + Resolve */ DRW_framebuffer_texture_detach(txl->sss_stencil); + if ((effects->enabled_effects & EFFECT_NORMAL_BUFFER) != 0) { + DRW_framebuffer_texture_detach(txl->ssr_normal_input); + } + if ((effects->enabled_effects & EFFECT_SSR) != 0) { + DRW_framebuffer_texture_detach(txl->ssr_specrough_input); + } DRW_framebuffer_texture_attach(fbl->main, txl->sss_stencil, 0, 0); DRW_framebuffer_bind(fbl->main); DRW_draw_pass(psl->sss_resolve_ps); @@ -254,14 +328,46 @@ void EEVEE_subsurface_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v DRW_framebuffer_texture_detach(txl->sss_stencil); DRW_framebuffer_texture_attach(fbl->sss_blur_fb, txl->sss_stencil, 0, 0); DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0, 0); + if ((effects->enabled_effects & EFFECT_NORMAL_BUFFER) != 0) { + DRW_framebuffer_texture_attach(fbl->main, txl->ssr_normal_input, 1, 0); + } + if ((effects->enabled_effects & EFFECT_SSR) != 0) { + DRW_framebuffer_texture_attach(fbl->main, txl->ssr_specrough_input, 2, 0); + } DRW_stats_group_end(); } } +void EEVEE_subsurface_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) +{ + EEVEE_PassList *psl = vedata->psl; + EEVEE_FramebufferList *fbl = vedata->fbl; + EEVEE_TextureList *txl = vedata->txl; + EEVEE_StorageList *stl = vedata->stl; + EEVEE_EffectsInfo *effects = stl->effects; + + if (((effects->enabled_effects & EFFECT_SSS) != 0) && (fbl->sss_accum_fb != NULL)) { + /* Copy stencil channel, could be avoided (see EEVEE_subsurface_init) */ + DRW_framebuffer_blit(fbl->main, fbl->sss_blur_fb, false, true); + + /* Only do vertical pass + Resolve */ + DRW_framebuffer_texture_detach(txl->sss_stencil); + DRW_framebuffer_texture_attach(fbl->sss_accum_fb, txl->sss_stencil, 0, 0); + DRW_framebuffer_bind(fbl->sss_accum_fb); + DRW_draw_pass(psl->sss_accum_ps); + + /* Restore */ + DRW_framebuffer_texture_detach(txl->sss_stencil); + DRW_framebuffer_texture_attach(fbl->sss_blur_fb, txl->sss_stencil, 0, 0); + DRW_framebuffer_bind(fbl->main); + } +} + void EEVEE_subsurface_free(void) { DRW_SHADER_FREE_SAFE(e_data.sss_sh[0]); DRW_SHADER_FREE_SAFE(e_data.sss_sh[1]); DRW_SHADER_FREE_SAFE(e_data.sss_sh[2]); + DRW_SHADER_FREE_SAFE(e_data.sss_sh[3]); } diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c index 24b8117b6f5..a417a9bdf56 100644 --- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c +++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c @@ -32,9 +32,14 @@ #include "eevee_private.h" #include "GPU_texture.h" +#define FILTER_CDF_TABLE_SIZE 512 + static struct { /* Temporal Anti Aliasing */ struct GPUShader *taa_resolve_sh; + + /* Pixel filter table: Only blackman-harris for now. */ + float inverted_cdf[FILTER_CDF_TABLE_SIZE]; } e_data = {NULL}; /* Engine data */ extern char datatoc_effect_temporal_aa_glsl[]; @@ -44,17 +49,107 @@ static void eevee_create_shader_temporal_sampling(void) e_data.taa_resolve_sh = DRW_shader_create_fullscreen(datatoc_effect_temporal_aa_glsl, NULL); } +static float UNUSED_FUNCTION(filter_box)(float UNUSED(x)) +{ + return 1.0f; +} + +static float filter_blackman_harris(float x) +{ + /* Hardcoded 1px footprint [-0.5..0.5]. We resize later. */ + const float width = 1.0f; + x = 2.0f * M_PI * (x / width + 0.5f); + return 0.35875f - 0.48829f * cosf(x) + 0.14128f * cosf(2.0f * x) - 0.01168f * cosf(3.0f * x); +} + +/* Compute cumulative distribution function of a discrete function. */ +static void compute_cdf(float (*func)(float x), float cdf[FILTER_CDF_TABLE_SIZE]) +{ + cdf[0] = 0.0f; + /* Actual CDF evaluation. */ + for (int u = 0; u < FILTER_CDF_TABLE_SIZE - 1; ++u) { + float x = (float)(u + 1) / (float)(FILTER_CDF_TABLE_SIZE - 1); + cdf[u + 1] = cdf[u] + func(x - 0.5f); /* [-0.5..0.5]. We resize later. */ + } + /* Normalize the CDF. */ + for (int u = 0; u < FILTER_CDF_TABLE_SIZE - 1; u++) { + cdf[u] /= cdf[FILTER_CDF_TABLE_SIZE - 1]; + } + /* Just to make sure. */ + cdf[FILTER_CDF_TABLE_SIZE - 1] = 1.0f; +} + +static void invert_cdf(const float cdf[FILTER_CDF_TABLE_SIZE], float invert_cdf[FILTER_CDF_TABLE_SIZE]) +{ + for (int u = 0; u < FILTER_CDF_TABLE_SIZE; u++) { + float x = (float)u / (float)(FILTER_CDF_TABLE_SIZE - 1); + for (int i = 0; i < FILTER_CDF_TABLE_SIZE; ++i) { + if (cdf[i] >= x) { + if (i == FILTER_CDF_TABLE_SIZE - 1) { + invert_cdf[u] = 1.0f; + } + else { + float t = (x - cdf[i]) / (cdf[i + 1] - cdf[i]); + invert_cdf[u] = ((float)i + t) / (float)(FILTER_CDF_TABLE_SIZE - 1); + } + break; + } + } + } +} + +/* Evaluate a discrete function table with linear interpolation. */ +static float eval_table(float *table, float x) +{ + CLAMP(x, 0.0f, 1.0f); + x = x * (FILTER_CDF_TABLE_SIZE - 1); + + int index = min_ii((int)(x), FILTER_CDF_TABLE_SIZE - 1); + int nindex = min_ii(index + 1, FILTER_CDF_TABLE_SIZE - 1); + float t = x - index; + + return (1.0f - t) * table[index] + t * table[nindex]; +} + +static void eevee_create_cdf_table_temporal_sampling(void) +{ + float *cdf_table = MEM_mallocN(sizeof(float) * FILTER_CDF_TABLE_SIZE, "Eevee Filter CDF table"); + + float filter_width = 2.0f; /* Use a 2 pixel footprint by default. */ + + { + /* Use blackman-harris filter. */ + filter_width *= 2.0f; + compute_cdf(filter_blackman_harris, cdf_table); + } + + invert_cdf(cdf_table, e_data.inverted_cdf); + + /* Scale and offset table. */ + for (int i = 0; i < FILTER_CDF_TABLE_SIZE; ++i) { + e_data.inverted_cdf[i] = (e_data.inverted_cdf[i] - 0.5f) * filter_width; + } + + MEM_freeN(cdf_table); +} + void EEVEE_temporal_sampling_matrices_calc( - EEVEE_EffectsInfo *effects, float viewmat[4][4], float persmat[4][4], double ht_point[2]) + EEVEE_EffectsInfo *effects, float viewmat[4][4], float persmat[4][4], const double ht_point[2]) { const float *viewport_size = DRW_viewport_size_get(); + const DRWContextState *draw_ctx = DRW_context_state_get(); + Scene *scene = draw_ctx->scene; + RenderData *rd = &scene->r; + + float filter_size = rd->gauss; /* Sigh.. Stupid legacy naming. */ - /* TODO Blackman-Harris filter */ + float ofs_x = eval_table(e_data.inverted_cdf, (float)(ht_point[0])) * filter_size; + float ofs_y = eval_table(e_data.inverted_cdf, (float)(ht_point[1])) * filter_size; window_translate_m4( effects->overide_winmat, persmat, - ((float)(ht_point[0]) * 2.0f - 1.0f) / viewport_size[0], - ((float)(ht_point[1]) * 2.0f - 1.0f) / viewport_size[1]); + ofs_x / viewport_size[0], + ofs_y / viewport_size[1]); mul_m4_m4m4(effects->overide_persmat, effects->overide_winmat, viewmat); invert_m4_m4(effects->overide_persinv, effects->overide_persmat); @@ -89,6 +184,7 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data if (!e_data.taa_resolve_sh) { eevee_create_shader_temporal_sampling(); + eevee_create_cdf_table_temporal_sampling(); } /* Until we support reprojection, we need to make sure diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c index a960682e8c9..2c5b9072837 100644 --- a/source/blender/draw/engines/eevee/eevee_volumes.c +++ b/source/blender/draw/engines/eevee/eevee_volumes.c @@ -30,7 +30,7 @@ #include "BLI_rand.h" #include "BLI_string_utils.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_smoke_types.h" #include "DNA_world_types.h" @@ -128,6 +128,21 @@ static void eevee_create_shader_volumes(void) e_data.volumetric_common_lib, NULL); } +void EEVEE_volumes_set_jitter(EEVEE_ViewLayerData *sldata, unsigned int current_sample) +{ + EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; + + double ht_point[3]; + double ht_offset[3] = {0.0, 0.0}; + unsigned int ht_primes[3] = {3, 7, 2}; + + BLI_halton_3D(ht_primes, ht_offset, current_sample, ht_point); + + common_data->vol_jitter[0] = (float)ht_point[0]; + common_data->vol_jitter[1] = (float)ht_point[1]; + common_data->vol_jitter[2] = (float)ht_point[2]; +} + int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) { EEVEE_StorageList *stl = vedata->stl; @@ -223,8 +238,6 @@ int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) } /* Temporal Super sampling jitter */ - double ht_point[3]; - double ht_offset[3] = {0.0, 0.0}; unsigned int ht_primes[3] = {3, 7, 2}; unsigned int current_sample = 0; @@ -248,11 +261,8 @@ int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) DRW_viewport_request_redraw(); } } - BLI_halton_3D(ht_primes, ht_offset, current_sample, ht_point); - common_data->vol_jitter[0] = (float)ht_point[0]; - common_data->vol_jitter[1] = (float)ht_point[1]; - common_data->vol_jitter[2] = (float)ht_point[2]; + EEVEE_volumes_set_jitter(sldata, current_sample); /* Framebuffer setup */ DRWFboTexture tex_vol[4] = {{&txl->volume_prop_scattering, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER}, @@ -304,7 +314,7 @@ int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) } else { const float clip_start = common_data->view_vecs[0][2]; - const float clip_end = common_data->view_vecs[1][2]; + const float clip_end = clip_start + common_data->view_vecs[1][2]; integration_start = min_ff(integration_end, clip_start); integration_end = max_ff(-integration_end, clip_end); diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl index 68299fe7546..f571d8c727b 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl @@ -325,7 +325,7 @@ vec2 get_uvs_from_view(vec3 view) vec3 get_view_space_from_depth(vec2 uvcoords, float depth) { if (ProjectionMatrix[3][3] == 0.0) { - return (viewVecs[0].xyz + vec3(uvcoords, 0.0) * viewVecs[1].xyz) * get_view_z_from_depth(depth); + return vec3(viewVecs[0].xy + uvcoords * viewVecs[1].xy, 1.0) * get_view_z_from_depth(depth); } else { return viewVecs[0].xyz + vec3(uvcoords, depth) * viewVecs[1].xyz; @@ -418,19 +418,19 @@ float get_btdf_lut(sampler2DArray btdf_lut_tex, float NV, float roughness, float * Using Method #4: Spheremap Transform */ vec2 normal_encode(vec3 n, vec3 view) { - float p = sqrt(n.z * 8.0 + 8.0); - return n.xy / p + 0.5; + float p = sqrt(n.z * 8.0 + 8.0); + return n.xy / p + 0.5; } vec3 normal_decode(vec2 enc, vec3 view) { - vec2 fenc = enc * 4.0 - 2.0; - float f = dot(fenc, fenc); - float g = sqrt(1.0 - f / 4.0); - vec3 n; - n.xy = fenc*g; - n.z = 1 - f / 2; - return n; + vec2 fenc = enc * 4.0 - 2.0; + float f = dot(fenc, fenc); + float g = sqrt(1.0 - f / 4.0); + vec3 n; + n.xy = fenc*g; + n.z = 1 - f / 2; + return n; } /* ---- RGBM (shared multiplier) encoding ---- */ @@ -654,12 +654,12 @@ Closure closure_add(Closure cl1, Closure cl2) struct Closure { vec3 radiance; float opacity; -#ifdef USE_SSS +# ifdef USE_SSS vec4 sss_data; -#ifdef USE_SSS_ALBEDO +# ifdef USE_SSS_ALBEDO vec3 sss_albedo; -#endif -#endif +# endif +# endif vec4 ssr_data; vec2 ssr_normal; int ssr_id; @@ -669,15 +669,15 @@ struct Closure { #define TRANSPARENT_CLOSURE_FLAG -2 #define REFRACT_CLOSURE_FLAG -3 -#ifdef USE_SSS -#ifdef USE_SSS_ALBEDO +# ifdef USE_SSS +# ifdef USE_SSS_ALBEDO #define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec3(0.0), vec4(0.0), vec2(0.0), -1) -#else +# else #define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec4(0.0), vec2(0.0), -1) -#endif -#else +# endif +# else #define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec2(0.0), -1) -#endif +# endif uniform int outputSsrId; @@ -685,45 +685,51 @@ Closure closure_mix(Closure cl1, Closure cl2, float fac) { Closure cl; - if (cl1.ssr_id == outputSsrId) { - cl.ssr_data = mix(cl1.ssr_data.xyzw, vec4(vec3(0.0), cl1.ssr_data.w), fac); /* do not blend roughness */ - cl.ssr_normal = cl1.ssr_normal; - cl.ssr_id = cl1.ssr_id; - } - else { - cl.ssr_data = mix(vec4(vec3(0.0), cl2.ssr_data.w), cl2.ssr_data.xyzw, fac); /* do not blend roughness */ - cl.ssr_normal = cl2.ssr_normal; - cl.ssr_id = cl2.ssr_id; - } if (cl1.ssr_id == TRANSPARENT_CLOSURE_FLAG) { cl1.radiance = cl2.radiance; -#ifdef USE_SSS + cl1.ssr_normal = cl2.ssr_normal; + cl1.ssr_data = cl2.ssr_data; + cl1.ssr_id = cl2.ssr_id; +# ifdef USE_SSS cl1.sss_data = cl2.sss_data; -#ifdef USE_SSS_ALBEDO +# ifdef USE_SSS_ALBEDO cl1.sss_albedo = cl2.sss_albedo; -#endif -#endif +# endif +# endif } if (cl2.ssr_id == TRANSPARENT_CLOSURE_FLAG) { cl2.radiance = cl1.radiance; -#ifdef USE_SSS + cl2.ssr_normal = cl1.ssr_normal; + cl2.ssr_data = cl1.ssr_data; + cl2.ssr_id = cl1.ssr_id; +# ifdef USE_SSS cl2.sss_data = cl1.sss_data; -#ifdef USE_SSS_ALBEDO +# ifdef USE_SSS_ALBEDO cl2.sss_albedo = cl1.sss_albedo; -#endif -#endif +# endif +# endif + } + if (cl1.ssr_id == outputSsrId) { + cl.ssr_data = mix(cl1.ssr_data.xyzw, vec4(vec3(0.0), cl1.ssr_data.w), fac); /* do not blend roughness */ + cl.ssr_normal = cl1.ssr_normal; + cl.ssr_id = cl1.ssr_id; + } + else { + cl.ssr_data = mix(vec4(vec3(0.0), cl2.ssr_data.w), cl2.ssr_data.xyzw, fac); /* do not blend roughness */ + cl.ssr_normal = cl2.ssr_normal; + cl.ssr_id = cl2.ssr_id; } cl.radiance = mix(cl1.radiance, cl2.radiance, fac); cl.opacity = mix(cl1.opacity, cl2.opacity, fac); -#ifdef USE_SSS +# ifdef USE_SSS cl.sss_data.rgb = mix(cl1.sss_data.rgb, cl2.sss_data.rgb, fac); cl.sss_data.a = (cl1.sss_data.a > 0.0) ? cl1.sss_data.a : cl2.sss_data.a; -#ifdef USE_SSS_ALBEDO +# ifdef USE_SSS_ALBEDO /* TODO Find a solution to this. Dither? */ cl.sss_albedo = (cl1.sss_data.a > 0.0) ? cl1.sss_albedo : cl2.sss_albedo; -#endif -#endif +# endif +# endif return cl; } @@ -731,80 +737,80 @@ Closure closure_mix(Closure cl1, Closure cl2, float fac) Closure closure_add(Closure cl1, Closure cl2) { Closure cl = (cl1.ssr_id == outputSsrId) ? cl1 : cl2; -#ifdef USE_SSS +# ifdef USE_SSS cl.sss_data = (cl1.sss_data.a > 0.0) ? cl1.sss_data : cl2.sss_data; -#ifdef USE_SSS_ALBEDO +# ifdef USE_SSS_ALBEDO /* TODO Find a solution to this. Dither? */ cl.sss_albedo = (cl1.sss_data.a > 0.0) ? cl1.sss_albedo : cl2.sss_albedo; -#endif -#endif +# endif +# endif cl.radiance = cl1.radiance + cl2.radiance; cl.opacity = saturate(cl1.opacity + cl2.opacity); return cl; } -#if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER) && !defined(USE_MULTIPLY) +# if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER) && !defined(USE_MULTIPLY) layout(location = 0) out vec4 fragColor; -#ifdef USE_SSS -#ifdef USE_SSS_ALBEDO +# ifdef USE_SSS +# ifdef USE_SSS_ALBEDO layout(location = 1) out vec4 sssData; layout(location = 2) out vec4 sssAlbedo; layout(location = 3) out vec4 ssrNormals; layout(location = 4) out vec4 ssrData; -#else +# else layout(location = 1) out vec4 sssData; layout(location = 2) out vec4 ssrNormals; layout(location = 3) out vec4 ssrData; -#endif /* USE_SSS_ALBEDO */ -#else +# endif /* USE_SSS_ALBEDO */ +# else layout(location = 1) out vec4 ssrNormals; layout(location = 2) out vec4 ssrData; -#endif /* USE_SSS */ +# endif /* USE_SSS */ Closure nodetree_exec(void); /* Prototype */ -#if defined(USE_ALPHA_BLEND_VOLUMETRICS) +# if defined(USE_ALPHA_BLEND_VOLUMETRICS) /* Prototype because this file is included before volumetric_lib.glsl */ vec4 volumetric_resolve(vec4 scene_color, vec2 frag_uvs, float frag_depth); -#endif +# endif #define NODETREE_EXEC void main() { Closure cl = nodetree_exec(); -#ifndef USE_ALPHA_BLEND +# ifndef USE_ALPHA_BLEND /* Prevent alpha hash material writing into alpha channel. */ cl.opacity = 1.0; -#endif +# endif -#if defined(USE_ALPHA_BLEND_VOLUMETRICS) +# if defined(USE_ALPHA_BLEND_VOLUMETRICS) /* XXX fragile, better use real viewport resolution */ vec2 uvs = gl_FragCoord.xy / vec2(2 * textureSize(maxzBuffer, 0).xy); fragColor = volumetric_resolve(vec4(cl.radiance, cl.opacity), uvs, gl_FragCoord.z); -#else +# else fragColor = vec4(cl.radiance, cl.opacity); -#endif +# endif ssrNormals = cl.ssr_normal.xyyy; ssrData = cl.ssr_data; -#ifdef USE_SSS +# ifdef USE_SSS sssData = cl.sss_data; -#ifdef USE_SSS_ALBEDO +# ifdef USE_SSS_ALBEDO sssAlbedo = cl.sss_albedo.rgbb; -#endif -#endif +# endif +# endif /* For Probe capture */ -#ifdef USE_SSS -#ifdef USE_SSS_ALBEDO +# ifdef USE_SSS +# ifdef USE_SSS_ALBEDO fragColor.rgb += cl.sss_data.rgb * cl.sss_albedo.rgb * float(!sssToggle); -#else +# else fragColor.rgb += cl.sss_data.rgb * float(!sssToggle); -#endif -#endif +# endif +# endif } -#endif /* MESH_SHADER && !SHADOW_SHADER */ +# endif /* MESH_SHADER && !SHADOW_SHADER */ #endif /* VOLUMETRICS */ diff --git a/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl index 32edf709d88..b7bcf5c8a8b 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl @@ -28,7 +28,8 @@ void main() gtao_deferred(normal, viewPosition, noise, depth, visibility, bent_normal); - FragColor = vec4(visibility); + /* Handle Background case. Prevent artifact due to uncleared Horizon Render Target. */ + FragColor = vec4((depth == 1.0) ? 0.0 : visibility); } #else diff --git a/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl index 65d3970a82a..05fef73b159 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl @@ -23,7 +23,9 @@ uniform sampler2D depthBuffer; #define minmax(a, b) max(a, b) #endif -#ifdef GPU_INTEL +/* On some AMD card / driver conbination, it is needed otherwise, + * the shader does not write anything. */ +#if defined(GPU_INTEL) || defined(GPU_ATI) out vec4 fragColor; #endif @@ -65,10 +67,9 @@ void main() } #endif -#ifdef GPU_INTEL +#if defined(GPU_INTEL) || defined(GPU_ATI) /* Use color format instead of 24bit depth texture */ fragColor = vec4(val); -#else - gl_FragDepth = val; #endif + gl_FragDepth = val; }
\ No newline at end of file diff --git a/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl new file mode 100644 index 00000000000..fe38b2e9aac --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl @@ -0,0 +1,31 @@ +/* Convert depth to Mist factor */ +uniform vec3 mistSettings; + +#define mistStart mistSettings.x +#define mistInvDistance mistSettings.y +#define mistFalloff mistSettings.z + +out vec4 fragColor; + +void main() +{ + vec2 texel_size = 1.0 / vec2(textureSize(depthBuffer, 0)).xy; + vec2 uvs = gl_FragCoord.xy * texel_size; + + float depth = textureLod(depthBuffer, uvs, 0.0).r; + vec3 co = get_view_space_from_depth(uvs, depth); + + float zcor = (ProjectionMatrix[3][3] == 0.0) ? length(co) : -co.z; + + /* bring depth into 0..1 range */ + float mist = saturate((zcor - mistStart) * mistInvDistance); + + /* falloff */ + mist = pow(mist, mistFalloff); + + fragColor = vec4(mist); + + // if (mist > 0.999) fragColor = vec4(1.0); + // else if (mist > 0.0001) fragColor = vec4(0.5); + // else fragColor = vec4(0.0); +} diff --git a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl index 184eac54c26..d9e12bcc4bd 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl @@ -18,7 +18,10 @@ uniform sampler2DArray utilTex; #define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0) #endif /* UTIL_TEX */ -out vec4 FragColor; +layout(location = 0) out vec4 FragColor; +#ifdef RESULT_ACCUM +layout(location = 1) out vec4 sssColor; +#endif uniform mat4 ProjectionMatrix; @@ -84,10 +87,15 @@ void main(void) #ifdef FIRST_PASS FragColor = vec4(accum, sss_data.a); #else /* SECOND_PASS */ - #ifdef USE_SEP_ALBEDO +# ifdef USE_SEP_ALBEDO +# ifdef RESULT_ACCUM + FragColor = vec4(accum, 1.0); + sssColor = texture(sssAlbedo, uvs); +# else FragColor = vec4(accum * texture(sssAlbedo, uvs).rgb, 1.0); - #else +# endif +# else FragColor = vec4(accum, 1.0); - #endif +# endif #endif } diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 528495b8710..f62b224b094 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -140,7 +140,7 @@ typedef struct DrawEngineType { void (*view_update)(void *vedata); void (*id_update)(void *vedata, struct ID *id); - void (*render_to_image)(void *vedata, struct RenderEngine *engine, struct Depsgraph *graph); + void (*render_to_image)(void *vedata, struct RenderEngine *engine, struct RenderResult *result, struct RenderLayer *layer); } DrawEngineType; #ifndef __DRW_ENGINE_H__ @@ -305,13 +305,33 @@ typedef enum { #define DRW_STATE_DEFAULT (DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS) +typedef enum { + DRW_ATTRIB_INT, + DRW_ATTRIB_FLOAT, +} DRWAttribType; + +typedef struct DRWInstanceAttribFormat { + char name[32]; + DRWAttribType type; + int components; +} DRWInstanceAttribFormat; + +struct Gwn_VertFormat *DRW_shgroup_instance_format_array(const DRWInstanceAttribFormat attribs[], int arraysize); +#define DRW_shgroup_instance_format(format, ...) do { \ + if (format == NULL) { \ + DRWInstanceAttribFormat drw_format[] = __VA_ARGS__;\ + format = DRW_shgroup_instance_format_array(drw_format, (sizeof(drw_format) / sizeof(DRWInstanceAttribFormat))); \ + } \ +} while (0) DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass); DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPass *pass); DRWShadingGroup *DRW_shgroup_material_instance_create( - struct GPUMaterial *material, DRWPass *pass, struct Gwn_Batch *geom, struct Object *ob); + struct GPUMaterial *material, DRWPass *pass, struct Gwn_Batch *geom, struct Object *ob, + struct Gwn_VertFormat *format); DRWShadingGroup *DRW_shgroup_material_empty_tri_batch_create(struct GPUMaterial *material, DRWPass *pass, int size); -DRWShadingGroup *DRW_shgroup_instance_create(struct GPUShader *shader, DRWPass *pass, struct Gwn_Batch *geom); +DRWShadingGroup *DRW_shgroup_instance_create( + struct GPUShader *shader, DRWPass *pass, struct Gwn_Batch *geom, struct Gwn_VertFormat *format); DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPass *pass); DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass *pass); DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(struct GPUShader *shader, DRWPass *pass, int size); @@ -335,12 +355,12 @@ void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *at DRW_shgroup_call_dynamic_add_array(shgroup, array, (sizeof(array) / sizeof(*array))); \ } while (0) /* Use this to set a high number of instances. */ -void DRW_shgroup_set_instance_count(DRWShadingGroup *shgroup, int count); +void DRW_shgroup_set_instance_count(DRWShadingGroup *shgroup, unsigned int count); +unsigned int DRW_shgroup_get_instance_count(const DRWShadingGroup *shgroup); void DRW_shgroup_state_enable(DRWShadingGroup *shgroup, DRWState state); void DRW_shgroup_state_disable(DRWShadingGroup *shgroup, DRWState state); void DRW_shgroup_stencil_mask(DRWShadingGroup *shgroup, unsigned int mask); -void DRW_shgroup_attrib_float(DRWShadingGroup *shgroup, const char *name, int size); void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const struct GPUTexture *tex); void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup, const char *name, const struct GPUUniformBuffer *ubo); @@ -393,6 +413,7 @@ void DRW_render_to_image(struct RenderEngine *re, struct Depsgraph *depsgraph); void DRW_render_object_iter( void *vedata, struct RenderEngine *engine, struct Depsgraph *graph, void (*callback)(void *vedata, struct Object *ob, struct RenderEngine *engine, struct Depsgraph *graph)); +void DRW_render_instance_buffer_finish(void); /* ViewLayers */ void *DRW_view_layer_engine_data_get(DrawEngineType *engine_type); @@ -445,6 +466,7 @@ bool DRW_state_is_select(void); bool DRW_state_is_depth(void); bool DRW_state_is_image_render(void); bool DRW_state_is_scene_render(void); +bool DRW_state_is_opengl_render(void); bool DRW_state_show_text(void); bool DRW_state_draw_support(void); bool DRW_state_draw_background(void); @@ -455,6 +477,7 @@ struct DRWTextStore *DRW_state_text_cache_get(void); /* Avoid too many lookups while drawing */ typedef struct DRWContextState { + struct ARegion *ar; /* 'CTX_wm_region(C)' */ struct RegionView3D *rv3d; /* 'CTX_wm_region_view3d(C)' */ struct View3D *v3d; /* 'CTX_wm_view3d(C)' */ @@ -462,16 +485,25 @@ typedef struct DRWContextState { struct Scene *scene; /* 'CTX_data_scene(C)' */ struct ViewLayer *view_layer; /* 'CTX_data_view_layer(C)' */ - /* Use 'scene->obedit' for edit-mode */ + /* Use 'object_edit' for edit-mode */ struct Object *obact; /* 'OBACT' */ struct RenderEngineType *engine_type; struct Depsgraph *depsgraph; + eObjectMode object_mode; + /* Last resort (some functions take this as an arg so we can't easily avoid). * May be NULL when used for selection or depth buffer. */ const struct bContext *evil_C; + + /* ---- */ + + /* Cache: initialized by 'drw_context_state_init'. */ + struct Object *object_pose; + struct Object *object_edit; + } DRWContextState; const DRWContextState *DRW_context_state_get(void); diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c index 09fe3d68651..c14fe70e0c3 100644 --- a/source/blender/draw/intern/draw_armature.c +++ b/source/blender/draw/intern/draw_armature.c @@ -1308,7 +1308,9 @@ static void draw_armature_pose(Object *ob, const float const_color[4]) // if (!(base->flag & OB_FROMDUPLI)) // TODO { - if (ob->mode & OB_MODE_POSE) { + const DRWContextState *draw_ctx = DRW_context_state_get(); + + if ((draw_ctx->object_mode & OB_MODE_POSE) || (ob == draw_ctx->object_pose)) { arm->flag |= ARM_POSEMODE; } diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index 0eb97a54ba5..62166092638 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -35,7 +35,6 @@ #include "draw_common.h" - #if 0 #define UI_COLOR_RGB_FROM_U8(r, g, b, v4) \ ARRAY_SET_ITEMS(v4, (float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, 1.0) @@ -157,6 +156,29 @@ void DRW_globals_update(void) /* ********************************* SHGROUP ************************************* */ +static struct { + struct Gwn_VertFormat *instance_screenspace; + struct Gwn_VertFormat *instance_color; + struct Gwn_VertFormat *instance_screen_aligned; + struct Gwn_VertFormat *instance_scaled; + struct Gwn_VertFormat *instance_sized; + struct Gwn_VertFormat *instance; + struct Gwn_VertFormat *instance_camera; + struct Gwn_VertFormat *instance_distance_lines; + struct Gwn_VertFormat *instance_spot; + struct Gwn_VertFormat *instance_bone_envelope_wire; + struct Gwn_VertFormat *instance_bone_envelope_solid; + struct Gwn_VertFormat *instance_mball_handles; +} g_formats = {NULL}; + +void DRW_globals_free(void) +{ + struct Gwn_VertFormat **format = &g_formats.instance_screenspace; + for (int i = 0; i < sizeof(g_formats) / sizeof(void *); ++i, ++format) { + MEM_SAFE_FREE(*format); + } +} + DRWShadingGroup *shgroup_dynlines_uniform_color(DRWPass *pass, float color[4]) { GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR); @@ -204,9 +226,12 @@ DRWShadingGroup *shgroup_instance_screenspace(DRWPass *pass, struct Gwn_Batch *g { GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR); - DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom); - DRW_shgroup_attrib_float(grp, "world_pos", 3); - DRW_shgroup_attrib_float(grp, "color", 3); + DRW_shgroup_instance_format(g_formats.instance_screenspace, { + {"world_pos", DRW_ATTRIB_FLOAT, 3}, + {"color" , DRW_ATTRIB_FLOAT, 3} + }); + + DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_screenspace); DRW_shgroup_uniform_float(grp, "size", size, 1); DRW_shgroup_uniform_float(grp, "pixel_size", DRW_viewport_pixelsize_get(), 1); DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2); @@ -220,9 +245,12 @@ DRWShadingGroup *shgroup_instance_solid(DRWPass *pass, struct Gwn_Batch *geom) static float light[3] = {0.0f, 0.0f, 1.0f}; GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR); - DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom); - DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16); - DRW_shgroup_attrib_float(grp, "color", 4); + DRW_shgroup_instance_format(g_formats.instance_color, { + {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}, + {"color" , DRW_ATTRIB_FLOAT, 4} + }); + + DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_color); DRW_shgroup_uniform_vec3(grp, "light", light, 1); return grp; @@ -232,9 +260,12 @@ DRWShadingGroup *shgroup_instance_wire(DRWPass *pass, struct Gwn_Batch *geom) { GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_OBJECTSPACE_VARIYING_COLOR); - DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom); - DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16); - DRW_shgroup_attrib_float(grp, "color", 4); + DRW_shgroup_instance_format(g_formats.instance_color, { + {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}, + {"color" , DRW_ATTRIB_FLOAT, 4} + }); + + DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_color); return grp; } @@ -243,10 +274,13 @@ DRWShadingGroup *shgroup_instance_screen_aligned(DRWPass *pass, struct Gwn_Batch { GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED); - DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom); - DRW_shgroup_attrib_float(grp, "color", 3); - DRW_shgroup_attrib_float(grp, "size", 1); - DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16); + DRW_shgroup_instance_format(g_formats.instance_screen_aligned, { + {"color" , DRW_ATTRIB_FLOAT, 3}, + {"size" , DRW_ATTRIB_FLOAT, 1}, + {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16} + }); + + DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_screen_aligned); DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2); return grp; @@ -256,10 +290,13 @@ DRWShadingGroup *shgroup_instance_axis_names(DRWPass *pass, struct Gwn_Batch *ge { GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS); - DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom); - DRW_shgroup_attrib_float(grp, "color", 3); - DRW_shgroup_attrib_float(grp, "size", 1); - DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16); + DRW_shgroup_instance_format(g_formats.instance_screen_aligned, { + {"color" , DRW_ATTRIB_FLOAT, 3}, + {"size" , DRW_ATTRIB_FLOAT, 1}, + {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16} + }); + + DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_screen_aligned); DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2); return grp; @@ -269,10 +306,13 @@ DRWShadingGroup *shgroup_instance_scaled(DRWPass *pass, struct Gwn_Batch *geom) { GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE); - DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom); - DRW_shgroup_attrib_float(grp, "color", 3); - DRW_shgroup_attrib_float(grp, "size", 3); - DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16); + DRW_shgroup_instance_format(g_formats.instance_scaled, { + {"color" , DRW_ATTRIB_FLOAT, 3}, + {"size" , DRW_ATTRIB_FLOAT, 3}, + {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16} + }); + + DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_scaled); return grp; } @@ -281,10 +321,13 @@ DRWShadingGroup *shgroup_instance(DRWPass *pass, struct Gwn_Batch *geom) { GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE); - DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom); - DRW_shgroup_attrib_float(grp, "color", 3); - DRW_shgroup_attrib_float(grp, "size", 1); - DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16); + DRW_shgroup_instance_format(g_formats.instance_sized, { + {"color" , DRW_ATTRIB_FLOAT, 3}, + {"size" , DRW_ATTRIB_FLOAT, 1}, + {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16} + }); + + DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_sized); return grp; } @@ -293,12 +336,15 @@ DRWShadingGroup *shgroup_camera_instance(DRWPass *pass, struct Gwn_Batch *geom) { GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_CAMERA); - DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom); - DRW_shgroup_attrib_float(grp, "color", 3); - DRW_shgroup_attrib_float(grp, "corners", 8); - DRW_shgroup_attrib_float(grp, "depth", 1); - DRW_shgroup_attrib_float(grp, "tria", 4); - DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16); + DRW_shgroup_instance_format(g_formats.instance_camera, { + {"color" , DRW_ATTRIB_FLOAT, 3}, + {"corners" , DRW_ATTRIB_FLOAT, 8}, + {"depth" , DRW_ATTRIB_FLOAT, 1}, + {"tria" , DRW_ATTRIB_FLOAT, 4}, + {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16} + }); + + DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_camera); return grp; } @@ -308,11 +354,14 @@ DRWShadingGroup *shgroup_distance_lines_instance(DRWPass *pass, struct Gwn_Batch GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_DISTANCE_LINES); static float point_size = 4.0f; - DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom); - DRW_shgroup_attrib_float(grp, "color", 3); - DRW_shgroup_attrib_float(grp, "start", 1); - DRW_shgroup_attrib_float(grp, "end", 1); - DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16); + DRW_shgroup_instance_format(g_formats.instance_distance_lines, { + {"color" , DRW_ATTRIB_FLOAT, 3}, + {"start" , DRW_ATTRIB_FLOAT, 1}, + {"end" , DRW_ATTRIB_FLOAT, 1}, + {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16} + }); + + DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_distance_lines); DRW_shgroup_uniform_float(grp, "size", &point_size, 1); return grp; @@ -324,9 +373,12 @@ DRWShadingGroup *shgroup_spot_instance(DRWPass *pass, struct Gwn_Batch *geom) static const int True = true; static const int False = false; - DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom); - DRW_shgroup_attrib_float(grp, "color", 3); - DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16); + DRW_shgroup_instance_format(g_formats.instance_spot, { + {"color" , DRW_ATTRIB_FLOAT, 3}, + {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16} + }); + + DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_spot); DRW_shgroup_uniform_bool(grp, "drawFront", &False, 1); DRW_shgroup_uniform_bool(grp, "drawBack", &False, 1); DRW_shgroup_uniform_bool(grp, "drawSilhouette", &True, 1); @@ -338,12 +390,15 @@ DRWShadingGroup *shgroup_instance_bone_envelope_wire(DRWPass *pass, struct Gwn_B { GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_WIRE); - DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom); - DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16); - DRW_shgroup_attrib_float(grp, "color", 4); - DRW_shgroup_attrib_float(grp, "radius_head", 1); - DRW_shgroup_attrib_float(grp, "radius_tail", 1); - DRW_shgroup_attrib_float(grp, "distance", 1); + DRW_shgroup_instance_format(g_formats.instance_bone_envelope_wire, { + {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}, + {"color" , DRW_ATTRIB_FLOAT, 4}, + {"radius_head" , DRW_ATTRIB_FLOAT, 1}, + {"radius_tail" , DRW_ATTRIB_FLOAT, 1}, + {"distance" , DRW_ATTRIB_FLOAT, 1} + }); + + DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_bone_envelope_wire); return grp; } @@ -353,24 +408,30 @@ DRWShadingGroup *shgroup_instance_bone_envelope_solid(DRWPass *pass, struct Gwn_ static float light[3] = {0.0f, 0.0f, 1.0f}; GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_SOLID); - DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom); - DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16); - DRW_shgroup_attrib_float(grp, "color", 4); - DRW_shgroup_attrib_float(grp, "radius_head", 1); - DRW_shgroup_attrib_float(grp, "radius_tail", 1); + DRW_shgroup_instance_format(g_formats.instance_bone_envelope_solid, { + {"InstanceModelMatrix" , DRW_ATTRIB_FLOAT, 16}, + {"color" , DRW_ATTRIB_FLOAT, 4}, + {"radius_head" , DRW_ATTRIB_FLOAT, 1}, + {"radius_tail" , DRW_ATTRIB_FLOAT, 1} + }); + + DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_bone_envelope_solid); DRW_shgroup_uniform_vec3(grp, "light", light, 1); return grp; } -DRWShadingGroup *shgroup_instance_mball_helpers(DRWPass *pass, struct Gwn_Batch *geom) +DRWShadingGroup *shgroup_instance_mball_handles(DRWPass *pass, struct Gwn_Batch *geom) { - GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_MBALL_HELPERS); + GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_MBALL_HANDLES); + + DRW_shgroup_instance_format(g_formats.instance_mball_handles, { + {"ScaleTranslationMatrix" , DRW_ATTRIB_FLOAT, 16}, + {"radius" , DRW_ATTRIB_FLOAT, 1}, + {"color" , DRW_ATTRIB_FLOAT, 3} + }); - DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom); - DRW_shgroup_attrib_float(grp, "ScaleTranslationMatrix", 12); - DRW_shgroup_attrib_float(grp, "radius", 1); - DRW_shgroup_attrib_float(grp, "color", 3); + DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_mball_handles); DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2); return grp; @@ -386,7 +447,8 @@ DRWShadingGroup *shgroup_instance_mball_helpers(DRWPass *pass, struct Gwn_Batch */ int DRW_object_wire_theme_get(Object *ob, ViewLayer *view_layer, float **r_color) { - const bool is_edit = (ob->mode & OB_MODE_EDIT) != 0; + const DRWContextState *draw_ctx = DRW_context_state_get(); + const bool is_edit = (draw_ctx->object_mode & OB_MODE_EDIT) != 0; const bool active = (view_layer->basact && view_layer->basact->object == ob); /* confusing logic here, there are 2 methods of setting the color * 'colortab[colindex]' and 'theme_id', colindex overrides theme_id. diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index cfd88effd15..ec646693207 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -100,6 +100,7 @@ typedef struct GlobalsUboStorage { /* Keep in sync with globalsBlock in shaders */ void DRW_globals_update(void); +void DRW_globals_free(void); struct DRWShadingGroup *shgroup_dynlines_uniform_color(struct DRWPass *pass, float color[4]); struct DRWShadingGroup *shgroup_dynpoints_uniform_color(struct DRWPass *pass, float color[4], float *size); @@ -118,9 +119,10 @@ struct DRWShadingGroup *shgroup_distance_lines_instance(struct DRWPass *pass, st struct DRWShadingGroup *shgroup_spot_instance(struct DRWPass *pass, struct Gwn_Batch *geom); struct DRWShadingGroup *shgroup_instance_bone_envelope_wire(struct DRWPass *pass, struct Gwn_Batch *geom); struct DRWShadingGroup *shgroup_instance_bone_envelope_solid(struct DRWPass *pass, struct Gwn_Batch *geom); -struct DRWShadingGroup *shgroup_instance_mball_helpers(struct DRWPass *pass, struct Gwn_Batch *geom); +struct DRWShadingGroup *shgroup_instance_mball_handles(struct DRWPass *pass, struct Gwn_Batch *geom); -int DRW_object_wire_theme_get(struct Object *ob, struct ViewLayer *view_layer, float **r_color); +int DRW_object_wire_theme_get( + struct Object *ob, struct ViewLayer *view_layer, float **r_color); float *DRW_color_background_blend_get(int theme_id); /* draw_armature.c */ diff --git a/source/blender/draw/intern/draw_instance_data.c b/source/blender/draw/intern/draw_instance_data.c index e7ce4374d1c..c2aae8e33ae 100644 --- a/source/blender/draw/intern/draw_instance_data.c +++ b/source/blender/draw/intern/draw_instance_data.c @@ -34,11 +34,20 @@ #include "draw_instance_data.h" #include "DRW_engine.h" +#include "DRW_render.h" /* For DRW_shgroup_get_instance_count() */ #include "MEM_guardedalloc.h" #include "BLI_utildefines.h" -#define MAX_INSTANCE_DATA_SIZE 32 /* Can be adjusted for more */ +#define BUFFER_CHUNK_SIZE 32 +#define BUFFER_VERTS_CHUNK 32 + +typedef struct DRWInstanceBuffer { + struct DRWShadingGroup *shgroup; /* Link back to the owning shGroup. Also tells if it's used */ + Gwn_VertFormat *format; /* Identifier. */ + Gwn_VertBuf *vert; /* Gwn_VertBuf contained in the Gwn_Batch. */ + Gwn_Batch *batch; /* Gwn_Batch containing the Gwn_VertBuf. */ +} DRWInstanceBuffer; struct DRWInstanceData { struct DRWInstanceData *next; @@ -56,10 +65,118 @@ struct DRWInstanceDataList { * This is done to minimize the reattribution misses. */ DRWInstanceData *idata_head[MAX_INSTANCE_DATA_SIZE]; DRWInstanceData *idata_tail[MAX_INSTANCE_DATA_SIZE]; + + struct { + size_t cursor; /* Offset to the next instance data. */ + size_t alloc_size; /* Number of DRWInstanceBuffer alloc'd in ibufs. */ + DRWInstanceBuffer *ibufs; + } ibuffers; }; /* -------------------------------------------------------------------- */ +/** \name Instance Buffer Management + * \{ */ + +/** + * This manager allows to distribute existing batches for instancing + * attributes. This reduce the number of batches creation. + * Querying a batch is done with a vertex format. This format should + * be static so that it's pointer never changes (because we are using + * this pointer as identifier [we don't want to check the full format + * that would be too slow]). + **/ + +void DRW_instance_buffer_request( + DRWInstanceDataList *idatalist, Gwn_VertFormat *format, struct DRWShadingGroup *shgroup, + Gwn_Batch **r_batch, Gwn_VertBuf **r_vert, Gwn_PrimType type) +{ + BLI_assert(format); + + DRWInstanceBuffer *ibuf = idatalist->ibuffers.ibufs; + int first_non_alloced = -1; + + /* Search for an unused batch. */ + for (int i = 0; i < idatalist->ibuffers.alloc_size; i++, ibuf++) { + if (ibuf->shgroup == NULL) { + if (ibuf->format == format) { + ibuf->shgroup = shgroup; + *r_batch = ibuf->batch; + *r_vert = ibuf->vert; + return; + } + else if (ibuf->format == NULL && first_non_alloced == -1) { + first_non_alloced = i; + } + } + } + + if (first_non_alloced == -1) { + /* There is no batch left. Allocate more. */ + first_non_alloced = idatalist->ibuffers.alloc_size; + idatalist->ibuffers.alloc_size += BUFFER_CHUNK_SIZE; + idatalist->ibuffers.ibufs = MEM_reallocN(idatalist->ibuffers.ibufs, + idatalist->ibuffers.alloc_size * sizeof(DRWInstanceBuffer)); + /* Clear new part of the memory. */ + memset(idatalist->ibuffers.ibufs + first_non_alloced, 0, sizeof(DRWInstanceBuffer) * BUFFER_CHUNK_SIZE); + } + + /* Create the batch. */ + ibuf = idatalist->ibuffers.ibufs + first_non_alloced; + ibuf->vert = *r_vert = GWN_vertbuf_create_dynamic_with_format(format); + ibuf->batch = *r_batch = GWN_batch_create_ex(type, ibuf->vert, NULL, GWN_BATCH_OWNS_VBO); + ibuf->format = format; + ibuf->shgroup = shgroup; + + GWN_vertbuf_data_alloc(*r_vert, BUFFER_VERTS_CHUNK); +} + +void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist) +{ + DRWInstanceBuffer *ibuf = idatalist->ibuffers.ibufs; + size_t minimum_alloc_size = 1; /* Avoid 0 size realloc. */ + + /* Resize down buffers in use and send data to GPU & free unused buffers. */ + for (int i = 0; i < idatalist->ibuffers.alloc_size; i++, ibuf++) { + if (ibuf->shgroup != NULL) { + minimum_alloc_size = i + 1; + unsigned int vert_ct = DRW_shgroup_get_instance_count(ibuf->shgroup); + /* Do not realloc to 0 size buffer */ + vert_ct += (vert_ct == 0) ? 1 : 0; + /* Resize buffer to reclame space. */ + if (vert_ct + BUFFER_VERTS_CHUNK <= ibuf->vert->vertex_ct) { + unsigned int size = vert_ct + BUFFER_VERTS_CHUNK - 1; + size = size - size % BUFFER_VERTS_CHUNK; + GWN_vertbuf_data_resize(ibuf->vert, size); + } + /* Send data. */ + GWN_vertbuf_use(ibuf->vert); + /* Set as non used for the next round. */ + ibuf->shgroup = NULL; + } + else { + GWN_BATCH_DISCARD_SAFE(ibuf->batch); + /* Tag as non alloced. */ + ibuf->format = NULL; + } + } + + /* Resize down the handle buffer (ibuffers). */ + /* Rounding up to nearest chunk size. */ + minimum_alloc_size += BUFFER_CHUNK_SIZE - 1; + minimum_alloc_size -= minimum_alloc_size % BUFFER_CHUNK_SIZE; + /* Resize down if necessary. */ + if (minimum_alloc_size < idatalist->ibuffers.alloc_size) { + idatalist->ibuffers.alloc_size = minimum_alloc_size; + idatalist->ibuffers.ibufs = MEM_reallocN(idatalist->ibuffers.ibufs, + minimum_alloc_size * sizeof(DRWInstanceBuffer)); + } +} + +/** \} */ + +/* -------------------------------------------------------------------- */ + /** \name Instance Data (DRWInstanceData) * \{ */ @@ -145,11 +262,16 @@ DRWInstanceData *DRW_instance_data_request( DRWInstanceDataList *DRW_instance_data_list_create(void) { - return MEM_callocN(sizeof(DRWInstanceDataList), "DRWInstanceDataList"); + DRWInstanceDataList *idatalist = MEM_callocN(sizeof(DRWInstanceDataList), "DRWInstanceDataList"); + idatalist->ibuffers.ibufs = MEM_callocN(sizeof(DRWInstanceBuffer) * BUFFER_CHUNK_SIZE, "DRWInstanceBuffers"); + idatalist->ibuffers.alloc_size = BUFFER_CHUNK_SIZE; + + return idatalist; } void DRW_instance_data_list_free(DRWInstanceDataList *idatalist) { + DRWInstanceBuffer *ibuf = idatalist->ibuffers.ibufs; DRWInstanceData *idata, *next_idata; for (int i = 0; i < MAX_INSTANCE_DATA_SIZE; ++i) { @@ -161,6 +283,11 @@ void DRW_instance_data_list_free(DRWInstanceDataList *idatalist) idatalist->idata_head[i] = NULL; idatalist->idata_tail[i] = NULL; } + + for (int i = 0; i < idatalist->ibuffers.alloc_size; i++, ibuf++) { + GWN_BATCH_DISCARD_SAFE(ibuf->batch); + } + MEM_freeN(idatalist->ibuffers.ibufs); } void DRW_instance_data_list_reset(DRWInstanceDataList *idatalist) diff --git a/source/blender/draw/intern/draw_instance_data.h b/source/blender/draw/intern/draw_instance_data.h index 637c0e3cc24..a7a66c9baff 100644 --- a/source/blender/draw/intern/draw_instance_data.h +++ b/source/blender/draw/intern/draw_instance_data.h @@ -26,14 +26,30 @@ #ifndef __DRAW_INSTANCE_DATA_H__ #define __DRAW_INSTANCE_DATA_H__ +#include "BLI_compiler_attrs.h" +#include "BLI_sys_types.h" + +#include "GPU_batch.h" + +#define MAX_INSTANCE_DATA_SIZE 42 /* Can be adjusted for more */ + typedef struct DRWInstanceData DRWInstanceData; typedef struct DRWInstanceDataList DRWInstanceDataList; +struct DRWShadingGroup; + void *DRW_instance_data_next(DRWInstanceData *idata); void *DRW_instance_data_get(DRWInstanceData *idata); DRWInstanceData *DRW_instance_data_request( DRWInstanceDataList *idatalist, unsigned int attrib_size, unsigned int instance_group); +void DRW_instance_buffer_request( + DRWInstanceDataList *idatalist, Gwn_VertFormat *format, struct DRWShadingGroup *shgroup, + Gwn_Batch **r_batch, Gwn_VertBuf **r_vert, Gwn_PrimType type); + +/* Upload all instance data to the GPU as soon as possible. */ +void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist); + void DRW_instance_data_list_reset(DRWInstanceDataList *idatalist); void DRW_instance_data_list_free_unused(DRWInstanceDataList *idatalist); void DRW_instance_data_list_resize(DRWInstanceDataList *idatalist); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 55195b88c05..a3a59efc799 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -75,6 +75,7 @@ #include "IMB_colormanagement.h" #include "RE_engine.h" +#include "RE_pipeline.h" #include "UI_interface.h" #include "UI_resources.h" @@ -171,26 +172,30 @@ typedef enum { DRW_UNIFORM_BLOCK } DRWUniformType; -typedef enum { - DRW_ATTRIB_INT, - DRW_ATTRIB_FLOAT, -} DRWAttribType; +#define MAX_UNIFORM_DATA_SIZE 16 struct DRWUniform { struct DRWUniform *next; - DRWUniformType type; - int location; - int length; - int arraysize; const void *value; + int location; + char type; /* DRWUniformType */ + char length; /* cannot be more than 16 */ + char arraysize; /* cannot be more than 16 too */ }; struct DRWInterface { DRWUniform *uniforms; /* DRWUniform, single-linked list */ - int attribs_count; - int attribs_stride; - int attribs_size[16]; - int attribs_loc[16]; + /* Dynamic batch */ +#ifdef USE_GPU_SELECT + struct DRWInstanceData *inst_selectid; + /* Override for single object instances. */ + int override_selectid; +#endif + Gwn_VertBuf *instance_vbo; + unsigned int instance_count; +#ifndef NDEBUG + char attribs_count; +#endif /* matrices locations */ int model; int modelinverse; @@ -209,17 +214,6 @@ struct DRWInterface { int orcotexfac; int eye; int clipplanes; - /* Dynamic batch */ - Gwn_Batch *instance_batch; /* contains instances attributes */ - GLuint instance_vbo; /* same as instance_batch but generated from DRWCalls */ - struct DRWInstanceData *inst_data; -#ifdef USE_GPU_SELECT - struct DRWInstanceData *inst_selectid; - /* Override for single object instances. */ - int override_selectid; -#endif - int instance_count; - Gwn_VertFormat vbo_format; }; struct DRWPass { @@ -276,6 +270,7 @@ struct DRWShadingGroup { ID *instance_data; /* Object->data to instance */ Gwn_Batch *instance_geom; /* Geometry to instance */ + Gwn_Batch *instancing_geom;/* Instances attributes */ Gwn_Batch *batch_geom; /* Result of call batching */ #ifdef USE_GPU_SELECT @@ -291,6 +286,7 @@ enum { DRW_SHG_LINE_BATCH, DRW_SHG_TRIANGLE_BATCH, DRW_SHG_INSTANCE, + DRW_SHG_INSTANCE_EXTERNAL, }; /* Used by DRWCall.type */ @@ -312,6 +308,7 @@ static struct DRWGlobalState { DRWCallGenerate *last_callgenerate; DRWShadingGroup *last_shgroup; DRWInstanceDataList *idatalist; + DRWInstanceData *common_instance_data[MAX_INSTANCE_DATA_SIZE]; /* Rendering state */ GPUShader *shader; @@ -349,6 +346,8 @@ static struct DRWGlobalState { ListBase enabled_engines; /* RenderEngineType */ + bool buffer_finish_called; /* Avoid bad usage of DRW_render_instance_buffer_finish */ + /* Profiling */ double cache_time; } DST = {NULL}; @@ -635,7 +634,7 @@ void DRW_shader_free(GPUShader *shader) /** \name Interface (DRW_interface) * \{ */ -static void drw_interface_create(DRWInterface *interface, GPUShader *shader) +static void drw_interface_init(DRWInterface *interface, GPUShader *shader) { interface->model = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_MODEL); interface->modelinverse = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_MODEL_INV); @@ -655,20 +654,56 @@ static void drw_interface_create(DRWInterface *interface, GPUShader *shader) interface->clipplanes = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_CLIPPLANES); interface->eye = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_EYE); interface->instance_count = 0; +#ifndef NDEBUG interface->attribs_count = 0; - interface->attribs_stride = 0; - interface->instance_vbo = 0; - interface->instance_batch = NULL; - interface->inst_data = NULL; +#endif interface->uniforms = NULL; #ifdef USE_GPU_SELECT interface->inst_selectid = NULL; interface->override_selectid = -1; #endif - - memset(&interface->vbo_format, 0, sizeof(Gwn_VertFormat)); } +static void drw_interface_instance_init( + DRWShadingGroup *shgroup, GPUShader *shader, Gwn_VertFormat *format) +{ + DRWInterface *interface = &shgroup->interface; + drw_interface_init(interface, shader); + +#ifndef NDEBUG + interface->attribs_count = (format != NULL) ? format->attrib_ct : 0; +#endif + + Gwn_PrimType type; + Gwn_Batch **r_batch = NULL; + switch (shgroup->type) { + case DRW_SHG_INSTANCE: + r_batch = &shgroup->instancing_geom; + type = GWN_PRIM_POINTS; + break; + case DRW_SHG_POINT_BATCH: + r_batch = &shgroup->batch_geom; + type = GWN_PRIM_POINTS; + break; + case DRW_SHG_LINE_BATCH: + r_batch = &shgroup->batch_geom; + type = GWN_PRIM_LINES; + break; + case DRW_SHG_TRIANGLE_BATCH: + r_batch = &shgroup->batch_geom; + type = GWN_PRIM_TRIS; + break; + default: + BLI_assert(0); + } + + if (format != NULL) { + DRW_instance_buffer_request(DST.idatalist, format, shgroup, r_batch, &interface->instance_vbo, type); + } + else { + *r_batch = NULL; + } +} static void drw_interface_uniform(DRWShadingGroup *shgroup, const char *name, DRWUniformType type, const void *value, int length, int arraysize) @@ -691,7 +726,8 @@ static void drw_interface_uniform(DRWShadingGroup *shgroup, const char *name, DRWUniform *uni = BLI_mempool_alloc(DST.vmempool->uniforms); - BLI_assert(arraysize > 0); + BLI_assert(arraysize > 0 && arraysize <= 16); + BLI_assert(arraysize * length <= MAX_UNIFORM_DATA_SIZE); uni->location = location; uni->type = type; @@ -704,36 +740,17 @@ static void drw_interface_uniform(DRWShadingGroup *shgroup, const char *name, shgroup->interface.uniforms = uni; } -static void drw_interface_attrib(DRWShadingGroup *shgroup, const char *name, DRWAttribType UNUSED(type), int size, bool dummy) +Gwn_VertFormat *DRW_shgroup_instance_format_array(const DRWInstanceAttribFormat attribs[], int arraysize) { - unsigned int attrib_id = shgroup->interface.attribs_count; - GLuint program = GPU_shader_get_program(shgroup->shader); + Gwn_VertFormat *format = MEM_callocN(sizeof(Gwn_VertFormat), "Gwn_VertFormat"); - shgroup->interface.attribs_loc[attrib_id] = glGetAttribLocation(program, name); - shgroup->interface.attribs_size[attrib_id] = size; - shgroup->interface.attribs_stride += size; - shgroup->interface.attribs_count += 1; - - if (shgroup->type != DRW_SHG_INSTANCE) { - BLI_assert(size <= 4); /* Matrices are not supported by Gawain. */ - GWN_vertformat_attr_add(&shgroup->interface.vbo_format, name, GWN_COMP_F32, size, GWN_FETCH_FLOAT); + for (int i = 0; i < arraysize; ++i) { + GWN_vertformat_attr_add(format, attribs[i].name, + (attribs[i].type == DRW_ATTRIB_INT) ? GWN_COMP_I32 : GWN_COMP_F32, + attribs[i].components, + (attribs[i].type == DRW_ATTRIB_INT) ? GWN_FETCH_INT : GWN_FETCH_FLOAT); } - - BLI_assert(shgroup->interface.attribs_count < MAX_ATTRIB_COUNT); - -/* Adding attribute even if not found for now (to keep memory alignment). - * Should ideally take vertex format automatically from batch eventually */ -#if 0 - if (attrib->location == -1 && !dummy) { - if (G.debug & G_DEBUG) - fprintf(stderr, "Attribute '%s' not found!\n", name); - BLI_assert(0); - MEM_freeN(attrib); - return; - } -#else - UNUSED_VARS(dummy); -#endif + return format; } /** \} */ @@ -744,7 +761,7 @@ static void drw_interface_attrib(DRWShadingGroup *shgroup, const char *name, DRW /** \name Shading Group (DRW_shgroup) * \{ */ -DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass) +static DRWShadingGroup *drw_shgroup_create_ex(struct GPUShader *shader, DRWPass *pass) { DRWShadingGroup *shgroup = BLI_mempool_alloc(DST.vmempool->shgroups); @@ -757,15 +774,13 @@ DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass) } pass->shgroups_last = shgroup; shgroup->next = NULL; - - drw_interface_create(&shgroup->interface, shader); - shgroup->type = DRW_SHG_NORMAL; shgroup->shader = shader; shgroup->state_extra = 0; shgroup->state_extra_disable = ~0x0; shgroup->stencil_mask = 0; shgroup->batch_geom = NULL; + shgroup->instancing_geom = NULL; shgroup->instance_geom = NULL; shgroup->instance_data = NULL; @@ -779,22 +794,22 @@ DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass) return shgroup; } -DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPass *pass) +static DRWShadingGroup *drw_shgroup_material_create_ex(GPUPass *gpupass, DRWPass *pass) { - double time = 0.0; /* TODO make time variable */ - - /* TODO : Ideally we should not convert. But since the whole codegen - * is relying on GPUPass we keep it as is for now. */ - GPUPass *gpupass = GPU_material_get_pass(material); - if (!gpupass) { /* Shader compilation error */ return NULL; } - struct GPUShader *shader = GPU_pass_shader(gpupass); + DRWShadingGroup *grp = drw_shgroup_create_ex(GPU_pass_shader(gpupass), pass); + return grp; +} - DRWShadingGroup *grp = DRW_shgroup_create(shader, pass); +static DRWShadingGroup *drw_shgroup_material_inputs( + DRWShadingGroup *grp, struct GPUMaterial *material, GPUPass *gpupass) +{ + /* TODO : Ideally we should not convert. But since the whole codegen + * is relying on GPUPass we keep it as is for now. */ /* Converting dynamic GPUInput to DRWUniform */ ListBase *inputs = &gpupass->inputs; @@ -802,6 +817,7 @@ DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPa for (GPUInput *input = inputs->first; input; input = input->next) { /* Textures */ if (input->ima) { + double time = 0.0; /* TODO make time variable */ GPUTexture *tex = GPU_texture_from_blender( input->ima, input->iuser, input->textarget, input->image_isdata, time, 1); @@ -842,15 +858,32 @@ DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPa return grp; } +DRWShadingGroup *DRW_shgroup_material_create( + struct GPUMaterial *material, DRWPass *pass) +{ + GPUPass *gpupass = GPU_material_get_pass(material); + DRWShadingGroup *shgroup = drw_shgroup_material_create_ex(gpupass, pass); + + if (shgroup) { + drw_interface_init(&shgroup->interface, GPU_pass_shader(gpupass)); + drw_shgroup_material_inputs(shgroup, material, gpupass); + } + + return shgroup; +} + DRWShadingGroup *DRW_shgroup_material_instance_create( - struct GPUMaterial *material, DRWPass *pass, Gwn_Batch *geom, Object *ob) + struct GPUMaterial *material, DRWPass *pass, Gwn_Batch *geom, Object *ob, Gwn_VertFormat *format) { - DRWShadingGroup *shgroup = DRW_shgroup_material_create(material, pass); + GPUPass *gpupass = GPU_material_get_pass(material); + DRWShadingGroup *shgroup = drw_shgroup_material_create_ex(gpupass, pass); if (shgroup) { shgroup->type = DRW_SHG_INSTANCE; shgroup->instance_geom = geom; shgroup->instance_data = ob->data; + drw_interface_instance_init(shgroup, GPU_pass_shader(gpupass), format); + drw_shgroup_material_inputs(shgroup, material, gpupass); } return shgroup; @@ -859,43 +892,64 @@ DRWShadingGroup *DRW_shgroup_material_instance_create( DRWShadingGroup *DRW_shgroup_material_empty_tri_batch_create( struct GPUMaterial *material, DRWPass *pass, int size) { - DRWShadingGroup *shgroup = DRW_shgroup_material_create(material, pass); +#ifdef USE_GPU_SELECT + BLI_assert((G.f & G_PICKSEL) == 0); +#endif + GPUPass *gpupass = GPU_material_get_pass(material); + DRWShadingGroup *shgroup = drw_shgroup_material_create_ex(gpupass, pass); if (shgroup) { shgroup->type = DRW_SHG_TRIANGLE_BATCH; shgroup->interface.instance_count = size * 3; - drw_interface_attrib(shgroup, "dummy", DRW_ATTRIB_FLOAT, 1, true); + /* Calling drw_interface_init will cause it to GWN_batch_draw_procedural. */ + drw_interface_init(&shgroup->interface, GPU_pass_shader(gpupass)); + drw_shgroup_material_inputs(shgroup, material, gpupass); } return shgroup; } -DRWShadingGroup *DRW_shgroup_instance_create(struct GPUShader *shader, DRWPass *pass, Gwn_Batch *geom) +DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass) { - DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass); + DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass); + drw_interface_init(&shgroup->interface, shader); + return shgroup; +} +DRWShadingGroup *DRW_shgroup_instance_create( + struct GPUShader *shader, DRWPass *pass, Gwn_Batch *geom, Gwn_VertFormat *format) +{ + DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass); shgroup->type = DRW_SHG_INSTANCE; shgroup->instance_geom = geom; + drw_interface_instance_init(shgroup, shader, format); + return shgroup; } +static Gwn_VertFormat *g_pos_format = NULL; + DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPass *pass) { - DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass); + DRW_shgroup_instance_format(g_pos_format, {{"pos", DRW_ATTRIB_FLOAT, 3}}); + DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass); shgroup->type = DRW_SHG_POINT_BATCH; - DRW_shgroup_attrib_float(shgroup, "pos", 3); + + drw_interface_instance_init(shgroup, shader, g_pos_format); return shgroup; } DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass *pass) { - DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass); + DRW_shgroup_instance_format(g_pos_format, {{"pos", DRW_ATTRIB_FLOAT, 3}}); + DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass); shgroup->type = DRW_SHG_LINE_BATCH; - DRW_shgroup_attrib_float(shgroup, "pos", 3); + + drw_interface_instance_init(shgroup, shader, g_pos_format); return shgroup; } @@ -905,24 +959,23 @@ DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass * and dont need any VBO attrib */ DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(struct GPUShader *shader, DRWPass *pass, int size) { - DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass); +#ifdef USE_GPU_SELECT + BLI_assert((G.f & G_PICKSEL) == 0); +#endif + DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass); + + /* Calling drw_interface_init will cause it to GWN_batch_draw_procedural. */ + drw_interface_init(&shgroup->interface, shader); shgroup->type = DRW_SHG_TRIANGLE_BATCH; shgroup->interface.instance_count = size * 3; - drw_interface_attrib(shgroup, "dummy", DRW_ATTRIB_FLOAT, 1, true); return shgroup; } -void DRW_shgroup_free(struct DRWShadingGroup *shgroup) +void DRW_shgroup_free(struct DRWShadingGroup *UNUSED(shgroup)) { - if (shgroup->interface.instance_vbo && - (shgroup->interface.instance_batch == 0)) - { - glDeleteBuffers(1, &shgroup->interface.instance_vbo); - } - - GWN_BATCH_DISCARD_SAFE(shgroup->batch_geom); + return; } #define CALL_PREPEND(shgroup, call) { \ @@ -937,12 +990,14 @@ void DRW_shgroup_free(struct DRWShadingGroup *shgroup) call->head.prev = NULL; \ } ((void)0) +/* Specify an external batch instead of adding each attrib one by one. */ void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct Gwn_Batch *instances) { BLI_assert(shgroup->type == DRW_SHG_INSTANCE); - BLI_assert(shgroup->interface.instance_batch == NULL); + BLI_assert(shgroup->instancing_geom == NULL); - shgroup->interface.instance_batch = instances; + shgroup->type = DRW_SHG_INSTANCE_EXTERNAL; + shgroup->instancing_geom = instances; #ifdef USE_GPU_SELECT DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls); @@ -1056,24 +1111,18 @@ void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *at BLI_assert(attr_len == interface->attribs_count); UNUSED_VARS_NDEBUG(attr_len); - if (interface->attribs_stride > 0) { - if (interface->inst_data == NULL) { - interface->inst_data = DRW_instance_data_request(DST.idatalist, interface->attribs_stride, 16); - } - - float *data = DRW_instance_data_next(interface->inst_data); - - for (int i = 0; i < interface->attribs_count; ++i) { - memcpy(data, attr[i], sizeof(float) * interface->attribs_size[i]); - data = data + interface->attribs_size[i]; + for (int i = 0; i < attr_len; ++i) { + if (interface->instance_count == interface->instance_vbo->vertex_ct) { + GWN_vertbuf_data_resize(interface->instance_vbo, interface->instance_count + 32); } + GWN_vertbuf_attr_set(interface->instance_vbo, i, interface->instance_count, attr[i]); } interface->instance_count += 1; } /* Used for instancing with no attributes */ -void DRW_shgroup_set_instance_count(DRWShadingGroup *shgroup, int count) +void DRW_shgroup_set_instance_count(DRWShadingGroup *shgroup, unsigned int count) { DRWInterface *interface = &shgroup->interface; @@ -1089,6 +1138,13 @@ void DRW_shgroup_set_instance_count(DRWShadingGroup *shgroup, int count) interface->instance_count = count; } +unsigned int DRW_shgroup_get_instance_count(const DRWShadingGroup *shgroup) +{ + BLI_assert(shgroup->type != DRW_SHG_NORMAL && shgroup->type != DRW_SHG_INSTANCE_EXTERNAL); + + return shgroup->interface.instance_count; +} + /** * State is added to #Pass.state while drawing. * Use to temporarily enable draw options. @@ -1105,14 +1161,10 @@ void DRW_shgroup_state_disable(DRWShadingGroup *shgroup, DRWState state) void DRW_shgroup_stencil_mask(DRWShadingGroup *shgroup, unsigned int mask) { + BLI_assert(mask <= 255); shgroup->stencil_mask = mask; } -void DRW_shgroup_attrib_float(DRWShadingGroup *shgroup, const char *name, int size) -{ - drw_interface_attrib(shgroup, name, DRW_ATTRIB_FLOAT, size, false); -} - void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex) { drw_interface_uniform(shgroup, name, DRW_UNIFORM_TEXTURE, tex, 0, 1); @@ -1188,88 +1240,6 @@ void DRW_shgroup_uniform_mat4(DRWShadingGroup *shgroup, const char *name, const drw_interface_uniform(shgroup, name, DRW_UNIFORM_MAT4, value, 16, 1); } -/* Creates a VBO containing OGL primitives for all DRWCallDynamic */ -static void shgroup_dynamic_batch(DRWShadingGroup *shgroup) -{ - DRWInterface *interface = &shgroup->interface; - int nbr = interface->instance_count; - - Gwn_PrimType type = (shgroup->type == DRW_SHG_POINT_BATCH) ? GWN_PRIM_POINTS : - (shgroup->type == DRW_SHG_TRIANGLE_BATCH) ? GWN_PRIM_TRIS : GWN_PRIM_LINES; - - if (nbr == 0) - return; - - /* Upload Data */ - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&interface->vbo_format); - if (interface->inst_data) { - GWN_vertbuf_data_set(vbo, nbr, DRW_instance_data_get(interface->inst_data), false); - } else { - /* Use unitialized memory. This is for dummy vertex buffers. */ - /* XXX TODO do not alloc at all. */ - GWN_vertbuf_data_alloc(vbo, nbr); - } - - /* TODO make the batch dynamic instead of freeing it every times */ - if (shgroup->batch_geom) - GWN_batch_discard(shgroup->batch_geom); - - shgroup->batch_geom = GWN_batch_create_ex(type, vbo, NULL, GWN_BATCH_OWNS_VBO); -} - -static void shgroup_dynamic_instance(DRWShadingGroup *shgroup) -{ - DRWInterface *interface = &shgroup->interface; - int buffer_size = 0; - void *data = NULL; - - if (interface->instance_batch != NULL) { - return; - } - - /* TODO We still need this because gawain does not support Matrix attribs. */ - if (interface->instance_count == 0) { - if (interface->instance_vbo) { - glDeleteBuffers(1, &interface->instance_vbo); - interface->instance_vbo = 0; - } - return; - } - - /* Gather Data */ - buffer_size = sizeof(float) * interface->attribs_stride * interface->instance_count; - - /* TODO poke mike to add this to gawain */ - if (interface->instance_vbo) { - glDeleteBuffers(1, &interface->instance_vbo); - interface->instance_vbo = 0; - } - - if (interface->inst_data) { - data = DRW_instance_data_get(interface->inst_data); - } - - glGenBuffers(1, &interface->instance_vbo); - glBindBuffer(GL_ARRAY_BUFFER, interface->instance_vbo); - glBufferData(GL_ARRAY_BUFFER, buffer_size, data, GL_STATIC_DRAW); -} - -static void shgroup_dynamic_batch_from_calls(DRWShadingGroup *shgroup) -{ - if ((shgroup->interface.instance_vbo || shgroup->batch_geom) && - (G.debug_value == 667)) - { - return; - } - - if (shgroup->type == DRW_SHG_INSTANCE) { - shgroup_dynamic_instance(shgroup); - } - else { - shgroup_dynamic_batch(shgroup); - } -} - /** \} */ @@ -1685,6 +1655,11 @@ static void draw_geometry_prepare( float mvp[4][4], mv[4][4], mi[4][4], mvi[4][4], pi[4][4], n[3][3], wn[3][3]; float orcofacs[2][3] = {{0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f}}; float eye[3] = { 0.0f, 0.0f, 1.0f }; /* looking into the screen */ + float viewcamtexcofac[4] = { 1.0f, 1.0f, 0.0f, 0.0f }; + + if (rv3d != NULL) { + copy_v4_v4(viewcamtexcofac, rv3d->viewcamtexcofac); + } bool do_pi = (interface->projectioninverse != -1); bool do_mvp = (interface->modelviewprojection != -1); @@ -1777,7 +1752,7 @@ static void draw_geometry_prepare( GPU_shader_uniform_vector(shgroup->shader, interface->modelviewinverse, 16, 1, (float *)mvi); GPU_shader_uniform_vector(shgroup->shader, interface->normal, 9, 1, (float *)n); GPU_shader_uniform_vector(shgroup->shader, interface->worldnormal, 9, 1, (float *)wn); - GPU_shader_uniform_vector(shgroup->shader, interface->camtexfac, 4, 1, (float *)rv3d->viewcamtexcofac); + GPU_shader_uniform_vector(shgroup->shader, interface->camtexfac, 4, 1, (float *)viewcamtexcofac); GPU_shader_uniform_vector(shgroup->shader, interface->orcotexfac, 3, 2, (float *)orcofacs); GPU_shader_uniform_vector(shgroup->shader, interface->eye, 3, 1, (float *)eye); GPU_shader_uniform_vector(shgroup->shader, interface->clipplanes, 4, DST.num_clip_planes, (float *)DST.clip_planes_eq); @@ -1786,17 +1761,19 @@ static void draw_geometry_prepare( static void draw_geometry_execute_ex( DRWShadingGroup *shgroup, Gwn_Batch *geom, unsigned int start, unsigned int count) { - DRWInterface *interface = &shgroup->interface; + /* Special case: empty drawcall, placement is done via shader, don't bind anything. */ + if (geom == NULL) { + BLI_assert(shgroup->type == DRW_SHG_TRIANGLE_BATCH); /* Add other type if needed. */ + /* Shader is already bound. */ + Gwn_Batch *batch = DRW_cache_fullscreen_quad_get(); + GWN_batch_draw_procedural(batch, GWN_PRIM_TRIS, count); + return; + } + /* step 2 : bind vertex array & draw */ GWN_batch_program_set(geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader)); - if (interface->instance_batch) { - /* Used for Particles. Cannot do partial drawing. */ - GWN_batch_draw_stupid_instanced_with_batch(geom, interface->instance_batch); - } - else if (interface->instance_vbo) { - GWN_batch_draw_stupid_instanced( - geom, interface->instance_vbo, start, count, interface->attribs_count, - interface->attribs_stride, interface->attribs_size, interface->attribs_loc); + if (ELEM(shgroup->type, DRW_SHG_INSTANCE, DRW_SHG_INSTANCE_EXTERNAL)) { + GWN_batch_draw_stupid_instanced(geom, shgroup->instancing_geom, start, count); } else { GWN_batch_draw_stupid(geom, start, count); @@ -1863,6 +1840,7 @@ static void bind_texture(GPUTexture *tex) GPU_texture_bind(tex, RST.bind_tex_inc); RST.bound_texs[RST.bind_tex_inc] = tex; RST.bound_tex_slots[RST.bind_tex_inc] = true; + // printf("Binds Texture %d %p\n", RST.bind_tex_inc, tex); return; } } @@ -1914,12 +1892,6 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) DST.shader = shgroup->shader; } - const bool is_normal = ELEM(shgroup->type, DRW_SHG_NORMAL); - - if (!is_normal) { - shgroup_dynamic_batch_from_calls(shgroup); - } - release_texture_slots(); release_ubo_slots(); @@ -2017,30 +1989,32 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) #endif /* Rendering Calls */ - if (!is_normal) { + if (!ELEM(shgroup->type, DRW_SHG_NORMAL)) { /* Replacing multiple calls with only one */ float obmat[4][4]; unit_m4(obmat); - if (shgroup->type == DRW_SHG_INSTANCE && - (interface->instance_count > 0 || interface->instance_batch != NULL)) - { - if (interface->instance_batch != NULL) { - GPU_SELECT_LOAD_IF_PICKSEL((DRWCall *)shgroup->calls_first); - draw_geometry(shgroup, shgroup->instance_geom, obmat, shgroup->instance_data, 0, 0); + if (ELEM(shgroup->type, DRW_SHG_INSTANCE, DRW_SHG_INSTANCE_EXTERNAL)) { + if (shgroup->type == DRW_SHG_INSTANCE_EXTERNAL) { + if (shgroup->instancing_geom != NULL) { + GPU_SELECT_LOAD_IF_PICKSEL((DRWCall *)shgroup->calls_first); + draw_geometry(shgroup, shgroup->instance_geom, obmat, shgroup->instance_data, 0, 0); + } } else { - unsigned int count, start; - GPU_SELECT_LOAD_IF_PICKSEL_LIST(shgroup, start, count) - { - draw_geometry(shgroup, shgroup->instance_geom, obmat, shgroup->instance_data, start, count); + if (shgroup->interface.instance_count > 0) { + unsigned int count, start; + GPU_SELECT_LOAD_IF_PICKSEL_LIST(shgroup, start, count) + { + draw_geometry(shgroup, shgroup->instance_geom, obmat, shgroup->instance_data, start, count); + } + GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count) } - GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count) } } else { /* Some dynamic batch can have no geom (no call to aggregate) */ - if (shgroup->batch_geom) { + if (shgroup->interface.instance_count > 0) { unsigned int count, start; GPU_SELECT_LOAD_IF_PICKSEL_LIST(shgroup, start, count) { @@ -2087,6 +2061,8 @@ static void drw_draw_pass_ex(DRWPass *pass, DRWShadingGroup *start_group, DRWSha /* Start fresh */ DST.shader = NULL; + BLI_assert(DST.buffer_finish_called && "DRW_render_instance_buffer_finish had not been called before drawing"); + drw_state_set(pass->state); DRW_stats_query_start(pass->name); @@ -2152,7 +2128,7 @@ void DRW_state_reset_ex(DRWState state) void DRW_state_reset(void) { /* Reset blending function */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); DRW_state_reset_ex(DRW_STATE_DEFAULT); } @@ -2199,13 +2175,10 @@ struct DRWTextStore *DRW_text_cache_ensure(void) bool DRW_object_is_renderable(Object *ob) { - Scene *scene = DST.draw_ctx.scene; - Object *obedit = scene->obedit; - BLI_assert(BKE_object_is_visible(ob, OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE)); if (ob->type == OB_MESH) { - if (ob == obedit) { + if (ob == DST.draw_ctx.object_edit) { IDProperty *props = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_EDIT, ""); bool do_show_occlude_wire = BKE_collection_engine_property_value_get_bool(props, "show_occlude_wire"); if (do_show_occlude_wire) { @@ -2250,8 +2223,8 @@ bool DRW_object_is_flat_normal(const Object *ob) int DRW_object_is_mode_shade(const Object *ob) { BLI_assert(ob == DST.draw_ctx.obact); - if ((ob->mode & OB_MODE_EDIT) == 0) { - if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) { + if ((DST.draw_ctx.object_mode & OB_MODE_EDIT) == 0) { + if (DST.draw_ctx.object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) { if ((DST.draw_ctx.v3d->flag2 & V3D_SHOW_MODE_SHADE_OVERRIDE) == 0) { return true; } @@ -2579,17 +2552,41 @@ static void drw_viewport_cache_resize(void) GPU_viewport_cache_release(DST.viewport); if (DST.vmempool != NULL) { - BLI_mempool_clear_ex(DST.vmempool->calls, BLI_mempool_count(DST.vmempool->calls)); - BLI_mempool_clear_ex(DST.vmempool->calls_generate, BLI_mempool_count(DST.vmempool->calls_generate)); - BLI_mempool_clear_ex(DST.vmempool->shgroups, BLI_mempool_count(DST.vmempool->shgroups)); - BLI_mempool_clear_ex(DST.vmempool->uniforms, BLI_mempool_count(DST.vmempool->uniforms)); - BLI_mempool_clear_ex(DST.vmempool->passes, BLI_mempool_count(DST.vmempool->passes)); + BLI_mempool_clear_ex(DST.vmempool->calls, BLI_mempool_len(DST.vmempool->calls)); + BLI_mempool_clear_ex(DST.vmempool->calls_generate, BLI_mempool_len(DST.vmempool->calls_generate)); + BLI_mempool_clear_ex(DST.vmempool->shgroups, BLI_mempool_len(DST.vmempool->shgroups)); + BLI_mempool_clear_ex(DST.vmempool->uniforms, BLI_mempool_len(DST.vmempool->uniforms)); + BLI_mempool_clear_ex(DST.vmempool->passes, BLI_mempool_len(DST.vmempool->passes)); } DRW_instance_data_list_free_unused(DST.idatalist); DRW_instance_data_list_resize(DST.idatalist); } + +/* Not a viewport variable, we could split this out. */ +static void drw_context_state_init(void) +{ + /* Edit object. */ + if (DST.draw_ctx.object_mode & OB_MODE_EDIT) { + DST.draw_ctx.object_edit = DST.draw_ctx.obact; + } + else { + DST.draw_ctx.object_edit = NULL; + } + + /* Pose object. */ + if (DST.draw_ctx.object_mode & OB_MODE_POSE) { + DST.draw_ctx.object_pose = DST.draw_ctx.obact; + } + else if (DST.draw_ctx.object_mode & OB_MODE_WEIGHT_PAINT) { + DST.draw_ctx.object_pose = BKE_object_pose_armature_get(DST.draw_ctx.obact); + } + else { + DST.draw_ctx.object_pose = NULL; + } +} + /* It also stores viewport variable to an immutable place: DST * This is because a cache uniform only store reference * to its value. And we don't want to invalidate the cache @@ -2597,7 +2594,6 @@ static void drw_viewport_cache_resize(void) static void drw_viewport_var_init(void) { RegionView3D *rv3d = DST.draw_ctx.rv3d; - /* Refresh DST.size */ if (DST.viewport) { int size[2]; @@ -2653,8 +2649,8 @@ static void drw_viewport_var_init(void) DST.backface = GL_CW; glFrontFace(DST.frontface); - if (DST.draw_ctx.scene->obedit) { - ED_view3d_init_mats_rv3d(DST.draw_ctx.scene->obedit, rv3d); + if (DST.draw_ctx.object_edit) { + ED_view3d_init_mats_rv3d(DST.draw_ctx.object_edit, rv3d); } /* Alloc array of texture reference. */ @@ -2666,6 +2662,7 @@ static void drw_viewport_var_init(void) } memset(viewport_matrix_override.override, 0x0, sizeof(viewport_matrix_override.override)); + memset(DST.common_instance_data, 0x0, sizeof(DST.common_instance_data)); } void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type) @@ -2812,7 +2809,22 @@ ObjectEngineData *DRW_object_engine_data_ensure( return oed; } /* Allocate new data. */ - oed = MEM_callocN(size, "ObjectEngineData"); + if ((ob->base_flag & BASE_FROMDUPLI) != 0) { + /* NOTE: data is not persistent in this case. It is reset each redraw. */ + BLI_assert(free_cb == NULL); /* No callback allowed. */ + /* Round to sizeof(float) for DRW_instance_data_request(). */ + const size_t t = sizeof(float) - 1; + size = (size + t) & ~t; + size_t fsize = size / sizeof(float); + if (DST.common_instance_data[fsize] == NULL) { + DST.common_instance_data[fsize] = DRW_instance_data_request(DST.idatalist, fsize, 16); + } + oed = (ObjectEngineData *)DRW_instance_data_next(DST.common_instance_data[fsize]); + memset(oed, 0, size); + } + else { + oed = MEM_callocN(size, "ObjectEngineData"); + } oed->engine_type = engine_type; oed->free = free_cb; /* Perform user-side initialization, if needed. */ @@ -3145,10 +3157,10 @@ static void drw_engines_enable_external(void) use_drw_engine(DRW_engine_viewport_external_type.draw_engine); } -static void drw_engines_enable(const Scene *scene, ViewLayer *view_layer, RenderEngineType *engine_type) +static void drw_engines_enable(ViewLayer *view_layer, RenderEngineType *engine_type) { Object *obact = OBACT(view_layer); - const int mode = CTX_data_mode_enum_ex(scene->obedit, obact); + const int mode = CTX_data_mode_enum_ex(DST.draw_ctx.object_edit, obact, DST.draw_ctx.object_mode); drw_engines_enable_from_engine(engine_type); @@ -3322,11 +3334,11 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx) DST.viewport = rv3d->viewport; DST.draw_ctx = (DRWContextState){ - ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, + ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, OB_MODE_OBJECT, NULL, }; - drw_engines_enable(scene, view_layer, engine_type); + drw_engines_enable(view_layer, engine_type); for (LinkData *link = DST.enabled_engines.first; link; link = link->next) { DrawEngineType *draw_engine = link->data; @@ -3369,9 +3381,9 @@ void DRW_notify_id_update(const DRWUpdateContext *update_ctx, ID *id) memset(&DST, 0x0, sizeof(DST)); DST.viewport = rv3d->viewport; DST.draw_ctx = (DRWContextState){ - ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, NULL, + ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, OB_MODE_OBJECT, NULL, }; - drw_engines_enable(scene, view_layer, engine_type); + drw_engines_enable(view_layer, engine_type); for (LinkData *link = DST.enabled_engines.first; link; link = link->next) { DrawEngineType *draw_engine = link->data; ViewportEngineData *data = DRW_viewport_engine_data_ensure(draw_engine); @@ -3395,14 +3407,15 @@ void DRW_notify_id_update(const DRWUpdateContext *update_ctx, ID *id) * for each relevant engine / mode engine. */ void DRW_draw_view(const bContext *C) { - struct Depsgraph *depsgraph = CTX_data_depsgraph(C); + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); RenderEngineType *engine_type = CTX_data_engine_type(C); ARegion *ar = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); /* Reset before using it. */ memset(&DST, 0x0, sizeof(DST)); - DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, C); + DRW_draw_render_loop_ex(eval_ctx.depsgraph, engine_type, ar, v3d, eval_ctx.object_mode, C); } /** @@ -3412,7 +3425,7 @@ void DRW_draw_view(const bContext *C) void DRW_draw_render_loop_ex( struct Depsgraph *depsgraph, RenderEngineType *engine_type, - ARegion *ar, View3D *v3d, + ARegion *ar, View3D *v3d, const eObjectMode object_mode, const bContext *evil_C) { Scene *scene = DEG_get_evaluated_scene(depsgraph); @@ -3428,16 +3441,16 @@ void DRW_draw_render_loop_ex( GPU_viewport_engines_data_validate(DST.viewport, DRW_engines_get_hash()); DST.draw_ctx = (DRWContextState){ - ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, + ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, object_mode, /* reuse if caller sets */ DST.draw_ctx.evil_C, }; - + drw_context_state_init(); drw_viewport_var_init(); /* Get list of enabled engines */ - drw_engines_enable(scene, view_layer, engine_type); + drw_engines_enable(view_layer, engine_type); /* Update ubos */ DRW_globals_update(); @@ -3457,6 +3470,8 @@ void DRW_draw_render_loop_ex( DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END drw_engines_cache_finish(); + + DRW_render_instance_buffer_finish(); PROFILE_END_ACCUM(DST.cache_time, stime); } @@ -3537,7 +3552,7 @@ void DRW_draw_render_loop_ex( void DRW_draw_render_loop( struct Depsgraph *depsgraph, - ARegion *ar, View3D *v3d) + ARegion *ar, View3D *v3d, const eObjectMode object_mode) { /* Reset before using it. */ memset(&DST, 0x0, sizeof(DST)); @@ -3545,13 +3560,14 @@ void DRW_draw_render_loop( Scene *scene = DEG_get_evaluated_scene(depsgraph); RenderEngineType *engine_type = RE_engines_find(scene->view_render.engine_id); - DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, NULL); + DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, object_mode, NULL); } /* @viewport CAN be NULL, in this case we create one. */ void DRW_draw_render_loop_offscreen( struct Depsgraph *depsgraph, RenderEngineType *engine_type, - ARegion *ar, View3D *v3d, const bool draw_background, GPUOffScreen *ofs, + ARegion *ar, View3D *v3d, const eObjectMode object_mode, + const bool draw_background, GPUOffScreen *ofs, GPUViewport *viewport) { RegionView3D *rv3d = ar->regiondata; @@ -3572,7 +3588,7 @@ void DRW_draw_render_loop_offscreen( memset(&DST, 0x0, sizeof(DST)); DST.options.is_image_render = true; DST.options.draw_background = draw_background; - DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, NULL); + DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, object_mode, NULL); /* restore */ { @@ -3590,21 +3606,25 @@ void DRW_draw_render_loop_offscreen( GPU_offscreen_bind(ofs, false); } -void DRW_render_to_image(RenderEngine *re, struct Depsgraph *depsgraph) +void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) { Scene *scene = DEG_get_evaluated_scene(depsgraph); - ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); - RenderEngineType *engine_type = re->type; + RenderEngineType *engine_type = engine->type; DrawEngineType *draw_engine_type = engine_type->draw_engine; RenderData *r = &scene->r; + Render *render = engine->re; + const EvaluationContext *eval_ctx = RE_GetEvalCtx(render); /* Reset before using it. */ memset(&DST, 0x0, sizeof(DST)); DST.options.is_image_render = true; + DST.options.is_scene_render = true; + DST.options.draw_background = scene->r.alphamode == R_ADDSKY; DST.draw_ctx = (DRWContextState){ - NULL, NULL, NULL, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, NULL + NULL, NULL, NULL, scene, NULL, NULL, engine_type, depsgraph, eval_ctx->object_mode, NULL, }; + drw_context_state_init(); DST.viewport = GPU_viewport_create(); const int size[2] = {(r->size * r->xsch) / 100, (r->size * r->ysch) / 100}; @@ -3619,7 +3639,36 @@ void DRW_render_to_image(RenderEngine *re, struct Depsgraph *depsgraph) glDisable(GL_SCISSOR_TEST); glViewport(0, 0, size[0], size[1]); - engine_type->draw_engine->render_to_image(data, re, depsgraph); + /* Main rendering loop. */ + + /* Init render result. */ + const float *render_size = DRW_viewport_size_get(); + RenderResult *render_result = RE_engine_begin_result(engine, 0, 0, (int)render_size[0], (int)render_size[1], NULL, NULL); + + for (RenderView *render_view = render_result->views.first; + render_view != NULL; + render_view = render_view->next) + { + RE_SetActiveRenderView(render, render_view->name); + for (RenderLayer *render_layer = render_result->layers.first; + render_layer != NULL; + render_layer = render_layer->next) + { + ViewLayer *view_layer = BLI_findstring(&scene->view_layers, render_layer->name, offsetof(ViewLayer, name)); + DST.draw_ctx.view_layer = view_layer; + + /* TODO(dfelinto/sergey) we should not get depsgraph from scene. + * For rendering depsgraph is to be owned by Render. */ + DST.draw_ctx.depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true); + + engine_type->draw_engine->render_to_image(data, engine, render_result, render_layer); + DST.buffer_finish_called = false; + /* Force cache to reset. */ + drw_viewport_cache_resize(); + } + } + + RE_engine_end_result(engine, render_result, false, false, false); /* TODO grease pencil */ @@ -3654,17 +3703,26 @@ void DRW_render_object_iter( DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END } +/* Must run after all instance datas have been added. */ +void DRW_render_instance_buffer_finish(void) +{ + BLI_assert(!DST.buffer_finish_called && "DRW_render_instance_buffer_finish called twice!"); + DST.buffer_finish_called = true; + DRW_instance_buffer_finish(DST.idatalist); +} + /** * object mode select-loop, see: ED_view3d_draw_select_loop (legacy drawing). */ void DRW_draw_select_loop( struct Depsgraph *depsgraph, - ARegion *ar, View3D *v3d, + ARegion *ar, View3D *v3d, const eObjectMode object_mode, bool UNUSED(use_obedit_skip), bool UNUSED(use_nearest), const rcti *rect) { Scene *scene = DEG_get_evaluated_scene(depsgraph); RenderEngineType *engine_type = RE_engines_find(scene->view_render.engine_id); ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); + Object *obact = OBACT(view_layer); #ifndef USE_GPU_SELECT UNUSED_VARS(vc, scene, view_layer, v3d, ar, rect); #else @@ -3679,14 +3737,12 @@ void DRW_draw_select_loop( bool use_obedit = false; int obedit_mode = 0; - if (scene->obedit && scene->obedit->type == OB_MBALL) { - use_obedit = true; - obedit_mode = CTX_MODE_EDIT_METABALL; - } - else if ((scene->obedit && scene->obedit->type == OB_ARMATURE)) { - /* if not drawing sketch, draw bones */ - // if (!BDR_drawSketchNames(vc)) - { + if (object_mode & OB_MODE_EDIT) { + if (obact->type == OB_MBALL) { + use_obedit = true; + obedit_mode = CTX_MODE_EDIT_METABALL; + } + else if (obact->type == OB_ARMATURE) { use_obedit = true; obedit_mode = CTX_MODE_EDIT_ARMATURE; } @@ -3715,9 +3771,10 @@ void DRW_draw_select_loop( /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */ DST.draw_ctx = (DRWContextState){ - ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, (bContext *)NULL, + ar, rv3d, v3d, scene, view_layer, obact, engine_type, depsgraph, object_mode, + (bContext *)NULL, }; - + drw_context_state_init(); drw_viewport_var_init(); /* Update ubos */ @@ -3733,7 +3790,7 @@ void DRW_draw_select_loop( drw_engines_cache_init(); if (use_obedit) { - drw_engines_cache_populate(scene->obedit); + drw_engines_cache_populate(obact); } else { DEG_OBJECT_ITER(depsgraph, ob, DRW_iterator_mode_get(), @@ -3750,6 +3807,8 @@ void DRW_draw_select_loop( } drw_engines_cache_finish(); + + DRW_render_instance_buffer_finish(); } /* Start Drawing */ @@ -3780,7 +3839,7 @@ void DRW_draw_select_loop( */ void DRW_draw_depth_loop( Depsgraph *depsgraph, - ARegion *ar, View3D *v3d) + ARegion *ar, View3D *v3d, const eObjectMode object_mode) { Scene *scene = DEG_get_evaluated_scene(depsgraph); RenderEngineType *engine_type = RE_engines_find(scene->view_render.engine_id); @@ -3814,9 +3873,10 @@ void DRW_draw_depth_loop( /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */ DST.draw_ctx = (DRWContextState){ - ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, (bContext *)NULL, + ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, object_mode, + (bContext *)NULL, }; - + drw_context_state_init(); drw_viewport_var_init(); /* Update ubos */ @@ -3838,6 +3898,8 @@ void DRW_draw_depth_loop( DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END drw_engines_cache_finish(); + + DRW_render_instance_buffer_finish(); } /* Start Drawing */ @@ -3917,6 +3979,14 @@ bool DRW_state_is_scene_render(void) } /** +* Whether we are rendering simple opengl render +*/ +bool DRW_state_is_opengl_render(void) +{ + return DST.options.is_image_render && !DST.options.is_scene_render; +} + +/** * Gives you the iterator mode to use for depsgraph. */ eDepsObjectIteratorMode DRW_iterator_mode_get(void) @@ -4052,6 +4122,7 @@ void DRW_engines_free(void) { DRW_shape_cache_free(); DRW_stats_free(); + DRW_globals_free(); DrawEngineType *next; for (DrawEngineType *type = DRW_engines.first; type; type = next) { @@ -4069,6 +4140,8 @@ void DRW_engines_free(void) if (globals_ramp) GPU_texture_free(globals_ramp); + MEM_SAFE_FREE(g_pos_format); + MEM_SAFE_FREE(RST.bound_texs); MEM_SAFE_FREE(RST.bound_tex_slots); diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c index 391c29e511f..d9ffbde38e7 100644 --- a/source/blender/draw/intern/draw_view.c +++ b/source/blender/draw/intern/draw_view.c @@ -611,21 +611,21 @@ void DRW_draw_background(void) /* **************************** 3D Cursor ******************************** */ -static bool is_cursor_visible(Scene *scene, ViewLayer *view_layer) +static bool is_cursor_visible(const DRWContextState *draw_ctx, Scene *scene, ViewLayer *view_layer) { Object *ob = OBACT(view_layer); /* don't draw cursor in paint modes, but with a few exceptions */ - if (ob && ob->mode & OB_MODE_ALL_PAINT) { + if (ob && draw_ctx->object_mode & OB_MODE_ALL_PAINT) { /* exception: object is in weight paint and has deforming armature in pose mode */ - if (ob->mode & OB_MODE_WEIGHT_PAINT) { + if (draw_ctx->object_mode & OB_MODE_WEIGHT_PAINT) { if (BKE_object_pose_armature_get(ob) != NULL) { return true; } } /* exception: object in texture paint mode, clone brush, use_clone_layer disabled */ - else if (ob->mode & OB_MODE_TEXTURE_PAINT) { - const Paint *p = BKE_paint_get_active(scene, view_layer); + else if (draw_ctx->object_mode & OB_MODE_TEXTURE_PAINT) { + const Paint *p = BKE_paint_get_active(scene, view_layer, draw_ctx->object_mode); if (p && p->brush && p->brush->imagepaint_tool == PAINT_TOOL_CLONE) { if ((scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) == 0) { @@ -654,7 +654,7 @@ void DRW_draw_cursor(void) glDisable(GL_DEPTH_TEST); glLineWidth(1.0f); - if (is_cursor_visible(scene, view_layer)) { + if (is_cursor_visible(draw_ctx, scene, view_layer)) { float *co = ED_view3d_cursor3d_get(scene, v3d); unsigned char crosshair_color[3]; diff --git a/source/blender/draw/modes/edit_curve_mode.c b/source/blender/draw/modes/edit_curve_mode.c index 54a1bd79572..73a4fb1e9e6 100644 --- a/source/blender/draw/modes/edit_curve_mode.c +++ b/source/blender/draw/modes/edit_curve_mode.c @@ -229,12 +229,11 @@ static void EDIT_CURVE_cache_populate(void *vedata, Object *ob) EDIT_CURVE_StorageList *stl = ((EDIT_CURVE_Data *)vedata)->stl; const DRWContextState *draw_ctx = DRW_context_state_get(); const Scene *scene = draw_ctx->scene; - const Object *obedit = scene->obedit; UNUSED_VARS(psl, stl); if (ob->type == OB_CURVE) { - if (ob == obedit) { + if (ob == draw_ctx->object_edit) { Curve *cu = ob->data; /* Get geometry cache */ struct Gwn_Batch *geom; diff --git a/source/blender/draw/modes/edit_lattice_mode.c b/source/blender/draw/modes/edit_lattice_mode.c index e676677ff97..0268f4eb453 100644 --- a/source/blender/draw/modes/edit_lattice_mode.c +++ b/source/blender/draw/modes/edit_lattice_mode.c @@ -188,13 +188,11 @@ static void EDIT_LATTICE_cache_populate(void *vedata, Object *ob) EDIT_LATTICE_PassList *psl = ((EDIT_LATTICE_Data *)vedata)->psl; EDIT_LATTICE_StorageList *stl = ((EDIT_LATTICE_Data *)vedata)->stl; const DRWContextState *draw_ctx = DRW_context_state_get(); - Scene *scene = draw_ctx->scene; - Object *obedit = scene->obedit; UNUSED_VARS(psl); if (ob->type == OB_LATTICE) { - if (ob == obedit) { + if (ob == draw_ctx->object_edit) { /* Get geometry cache */ struct Gwn_Batch *geom; diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c index 29ba658f79d..cc1373dc29f 100644 --- a/source/blender/draw/modes/edit_mesh_mode.c +++ b/source/blender/draw/modes/edit_mesh_mode.c @@ -443,11 +443,10 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob) const DRWContextState *draw_ctx = DRW_context_state_get(); View3D *v3d = draw_ctx->v3d; Scene *scene = draw_ctx->scene; - Object *obedit = scene->obedit; struct Gwn_Batch *geom; if (ob->type == OB_MESH) { - if (ob == obedit) { + if (ob == draw_ctx->object_edit) { const Mesh *me = ob->data; IDProperty *ces_mode_ed = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_EDIT, ""); bool do_occlude_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "show_occlude_wire"); diff --git a/source/blender/draw/modes/edit_metaball_mode.c b/source/blender/draw/modes/edit_metaball_mode.c index 78ceaf8b6f1..bcabeef5bc3 100644 --- a/source/blender/draw/modes/edit_metaball_mode.c +++ b/source/blender/draw/modes/edit_metaball_mode.c @@ -119,11 +119,11 @@ static void EDIT_METABALL_cache_init(void *vedata) psl->pass = DRW_pass_create("My Pass", state); /* Create a shadingGroup using a function in draw_common.c or custom one */ - stl->g_data->group = shgroup_instance_mball_helpers(psl->pass, DRW_cache_screenspace_circle_get()); + stl->g_data->group = shgroup_instance_mball_handles(psl->pass, DRW_cache_screenspace_circle_get()); } } -static void EDIT_METABALL_cache_populate_radius_visualization( +static void EDIT_METABALL_cache_populate_radius( DRWShadingGroup *group, MetaElem *ml, const float scale_xform[3][4], const float *radius, const int selection_id) { @@ -142,7 +142,7 @@ static void EDIT_METABALL_cache_populate_radius_visualization( DRW_shgroup_call_dynamic_add(group, scale_xform, radius, color); } -static void EDIT_METABALL_cache_populate_stiffness_visualization( +static void EDIT_METABALL_cache_populate_stiffness( DRWShadingGroup *group, MetaElem *ml, const float scale_xform[3][4], const float *radius, const int selection_id) { @@ -169,11 +169,9 @@ static void EDIT_METABALL_cache_populate(void *vedata, Object *ob) if (ob->type == OB_MBALL) { const DRWContextState *draw_ctx = DRW_context_state_get(); - Scene *scene = draw_ctx->scene; - Object *obedit = scene->obedit; DRWShadingGroup *group = stl->g_data->group; - if (ob == obedit) { + if (ob == draw_ctx->object_edit) { MetaBall *mb = ob->data; const bool is_select = DRW_state_is_select(); @@ -181,13 +179,13 @@ static void EDIT_METABALL_cache_populate(void *vedata, Object *ob) int selection_id = 0; for (MetaElem *ml = mb->editelems->first; ml != NULL; ml = ml->next) { - BKE_mball_element_calc_display_m3x4(ml->draw_scale_xform, ob->obmat, &ml->x); + BKE_mball_element_calc_scale_xform(ml->draw_scale_xform, ob->obmat, &ml->x); ml->draw_stiffness_radius = ml->rad * atanf(ml->s) / (float)M_PI_2; - EDIT_METABALL_cache_populate_radius_visualization( + EDIT_METABALL_cache_populate_radius( group, ml, ml->draw_scale_xform, &ml->rad, is_select ? ++selection_id : -1); - EDIT_METABALL_cache_populate_stiffness_visualization( + EDIT_METABALL_cache_populate_stiffness( group, ml, ml->draw_scale_xform, &ml->draw_stiffness_radius, is_select ? ++selection_id : -1); } } diff --git a/source/blender/draw/modes/edit_text_mode.c b/source/blender/draw/modes/edit_text_mode.c index 60f28d89f4b..43c4a356279 100644 --- a/source/blender/draw/modes/edit_text_mode.c +++ b/source/blender/draw/modes/edit_text_mode.c @@ -190,13 +190,11 @@ static void EDIT_TEXT_cache_populate(void *vedata, Object *ob) EDIT_TEXT_PassList *psl = ((EDIT_TEXT_Data *)vedata)->psl; EDIT_TEXT_StorageList *stl = ((EDIT_TEXT_Data *)vedata)->stl; const DRWContextState *draw_ctx = DRW_context_state_get(); - Scene *scene = draw_ctx->scene; - Object *obedit = scene->obedit; UNUSED_VARS(psl, stl); if (ob->type == OB_FONT) { - if (ob == obedit) { + if (ob == draw_ctx->object_edit) { const Curve *cu = ob->data; /* Get geometry cache */ struct Gwn_Batch *geom; diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index f27f41c3d2a..4a7a5d25b11 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -32,7 +32,7 @@ #include "DNA_curve_types.h" #include "DNA_mesh_types.h" #include "DNA_meta_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_lightprobe_types.h" #include "DNA_particle_types.h" #include "DNA_view3d_types.h" @@ -55,6 +55,8 @@ #include "GPU_shader.h" #include "GPU_texture.h" +#include "MEM_guardedalloc.h" + #include "UI_resources.h" #include "draw_mode_engines.h" @@ -154,7 +156,7 @@ typedef struct OBJECT_PrivateData { DRWShadingGroup *probe_grid; /* MetaBalls */ - DRWShadingGroup *mball_circle; + DRWShadingGroup *mball_handle; /* Lamps */ DRWShadingGroup *lamp_center; @@ -215,6 +217,10 @@ typedef struct OBJECT_PrivateData { } OBJECT_PrivateData; /* Transient data */ static struct { + /* Instance Data format */ + struct Gwn_VertFormat *empty_image_format; + struct Gwn_VertFormat *empty_image_wire_format; + /* fullscreen shaders */ GPUShader *outline_resolve_sh; GPUShader *outline_resolve_aa_sh; @@ -531,6 +537,8 @@ static void OBJECT_engine_init(void *vedata) static void OBJECT_engine_free(void) { + MEM_SAFE_FREE(e_data.empty_image_format); + MEM_SAFE_FREE(e_data.empty_image_wire_format); DRW_SHADER_FREE_SAFE(e_data.outline_resolve_sh); DRW_SHADER_FREE_SAFE(e_data.outline_resolve_aa_sh); DRW_SHADER_FREE_SAFE(e_data.outline_detect_sh); @@ -663,14 +671,16 @@ static void DRW_shgroup_empty_image( image_calc_aspect(ob->data, ob->iuser, empty_image_data->image_aspect); if (tex) { + DRW_shgroup_instance_format(e_data.empty_image_format, { + {"objectColor" , DRW_ATTRIB_FLOAT, 4}, + {"size" , DRW_ATTRIB_FLOAT, 1}, + {"offset" , DRW_ATTRIB_FLOAT, 2}, + {"InstanceModelMatrix" , DRW_ATTRIB_FLOAT, 16}, + }); + struct Gwn_Batch *geom = DRW_cache_image_plane_get(); DRWShadingGroup *grp = DRW_shgroup_instance_create( - e_data.object_empty_image_sh, psl->non_meshes, geom); - DRW_shgroup_attrib_float(grp, "objectColor", 4); - DRW_shgroup_attrib_float(grp, "size", 1); - DRW_shgroup_attrib_float(grp, "offset", 2); - DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16); - + e_data.object_empty_image_sh, psl->non_meshes, geom, e_data.empty_image_format); DRW_shgroup_uniform_texture(grp, "image", tex); DRW_shgroup_uniform_vec2(grp, "aspect", empty_image_data->image_aspect, 1); @@ -681,14 +691,16 @@ static void DRW_shgroup_empty_image( } { + DRW_shgroup_instance_format(e_data.empty_image_wire_format, { + {"objectColor" , DRW_ATTRIB_FLOAT, 4}, + {"size" , DRW_ATTRIB_FLOAT, 1}, + {"offset" , DRW_ATTRIB_FLOAT, 2}, + {"InstanceModelMatrix" , DRW_ATTRIB_FLOAT, 16} + }); + struct Gwn_Batch *geom = DRW_cache_image_plane_wire_get(); DRWShadingGroup *grp = DRW_shgroup_instance_create( - e_data.object_empty_image_wire_sh, psl->non_meshes, geom); - DRW_shgroup_attrib_float(grp, "color", 3); - DRW_shgroup_attrib_float(grp, "size", 1); - DRW_shgroup_attrib_float(grp, "offset", 2); - DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16); - + e_data.object_empty_image_wire_sh, psl->non_meshes, geom, e_data.empty_image_wire_format); DRW_shgroup_uniform_vec2(grp, "aspect", empty_image_data->image_aspect, 1); empty_image_data->shgrp_wire = grp; @@ -968,10 +980,10 @@ static void OBJECT_cache_init(void *vedata) } { - /* Metaballs Helpers */ + /* Metaballs Handles */ struct Gwn_Batch *geom; geom = DRW_cache_screenspace_circle_get(); - stl->g_data->mball_circle = shgroup_instance_mball_helpers(psl->non_meshes, geom); + stl->g_data->mball_handle = shgroup_instance_mball_handles(psl->non_meshes, geom); } { @@ -1103,7 +1115,7 @@ static void OBJECT_cache_init(void *vedata) } } -static void DRW_shgroup_mball_helpers(OBJECT_StorageList *stl, Object *ob, ViewLayer *view_layer) +static void DRW_shgroup_mball_handles(OBJECT_StorageList *stl, Object *ob, ViewLayer *view_layer) { MetaBall *mb = ob->data; @@ -1112,8 +1124,8 @@ static void DRW_shgroup_mball_helpers(OBJECT_StorageList *stl, Object *ob, ViewL for (MetaElem *ml = mb->elems.first; ml != NULL; ml = ml->next) { /* draw radius */ - BKE_mball_element_calc_display_m3x4(ml->draw_scale_xform, ob->obmat, &ml->x); - DRW_shgroup_call_dynamic_add(stl->g_data->mball_circle, ml->draw_scale_xform, &ml->rad, color); + BKE_mball_element_calc_scale_xform(ml->draw_scale_xform, ob->obmat, &ml->x); + DRW_shgroup_call_dynamic_add(stl->g_data->mball_handle, ml->draw_scale_xform, &ml->rad, color); } } @@ -1471,6 +1483,8 @@ static void DRW_shgroup_speaker(OBJECT_StorageList *stl, Object *ob, ViewLayer * } typedef struct OBJECT_LightProbeEngineData { + ObjectEngineData engine_data; + float prb_mats[6][4][4]; float probe_cube_mat[4][4]; float draw_size; @@ -1531,7 +1545,8 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl mul_m4_v3(ob->obmat, prb_data->increment_z); sub_v3_v3(prb_data->increment_z, prb_data->corner); - DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.lightprobe_grid_sh, psl->lightprobes, DRW_cache_sphere_get()); + DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.lightprobe_grid_sh, psl->lightprobes, + DRW_cache_sphere_get(), NULL); DRW_shgroup_set_instance_count(grp, prb->grid_resolution_x * prb->grid_resolution_y * prb->grid_resolution_z); DRW_shgroup_uniform_vec4(grp, "color", color, 1); DRW_shgroup_uniform_vec3(grp, "corner", prb_data->corner, 1); @@ -1751,21 +1766,21 @@ static void OBJECT_cache_populate_particles(Object *ob, break; case PART_DRAW_CROSS: shgrp = DRW_shgroup_instance_create( - e_data.part_prim_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_CROSS)); + e_data.part_prim_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_CROSS), NULL); DRW_shgroup_uniform_texture(shgrp, "ramp", globals_ramp); DRW_shgroup_uniform_vec3(shgrp, "color", ma ? &ma->r : def_prim_col, 1); DRW_shgroup_uniform_int(shgrp, "screen_space", &screen_space[0], 1); break; case PART_DRAW_CIRC: shgrp = DRW_shgroup_instance_create( - e_data.part_prim_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_CIRC)); + e_data.part_prim_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_CIRC), NULL); DRW_shgroup_uniform_texture(shgrp, "ramp", globals_ramp); DRW_shgroup_uniform_vec3(shgrp, "color", ma ? &ma->r : def_prim_col, 1); DRW_shgroup_uniform_int(shgrp, "screen_space", &screen_space[1], 1); break; case PART_DRAW_AXIS: shgrp = DRW_shgroup_instance_create( - e_data.part_axis_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_AXIS)); + e_data.part_axis_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_AXIS), NULL); DRW_shgroup_uniform_int(shgrp, "screen_space", &screen_space[0], 1); break; default: @@ -1788,7 +1803,6 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) OBJECT_PassList *psl = ((OBJECT_Data *)vedata)->psl; OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl; const DRWContextState *draw_ctx = DRW_context_state_get(); - Scene *scene = draw_ctx->scene; ViewLayer *view_layer = draw_ctx->view_layer; View3D *v3d = draw_ctx->v3d; int theme_id = TH_UNDEFINED; @@ -1808,8 +1822,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) bool do_outlines = ((ob->base_flag & BASE_SELECTED) != 0); if (do_outlines) { - Object *obedit = scene->obedit; - if (ob != obedit && !((ob == draw_ctx->obact) && (ob->mode & OB_MODE_ALL_PAINT))) { + if ((ob != draw_ctx->object_edit) && !((ob == draw_ctx->obact) && (draw_ctx->object_mode & OB_MODE_ALL_PAINT))) { struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob); if (geom) { theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); @@ -1826,8 +1839,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) { Mesh *me = ob->data; if (me->totpoly == 0) { - Object *obedit = scene->obedit; - if (ob != obedit) { + if (ob != draw_ctx->object_edit) { struct Gwn_Batch *geom = DRW_cache_mesh_edges_get(ob); if (geom) { if (theme_id == TH_UNDEFINED) { @@ -1845,8 +1857,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) break; case OB_LATTICE: { - Object *obedit = scene->obedit; - if (ob != obedit) { + if (ob != draw_ctx->object_edit) { struct Gwn_Batch *geom = DRW_cache_lattice_wire_get(ob, false); if (theme_id == TH_UNDEFINED) { theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); @@ -1860,8 +1871,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) case OB_CURVE: { - Object *obedit = scene->obedit; - if (ob != obedit) { + if (ob != draw_ctx->object_edit) { struct Gwn_Batch *geom = DRW_cache_curve_edge_wire_get(ob); if (theme_id == TH_UNDEFINED) { theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); @@ -1873,9 +1883,8 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) } case OB_MBALL: { - Object *obedit = scene->obedit; - if (ob != obedit) { - DRW_shgroup_mball_helpers(stl, ob, view_layer); + if (ob != draw_ctx->object_edit) { + DRW_shgroup_mball_handles(stl, ob, view_layer); } break; } diff --git a/source/blender/draw/modes/particle_mode.c b/source/blender/draw/modes/particle_mode.c index 0d0758971d5..f92505a8778 100644 --- a/source/blender/draw/modes/particle_mode.c +++ b/source/blender/draw/modes/particle_mode.c @@ -200,7 +200,7 @@ static void PARTICLE_draw_scene(void *vedata) DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - UNUSED_VARS(fbl, dfbl, dtxl); + UNUSED_VARS(fbl, dfbl, dtxl, psl); /* Show / hide entire passes, swap framebuffers ... whatever you fancy */ /* @@ -212,7 +212,7 @@ static void PARTICLE_draw_scene(void *vedata) */ /* ... or just render passes on default framebuffer. */ - DRW_draw_pass(psl->pass); + //DRW_draw_pass(psl->pass); /* If you changed framebuffer, double check you rebind * the default one with its textures attached before finishing */ diff --git a/source/blender/draw/modes/pose_mode.c b/source/blender/draw/modes/pose_mode.c index 560773f2d05..749c3e71368 100644 --- a/source/blender/draw/modes/pose_mode.c +++ b/source/blender/draw/modes/pose_mode.c @@ -136,14 +136,16 @@ static void POSE_cache_populate(void *vedata, Object *ob) */ bool DRW_pose_mode_armature(Object *ob, Object *active_ob) { + const DRWContextState *draw_ctx = DRW_context_state_get(); + /* Pode armature is handled by pose mode engine. */ - if ((ob == active_ob) && ((ob->mode & OB_MODE_POSE) != 0)) { + if ((ob == active_ob) && ((draw_ctx->object_mode & OB_MODE_POSE) != 0)) { return true; } /* Armature parent is also handled by pose mode engine. */ - if ((active_ob != NULL) && ((active_ob->mode & OB_MODE_WEIGHT_PAINT) != 0)) { - if (active_ob->parent == ob) { + if ((active_ob != NULL) && ((draw_ctx->object_mode & OB_MODE_WEIGHT_PAINT) != 0)) { + if (ob == draw_ctx->object_pose) { return true; } } diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 9fb30dc8066..87fe002e536 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -3827,7 +3827,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float selected = 0; /* set blending again, as may not be set in previous step */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); /* step 1) draw backdrop ........................................... */ diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index 0db465e583b..d137e5f1c74 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -225,6 +225,33 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datat ANIM_animdata_freelist(&anim_data); } +static void select_pchan_for_action_group(bAnimContext *ac, bActionGroup *agrp, bAnimListElem *ale) +{ + /* Armatures-Specific Feature: + * See mouse_anim_channels() -> ANIMTYPE_GROUP case for more details (T38737) + */ + if ((ac->ads->filterflag & ADS_FILTER_ONLYSEL) == 0) { + if ((ale->id) && (GS(ale->id->name) == ID_OB)) { + Object *ob = (Object *)ale->id; + if (ob->type == OB_ARMATURE) { + /* Assume for now that any group with corresponding name is what we want + * (i.e. for an armature whose location is animated, things would break + * if the user were to add a bone named "Location"). + * + * TODO: check the first F-Curve or so to be sure... + */ + bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, agrp->name); + if (agrp->flag & AGRP_SELECTED) { + ED_pose_bone_select(ob, pchan, true); + } + else { + ED_pose_bone_select(ob, pchan, false); + } + } + } + } +} + /* Deselect all animation channels * - data: pointer to datatype, as contained in bAnimContext * - datatype: the type of data that 'data' represents (eAnimCont_Types) @@ -345,8 +372,8 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d case ANIMTYPE_GROUP: { bActionGroup *agrp = (bActionGroup *)ale->data; - ACHANNEL_SET_FLAG(agrp, sel, AGRP_SELECTED); + select_pchan_for_action_group(ac, agrp, ale); agrp->flag &= ~AGRP_ACTIVE; break; } @@ -2398,33 +2425,7 @@ static void borderselect_anim_channels(bAnimContext *ac, rcti *rect, short selec case ANIMTYPE_GROUP: { bActionGroup *agrp = (bActionGroup *)ale->data; - - /* Armatures-Specific Feature: - * See mouse_anim_channels() -> ANIMTYPE_GROUP case for more details (T38737) - */ - if ((ac->ads->filterflag & ADS_FILTER_ONLYSEL) == 0) { - if ((ale->id) && (GS(ale->id->name) == ID_OB)) { - Object *ob = (Object *)ale->id; - - if (ob->type == OB_ARMATURE) { - /* Assume for now that any group with corresponding name is what we want - * (i.e. for an armature whose location is animated, things would break - * if the user were to add a bone named "Location"). - * - * TODO: check the first F-Curve or so to be sure... - */ - bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, agrp->name); - - if (agrp->flag & AGRP_SELECTED) { - ED_pose_bone_select(ob, pchan, true); - } - else { - ED_pose_bone_select(ob, pchan, false); - } - } - } - } - + select_pchan_for_action_group(ac, agrp, ale); /* always clear active flag after doing this */ agrp->flag &= ~AGRP_ACTIVE; break; @@ -2682,8 +2683,10 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index, } case ANIMTYPE_OBJECT: { +#if 0 bDopeSheet *ads = (bDopeSheet *)ac->data; Scene *sce = (Scene *)ads->source; +#endif ViewLayer *view_layer = ac->view_layer; Base *base = (Base *)ale->data; Object *ob = base->object; @@ -2722,7 +2725,7 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index, adt->flag |= ADT_UI_ACTIVE; /* ensure we exit editmode on whatever object was active before to avoid getting stuck there - T48747 */ - if (ob != sce->obedit) + if (ob != CTX_data_edit_object(C)) ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index 08851cebf51..9a07eaf896c 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -160,7 +160,7 @@ void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width) /* only draw this if preview range is set */ if (PRVRANGEON) { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); Gwn_VertFormat *format = immVertexFormat(); diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index 107a46999f0..e43735c51fb 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -345,7 +345,7 @@ static void draw_marker( int icon_id; glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* vertical line - dotted */ #ifdef DURIAN_CAMERA_SWITCH @@ -462,7 +462,7 @@ void ED_markers_draw(const bContext *C, int flag) immUniformColor4ubv(shade); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); immRectf(pos, v2d->cur.xmin, 0, v2d->cur.xmax, UI_MARKER_MARGIN_Y); @@ -1113,14 +1113,15 @@ static void select_timeline_marker_frame(ListBase *markers, int frame, bool exte } } - BLI_LISTBASE_CIRCULAR_FORWARD_BEGIN (markers, marker, marker_first) { + LISTBASE_CIRCULAR_FORWARD_BEGIN(markers, marker, marker_first) + { /* this way a not-extend select will always give 1 selected marker */ if (marker->frame == frame) { marker->flag ^= SELECT; break; } } - BLI_LISTBASE_CIRCULAR_FORWARD_END (markers, marker, marker_first); + LISTBASE_CIRCULAR_FORWARD_END(markers, marker, marker_first); } static int ed_marker_select(bContext *C, const wmEvent *event, bool extend, bool camera) diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c index 9d25fc9e1a3..0ef6aa4bd4a 100644 --- a/source/blender/editors/animation/keyframes_edit.c +++ b/source/blender/editors/animation/keyframes_edit.c @@ -36,7 +36,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" -#include "BLI_lasso.h" +#include "BLI_lasso_2d.h" #include "BLI_math.h" #include "DNA_anim_types.h" diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 24f6a2dab2c..6df0a1cd302 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -1579,6 +1579,9 @@ void ANIM_OT_keyframe_delete(wmOperatorType *ot) static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op)) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + bool changed = false; CTX_DATA_BEGIN (C, Object *, ob, selected_objects) @@ -1595,7 +1598,7 @@ static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op)) fcn = fcu->next; /* in pose mode, only delete the F-Curve if it belongs to a selected bone */ - if (ob->mode & OB_MODE_POSE) { + if (eval_ctx.object_mode & OB_MODE_POSE) { if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones[")) { bPoseChannel *pchan; char *bone_name; @@ -1658,8 +1661,10 @@ void ANIM_OT_keyframe_clear_v3d(wmOperatorType *ot) static int delete_key_v3d_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); - float cfra = (float)CFRA; + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + + const float cfra = eval_ctx.ctime; CTX_DATA_BEGIN (C, Object *, ob, selected_objects) { @@ -1687,7 +1692,7 @@ static int delete_key_v3d_exec(bContext *C, wmOperator *op) /* special exception for bones, as this makes this operator more convenient to use * NOTE: This is only done in pose mode. In object mode, we're dealign with the entire object. */ - if ((ob->mode & OB_MODE_POSE) && strstr(fcu->rna_path, "pose.bones[\"")) { + if ((eval_ctx.object_mode & OB_MODE_POSE) && strstr(fcu->rna_path, "pose.bones[\"")) { bPoseChannel *pchan; char *bone_name; diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c index a2fbfe645f7..6c8779202e9 100644 --- a/source/blender/editors/armature/armature_edit.c +++ b/source/blender/editors/armature/armature_edit.c @@ -50,6 +50,7 @@ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_report.h" +#include "BKE_object.h" #include "RNA_access.h" #include "RNA_define.h" @@ -138,17 +139,16 @@ void ED_armature_transform(struct bArmature *arm, float mat[4][4], const bool do /* exported for use in editors/object/ */ /* 0 == do center, 1 == center new, 2 == center cursor */ -void ED_armature_origin_set(Scene *scene, Object *ob, float cursor[3], int centermode, int around) +void ED_armature_origin_set(Object *ob, float cursor[3], int centermode, int around) { - Object *obedit = scene->obedit; // XXX get from context + const bool is_editmode = BKE_object_is_in_editmode(ob); EditBone *ebone; bArmature *arm = ob->data; float cent[3]; /* Put the armature into editmode */ - if (ob != obedit) { + if (is_editmode == false) { ED_armature_to_edit(arm); - obedit = NULL; /* we cant use this so behave as if there is no obedit */ } /* Find the centerpoint */ @@ -188,13 +188,13 @@ void ED_armature_origin_set(Scene *scene, Object *ob, float cursor[3], int cente } /* Turn the list into an armature */ - if (obedit == NULL) { + if (is_editmode == false) { ED_armature_from_edit(arm); ED_armature_edit_free(arm); } /* Adjust object location for new centerpoint */ - if (centermode && obedit == NULL) { + if (centermode && (is_editmode == false)) { mul_mat3_m4_v3(ob->obmat, cent); /* omit translation part */ add_v3_v3(ob->loc, cent); } diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h index 192bb8eea61..0ba720a17d0 100644 --- a/source/blender/editors/armature/armature_intern.h +++ b/source/blender/editors/armature/armature_intern.h @@ -250,7 +250,7 @@ void armature_tag_unselect(struct bArmature *arm); void *get_nearest_bone(struct bContext *C, const int xy[2], bool findunsel); void *get_bone_from_selectbuffer( - struct Scene *scene, struct Base *base, const unsigned int *buffer, short hits, + struct Base *base, struct Object *obedit, const unsigned int *buffer, short hits, bool findunsel, bool do_nearest); int bone_looper(struct Object *ob, struct Bone *bone, void *data, diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c index de2611f7092..8fc7aeaf029 100644 --- a/source/blender/editors/armature/armature_relations.c +++ b/source/blender/editors/armature/armature_relations.c @@ -281,7 +281,6 @@ int join_armature_exec(bContext *C, wmOperator *op) /* get pose of active object and move it out of posemode */ pose = ob->pose; - ob->mode &= ~OB_MODE_POSE; CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases) { @@ -302,8 +301,6 @@ int join_armature_exec(bContext *C, wmOperator *op) /* Get Pose of current armature */ opose = base->object->pose; - base->object->mode &= ~OB_MODE_POSE; - //BASACT->flag &= ~OB_MODE_POSE; /* Find the difference matrix */ invert_m4_m4(oimat, ob->obmat); @@ -608,8 +605,6 @@ static int separate_armature_exec(bContext *C, wmOperator *op) /* 1) store starting settings and exit editmode */ oldob = obedit; oldbase = view_layer->basact; - oldob->mode &= ~OB_MODE_POSE; - //oldbase->flag &= ~OB_POSEMODE; ED_armature_from_edit(obedit->data); ED_armature_edit_free(obedit->data); diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index b87942fed84..f178ad640b6 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -77,10 +77,9 @@ Bone *get_indexed_bone(Object *ob, int index) /* See if there are any selected bones in this buffer */ /* only bones from base are checked on */ void *get_bone_from_selectbuffer( - Scene *scene, Base *base, const unsigned int *buffer, short hits, + Base *base, Object *obedit, const unsigned int *buffer, short hits, bool findunsel, bool do_nearest) { - Object *obedit = scene->obedit; // XXX get from context Bone *bone; EditBone *ebone; void *firstunSel = NULL, *firstSel = NULL, *data; @@ -183,9 +182,9 @@ void *get_nearest_bone(bContext *C, const int xy[2], bool findunsel) hits = view3d_opengl_select(&eval_ctx, &vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST); - if (hits > 0) - return get_bone_from_selectbuffer(vc.scene, vc.view_layer->basact, buffer, hits, findunsel, true); - + if (hits > 0) { + return get_bone_from_selectbuffer(vc.view_layer->basact, vc.obedit, buffer, hits, findunsel, true); + } return NULL; } diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c index 72b4837c1b8..8900da900c0 100644 --- a/source/blender/editors/armature/armature_skinning.c +++ b/source/blender/editors/armature/armature_skinning.c @@ -66,7 +66,7 @@ /* ********************************** Bone Skinning *********************************************** */ -static int bone_skinnable_cb(Object *ob, Bone *bone, void *datap) +static int bone_skinnable_cb(Object *UNUSED(ob), Bone *bone, void *datap) { /* Bones that are deforming * are regarded to be "skinnable" and are eligible for @@ -92,9 +92,9 @@ static int bone_skinnable_cb(Object *ob, Bone *bone, void *datap) */ Bone ***hbone; int a, segments; - struct { Object *armob; void *list; int heat; } *data = datap; + struct { Object *armob; void *list; int heat; bool is_weight_paint; } *data = datap; - if (!(ob->mode & OB_MODE_WEIGHT_PAINT) || !(bone->flag & BONE_HIDDEN_P)) { + if (!(data->is_weight_paint) || !(bone->flag & BONE_HIDDEN_P)) { if (!(bone->flag & BONE_NO_DEFORM)) { if (data->heat && data->armob->pose && BKE_pose_channel_find_name(data->armob->pose, bone->name)) segments = bone->segments; @@ -157,18 +157,17 @@ static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap) */ bDeformGroup ***hgroup, *defgroup = NULL; int a, segments; - struct { Object *armob; void *list; int heat; } *data = datap; - int wpmode = (ob->mode & OB_MODE_WEIGHT_PAINT); + struct { Object *armob; void *list; int heat; bool is_weight_paint; } *data = datap; bArmature *arm = data->armob->data; - if (!wpmode || !(bone->flag & BONE_HIDDEN_P)) { + if (!data->is_weight_paint || !(bone->flag & BONE_HIDDEN_P)) { if (!(bone->flag & BONE_NO_DEFORM)) { if (data->heat && data->armob->pose && BKE_pose_channel_find_name(data->armob->pose, bone->name)) segments = bone->segments; else segments = 1; - if (!wpmode || ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED))) { + if (!data->is_weight_paint || ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED))) { if (!(defgroup = defgroup_find_name(ob, bone->name))) { defgroup = BKE_object_defgroup_add_name(ob, bone->name); } @@ -192,9 +191,11 @@ static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap) return 0; } -static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], int numbones, Bone **bonelist, - bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, - float (*root)[3], float (*tip)[3], const int *selected, float scale) +static void envelope_bone_weighting( + const EvaluationContext *eval_ctx, + Object *ob, Mesh *mesh, float (*verts)[3], int numbones, Bone **bonelist, + bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, + float (*root)[3], float (*tip)[3], const int *selected, float scale) { /* Create vertex group weights from envelopes */ @@ -205,7 +206,7 @@ static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], i bool use_topology = (mesh->editflag & ME_EDIT_MIRROR_TOPO) != 0; bool use_mask = false; - if ((ob->mode & OB_MODE_WEIGHT_PAINT) && + if ((eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) && (mesh->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL))) { use_mask = true; @@ -276,12 +277,12 @@ static void add_verts_to_dgroups( float (*root)[3], (*tip)[3], (*verts)[3]; int *selected; int numbones, vertsfilled = 0, i, j, segments = 0; - int wpmode = (ob->mode & OB_MODE_WEIGHT_PAINT); - struct { Object *armob; void *list; int heat; } looper_data; + struct { Object *armob; void *list; int heat; bool is_weight_paint; } looper_data; looper_data.armob = par; looper_data.heat = heat; looper_data.list = NULL; + looper_data.is_weight_paint = (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT); /* count the number of skinnable bones */ numbones = bone_looper(ob, arm->bonebase.first, &looper_data, bone_skinnable_cb); @@ -354,7 +355,7 @@ static void add_verts_to_dgroups( mul_m4_v3(par->obmat, tip[j]); /* set selected */ - if (wpmode) { + if (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) { if ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED)) selected[j] = 1; } @@ -374,7 +375,7 @@ static void add_verts_to_dgroups( mesh = (Mesh *)ob->data; verts = MEM_callocN(mesh->totvert * sizeof(*verts), "closestboneverts"); - if (wpmode) { + if (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) { /* if in weight paint mode, use final verts from derivedmesh */ DerivedMesh *dm = mesh_get_derived_final(eval_ctx, scene, ob, CD_MASK_BAREMESH); @@ -404,15 +405,17 @@ static void add_verts_to_dgroups( if (heat) { const char *error = NULL; - heat_bone_weighting(ob, mesh, verts, numbones, dgrouplist, dgroupflip, - root, tip, selected, &error); + heat_bone_weighting( + eval_ctx, ob, mesh, verts, numbones, dgrouplist, dgroupflip, + root, tip, selected, &error); if (error) { BKE_report(reports, RPT_WARNING, error); } } else { - envelope_bone_weighting(ob, mesh, verts, numbones, bonelist, dgrouplist, - dgroupflip, root, tip, selected, mat4_to_scale(par->obmat)); + envelope_bone_weighting( + eval_ctx, ob, mesh, verts, numbones, bonelist, dgrouplist, + dgroupflip, root, tip, selected, mat4_to_scale(par->obmat)); } /* only generated in some cases but can call anyway */ diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index f4bebfd85e0..c91f92bc70b 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -178,7 +178,7 @@ const char *BIF_listTemplates(const bContext *UNUSED(C)) GHashIterator ghi; const char *menu_header = IFACE_("Template %t|None %x0|"); char *p; - const size_t template_size = (BLI_ghash_size(TEMPLATES_HASH) * 32 + 30); + const size_t template_size = (BLI_ghash_len(TEMPLATES_HASH) * 32 + 30); if (TEMPLATES_MENU != NULL) { MEM_freeN(TEMPLATES_MENU); @@ -2031,7 +2031,7 @@ static void sk_drawSketch(Scene *scene, View3D *UNUSED(v3d), SK_Sketch *sketch, gpuPushMatrix(); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); switch (sketch->next_point.mode) { case PT_SNAP: diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 9500fd59b8b..d53350ab3cb 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -46,6 +46,8 @@ #include "ED_mesh.h" #include "ED_armature.h" +#include "DEG_depsgraph.h" + #include "eigen_capi.h" #include "meshlaplacian.h" @@ -600,9 +602,11 @@ static float heat_limit_weight(float weight) return weight; } -void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource, - bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, - float (*root)[3], float (*tip)[3], int *selected, const char **err_str) +void heat_bone_weighting( + const EvaluationContext *eval_ctx, + Object *ob, Mesh *me, float (*verts)[3], int numsource, + bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, + float (*root)[3], float (*tip)[3], int *selected, const char **err_str) { LaplacianSystem *sys; MLoopTri *mlooptri; @@ -623,7 +627,7 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource, tottri = poly_to_tri_count(me->totpoly, me->totloop); /* count triangles and create mask */ - if (ob->mode & OB_MODE_WEIGHT_PAINT && + if (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT && (use_face_sel || use_vert_sel)) { mask = MEM_callocN(sizeof(int) * me->totvert, "heat_bone_weighting mask"); diff --git a/source/blender/editors/armature/meshlaplacian.h b/source/blender/editors/armature/meshlaplacian.h index bba8c739abf..c790c2fbee7 100644 --- a/source/blender/editors/armature/meshlaplacian.h +++ b/source/blender/editors/armature/meshlaplacian.h @@ -52,10 +52,12 @@ float laplacian_system_get_solution(LaplacianSystem *sys, int v); /* Heat Weighting */ -void heat_bone_weighting(struct Object *ob, struct Mesh *me, float (*verts)[3], - int numbones, struct bDeformGroup **dgrouplist, - struct bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3], - int *selected, const char **error); +void heat_bone_weighting( + const struct EvaluationContext *eval_ctx, + struct Object *ob, struct Mesh *me, float (*verts)[3], + int numbones, struct bDeformGroup **dgrouplist, + struct bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3], + int *selected, const char **error); #ifdef RIGID_DEFORM /* As-Rigid-As-Possible Deformation */ diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c index 74e29b2e8da..119a27cd4a7 100644 --- a/source/blender/editors/armature/pose_edit.c +++ b/source/blender/editors/armature/pose_edit.c @@ -94,13 +94,16 @@ void ED_armature_enter_posemode(bContext *C, Base *base) switch (ob->type) { case OB_ARMATURE: - ob->restore_mode = ob->mode; - ob->mode |= OB_MODE_POSE; + { + WorkSpace *workspace = CTX_wm_workspace(C); + workspace->object_mode_restore = workspace->object_mode; + workspace->object_mode |= OB_MODE_POSE; /* Inform all CoW versions that we changed the mode. */ DEG_id_tag_update_ex(CTX_data_main(C), &ob->id, DEG_TAG_COPY_ON_WRITE); WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_POSE, NULL); break; + } default: return; } @@ -112,10 +115,11 @@ void ED_armature_enter_posemode(bContext *C, Base *base) void ED_armature_exit_posemode(bContext *C, Base *base) { if (base) { + WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = base->object; - ob->restore_mode = ob->mode; - ob->mode &= ~OB_MODE_POSE; + workspace->object_mode_restore = workspace->object_mode; + workspace->object_mode &= ~OB_MODE_POSE; /* Inform all CoW versions that we changed the mode. */ DEG_id_tag_update_ex(CTX_data_main(C), &ob->id, DEG_TAG_COPY_ON_WRITE); diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c index 9bc678cd9e6..16f5bb59641 100644 --- a/source/blender/editors/armature/pose_select.c +++ b/source/blender/editors/armature/pose_select.c @@ -134,7 +134,8 @@ void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select) /* called from editview.c, for mode-less pose selection */ /* assumes scene obact and basact is still on old situation */ bool ED_do_pose_selectbuffer( - Scene *scene, ViewLayer *view_layer, Base *base, const unsigned int *buffer, short hits, + const EvaluationContext *eval_ctx, + ViewLayer *view_layer, Base *base, const unsigned int *buffer, short hits, bool extend, bool deselect, bool toggle, bool do_nearest) { Object *ob = base->object; @@ -142,11 +143,13 @@ bool ED_do_pose_selectbuffer( if (!ob || !ob->pose) return 0; - nearBone = get_bone_from_selectbuffer(scene, base, buffer, hits, 1, do_nearest); + Object *ob_act = OBACT(view_layer); + Object *obedit = OBEDIT_FROM_EVAL_CTX(eval_ctx); + + nearBone = get_bone_from_selectbuffer(base, obedit, buffer, hits, 1, do_nearest); /* if the bone cannot be affected, don't do anything */ if ((nearBone) && !(nearBone->flag & BONE_UNSELECTABLE)) { - Object *ob_act = OBACT(view_layer); bArmature *arm = ob->data; /* since we do unified select, we don't shift+select a bone if the @@ -154,7 +157,7 @@ bool ED_do_pose_selectbuffer( * note, special exception for armature mode so we can do multi-select * we could check for multi-select explicitly but think its fine to * always give predictable behavior in weight paint mode - campbell */ - if ((ob_act == NULL) || ((ob_act != ob) && (ob_act->mode & OB_MODE_WEIGHT_PAINT) == 0)) { + if ((ob_act == NULL) || ((ob_act != ob) && (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) == 0)) { /* when we are entering into posemode via toggle-select, * from another active object - always select the bone. */ if (!extend && !deselect && toggle) { @@ -195,7 +198,7 @@ bool ED_do_pose_selectbuffer( if (ob_act) { /* in weightpaint we select the associated vertex group too */ - if (ob_act->mode & OB_MODE_WEIGHT_PAINT) { + if (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) { if (nearBone == arm->act_bone) { ED_vgroup_select_by_name(ob_act, nearBone->name); DEG_id_tag_update(&ob_act->id, OB_RECALC_DATA); @@ -873,6 +876,7 @@ void POSE_OT_select_grouped(wmOperatorType *ot) */ static int pose_select_mirror_exec(bContext *C, wmOperator *op) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob_act = CTX_data_active_object(C); Object *ob = BKE_object_pose_armature_get(ob_act); bArmature *arm; @@ -880,10 +884,6 @@ static int pose_select_mirror_exec(bContext *C, wmOperator *op) const bool active_only = RNA_boolean_get(op->ptr, "only_active"); const bool extend = RNA_boolean_get(op->ptr, "extend"); - if ((ob && (ob->mode & OB_MODE_POSE)) == 0) { - return OPERATOR_CANCELLED; - } - arm = ob->data; for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { @@ -920,7 +920,7 @@ static int pose_select_mirror_exec(bContext *C, wmOperator *op) arm->act_bone = pchan_mirror_act->bone; /* in weightpaint we select the associated vertex group too */ - if (ob_act->mode & OB_MODE_WEIGHT_PAINT) { + if (workspace->object_mode & OB_MODE_WEIGHT_PAINT) { ED_vgroup_select_by_name(ob_act, pchan_mirror_act->name); DEG_id_tag_update(&ob_act->id, OB_RECALC_DATA); } diff --git a/source/blender/editors/armature/reeb.c b/source/blender/editors/armature/reeb.c index 0eb44085bae..fda7012e955 100644 --- a/source/blender/editors/armature/reeb.c +++ b/source/blender/editors/armature/reeb.c @@ -546,7 +546,7 @@ void verifyFaces(ReebGraph *rg) int total = 0; ReebArc *arc = NULL; for (arc = rg->arcs.first; arc; arc = arc->next) { - total += BLI_ghash_size(arc->faces); + total += BLI_ghash_len(arc->faces); } #endif @@ -1656,7 +1656,7 @@ int filterSmartReebGraph(ReebGraph *UNUSED(rg), float UNUSED(threshold)) { GHashIterator ghi; int merging = 0; - int total = BLI_ghash_size(arc->faces); + int total = BLI_ghash_len(arc->faces); float avg_angle = 0; float avg_vec[3] = {0, 0, 0}; @@ -1932,7 +1932,7 @@ void REEB_exportGraph(ReebGraph *rg, int count) add_v3_v3v3(p, arc->tail->p, arc->head->p); mul_v3_fl(p, 0.5f); - fprintf(f, "angle %0.3f %0.3f %0.3f %0.3f %i\n", p[0], p[1], p[2], arc->angle, BLI_ghash_size(arc->faces)); + fprintf(f, "angle %0.3f %0.3f %0.3f %0.3f %i\n", p[0], p[1], p[2], arc->angle, BLI_ghash_len(arc->faces)); exportNode(f, "v2", arc->tail); } @@ -2678,7 +2678,7 @@ static void shortestPathsFromVert(EditMesh *em, EditVert *starting_vert, EdgeInd eed->f1 = 0; } - while (BLI_heap_size(edge_heap) > 0) { + while (BLI_heap_len(edge_heap) > 0) { float current_weight; current_eve->f1 = 1; /* mark vertex as selected */ @@ -2695,7 +2695,7 @@ static void shortestPathsFromVert(EditMesh *em, EditVert *starting_vert, EdgeInd /* Find next shortest edge with unselected verts */ do { current_weight = BLI_heap_node_value(BLI_heap_top(edge_heap)); - select_eed = BLI_heap_popmin(edge_heap); + select_eed = BLI_heap_pop_min(edge_heap); } while (select_eed != NULL && select_eed->v1->f1 != 0 && select_eed->v2->f1); if (select_eed != NULL) { diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 4b578ba389e..94b090bff05 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -530,7 +530,7 @@ static GHash *dupli_keyIndexHash(GHash *keyindex) GHash *gh; GHashIterator gh_iter; - gh = BLI_ghash_ptr_new_ex("dupli_keyIndex gh", BLI_ghash_size(keyindex)); + gh = BLI_ghash_ptr_new_ex("dupli_keyIndex gh", BLI_ghash_len(keyindex)); GHASH_ITER (gh_iter, keyindex) { void *cv = BLI_ghashIterator_getKey(&gh_iter); @@ -5027,7 +5027,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event) snap_context, SCE_SELECT_FACE, &(const struct SnapObjectParams){ - .snap_select = (vc.scene->obedit != NULL) ? SNAP_NOT_ACTIVE : SNAP_ALL, + .snap_select = (vc.obedit != NULL) ? SNAP_NOT_ACTIVE : SNAP_ALL, .use_object_edit_cage = false, }, mval, NULL, true, diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c index 062b9c94a1b..169afb140fb 100644 --- a/source/blender/editors/curve/editcurve_paint.c +++ b/source/blender/editors/curve/editcurve_paint.c @@ -365,7 +365,7 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS wmOperator *op = arg; struct CurveDrawData *cdd = op->customdata; - const int stroke_len = BLI_mempool_count(cdd->stroke_elem_pool); + const int stroke_len = BLI_mempool_len(cdd->stroke_elem_pool); if (stroke_len == 0) { return; @@ -706,7 +706,7 @@ static void curve_draw_exec_precalc(wmOperator *op) if (!RNA_property_is_set(op->ptr, prop)) { bool use_cyclic = false; - if (BLI_mempool_count(cdd->stroke_elem_pool) > 2) { + if (BLI_mempool_len(cdd->stroke_elem_pool) > 2) { BLI_mempool_iter iter; const struct StrokeElem *selem, *selem_first, *selem_last; @@ -732,7 +732,7 @@ static void curve_draw_exec_precalc(wmOperator *op) (cps->radius_taper_end != 0.0f)) { /* note, we could try to de-duplicate the length calculations above */ - const int stroke_len = BLI_mempool_count(cdd->stroke_elem_pool); + const int stroke_len = BLI_mempool_len(cdd->stroke_elem_pool); BLI_mempool_iter iter; struct StrokeElem *selem, *selem_prev; @@ -788,18 +788,18 @@ static int curve_draw_exec(bContext *C, wmOperator *op) struct CurveDrawData *cdd = op->customdata; const CurvePaintSettings *cps = &cdd->vc.scene->toolsettings->curve_paint_settings; - Object *obedit = cdd->vc.scene->obedit; + Object *obedit = cdd->vc.obedit; Curve *cu = obedit->data; ListBase *nurblist = object_editcurve_get(obedit); - int stroke_len = BLI_mempool_count(cdd->stroke_elem_pool); + int stroke_len = BLI_mempool_len(cdd->stroke_elem_pool); const bool is_3d = (cu->flag & CU_3D) != 0; invert_m4_m4(obedit->imat, obedit->obmat); - if (BLI_mempool_count(cdd->stroke_elem_pool) == 0) { + if (BLI_mempool_len(cdd->stroke_elem_pool) == 0) { curve_draw_stroke_from_operator(op); - stroke_len = BLI_mempool_count(cdd->stroke_elem_pool); + stroke_len = BLI_mempool_len(cdd->stroke_elem_pool); } ED_curve_deselect_all(cu->editnurb); diff --git a/source/blender/editors/curve/editcurve_select.c b/source/blender/editors/curve/editcurve_select.c index 02b8970731c..4a4b13d0d1b 100644 --- a/source/blender/editors/curve/editcurve_select.c +++ b/source/blender/editors/curve/editcurve_select.c @@ -1607,7 +1607,7 @@ static void curve_select_shortest_path_surf(Nurb *nu, int vert_src, int vert_dst int axis, sign; int u, v; - vert_curr = *((int *)BLI_heap_popmin(heap)); + vert_curr = *((int *)BLI_heap_pop_min(heap)); if (vert_curr == vert_dst) { break; } diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 4a95027528b..942aa861cec 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -41,7 +41,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_polyfill2d.h" +#include "BLI_polyfill_2d.h" #include "BLF_api.h" #include "BLT_translation.h" @@ -1479,7 +1479,7 @@ static void gp_draw_status_text(const bGPdata *gpd, ARegion *ar) /* grease pencil icon... */ // XXX: is this too intrusive? - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); xco -= U.widget_unit; diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c index 76fa3b3f9ea..e2b22d063bd 100644 --- a/source/blender/editors/gpencil/gpencil_convert.c +++ b/source/blender/editors/gpencil/gpencil_convert.c @@ -55,6 +55,7 @@ #include "DNA_space_types.h" #include "DNA_view3d_types.h" #include "DNA_gpencil_types.h" +#include "DNA_workspace_types.h" #include "BKE_collection.h" #include "BKE_context.h" @@ -1293,6 +1294,7 @@ static int gp_convert_poll(bContext *C) bGPDframe *gpf = NULL; ScrArea *sa = CTX_wm_area(C); Scene *scene = CTX_data_scene(C); + const WorkSpace *workspace = CTX_wm_workspace(C); /* only if the current view is 3D View, if there's valid data (i.e. at least one stroke!), * and if we are not in edit mode! @@ -1301,7 +1303,7 @@ static int gp_convert_poll(bContext *C) (gpl = BKE_gpencil_layer_getactive(gpd)) && (gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0)) && (gpf->strokes.first) && - (scene->obedit == NULL)); + ((workspace->object_mode & OB_MODE_EDIT) == 0)); } static int gp_convert_layer_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 472b88cb18b..c25e4d3ea73 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1862,7 +1862,7 @@ static void gpencil_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr) glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); immUniformColor4ub(255, 100, 100, 20); imm_draw_circle_fill_2d(shdr_pos, x, y, p->radius, 40); diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c index 07abab8af2e..dc3483163bf 100644 --- a/source/blender/editors/gpencil/gpencil_select.c +++ b/source/blender/editors/gpencil/gpencil_select.c @@ -37,7 +37,7 @@ #include "BLI_blenlib.h" #include "BLI_ghash.h" -#include "BLI_lasso.h" +#include "BLI_lasso_2d.h" #include "BLI_utildefines.h" #include "BLI_math_vector.h" diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h index 3184ebee4d9..863d817d19a 100644 --- a/source/blender/editors/include/BIF_glutil.h +++ b/source/blender/editors/include/BIF_glutil.h @@ -107,38 +107,6 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect, float scaleX, float scaleY, float clip_min_x, float clip_min_y, float clip_max_x, float clip_max_y, float xzoom, float yzoom, float color[4]); -/* 2D Drawing Assistance */ - -/** Define a 2D area (viewport, scissor, matrices) for OpenGL rendering. - * - * glaDefine2DArea and glaBegin2DDraw set up an OpenGL state appropriate - * for drawing using both vertex (Vertex, etc) and raster (RasterPos, Rect) - * commands. All coordinates should be at integer positions. There is little - * to no reason to use glVertex2f etc. functions during 2D rendering, and - * thus no reason to +-0.5 the coordinates or perform other silly - * tricks. - * - * \param screen_rect The screen rectangle to be defined for 2D drawing. - */ -void glaDefine2DArea(struct rcti *screen_rect); - -/* TODO(merwin): put the following 2D code to use, or build new 2D code inspired & informd by it */ - -#if 0 /* UNUSED */ - -typedef struct gla2DDrawInfo gla2DDrawInfo; - -gla2DDrawInfo *glaBegin2DDraw(struct rcti *screen_rect, struct rctf *world_rect); -void gla2DDrawTranslatePt(gla2DDrawInfo *di, float wo_x, float wo_y, int *r_sc_x, int *r_sc_y); -void gla2DDrawTranslatePtv(gla2DDrawInfo *di, float world[2], int r_screen[2]); - -void glaEnd2DDraw(gla2DDrawInfo *di); - -/** Adjust the transformation mapping of a 2d area */ -void gla2DGetMap(gla2DDrawInfo *di, struct rctf *rect); -void gla2DSetMap(gla2DDrawInfo *di, struct rctf *rect); - -#endif /* UNUSED */ void set_inverted_drawing(int enable); void setlinestyle(int nr); diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 4595bcfa86d..18eb442766b 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -143,7 +143,8 @@ void ED_armature_deselect_all(struct Object *obedit); void ED_armature_deselect_all_visible(struct Object *obedit); bool ED_do_pose_selectbuffer( - struct Scene *scene, struct ViewLayer *view_layer, struct Base *base, const unsigned int *buffer, short hits, + const struct EvaluationContext *eval_ctx, + struct ViewLayer *view_layer, struct Base *base, const unsigned int *buffer, short hits, bool extend, bool deselect, bool toggle, bool do_nearest); bool ED_armature_select_pick(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle); int join_armature_exec(struct bContext *C, struct wmOperator *op); @@ -168,7 +169,7 @@ void ED_armature_ebone_from_mat3(EditBone *ebone, float mat[3][3]); void ED_armature_ebone_from_mat4(EditBone *ebone, float mat[4][4]); void transform_armature_mirror_update(struct Object *obedit); -void ED_armature_origin_set(struct Scene *scene, struct Object *ob, float cursor[3], int centermode, int around); +void ED_armature_origin_set(struct Object *ob, float cursor[3], int centermode, int around); void ED_armature_transform_bones(struct bArmature *arm, float mat[4][4], const bool do_props); void ED_armature_apply_transform(struct Object *ob, float mat[4][4], const bool do_props); diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h index 95ba6095517..9802f8c3c03 100644 --- a/source/blender/editors/include/ED_image.h +++ b/source/blender/editors/include/ED_image.h @@ -40,6 +40,7 @@ struct wmWindowManager; struct ARegion; struct Scene; struct ViewLayer; +struct WorkSpace; /* image_edit.c, exported for transform */ struct Image *ED_space_image(struct SpaceImage *sima); @@ -75,7 +76,10 @@ bool ED_space_image_show_uvedit(struct SpaceImage *sima, struct Object *obedit); bool ED_space_image_paint_curve(const struct bContext *C); -bool ED_space_image_check_show_maskedit(struct ViewLayer *view_layer, struct SpaceImage *sima); +bool ED_space_image_check_show_maskedit( + struct SpaceImage *sima, + const struct WorkSpace *workspace, + struct ViewLayer *view_layer); int ED_space_image_maskedit_poll(struct bContext *C); int ED_space_image_maskedit_mask_poll(struct bContext *C); diff --git a/source/blender/editors/include/ED_info.h b/source/blender/editors/include/ED_info.h index 072b1a135a3..3d873906ecf 100644 --- a/source/blender/editors/include/ED_info.h +++ b/source/blender/editors/include/ED_info.h @@ -27,8 +27,11 @@ #ifndef __ED_INFO_H__ #define __ED_INFO_H__ +struct EvaluationContext; + /* info_stats.c */ void ED_info_stats_clear(struct ViewLayer *view_layer); -const char *ED_info_stats_string(struct Scene *scene, struct ViewLayer *view_layer); +const char *ED_info_stats_string( + struct Scene *scene, struct WorkSpace *workspace, struct ViewLayer *view_layer); #endif /* __ED_INFO_H__ */ diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 78497b29313..0293f7cd204 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -219,12 +219,14 @@ typedef struct MirrTopoStore_t { intptr_t *index_lookup; int prev_vert_tot; int prev_edge_tot; - int prev_ob_mode; + bool prev_is_editmode; } MirrTopoStore_t; -bool ED_mesh_mirrtopo_recalc_check(struct Mesh *me, struct DerivedMesh *dm, const int ob_mode, MirrTopoStore_t *mesh_topo_store); -void ED_mesh_mirrtopo_init(struct Mesh *me, struct DerivedMesh *dm, const int ob_mode, MirrTopoStore_t *mesh_topo_store, - const bool skip_em_vert_array_init); +bool ED_mesh_mirrtopo_recalc_check( + struct Mesh *me, struct DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store); +void ED_mesh_mirrtopo_init( + struct Mesh *me, struct DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store, + const bool skip_em_vert_array_init); void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store); diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 8d2ff327c51..5df46dd26b8 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -55,6 +55,11 @@ struct wmOperatorType; struct PointerRNA; struct PropertyRNA; struct EnumPropertyItem; +struct EvaluationContext; +struct WorkSpace; +struct wmWindowManager; + +#include "DNA_object_enums.h" /* object_edit.c */ struct Object *ED_object_context(struct bContext *C); /* context.object */ @@ -113,8 +118,8 @@ struct Base *ED_object_add_duplicate(struct Main *bmain, struct Scene *scene, st void ED_object_parent(struct Object *ob, struct Object *parent, const int type, const char *substr); -bool ED_object_mode_compat_set(struct bContext *C, struct Object *ob, int mode, struct ReportList *reports); -void ED_object_toggle_modes(struct bContext *C, int mode); +bool ED_object_mode_compat_set(struct bContext *C, struct WorkSpace *workspace, eObjectMode mode, struct ReportList *reports); +void ED_object_toggle_modes(struct bContext *C, eObjectMode mode); /* bitflags for enter/exit editmode */ #define EM_FREEDATA 1 @@ -122,12 +127,34 @@ void ED_object_toggle_modes(struct bContext *C, int mode); #define EM_WAITCURSOR 4 #define EM_DO_UNDO 8 #define EM_IGNORE_LAYER 16 +void ED_object_editmode_exit_ex( + struct bContext *C, struct WorkSpace *workspace, struct Scene *scene, struct Object *obedit, int flag); void ED_object_editmode_exit(struct bContext *C, int flag); void ED_object_editmode_enter(struct bContext *C, int flag); bool ED_object_editmode_load(struct Object *obedit); bool ED_object_editmode_calc_active_center(struct Object *obedit, const bool select_only, float r_center[3]); + +void ED_object_vpaintmode_enter_ex( + const struct EvaluationContext *eval_ctx, struct wmWindowManager *wm, + struct WorkSpace *workspace, struct Scene *scene, struct Object *ob); +void ED_object_vpaintmode_enter(struct bContext *C); +void ED_object_wpaintmode_enter_ex( + const struct EvaluationContext *eval_ctx, struct wmWindowManager *wm, + struct WorkSpace *workspace, struct Scene *scene, struct Object *ob); +void ED_object_wpaintmode_enter(struct bContext *C); + +void ED_object_vpaintmode_exit_ex(struct WorkSpace *workspace, struct Object *ob); +void ED_object_vpaintmode_exit(struct bContext *C); +void ED_object_wpaintmode_exit_ex(struct WorkSpace *workspace, struct Object *ob); +void ED_object_wpaintmode_exit(struct bContext *C); + +void ED_object_sculptmode_exit_ex( + const struct EvaluationContext *eval_ctx, + struct WorkSpace *workspace, struct Scene *scene, struct Object *ob); +void ED_object_sculptmode_exit(struct bContext *C); + void ED_object_location_from_view(struct bContext *C, float loc[3]); void ED_object_rotation_from_view(struct bContext *C, float rot[3], const char align_axis); void ED_object_base_init_transform(struct bContext *C, struct Base *base, const float loc[3], const float rot[3]); @@ -160,9 +187,9 @@ void ED_objects_clear_paths(struct bContext *C, bool only_selected); void ED_objects_recalculate_paths(struct bContext *C, struct Scene *scene); /* constraints */ -struct ListBase *get_active_constraints(struct Object *ob); +struct ListBase *get_active_constraints(const struct EvaluationContext *eval_ctx, struct Object *ob); struct ListBase *get_constraint_lb(struct Object *ob, struct bConstraint *con, struct bPoseChannel **r_pchan); -struct bConstraint *get_active_constraint(struct Object *ob); +struct bConstraint *get_active_constraint(const struct EvaluationContext *eval_ctx, struct Object *ob); void object_test_constraints(struct Object *ob); @@ -187,24 +214,30 @@ enum { MODIFIER_APPLY_SHAPE }; -struct ModifierData *ED_object_modifier_add(struct ReportList *reports, struct Main *bmain, struct Scene *scene, - struct Object *ob, const char *name, int type); +struct ModifierData *ED_object_modifier_add( + struct ReportList *reports, struct Main *bmain, struct Scene *scene, + struct Object *ob, eObjectMode object_mode, const char *name, int type); bool ED_object_modifier_remove(struct ReportList *reports, struct Main *bmain, struct Object *ob, struct ModifierData *md); void ED_object_modifier_clear(struct Main *bmain, struct Object *ob); int ED_object_modifier_move_down(struct ReportList *reports, struct Object *ob, struct ModifierData *md); int ED_object_modifier_move_up(struct ReportList *reports, struct Object *ob, struct ModifierData *md); -int ED_object_modifier_convert(struct ReportList *reports, struct Main *bmain, struct Scene *scene, - struct ViewLayer *view_layer, struct Object *ob, struct ModifierData *md); +int ED_object_modifier_convert( + struct ReportList *reports, struct Main *bmain, struct Scene *scene, + struct ViewLayer *view_layer, struct Object *ob, eObjectMode object_mode, struct ModifierData *md); int ED_object_modifier_apply(struct ReportList *reports, const struct bContext *C, struct Scene *scene, struct Object *ob, struct ModifierData *md, int mode); int ED_object_modifier_copy(struct ReportList *reports, struct Object *ob, struct ModifierData *md); -bool ED_object_iter_other(struct Main *bmain, struct Object *orig_ob, const bool include_orig, - bool (*callback)(struct Object *ob, void *callback_data), - void *callback_data); +bool ED_object_iter_other( + const struct EvaluationContext *eval_ctx, struct Main *bmain, + struct Object *orig_ob, const bool include_orig, + bool (*callback)(const struct EvaluationContext *eval_ctx, struct Object *ob, void *callback_data), + void *callback_data); -bool ED_object_multires_update_totlevels_cb(struct Object *ob, void *totlevel_v); +bool ED_object_multires_update_totlevels_cb( + const struct EvaluationContext *eval_ctx, + struct Object *ob, void *totlevel_v); /* object_select.c */ void ED_object_select_linked_by_id(struct bContext *C, struct ID *id); @@ -216,7 +249,9 @@ const struct EnumPropertyItem *ED_object_vgroup_selection_itemf_helper( bool *r_free, const unsigned int selection_mask); -void ED_object_check_force_modifiers(struct Main *bmain, struct Scene *scene, struct Object *object); +void ED_object_check_force_modifiers( + struct Main *bmain, struct Scene *scene, + struct Object *object, eObjectMode object_mode); /* object_facemap_ops.c */ void ED_object_facemap_face_add(struct Object *ob, struct bFaceMap *fmap, int facenum); diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 32e6ddf6f54..6513a55ec2b 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -66,7 +66,6 @@ void ED_region_do_listen( void ED_region_do_draw(struct bContext *C, struct ARegion *ar); void ED_region_exit(struct bContext *C, struct ARegion *ar); void ED_region_pixelspace(struct ARegion *ar); -void ED_region_set(const struct bContext *C, struct ARegion *ar); void ED_region_update_rect(struct bContext *C, struct ARegion *ar); void ED_region_init(struct bContext *C, struct ARegion *ar); void ED_region_tag_redraw(struct ARegion *ar); @@ -152,7 +151,7 @@ void ED_screen_update_after_scene_change( const struct bScreen *screen, struct Scene *scene_new, struct ViewLayer *view_layer); -void ED_screen_set_subwinactive(struct bContext *C, const struct wmEvent *event); +void ED_screen_set_active_region(struct bContext *C, const struct wmEvent *event); void ED_screen_exit(struct bContext *C, struct wmWindow *window, struct bScreen *screen); void ED_screen_animation_timer(struct bContext *C, int redraws, int refresh, int sync, int enable); void ED_screen_animation_timer_update(struct bScreen *screen, int redraws, int refresh); @@ -164,6 +163,8 @@ struct ScrArea *ED_screen_state_toggle(struct bContext *C, struct wmWindow *win, void ED_screens_header_tools_menu_create(struct bContext *C, struct uiLayout *layout, void *arg); bool ED_screen_stereo3d_required(const struct bScreen *screen, const struct Scene *scene); Scene *ED_screen_scene_find(const struct bScreen *screen, const struct wmWindowManager *wm); +Scene *ED_screen_scene_find_with_window(const struct bScreen *screen, const struct wmWindowManager *wm, struct wmWindow **r_window); +struct wmWindow *ED_screen_window_find(const struct bScreen *screen, const struct wmWindowManager *wm); void ED_screen_preview_render(const struct bScreen *screen, int size_x, int size_y, unsigned int *r_rect) ATTR_NONNULL(); /* workspaces */ @@ -176,7 +177,7 @@ struct WorkSpace *ED_workspace_add( bool ED_workspace_change( struct WorkSpace *workspace_new, struct bContext *C, - struct wmWindowManager *wm, struct wmWindow *win) ATTR_NONNULL(); + struct wmWindow *win) ATTR_NONNULL(); struct WorkSpace *ED_workspace_duplicate( struct WorkSpace *workspace_old, struct Main *bmain, struct wmWindow *win); diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h index 96b4004b6a6..e25c34ddb78 100644 --- a/source/blender/editors/include/ED_uvedit.h +++ b/source/blender/editors/include/ED_uvedit.h @@ -62,7 +62,7 @@ void ED_object_assign_active_image(struct Main *bmain, struct Object *ob, int ma bool ED_uvedit_test(struct Object *obedit); /* visibility and selection */ -bool uvedit_face_visible_test(struct Scene *scene, struct Image *ima, struct BMFace *efa); +bool uvedit_face_visible_test(struct Scene *scene, struct Object *obedit, struct Image *ima, struct BMFace *efa); bool uvedit_face_select_test(struct Scene *scene, struct BMFace *efa, const int cd_loop_uv_offset); bool uvedit_edge_select_test(struct Scene *scene, struct BMLoop *l, @@ -112,7 +112,10 @@ void ED_unwrap_lscm(struct Scene *scene, struct Object *obedit, const short sel) /* uvedit_draw.c */ void ED_image_draw_cursor(struct ARegion *ar, const float cursor[2]); -void ED_uvedit_draw_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene, struct ViewLayer *view_layer, struct Object *obedit, struct Object *obact, struct Depsgraph *depsgraph); +void ED_uvedit_draw_main( + struct SpaceImage *sima, const struct EvaluationContext *eval_ctx, + struct ARegion *ar, struct Scene *scene, struct ViewLayer *view_layer, + struct Object *obedit, struct Object *obact, struct Depsgraph *depsgraph); /* uvedit_buttons.c */ void ED_uvedit_buttons_register(struct ARegionType *art); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 7eee053061e..e3eb4c7ac97 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -476,7 +476,7 @@ void ED_view3d_operator_properties_viewmat_get(struct wmOperator *op, int *winx, /* render */ void ED_view3d_stop_render_preview(struct wmWindowManager *wm, struct ARegion *ar); -void ED_view3d_shade_update(struct Main *bmain, struct Scene *scene, struct View3D *v3d, struct ScrArea *sa); +void ED_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrArea *sa); #define V3D_IS_ZBUF(v3d) \ (((v3d)->flag & V3D_ZBUF_SELECT) && ((v3d)->drawtype > OB_WIRE)) diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt index 94f377fb35e..c023816b52c 100644 --- a/source/blender/editors/interface/CMakeLists.txt +++ b/source/blender/editors/interface/CMakeLists.txt @@ -70,7 +70,9 @@ set(SRC view2d.c view2d_ops.c + interface_eyedropper_intern.h interface_intern.h + interface_regions_intern.h ) if(WITH_INTERNATIONAL) @@ -81,6 +83,10 @@ if(WITH_HEADLESS) add_definitions(-DWITH_HEADLESS) endif() +if(WITH_CYCLES) + add_definitions(-DWITH_CYCLES) +endif() + if(WITH_PYTHON) add_definitions(-DWITH_PYTHON) endif() diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index a5ef2943387..bfaa986d1ca 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -69,7 +69,6 @@ #include "WM_api.h" #include "WM_types.h" -#include "wm_subwindow.h" #include "WM_message.h" #include "RNA_access.h" @@ -1393,7 +1392,6 @@ void UI_block_draw(const bContext *C, uiBlock *block) ARegion *ar; uiBut *but; rcti rect; - int multisample_enabled; /* get menu region or area region */ ar = CTX_wm_menu(C); @@ -1403,13 +1401,8 @@ void UI_block_draw(const bContext *C, uiBlock *block) if (!block->endblock) UI_block_end(C, block); - /* disable AA, makes widgets too blurry */ - multisample_enabled = glIsEnabled(GL_MULTISAMPLE); - if (multisample_enabled) - glDisable(GL_MULTISAMPLE); - /* we set this only once */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* scale fonts */ ui_fontscale(&style.paneltitle.points, block->aspect); @@ -1451,9 +1444,6 @@ void UI_block_draw(const bContext *C, uiBlock *block) gpuPopProjectionMatrix(); gpuPopMatrix(); - if (multisample_enabled) - glEnable(GL_MULTISAMPLE); - ui_draw_links(block); } @@ -2895,7 +2885,6 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, sh uiBlock *block; wmWindow *window; Scene *scn; - int getsizex, getsizey; window = CTX_wm_window(C); scn = CTX_data_scene(C); @@ -2926,22 +2915,22 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, sh UI_block_region_set(block, region); /* window matrix and aspect */ - if (region && region->swinid) { - wm_subwindow_matrix_get(window, region->swinid, block->winmat); - wm_subwindow_size_get(window, region->swinid, &getsizex, &getsizey); + if (region && region->visible) { + gpuGetProjectionMatrix(block->winmat); - block->aspect = 2.0f / fabsf(getsizex * block->winmat[0][0]); + block->aspect = 2.0f / fabsf(region->winx * block->winmat[0][0]); } else { - const bScreen *screen = WM_window_get_active_screen(window); - /* no subwindow created yet, for menus for example, so we * use the main window instead, since buttons are created * there anyway */ - wm_subwindow_matrix_get(window, screen->mainwin, block->winmat); - wm_subwindow_size_get(window, screen->mainwin, &getsizex, &getsizey); + int width = WM_window_pixels_x(window); + int height = WM_window_pixels_y(window); + rcti winrct = {0, width -1, 0, height - 1}; + + wmGetProjectionMatrix(block->winmat, &winrct); - block->aspect = 2.0f / fabsf(getsizex * block->winmat[0][0]); + block->aspect = 2.0f / fabsf(width * block->winmat[0][0]); block->auto_open = true; block->flag |= UI_BLOCK_LOOP; /* tag as menu */ } diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 3ecb72353bc..5e5da60593c 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -615,7 +615,7 @@ static void draw_scope_end(const rctf *rect, GLint *scissor) /* restore scissortest */ glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* outline */ UI_draw_roundbox_corner_set(UI_CNR_ALL); @@ -635,7 +635,7 @@ static void histogram_draw_one( return; glEnable(GL_LINE_SMOOTH); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ONE); immUniformColor4fv(color); @@ -665,7 +665,7 @@ static void histogram_draw_one( /* curve outline */ immUniformColor4f(0.0f, 0.0f, 0.0f, 0.25f); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); immBegin(GWN_PRIM_LINE_STRIP, res); for (int i = 0; i < res; i++) { float x2 = x + i * (w / (float)res); @@ -696,7 +696,7 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol) float h = BLI_rctf_size_y(&rect) * hist->ymax; glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); float color[4]; UI_GetThemeColor4fv(TH_PREVIEW_BACK, color); @@ -705,7 +705,7 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol) /* need scissor test, histogram can draw outside of boundary */ GLint scissor[4]; - glGetIntegerv(GL_VIEWPORT, scissor); + glGetIntegerv(GL_SCISSOR_BOX, scissor); glScissor(ar->winrct.xmin + (rect.xmin - 1), ar->winrct.ymin + (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), @@ -817,7 +817,7 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), } glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); float color[4]; UI_GetThemeColor4fv(TH_PREVIEW_BACK, color); @@ -825,7 +825,7 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color); /* need scissor test, waveform can draw outside of boundary */ - glGetIntegerv(GL_VIEWPORT, scissor); + glGetIntegerv(GL_SCISSOR_BOX, scissor); glScissor(ar->winrct.xmin + (rect.xmin - 1), ar->winrct.ymin + (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), @@ -841,7 +841,7 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), } glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); Gwn_VertFormat *format = immVertexFormat(); unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); @@ -1085,7 +1085,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wco float alpha = scopes->vecscope_alpha * scopes->vecscope_alpha * scopes->vecscope_alpha; glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); float color[4]; UI_GetThemeColor4fv(TH_PREVIEW_BACK, color); @@ -1094,7 +1094,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wco /* need scissor test, hvectorscope can draw outside of boundary */ GLint scissor[4]; - glGetIntegerv(GL_VIEWPORT, scissor); + glGetIntegerv(GL_SCISSOR_BOX, scissor); glScissor(ar->winrct.xmin + (rect.xmin - 1), ar->winrct.ymin + (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), @@ -1520,7 +1520,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti /* need scissor test, curve can draw outside of boundary */ GLint scissor[4]; - glGetIntegerv(GL_VIEWPORT, scissor); + glGetIntegerv(GL_SCISSOR_BOX, scissor); rcti scissor_new = { .xmin = ar->winrct.xmin + rect->xmin, .ymin = ar->winrct.ymin + rect->ymin, @@ -1564,7 +1564,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti if (but->a1 == UI_GRAD_H) { /* grid, hsv uses different grid */ glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); immUniformColor4ub(0, 0, 0, 48); ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.1666666f); glDisable(GL_BLEND); @@ -1738,11 +1738,11 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc int height = BLI_rctf_size_y(&rect); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* need scissor test, preview image can draw outside of boundary */ GLint scissor[4]; - glGetIntegerv(GL_VIEWPORT, scissor); + glGetIntegerv(GL_SCISSOR_BOX, scissor); glScissor(ar->winrct.xmin + (rect.xmin - 1), ar->winrct.ymin + (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), @@ -1874,7 +1874,7 @@ void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol GLint scissor[4]; /* need scissor test, can draw outside of boundary */ - glGetIntegerv(GL_VIEWPORT, scissor); + glGetIntegerv(GL_SCISSOR_BOX, scissor); rcti scissor_new = { .xmin = ar->winrct.xmin + recti->xmin, diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 9ccb47938d2..9e1697bc39a 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -46,6 +46,7 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" +#include "DNA_workspace_types.h" #include "BLI_math.h" #include "BLI_listbase.h" @@ -73,6 +74,8 @@ #include "BKE_unit.h" #include "BKE_paint.h" +#include "DEG_depsgraph.h" + #include "ED_screen.h" #include "ED_util.h" #include "ED_keyframing.h" @@ -185,6 +188,7 @@ typedef struct uiSelectContextStore { uiSelectContextElem *elems; int elems_len; bool do_free; + bool is_enabled; /* When set, simply copy values (don't apply difference). * Rules are: * - dragging numbers uses delta. @@ -200,9 +204,7 @@ static void ui_selectcontext_apply( bContext *C, uiBut *but, struct uiSelectContextStore *selctx_data, const double value, const double value_orig); -#if 0 #define IS_ALLSELECT_EVENT(event) ((event)->alt != 0) -#endif /** just show a tinted color so users know its activated */ #define UI_BUT_IS_SELECT_CONTEXT UI_BUT_NODE_ACTIVE @@ -1194,11 +1196,14 @@ static void ui_multibut_states_apply(bContext *C, uiHandleButtonData *data, uiBl ui_but_execute_begin(C, ar, but, &active_back); #ifdef USE_ALLSELECT - if (mbut_state->select_others.elems_len == 0) { - ui_selectcontext_begin(C, but, &mbut_state->select_others); - } - if (mbut_state->select_others.elems_len == 0) { - mbut_state->select_others.elems_len = -1; + if (data->select_others.is_enabled) { + /* init once! */ + if (mbut_state->select_others.elems_len == 0) { + ui_selectcontext_begin(C, but, &mbut_state->select_others); + } + if (mbut_state->select_others.elems_len == 0) { + mbut_state->select_others.elems_len = -1; + } } /* needed so we apply the right deltas */ @@ -2081,7 +2086,12 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton else # endif if (data->select_others.elems_len == 0) { - ui_selectcontext_begin(C, but, &data->select_others); + wmWindow *win = CTX_wm_window(C); + /* may have been enabled before activating */ + if (data->select_others.is_enabled || IS_ALLSELECT_EVENT(win->eventstate)) { + ui_selectcontext_begin(C, but, &data->select_others); + data->select_others.is_enabled = true; + } } if (data->select_others.elems_len == 0) { /* dont check again */ @@ -3086,7 +3096,11 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data) #ifdef USE_ALLSELECT if (is_num_but) { - data->select_others.is_copy = true; + if (IS_ALLSELECT_EVENT(win->eventstate)) { + data->select_others.is_enabled = true; + data->select_others.is_copy = true; + + } } #endif @@ -3691,6 +3705,15 @@ static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *dat data->menu->popup = but->block->handle->popup; } +#ifdef USE_ALLSELECT + { + wmWindow *win = CTX_wm_window(C); + if (IS_ALLSELECT_EVENT(win->eventstate)) { + data->select_others.is_enabled = true; + } + } +#endif + /* this makes adjacent blocks auto open from now on */ //if (but->block->auto_open == 0) but->block->auto_open = 1; } @@ -5252,9 +5275,10 @@ static int ui_do_but_COLOR( if ((int)(but->a1) == UI_PALETTE_COLOR) { if (!event->ctrl) { float color[3]; + const WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - Paint *paint = BKE_paint_get_active(scene, view_layer); + Paint *paint = BKE_paint_get_active(scene, view_layer, workspace->object_mode); Brush *brush = BKE_paint_brush(paint); if (brush->flag & BRUSH_USE_GRADIENT) { @@ -6170,6 +6194,7 @@ static int ui_do_but_CURVE( { int mx, my, a; bool changed = false; + Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); @@ -6286,6 +6311,7 @@ static int ui_do_but_CURVE( } else if (event->type == LEFTMOUSE && event->val != KM_PRESS) { if (data->dragsel != -1) { + const WorkSpace *workspace = CTX_wm_workspace(C); CurveMapping *cumap = (CurveMapping *)but->poin; CurveMap *cuma = cumap->cm + cumap->cur; CurveMapPoint *cmp = cuma->curve; @@ -6300,7 +6326,7 @@ static int ui_do_but_CURVE( } else { curvemapping_changed(cumap, true); /* remove doubles */ - BKE_paint_invalidate_cursor_overlay(scene, view_layer, cumap); + BKE_paint_invalidate_cursor_overlay(scene, view_layer, cumap, workspace->object_mode); } } diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index d048324d35e..0a36fbafc39 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -46,6 +46,7 @@ #include "DNA_object_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" +#include "DNA_workspace_types.h" #include "RNA_access.h" #include "RNA_enum_types.h" @@ -61,6 +62,8 @@ #include "BIF_glutil.h" +#include "DEG_depsgraph.h" + #include "ED_datafiles.h" #include "ED_keyframes_draw.h" #include "ED_render.h" @@ -1112,7 +1115,7 @@ static void icon_draw_size( glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); icon_draw_texture(x, y, (float)w, (float)h, di->data.texture.x, di->data.texture.y, di->data.texture.w, di->data.texture.h, alpha, rgb); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } else if (di->type == ICON_TYPE_BUFFER) { /* it is a builtin icon */ @@ -1122,9 +1125,9 @@ static void icon_draw_size( #endif if (!iimg->rect) return; /* something has gone wrong! */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); icon_draw_rect(x, y, w, h, aspect, iimg->w, iimg->h, iimg->rect, alpha, rgb, is_preview); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } else if (di->type == ICON_TYPE_PREVIEW) { PreviewImage *pi = (icon->type != 0) ? BKE_previewimg_id_ensure((ID *)icon->obj) : icon->obj; @@ -1137,7 +1140,7 @@ static void icon_draw_size( glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); icon_draw_rect(x, y, w, h, aspect, pi->w[size], pi->h[size], pi->rect[size], alpha, rgb, is_preview); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } } } @@ -1193,6 +1196,7 @@ static int ui_id_brush_get_icon(const bContext *C, ID *id) ui_id_icon_render(C, id, true); } else { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = CTX_data_active_object(C); SpaceImage *sima; const EnumPropertyItem *items = NULL; @@ -1203,11 +1207,11 @@ static int ui_id_brush_get_icon(const bContext *C, ID *id) * checking various context stuff here */ if (CTX_wm_view3d(C) && ob) { - if (ob->mode & OB_MODE_SCULPT) + if (workspace->object_mode & OB_MODE_SCULPT) mode = OB_MODE_SCULPT; - else if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) + else if (workspace->object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) mode = OB_MODE_VERTEX_PAINT; - else if (ob->mode & OB_MODE_TEXTURE_PAINT) + else if (workspace->object_mode & OB_MODE_TEXTURE_PAINT) mode = OB_MODE_TEXTURE_PAINT; } else if ((sima = CTX_wm_space_image(C)) && diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c index 24990c593ac..c3d6d635c17 100644 --- a/source/blender/editors/interface/interface_region_popup.c +++ b/source/blender/editors/interface/interface_region_popup.c @@ -48,7 +48,6 @@ #include "WM_api.h" #include "WM_types.h" -#include "wm_subwindow.h" #include "UI_interface.h" @@ -589,9 +588,7 @@ uiBlock *ui_popup_block_refresh( ED_region_init(C, ar); /* get winmat now that we actually have the subwindow */ - wmSubWindowSet(window, ar->swinid); - - wm_subwindow_matrix_get(window, ar->swinid, block->winmat); + wmGetProjectionMatrix(block->winmat, &ar->winrct); /* notify change and redraw */ ED_region_tag_redraw(ar); diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c index 07fbefa42e1..449e783b03e 100644 --- a/source/blender/editors/interface/interface_region_tooltip.c +++ b/source/blender/editors/interface/interface_region_tooltip.c @@ -175,12 +175,7 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar) float background_color[3]; float tone_bg; - int i, multisample_enabled; - - /* disable AA, makes widgets too blurry */ - multisample_enabled = glIsEnabled(GL_MULTISAMPLE); - if (multisample_enabled) - glDisable(GL_MULTISAMPLE); + int i; wmOrtho2_region_pixelspace(ar); @@ -285,9 +280,6 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar) BLF_disable(data->fstyle.uifont_id, BLF_WORD_WRAP); BLF_disable(blf_mono_font, BLF_WORD_WRAP); - - if (multisample_enabled) - glEnable(GL_MULTISAMPLE); } static void ui_tooltip_region_free_cb(ARegion *ar) diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index ce2d3bebb97..af7065a81ba 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -36,7 +36,7 @@ #include "DNA_node_types.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_brush_types.h" #include "DNA_texture_types.h" @@ -638,6 +638,9 @@ static void template_ID( bContext *C, uiLayout *layout, TemplateID *template_ui, StructRNA *type, int flag, const char *newop, const char *openop, const char *unlinkop) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + uiBut *but; uiBlock *block; PointerRNA idptr; @@ -722,7 +725,7 @@ static void template_ID( (idfrom && idfrom->lib) || (!editable) || /* object in editmode - don't change data */ - (idfrom && GS(idfrom->name) == ID_OB && (((Object *)idfrom)->mode & OB_MODE_EDIT))) + (idfrom && GS(idfrom->name) == ID_OB && (eval_ctx.object_mode & OB_MODE_EDIT))) { UI_but_flag_enable(but, UI_BUT_DISABLED); } @@ -1306,7 +1309,8 @@ static int modifier_is_simulation(ModifierData *md) } static uiLayout *draw_modifier( - uiLayout *layout, Scene *scene, Object *ob, + uiLayout *layout, + const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ModifierData *md, int index, int cageIndex, int lastCageIndex) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); @@ -1443,7 +1447,7 @@ static uiLayout *draw_modifier( if (md->type == eModifierType_ParticleSystem) { ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys; - if (!(ob->mode & OB_MODE_PARTICLE_EDIT)) { + if (!(eval_ctx->object_mode & OB_MODE_PARTICLE_EDIT)) { if (ELEM(psys->part->ren_as, PART_DRAW_GR, PART_DRAW_OB)) uiItemO(row, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Convert"), ICON_NONE, "OBJECT_OT_duplicates_make_real"); @@ -1492,6 +1496,8 @@ static uiLayout *draw_modifier( uiLayout *uiTemplateModifier(uiLayout *layout, bContext *C, PointerRNA *ptr) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Scene *scene = CTX_data_scene(C); Object *ob; ModifierData *md, *vmd; @@ -1522,7 +1528,7 @@ uiLayout *uiTemplateModifier(uiLayout *layout, bContext *C, PointerRNA *ptr) for (i = 0; vmd; i++, vmd = vmd->next) { if (md == vmd) - return draw_modifier(layout, scene, ob, md, i, cageIndex, lastCageIndex); + return draw_modifier(layout, &eval_ctx, scene, ob, md, i, cageIndex, lastCageIndex); else if (vmd->mode & eModifierMode_Virtual) i--; } diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index a9c3f973569..2c509a949b5 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -729,7 +729,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4ubv((unsigned char *)wcol->inner); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); for (a = 0; a < wtb->totvert; a++) { x_mid += wtb->inner_v[a][0]; diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index ac5fb3e40cb..74332be0996 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -45,6 +45,7 @@ #include "BLI_utildefines.h" #include "BLI_math.h" +#include "BKE_addon.h" #include "BKE_appdir.h" #include "BKE_colorband.h" #include "BKE_DerivedMesh.h" @@ -2318,13 +2319,9 @@ void init_userdef_do_versions(void) if (btheme->tipo.handle_sel_auto_clamped[3] == 0) rgba_char_args_set(btheme->tipo.handle_sel_auto_clamped, 0xf0, 0xaf, 0x90, 255); } - + /* enable (Cycles) addon by default */ - if (!BLI_findstring(&U.addons, "cycles", offsetof(bAddon, module))) { - bAddon *baddon = MEM_callocN(sizeof(bAddon), "bAddon"); - BLI_strncpy(baddon->module, "cycles", sizeof(baddon->module)); - BLI_addtail(&U.addons, baddon); - } + BKE_addon_ensure(&U.addons, "cycles"); } if (!USER_VERSION_ATLEAST(260, 5)) { @@ -2992,6 +2989,15 @@ void init_userdef_do_versions(void) // we default to the first audio device U.audiodevice = 0; + /* Not versioning, just avoid errors. */ +#ifndef WITH_CYCLES + bAddon *addon = BLI_findstring(&U.addons, "cycles", offsetof(bAddon, module)); + if (addon) { + BLI_remlink(&U.addons, addon); + BKE_addon_free(addon); + } +#endif + /* funny name, but it is GE stuff, moves userdef stuff to engine */ // XXX space_set_commmandline_options(); /* this timer uses U */ diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index a94ef0d1d5b..d31f2dec145 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -1027,6 +1027,13 @@ bool UI_view2d_tab_set(View2D *v2d, int tab) void UI_view2d_zoom_cache_reset(void) { + /* TODO(sergey): This way we avoid threading conflict with VSE rendering + * text strip. But ideally we want to make glyph cache to be fully safe + * for threading. + */ + if (G.is_rendering) { + return; + } /* While scaling we can accumulate fonts at many sizes (~20 or so). * Not an issue with embedded font, but can use over 500Mb with i18n ones! See [#38244]. */ diff --git a/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c index 0299a33d0fe..23c6030f091 100644 --- a/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c +++ b/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c @@ -37,7 +37,7 @@ #include "MEM_guardedalloc.h" #include "BLI_math.h" -#include "BLI_dial.h" +#include "BLI_dial_2d.h" #include "BLI_rect.h" #include "BKE_context.h" diff --git a/source/blender/editors/manipulator_library/manipulator_types/cage3d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/cage3d_manipulator.c index d58cdb4b187..67fb2419931 100644 --- a/source/blender/editors/manipulator_library/manipulator_types/cage3d_manipulator.c +++ b/source/blender/editors/manipulator_library/manipulator_types/cage3d_manipulator.c @@ -37,7 +37,7 @@ #include "MEM_guardedalloc.h" #include "BLI_math.h" -#include "BLI_dial.h" +#include "BLI_dial_2d.h" #include "BLI_rect.h" #include "BKE_context.h" diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index c60b673ec69..689a96a3dec 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -555,7 +555,7 @@ static void draw_masklays(const bContext *C, Mask *mask, const char draw_flag, c const int width, const int height) { glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); GPU_enable_program_point_size(); MaskLayer *masklay; diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index 9f2f6de8a09..7ffd82e262c 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -33,7 +33,7 @@ #include "BLI_utildefines.h" #include "BLI_rect.h" -#include "BLI_lasso.h" +#include "BLI_lasso_2d.h" #include "BLI_math.h" #include "BKE_context.h" diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 992d0fada5e..113173c1c03 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -635,8 +635,9 @@ static int mirrtopo_vert_sort(const void *v1, const void *v2) return 0; } -bool ED_mesh_mirrtopo_recalc_check(Mesh *me, DerivedMesh *dm, const int ob_mode, MirrTopoStore_t *mesh_topo_store) +bool ED_mesh_mirrtopo_recalc_check(Mesh *me, DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store) { + const bool is_editmode = (me->edit_btmesh != NULL); int totvert; int totedge; @@ -654,7 +655,7 @@ bool ED_mesh_mirrtopo_recalc_check(Mesh *me, DerivedMesh *dm, const int ob_mode, } if ((mesh_topo_store->index_lookup == NULL) || - (mesh_topo_store->prev_ob_mode != ob_mode) || + (mesh_topo_store->prev_is_editmode != is_editmode) || (totvert != mesh_topo_store->prev_vert_tot) || (totedge != mesh_topo_store->prev_edge_tot)) { @@ -666,9 +667,11 @@ bool ED_mesh_mirrtopo_recalc_check(Mesh *me, DerivedMesh *dm, const int ob_mode, } -void ED_mesh_mirrtopo_init(Mesh *me, DerivedMesh *dm, const int ob_mode, MirrTopoStore_t *mesh_topo_store, - const bool skip_em_vert_array_init) +void ED_mesh_mirrtopo_init( + Mesh *me, DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store, + const bool skip_em_vert_array_init) { + const bool is_editmode = (me->edit_btmesh != NULL); MEdge *medge = NULL, *med; BMEditMesh *em = dm ? NULL : me->edit_btmesh; @@ -691,7 +694,7 @@ void ED_mesh_mirrtopo_init(Mesh *me, DerivedMesh *dm, const int ob_mode, MirrTop /* reallocate if needed */ ED_mesh_mirrtopo_free(mesh_topo_store); - mesh_topo_store->prev_ob_mode = ob_mode; + mesh_topo_store->prev_is_editmode = is_editmode; if (em) { BM_mesh_elem_index_ensure(em->bm, BM_VERT); diff --git a/source/blender/editors/mesh/editmesh_intersect.c b/source/blender/editors/mesh/editmesh_intersect.c index 3498c6246d7..d681d904e74 100644 --- a/source/blender/editors/mesh/editmesh_intersect.c +++ b/source/blender/editors/mesh/editmesh_intersect.c @@ -400,7 +400,7 @@ static void bm_face_split_by_edges( bm, f, edge_net_temp_buf->data, edge_net_temp_buf->count, &face_arr, &face_arr_len); - BLI_buffer_empty(edge_net_temp_buf); + BLI_buffer_clear(edge_net_temp_buf); if (face_arr_len) { int i; diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 5d5e54edf56..d9bbec7082d 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1116,7 +1116,7 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) int i; glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* draw any snapped verts first */ immUniformColor4ubv(kcd->colors.point_a); @@ -1158,7 +1158,7 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) immUniformColor3ubv(kcd->colors.line); glLineWidth(1.0); - immBeginAtMost(GWN_PRIM_LINES, BLI_mempool_count(kcd->kedges) * 2); + immBeginAtMost(GWN_PRIM_LINES, BLI_mempool_len(kcd->kedges) * 2); BLI_mempool_iternew(kcd->kedges, &iter); for (kfe = BLI_mempool_iterstep(&iter); kfe; kfe = BLI_mempool_iterstep(&iter)) { @@ -1179,7 +1179,7 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) immUniformColor3ubv(kcd->colors.point); glPointSize(5.0); - immBeginAtMost(GWN_PRIM_POINTS, BLI_mempool_count(kcd->kverts)); + immBeginAtMost(GWN_PRIM_POINTS, BLI_mempool_len(kcd->kverts)); BLI_mempool_iternew(kcd->kverts, &iter); for (kfv = BLI_mempool_iterstep(&iter); kfv; kfv = BLI_mempool_iterstep(&iter)) { @@ -2300,7 +2300,7 @@ static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMFace *f, ListBase *kfe /* point to knife edges we've created edges in, edge_array aligned */ KnifeEdge **kfe_array = BLI_array_alloca(kfe_array, edge_array_len); - BLI_assert(BLI_gset_size(kcd->edgenet.edge_visit) == 0); + BLI_assert(BLI_gset_len(kcd->edgenet.edge_visit) == 0); i = 0; for (ref = kfedges->first; ref; ref = ref->next) { diff --git a/source/blender/editors/mesh/editmesh_path.c b/source/blender/editors/mesh/editmesh_path.c index b71dd029bf2..795c7b6aa53 100644 --- a/source/blender/editors/mesh/editmesh_path.c +++ b/source/blender/editors/mesh/editmesh_path.c @@ -121,10 +121,9 @@ static void verttag_set_cb(BMVert *v, bool val, void *user_data_v) } static void mouse_mesh_shortest_path_vert( - Scene *scene, const struct PathSelectParams *op_params, + Scene *UNUSED(scene), Object *obedit, const struct PathSelectParams *op_params, BMVert *v_act, BMVert *v_dst) { - Object *obedit = scene->obedit; BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; @@ -280,11 +279,11 @@ static void edgetag_set_cb(BMEdge *e, bool val, void *user_data_v) } } -static void edgetag_ensure_cd_flag(Scene *scene, Mesh *me) +static void edgetag_ensure_cd_flag(Mesh *me, const char edge_mode) { BMesh *bm = me->edit_btmesh->bm; - switch (scene->toolsettings->edge_mode) { + switch (edge_mode) { case EDGE_MODE_TAG_CREASE: BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_CREASE); break; @@ -307,10 +306,9 @@ static void edgetag_ensure_cd_flag(Scene *scene, Mesh *me) /* since you want to create paths with multiple selects, it doesn't have extend option */ static void mouse_mesh_shortest_path_edge( - Scene *scene, const struct PathSelectParams *op_params, + Scene *scene, Object *obedit, const struct PathSelectParams *op_params, BMEdge *e_act, BMEdge *e_dst) { - Object *obedit = scene->obedit; BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; @@ -319,7 +317,7 @@ static void mouse_mesh_shortest_path_edge( Mesh *me = obedit->data; bool is_path_ordered = false; - edgetag_ensure_cd_flag(scene, obedit->data); + edgetag_ensure_cd_flag(obedit->data, op_params->edge_mode); if (e_act && (e_act != e_dst)) { if (op_params->use_fill) { @@ -377,7 +375,7 @@ static void mouse_mesh_shortest_path_edge( } else { const bool is_act = !edgetag_test_cb(e_dst, &user_data); - edgetag_ensure_cd_flag(scene, obedit->data); + edgetag_ensure_cd_flag(obedit->data, op_params->edge_mode); edgetag_set_cb(e_dst, is_act, &user_data); /* switch the edge option */ } @@ -452,10 +450,9 @@ static void facetag_set_cb(BMFace *f, bool val, void *user_data_v) } static void mouse_mesh_shortest_path_face( - Scene *scene, const struct PathSelectParams *op_params, + Scene *UNUSED(scene), Object *obedit, const struct PathSelectParams *op_params, BMFace *f_act, BMFace *f_dst) { - Object *obedit = scene->obedit; BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; @@ -547,7 +544,7 @@ static void mouse_mesh_shortest_path_face( /* Main Operator for vert/edge/face tag */ static bool edbm_shortest_path_pick_ex( - Scene *scene, const struct PathSelectParams *op_params, + Scene *scene, Object *obedit, const struct PathSelectParams *op_params, BMElem *ele_src, BMElem *ele_dst) { @@ -555,15 +552,15 @@ static bool edbm_shortest_path_pick_ex( /* pass */ } else if (ele_src->head.htype == BM_VERT) { - mouse_mesh_shortest_path_vert(scene, op_params, (BMVert *)ele_src, (BMVert *)ele_dst); + mouse_mesh_shortest_path_vert(scene, obedit, op_params, (BMVert *)ele_src, (BMVert *)ele_dst); return true; } else if (ele_src->head.htype == BM_EDGE) { - mouse_mesh_shortest_path_edge(scene, op_params, (BMEdge *)ele_src, (BMEdge *)ele_dst); + mouse_mesh_shortest_path_edge(scene, obedit, op_params, (BMEdge *)ele_src, (BMEdge *)ele_dst); return true; } else if (ele_src->head.htype == BM_FACE) { - mouse_mesh_shortest_path_face(scene, op_params, (BMFace *)ele_src, (BMFace *)ele_dst); + mouse_mesh_shortest_path_face(scene, obedit, op_params, (BMFace *)ele_src, (BMFace *)ele_dst); return true; } @@ -644,7 +641,7 @@ static int edbm_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmE op_params.track_active = track_active; op_params.edge_mode = vc.scene->toolsettings->edge_mode; - if (!edbm_shortest_path_pick_ex(vc.scene, &op_params, ele_src, ele_dst)) { + if (!edbm_shortest_path_pick_ex(vc.scene, vc.obedit, &op_params, ele_src, ele_dst)) { return OPERATOR_PASS_THROUGH; } @@ -681,7 +678,7 @@ static int edbm_shortest_path_pick_exec(bContext *C, wmOperator *op) op_params.track_active = true; op_params.edge_mode = scene->toolsettings->edge_mode; - if (!edbm_shortest_path_pick_ex(scene, &op_params, ele_src, ele_dst)) { + if (!edbm_shortest_path_pick_ex(scene, obedit, &op_params, ele_src, ele_dst)) { return OPERATOR_CANCELLED; } @@ -720,8 +717,8 @@ void MESH_OT_shortest_path_pick(wmOperatorType *ot) static int edbm_shortest_path_select_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Object *ob = CTX_data_edit_object(C); - BMEditMesh *em = BKE_editmesh_from_object(ob); + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; BMIter iter; BMEditSelection *ese_src, *ese_dst; @@ -773,7 +770,7 @@ static int edbm_shortest_path_select_exec(bContext *C, wmOperator *op) struct PathSelectParams op_params; path_select_params_from_op(op, &op_params); - edbm_shortest_path_pick_ex(scene, &op_params, ele_src, ele_dst); + edbm_shortest_path_pick_ex(scene, obedit, &op_params, ele_src, ele_dst); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 3e0afd3095e..7b88b091672 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -280,7 +280,7 @@ bool EDBM_backbuf_border_mask_init(const struct EvaluationContext *eval_ctx, Vie /* method in use for face selecting too */ if (vc->obedit == NULL) { - if (!BKE_paint_select_elem_test(vc->obact)) { + if (!BKE_paint_select_elem_test(vc->obact, eval_ctx->object_mode)) { return false; } } @@ -332,7 +332,7 @@ bool EDBM_backbuf_circle_init( /* method in use for face selecting too */ if (vc->obedit == NULL) { - if (!BKE_paint_select_elem_test(vc->obact)) { + if (!BKE_paint_select_elem_test(vc->obact, eval_ctx->object_mode)) { return false; } } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 75a13a916e6..b2371ef1ad3 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -3374,7 +3374,11 @@ static int edbm_separate_exec(bContext *C, wmOperator *op) } if (retval_iter) { - BM_mesh_bm_to_me(bm_old, me, (&(struct BMeshToMeshParams){0})); + BM_mesh_bm_to_me( + bm_old, me, + (&(struct BMeshToMeshParams){ + .calc_object_remap = true, + })); DEG_id_tag_update(&me->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM | ND_DATA, me); diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c index 534ca22178e..11667ed5710 100644 --- a/source/blender/editors/mesh/editmesh_undo.c +++ b/source/blender/editors/mesh/editmesh_undo.c @@ -496,6 +496,8 @@ static void *editbtMesh_to_undoMesh(void *emv, void *obdata) BM_mesh_bm_to_me( em->bm, &um->me, (&(struct BMeshToMeshParams){ + /* Undo code should not be manipulating 'G.main->object' hooks/vertex-parent. */ + .calc_object_remap = false, .cd_mask_extra = CD_MASK_SHAPE_KEYINDEX, })); diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index a52f12ec055..7b727e75b55 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -381,7 +381,10 @@ void EDBM_mesh_load(Object *ob) bm->shapenr = 1; } - BM_mesh_bm_to_me(bm, me, (&(struct BMeshToMeshParams){0})); + BM_mesh_bm_to_me( + bm, me, (&(struct BMeshToMeshParams){ + .calc_object_remap = true, + })); #ifdef USE_TESSFACE_DEFAULT BKE_mesh_tessface_calc(me); @@ -1013,7 +1016,7 @@ void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, const int axis, const bool BM_mesh_elem_index_ensure(bm, BM_VERT); if (use_topology) { - ED_mesh_mirrtopo_init(me, NULL, -1, &mesh_topo_store, true); + ED_mesh_mirrtopo_init(me, NULL, &mesh_topo_store, true); } else { tree = BLI_kdtree_new(bm->totvert); diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 218b97d3ede..bd3d2f652c0 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -506,13 +506,14 @@ static int layers_poll(bContext *C) static int mesh_uv_texture_add_exec(bContext *C, wmOperator *UNUSED(op)) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = ED_object_context(C); Mesh *me = ob->data; if (ED_mesh_uv_texture_add(me, NULL, true) == -1) return OPERATOR_CANCELLED; - if (ob->mode & OB_MODE_TEXTURE_PAINT) { + if (workspace->object_mode & OB_MODE_TEXTURE_PAINT) { Scene *scene = CTX_data_scene(C); BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL); @@ -622,13 +623,14 @@ void MESH_OT_drop_named_image(wmOperatorType *ot) static int mesh_uv_texture_remove_exec(bContext *C, wmOperator *UNUSED(op)) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = ED_object_context(C); Mesh *me = ob->data; if (!ED_mesh_uv_texture_remove_active(me)) return OPERATOR_CANCELLED; - if (ob->mode & OB_MODE_TEXTURE_PAINT) { + if (workspace->object_mode & OB_MODE_TEXTURE_PAINT) { Scene *scene = CTX_data_scene(C); BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL); @@ -742,13 +744,14 @@ static int mesh_customdata_mask_clear_poll(bContext *C) { Object *ob = ED_object_context(C); if (ob && ob->type == OB_MESH) { - Mesh *me = ob->data; + const WorkSpace *workspace = CTX_wm_workspace(C); /* special case - can't run this if we're in sculpt mode */ - if (ob->mode & OB_MODE_SCULPT) { + if (workspace->object_mode & OB_MODE_SCULPT) { return false; } + Mesh *me = ob->data; if (!ID_IS_LINKED(me)) { CustomData *data = GET_CD_DATA(me, vdata); if (CustomData_has_layer(data, CD_PAINT_MASK)) { diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c index bd2ad21d51c..aaa06951ec6 100644 --- a/source/blender/editors/mesh/mesh_navmesh.c +++ b/source/blender/editors/mesh/mesh_navmesh.c @@ -662,8 +662,10 @@ void MESH_OT_navmesh_face_add(struct wmOperatorType *ot) static int navmesh_obmode_data_poll(bContext *C) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Object *ob = ED_object_active_context(C); - if (ob && (ob->mode == OB_MODE_OBJECT) && (ob->type == OB_MESH)) { + if (ob && (eval_ctx.object_mode == OB_MODE_OBJECT) && (ob->type == OB_MESH)) { Mesh *me = ob->data; return CustomData_has_layer(&me->pdata, CD_RECAST); } @@ -672,8 +674,10 @@ static int navmesh_obmode_data_poll(bContext *C) static int navmesh_obmode_poll(bContext *C) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Object *ob = ED_object_active_context(C); - if (ob && (ob->mode == OB_MODE_OBJECT) && (ob->type == OB_MESH)) { + if (ob && (eval_ctx.object_mode == OB_MODE_OBJECT) && (ob->type == OB_MESH)) { return true; } return false; diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index dd1fbc36d8a..64b6f5b8010 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -42,6 +42,7 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_view3d_types.h" +#include "DNA_workspace_types.h" #include "BLI_math.h" #include "BLI_blenlib.h" @@ -222,9 +223,10 @@ static void join_mesh_single( multiresModifier_prepare_join(&eval_ctx, scene, ob_src, ob_dst); if ((mmd = get_multires_modifier(scene, ob_src, true))) { - ED_object_iter_other(bmain, ob_src, true, - ED_object_multires_update_totlevels_cb, - &mmd->totlvl); + ED_object_iter_other( + &eval_ctx, bmain, ob_src, true, + ED_object_multires_update_totlevels_cb, + &mmd->totlvl); } } @@ -274,6 +276,7 @@ static void join_mesh_single( int join_mesh_exec(bContext *C, wmOperator *op) { + const WorkSpace *workspace = CTX_wm_workspace(C); Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); @@ -293,7 +296,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) bDeformGroup *dg, *odg; CustomData vdata, edata, fdata, ldata, pdata; - if (scene->obedit) { + if (workspace->object_mode & OB_MODE_EDIT) { BKE_report(op->reports, RPT_WARNING, "Cannot join while in edit mode"); return OPERATOR_CANCELLED; } @@ -777,15 +780,16 @@ static MirrTopoStore_t mesh_topo_store = {NULL, -1. - 1, -1}; /* mode is 's' start, or 'e' end, or 'u' use */ /* if end, ob can be NULL */ /* note, is supposed return -1 on error, which callers are currently checking for, but is not used so far */ -int ED_mesh_mirror_topo_table(Object *ob, DerivedMesh *dm, char mode) +int ED_mesh_mirror_topo_table( + Object *ob, DerivedMesh *dm, char mode) { if (mode == 'u') { /* use table */ - if (ED_mesh_mirrtopo_recalc_check(ob->data, dm, ob->mode, &mesh_topo_store)) { + if (ED_mesh_mirrtopo_recalc_check(ob->data, dm, &mesh_topo_store)) { ED_mesh_mirror_topo_table(ob, dm, 's'); } } else if (mode == 's') { /* start table */ - ED_mesh_mirrtopo_init(ob->data, dm, ob->mode, &mesh_topo_store, false); + ED_mesh_mirrtopo_init(ob->data, dm, &mesh_topo_store, false); } else if (mode == 'e') { /* end table */ ED_mesh_mirrtopo_free(&mesh_topo_store); @@ -1339,17 +1343,17 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int MDeformVert *ED_mesh_active_dvert_get_em(Object *ob, BMVert **r_eve) { - if (ob->mode & OB_MODE_EDIT && ob->type == OB_MESH && ob->defbase.first) { + if (ob->type == OB_MESH && ob->defbase.first) { Mesh *me = ob->data; - BMesh *bm = me->edit_btmesh->bm; - const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT); - - if (cd_dvert_offset != -1) { - BMVert *eve = BM_mesh_active_vert_get(bm); - - if (eve) { - if (r_eve) *r_eve = eve; - return BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); + if (me->edit_btmesh != NULL) { + BMesh *bm = me->edit_btmesh->bm; + const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT); + if (cd_dvert_offset != -1) { + BMVert *eve = BM_mesh_active_vert_get(bm); + if (eve) { + if (r_eve) *r_eve = eve; + return BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); + } } } } @@ -1374,7 +1378,8 @@ MDeformVert *ED_mesh_active_dvert_get_ob(Object *ob, int *r_index) MDeformVert *ED_mesh_active_dvert_get_only(Object *ob) { if (ob->type == OB_MESH) { - if (ob->mode & OB_MODE_EDIT) { + Mesh *me = ob->data; + if (me->edit_btmesh != NULL) { return ED_mesh_active_dvert_get_em(ob, NULL); } else { diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 5c96c13ebed..c4bad6f76c9 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -42,8 +42,8 @@ #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meta_types.h" -#include "DNA_object_fluidsim.h" -#include "DNA_object_force.h" +#include "DNA_object_fluidsim_types.h" +#include "DNA_object_force_types.h" #include "DNA_object_types.h" #include "DNA_lightprobe_types.h" #include "DNA_scene_types.h" @@ -1673,7 +1673,7 @@ static int convert_poll(bContext *C) Base *base_act = CTX_data_active_base(C); Object *obact = base_act ? base_act->object : NULL; - return (!ID_IS_LINKED(scene) && obact && scene->obedit != obact && + return (!ID_IS_LINKED(scene) && obact && (BKE_object_is_in_editmode(obact) == false) && (base_act->flag & BASE_SELECTED) && !ID_IS_LINKED(obact)); } @@ -2081,7 +2081,9 @@ void OBJECT_OT_convert(wmOperatorType *ot) /* used below, assumes id.new is correct */ /* leaves selection of base/object unaltered */ /* Does set ID->newid pointers. */ -static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, ViewLayer *view_layer, Object *ob, int dupflag) +static Base *object_add_duplicate_internal( + Main *bmain, Scene *scene, + ViewLayer *view_layer, Object *ob, int dupflag) { #define ID_NEW_REMAP_US(a) if ( (a)->id.newid) { (a) = (void *)(a)->id.newid; (a)->id.us++; } #define ID_NEW_REMAP_US2(a) if (((ID *)a)->newid) { (a) = ((ID *)a)->newid; ((ID *)a)->us++; } @@ -2092,10 +2094,14 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, ViewLayer ID *id; int a, didit; - if (ob->mode & OB_MODE_POSE) { + /* ignore pose mode now, Caller can inspect mode. */ +#if 0 + if (eval_ctx->object_mode & OB_MODE_POSE) { ; /* nothing? */ } - else { + else +#endif + { obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob)); DEG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); @@ -2523,10 +2529,10 @@ static int join_poll(bContext *C) static int join_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = CTX_data_active_object(C); - if (scene->obedit) { + if (workspace->object_mode & OB_MODE_EDIT) { BKE_report(op->reports, RPT_ERROR, "This data does not support joining in edit mode"); return OPERATOR_CANCELLED; } @@ -2577,10 +2583,10 @@ static int join_shapes_poll(bContext *C) static int join_shapes_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = CTX_data_active_object(C); - if (scene->obedit) { + if (workspace->object_mode & OB_MODE_EDIT) { BKE_report(op->reports, RPT_ERROR, "This data does not support joining in edit mode"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 3efb6253f6f..a13df441c5f 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -206,7 +206,8 @@ static bool multiresbake_check(bContext *C, wmOperator *op) return ok; } -static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *lvl) +static DerivedMesh *multiresbake_create_loresdm( + Scene *scene, Object *ob, eObjectMode object_mode, int *lvl) { DerivedMesh *dm; MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); @@ -226,13 +227,15 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l tmp_mmd.lvl = *lvl; tmp_mmd.sculptlvl = *lvl; - dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0); + dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0, object_mode); cddm->release(cddm); return dm; } -static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *lvl, bool *simple) +static DerivedMesh *multiresbake_create_hiresdm( + Scene *scene, Object *ob, eObjectMode object_mode, + int *lvl, bool *simple) { Mesh *me = (Mesh *)ob->data; MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); @@ -253,7 +256,7 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l tmp_mmd.lvl = mmd->totlvl; tmp_mmd.sculptlvl = mmd->totlvl; - dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0); + dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0, object_mode); cddm->release(cddm); return dm; @@ -317,6 +320,7 @@ static void clear_images_poly(Image **ob_image_array, int ob_image_array_len, Cl static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) { Object *ob; + const WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene = CTX_data_scene(C); int objects_baked = 0; @@ -371,8 +375,8 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) bkr.ob_image.array = BKE_object_material_edit_image_get_array(ob); bkr.ob_image.len = ob->totcol; - bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple); - bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl); + bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, workspace->object_mode, &bkr.tot_lvl, &bkr.simple); + bkr.lores_dm = multiresbake_create_loresdm(scene, ob, workspace->object_mode, &bkr.lvl); RE_multires_bake_images(&bkr); @@ -396,6 +400,7 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) /* Multiresbake adopted for job-system executing */ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj) { + const WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene = CTX_data_scene(C); Object *ob; @@ -427,8 +432,8 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj) data->ob_image.len = ob->totcol; /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ - data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple); - data->lores_dm = multiresbake_create_loresdm(scene, ob, &lvl); + data->hires_dm = multiresbake_create_hiresdm(scene, ob, workspace->object_mode, &data->tot_lvl, &data->simple); + data->lores_dm = multiresbake_create_loresdm(scene, ob, workspace->object_mode, &lvl); data->lvl = lvl; BLI_addtail(&bkj->data, data); @@ -861,9 +866,9 @@ static int bake_image_exec(bContext *C, wmOperator *op) RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT(view_layer) : NULL); /* baking itself is threaded, cannot use test_break in threads */ - BLI_init_threads(&threads, do_bake_render, 1); + BLI_threadpool_init(&threads, do_bake_render, 1); bkr.ready = 0; - BLI_insert_thread(&threads, &bkr); + BLI_threadpool_insert(&threads, &bkr); while (bkr.ready == 0) { PIL_sleep_ms(50); @@ -874,7 +879,7 @@ static int bake_image_exec(bContext *C, wmOperator *op) if (!G.background) BKE_blender_test_break(); } - BLI_end_threads(&threads); + BLI_threadpool_end(&threads); if (bkr.result == BAKE_RESULT_NO_OBJECTS) BKE_report(op->reports, RPT_ERROR, "No valid images found to bake to"); diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index 0174a307c16..c8bcc9224e9 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -623,8 +623,7 @@ static size_t initialize_internal_images(BakeImages *bake_images, ReportList *re /* create new mesh with edit mode changes and modifiers applied */ static Mesh *bake_mesh_new_from_object(EvaluationContext *eval_ctx, Main *bmain, Scene *scene, Object *ob) { - if (ob->mode & OB_MODE_EDIT) - ED_object_editmode_load(ob); + ED_object_editmode_load(ob); Mesh *me = BKE_mesh_new_from_object(eval_ctx, bmain, scene, ob, 1, 2, 0, 0); if (me->flag & ME_AUTOSMOOTH) { @@ -852,7 +851,7 @@ static int bake( /* triangulating so BVH returns the primitive_id that will be used for rendering */ highpoly[i].tri_mod = ED_object_modifier_add( - reports, bmain, scene, highpoly[i].ob, + reports, bmain, scene, highpoly[i].ob, OB_MODE_OBJECT, "TmpTriangulate", eModifierType_Triangulate); tmd = (TriangulateModifierData *)highpoly[i].tri_mod; tmd->quad_method = MOD_TRIANGULATE_QUAD_FIXED; diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 05a5f652382..1b462e92ca4 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -87,12 +87,12 @@ /* -------------- Get Active Constraint Data ---------------------- */ /* if object in posemode, active bone constraints, else object constraints */ -ListBase *get_active_constraints(Object *ob) +ListBase *get_active_constraints(const EvaluationContext *eval_ctx, Object *ob) { if (ob == NULL) return NULL; - if (ob->mode & OB_MODE_POSE) { + if (eval_ctx->object_mode & OB_MODE_POSE) { bPoseChannel *pchan; pchan = BKE_pose_channel_active(ob); @@ -142,9 +142,9 @@ ListBase *get_constraint_lb(Object *ob, bConstraint *con, bPoseChannel **r_pchan } /* single constraint */ -bConstraint *get_active_constraint(Object *ob) +bConstraint *get_active_constraint(const EvaluationContext *eval_ctx, Object *ob) { - return BKE_constraints_active_get(get_active_constraints(ob)); + return BKE_constraints_active_get(get_active_constraints(eval_ctx, ob)); } /* -------------- Constraint Management (Add New, Remove, Rename) -------------------- */ @@ -639,7 +639,8 @@ static int edit_constraint_invoke_properties(bContext *C, wmOperator *op) return 0; } -static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int type) +static bConstraint *edit_constraint_property_get( + const EvaluationContext *eval_ctx, wmOperator *op, Object *ob, int type) { char constraint_name[MAX_NAME]; int owner = RNA_enum_get(op->ptr, "owner"); @@ -664,7 +665,7 @@ static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int else { //if (G.debug & G_DEBUG) //printf("edit_constraint_property_get: defaulting to getting list in the standard way\n"); - list = get_active_constraints(ob); + list = get_active_constraints(eval_ctx, ob); } con = BKE_constraints_find_name(list, constraint_name); @@ -684,8 +685,10 @@ static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int static int stretchto_reset_exec(bContext *C, wmOperator *op) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_STRETCHTO); + bConstraint *con = edit_constraint_property_get(&eval_ctx, op, ob, CONSTRAINT_TYPE_STRETCHTO); bStretchToConstraint *data = (con) ? (bStretchToConstraint *)con->data : NULL; /* despite 3 layers of checks, we may still not be able to find a constraint */ @@ -730,8 +733,10 @@ void CONSTRAINT_OT_stretchto_reset(wmOperatorType *ot) static int limitdistance_reset_exec(bContext *C, wmOperator *op) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_DISTLIMIT); + bConstraint *con = edit_constraint_property_get(&eval_ctx, op, ob, CONSTRAINT_TYPE_DISTLIMIT); bDistLimitConstraint *data = (con) ? (bDistLimitConstraint *)con->data : NULL; /* despite 3 layers of checks, we may still not be able to find a constraint */ @@ -866,9 +871,11 @@ static void child_get_inverse_matrix(const bContext *C, Scene *scene, Object *ob /* ChildOf Constraint - set inverse callback */ static int childof_set_inverse_exec(bContext *C, wmOperator *op) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Scene *scene = CTX_data_scene(C); Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_CHILDOF); + bConstraint *con = edit_constraint_property_get(&eval_ctx, op, ob, CONSTRAINT_TYPE_CHILDOF); bChildOfConstraint *data = (con) ? (bChildOfConstraint *)con->data : NULL; const int owner = RNA_enum_get(op->ptr, "owner"); @@ -917,7 +924,9 @@ void CONSTRAINT_OT_childof_set_inverse(wmOperatorType *ot) static int childof_clear_inverse_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_CHILDOF); + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + bConstraint *con = edit_constraint_property_get(&eval_ctx, op, ob, CONSTRAINT_TYPE_CHILDOF); bChildOfConstraint *data = (con) ? (bChildOfConstraint *)con->data : NULL; if (data == NULL) { @@ -964,8 +973,10 @@ void CONSTRAINT_OT_childof_clear_inverse(wmOperatorType *ot) static int followpath_path_animate_exec(bContext *C, wmOperator *op) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_FOLLOWPATH); + bConstraint *con = edit_constraint_property_get(&eval_ctx, op, ob, CONSTRAINT_TYPE_FOLLOWPATH); bFollowPathConstraint *data = (con) ? (bFollowPathConstraint *)con->data : NULL; bAction *act = NULL; @@ -1088,9 +1099,11 @@ void CONSTRAINT_OT_followpath_path_animate(wmOperatorType *ot) static int objectsolver_set_inverse_exec(bContext *C, wmOperator *op) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Scene *scene = CTX_data_scene(C); Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_OBJECTSOLVER); + bConstraint *con = edit_constraint_property_get(&eval_ctx, op, ob, CONSTRAINT_TYPE_OBJECTSOLVER); bObjectSolverConstraint *data = (con) ? (bObjectSolverConstraint *)con->data : NULL; const int owner = RNA_enum_get(op->ptr, "owner"); @@ -1137,8 +1150,10 @@ void CONSTRAINT_OT_objectsolver_set_inverse(wmOperatorType *ot) static int objectsolver_clear_inverse_exec(bContext *C, wmOperator *op) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_OBJECTSOLVER); + bConstraint *con = edit_constraint_property_get(&eval_ctx, op, ob, CONSTRAINT_TYPE_OBJECTSOLVER); bObjectSolverConstraint *data = (con) ? (bObjectSolverConstraint *)con->data : NULL; if (data == NULL) { @@ -1306,8 +1321,10 @@ void CONSTRAINT_OT_delete(wmOperatorType *ot) static int constraint_move_down_exec(bContext *C, wmOperator *op) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, 0); + bConstraint *con = edit_constraint_property_get(&eval_ctx, op, ob, 0); if (con && con->next) { ListBase *conlist = get_constraint_lb(ob, con, NULL); @@ -1355,8 +1372,10 @@ void CONSTRAINT_OT_move_down(wmOperatorType *ot) static int constraint_move_up_exec(bContext *C, wmOperator *op) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Object *ob = ED_object_active_context(C); - bConstraint *con = edit_constraint_property_get(op, ob, 0); + bConstraint *con = edit_constraint_property_get(&eval_ctx, op, ob, 0); if (con && con->prev) { ListBase *conlist = get_constraint_lb(ob, con, NULL); @@ -1575,6 +1594,8 @@ void OBJECT_OT_constraints_copy(wmOperatorType *ot) /* get the Object and/or PoseChannel to use as target */ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob, bPoseChannel **tar_pchan, bool add) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Object *obact = ED_object_active_context(C); bPoseChannel *pchanact = BKE_pose_channel_active(obact); bool only_curve = false, only_mesh = false, only_ob = false; @@ -1653,7 +1674,7 @@ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob /* for armatures in pose mode, look inside the armature for the active bone * so that we set up cross-armature constraints with less effort */ - if ((ob->type == OB_ARMATURE) && (ob->mode & OB_MODE_POSE) && + if ((ob->type == OB_ARMATURE) && (eval_ctx.mode & OB_MODE_POSE) && (!only_curve && !only_mesh)) { /* just use the active bone, and assume that it is visible + usable */ @@ -1871,6 +1892,8 @@ static int object_constraint_add_exec(bContext *C, wmOperator *op) /* dummy operator callback */ static int pose_constraint_add_exec(bContext *C, wmOperator *op) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Object *ob = BKE_object_pose_armature_get(ED_object_active_context(C)); int type = RNA_enum_get(op->ptr, "type"); short with_targets = 0; @@ -1886,7 +1909,7 @@ static int pose_constraint_add_exec(bContext *C, wmOperator *op) if (strstr(op->idname, "with_targets")) with_targets = 1; - return constraint_add_exec(C, op, ob, get_active_constraints(ob), type, with_targets); + return constraint_add_exec(C, op, ob, get_active_constraints(&eval_ctx, ob), type, with_targets); } /* ------------------ */ @@ -2027,11 +2050,13 @@ static int pose_ik_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED /* call constraint_add_exec() to add the IK constraint */ static int pose_ik_add_exec(bContext *C, wmOperator *op) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Object *ob = CTX_data_active_object(C); const bool with_targets = RNA_boolean_get(op->ptr, "with_targets"); /* add the constraint - all necessary checks should have been done by the invoke() callback already... */ - return constraint_add_exec(C, op, ob, get_active_constraints(ob), CONSTRAINT_TYPE_KINEMATIC, with_targets); + return constraint_add_exec(C, op, ob, get_active_constraints(&eval_ctx, ob), CONSTRAINT_TYPE_KINEMATIC, with_targets); } void POSE_OT_ik_add(wmOperatorType *ot) diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 5697c48d381..c6f9ced51a3 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -54,10 +54,11 @@ #include "DNA_property_types.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_meshdata_types.h" #include "DNA_vfont_types.h" #include "DNA_mesh_types.h" +#include "DNA_lattice_types.h" #include "DNA_workspace_types.h" #include "IMB_imbuf_types.h" @@ -83,6 +84,7 @@ #include "BKE_modifier.h" #include "BKE_editmesh.h" #include "BKE_report.h" +#include "BKE_object.h" #include "BKE_workspace.h" #include "DEG_depsgraph.h" @@ -171,6 +173,9 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f if (obedit->type == OB_MESH) { Mesh *me = obedit->data; + if (me->edit_btmesh == NULL) { + return false; + } if (me->edit_btmesh->bm->totvert > MESH_MAX_VERTS) { error("Too many vertices"); @@ -184,15 +189,21 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f MEM_freeN(me->edit_btmesh); me->edit_btmesh = NULL; } - if (obedit->restore_mode & OB_MODE_WEIGHT_PAINT) { + /* will be recalculated as needed. */ + { ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e'); ED_mesh_mirror_topo_table(NULL, NULL, 'e'); } } else if (obedit->type == OB_ARMATURE) { + const bArmature *arm = obedit->data; + if (arm->edbo == NULL) { + return false; + } ED_armature_from_edit(obedit->data); - if (freedata) + if (freedata) { ED_armature_edit_free(obedit->data); + } /* TODO(sergey): Pose channels might have been changed, so need * to inform dependency graph about this. But is it really the * best place to do this? @@ -200,27 +211,46 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f DEG_relations_tag_update(bmain); } else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { + const Curve *cu = obedit->data; + if (cu->editnurb == NULL) { + return false; + } ED_curve_editnurb_load(obedit); - if (freedata) ED_curve_editnurb_free(obedit); + if (freedata) { + ED_curve_editnurb_free(obedit); + } } else if (obedit->type == OB_FONT) { + const Curve *cu = obedit->data; + if (cu->editfont == NULL) { + return false; + } ED_curve_editfont_load(obedit); - if (freedata) ED_curve_editfont_free(obedit); + if (freedata) { + ED_curve_editfont_free(obedit); + } } else if (obedit->type == OB_LATTICE) { + const Lattice *lt = obedit->data; + if (lt->editlatt == NULL) { + return false; + } ED_lattice_editlatt_load(obedit); - if (freedata) ED_lattice_editlatt_free(obedit); + if (freedata) { + ED_lattice_editlatt_free(obedit); + } } else if (obedit->type == OB_MBALL) { + const MetaBall *mb = obedit->data; + if (mb->editelems == NULL) { + return false; + } ED_mball_editmball_load(obedit); - if (freedata) ED_mball_editmball_free(obedit); + if (freedata) { + ED_mball_editmball_free(obedit); + } } - /* Tag update so no access to freed data referenced from - * derived cache will happen. - */ - DEG_id_tag_update((ID *)obedit->data, 0); - return true; } @@ -230,23 +260,23 @@ bool ED_object_editmode_load(Object *obedit) return ED_object_editmode_load_ex(G.main, obedit, false); } -void ED_object_editmode_exit(bContext *C, int flag) +/** + * \param C: Can be NULL, only if #EM_DO_UNDO isn't set. + * \param flag: + * - Only in exceptional cases should #EM_DO_UNDO NOT be in the flag. + * - If #EM_FREEDATA isn't in the flag, use ED_object_editmode_load directly. + */ +void ED_object_editmode_exit_ex(bContext *C, WorkSpace *workspace, Scene *scene, Object *obedit, int flag) { - /* Note! only in exceptional cases should 'EM_DO_UNDO' NOT be in the flag */ - /* Note! if 'EM_FREEDATA' isn't in the flag, use ED_object_editmode_load directly */ - Scene *scene = CTX_data_scene(C); - ViewLayer *view_layer = CTX_data_view_layer(C); - Object *obedit = CTX_data_edit_object(C); + BLI_assert(C || !(flag & EM_DO_UNDO)); const bool freedata = (flag & EM_FREEDATA) != 0; if (flag & EM_WAITCURSOR) waitcursor(1); - if (ED_object_editmode_load_ex(CTX_data_main(C), obedit, freedata) == false) { + if (ED_object_editmode_load_ex(G.main, obedit, freedata) == false) { /* in rare cases (background mode) its possible active object * is flagged for editmode, without 'obedit' being set [#35489] */ - if (UNLIKELY(view_layer->basact && (view_layer->basact->object->mode & OB_MODE_EDIT))) { - view_layer->basact->object->mode &= ~OB_MODE_EDIT; - } + workspace->object_mode &= ~OB_MODE_EDIT; if (flag & EM_WAITCURSOR) waitcursor(0); return; } @@ -256,9 +286,6 @@ void ED_object_editmode_exit(bContext *C, int flag) ListBase pidlist; PTCacheID *pid; - /* for example; displist make is different in editmode */ - scene->obedit = NULL; // XXX for context - /* flag object caches as outdated */ BKE_ptcache_ids_from_object(&pidlist, obedit, scene, 0); for (pid = pidlist.first; pid; pid = pid->next) { @@ -275,9 +302,14 @@ void ED_object_editmode_exit(bContext *C, int flag) if (flag & EM_DO_UNDO) ED_undo_push(C, "Editmode"); - WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, scene); + if (C != NULL) { + WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, scene); + } + else { + WM_main_add_notifier(NC_SCENE | ND_MODE | NS_MODE_OBJECT, scene); + } - obedit->mode &= ~OB_MODE_EDIT; + workspace->object_mode &= ~OB_MODE_EDIT; } if (flag & EM_WAITCURSOR) waitcursor(0); @@ -286,9 +318,17 @@ void ED_object_editmode_exit(bContext *C, int flag) DEG_id_tag_update(&scene->id, 0); } +void ED_object_editmode_exit(bContext *C, int flag) +{ + WorkSpace *workspace = CTX_wm_workspace(C); + Scene *scene = CTX_data_scene(C); + Object *obedit = CTX_data_edit_object(C); + ED_object_editmode_exit_ex(C, workspace, scene, obedit, flag); +} void ED_object_editmode_enter(bContext *C, int flag) { + WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob; @@ -318,20 +358,18 @@ void ED_object_editmode_enter(bContext *C, int flag) if (flag & EM_WAITCURSOR) waitcursor(1); - ob->restore_mode = ob->mode; + workspace->object_mode_restore = workspace->object_mode; /* note, when switching scenes the object can have editmode data but * not be scene->obedit: bug 22954, this avoids calling self eternally */ - if ((ob->restore_mode & OB_MODE_EDIT) == 0) - ED_object_toggle_modes(C, ob->mode); + if ((workspace->object_mode_restore & OB_MODE_EDIT) == 0) + ED_object_toggle_modes(C, workspace->object_mode); - ob->mode = OB_MODE_EDIT; + workspace->object_mode = OB_MODE_EDIT; if (ob->type == OB_MESH) { BMEditMesh *em; ok = 1; - scene->obedit = ob; /* context sees this */ - const bool use_key_index = mesh_needs_keyindex(ob->data); EDBM_mesh_make(scene->toolsettings, ob, use_key_index); @@ -361,7 +399,6 @@ void ED_object_editmode_enter(bContext *C, int flag) return; } ok = 1; - scene->obedit = ob; ED_armature_to_edit(arm); /* to ensure all goes in restposition and without striding */ DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); /* XXX: should this be OB_RECALC_DATA? */ @@ -369,21 +406,18 @@ void ED_object_editmode_enter(bContext *C, int flag) WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_ARMATURE, scene); } else if (ob->type == OB_FONT) { - scene->obedit = ob; /* XXX for context */ ok = 1; ED_curve_editfont_make(ob); WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_TEXT, scene); } else if (ob->type == OB_MBALL) { - scene->obedit = ob; /* XXX for context */ ok = 1; ED_mball_editmball_make(ob); WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_MBALL, scene); } else if (ob->type == OB_LATTICE) { - scene->obedit = ob; /* XXX for context */ ok = 1; ED_lattice_editlatt_make(ob); @@ -391,7 +425,6 @@ void ED_object_editmode_enter(bContext *C, int flag) } else if (ob->type == OB_SURF || ob->type == OB_CURVE) { ok = 1; - scene->obedit = ob; /* XXX for context */ ED_curve_editnurb_make(ob); WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_CURVE, scene); @@ -403,8 +436,7 @@ void ED_object_editmode_enter(bContext *C, int flag) DEG_id_tag_update(&scene->id, 0); } else { - scene->obedit = NULL; /* XXX for context */ - ob->mode &= ~OB_MODE_EDIT; + workspace->object_mode &= ~OB_MODE_EDIT; WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, scene); } @@ -414,13 +446,13 @@ void ED_object_editmode_enter(bContext *C, int flag) static int editmode_toggle_exec(bContext *C, wmOperator *op) { + WorkSpace *workspace = CTX_wm_workspace(C); const int mode_flag = OB_MODE_EDIT; const bool is_mode_set = (CTX_data_edit_object(C) != NULL); Scene *scene = CTX_data_scene(C); if (!is_mode_set) { - Object *ob = CTX_data_active_object(C); - if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) { + if (!ED_object_mode_compat_set(C, workspace, mode_flag, op->reports)) { return OPERATOR_CANCELLED; } } @@ -443,9 +475,12 @@ static int editmode_toggle_poll(bContext *C) if (ELEM(NULL, ob, ob->data) || ID_IS_LINKED(ob->data)) return 0; + const WorkSpace *workspace = CTX_wm_workspace(C); + /* if hidden but in edit mode, we still display */ - if ((ob->restrictflag & OB_RESTRICT_VIEW) && !(ob->mode & OB_MODE_EDIT)) + if ((ob->restrictflag & OB_RESTRICT_VIEW) && !(workspace->object_mode & OB_MODE_EDIT)) { return 0; + } return OB_TYPE_SUPPORT_EDITMODE(ob->type); } @@ -470,13 +505,14 @@ void OBJECT_OT_editmode_toggle(wmOperatorType *ot) static int posemode_exec(bContext *C, wmOperator *op) { + WorkSpace *workspace = CTX_wm_workspace(C); Base *base = CTX_data_active_base(C); Object *ob = base->object; const int mode_flag = OB_MODE_POSE; - const bool is_mode_set = (ob->mode & mode_flag) != 0; - + const bool is_mode_set = (workspace->object_mode & mode_flag) != 0; + if (!is_mode_set) { - if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) { + if (!ED_object_mode_compat_set(C, workspace, mode_flag, op->reports)) { return OPERATOR_CANCELLED; } } @@ -671,7 +707,7 @@ static void copy_attr(Main *bmain, Scene *scene, ViewLayer *view_layer, short ev if (!(ob = OBACT(view_layer))) return; - if (scene->obedit) { // XXX get from context + if (BKE_object_is_in_editmode(ob)) { /* obedit_copymenu(); */ return; } @@ -910,7 +946,7 @@ static void copy_attr(Main *bmain, Scene *scene, ViewLayer *view_layer, short ev DEG_relations_tag_update(bmain); } -static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, ViewLayer *view_layer) +static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, ViewLayer *view_layer, Object *obedit) { Object *ob; short event; @@ -918,7 +954,7 @@ static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, ViewLaye if (!(ob = OBACT(view_layer))) return; - if (scene->obedit) { /* XXX get from context */ + if (obedit) { /* if (ob->type == OB_MESH) */ /* XXX mesh_copy_menu(); */ return; @@ -969,7 +1005,7 @@ static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, ViewLaye /* ******************* force field toggle operator ***************** */ -void ED_object_check_force_modifiers(Main *bmain, Scene *scene, Object *object) +void ED_object_check_force_modifiers(Main *bmain, Scene *scene, Object *object, eObjectMode object_mode) { PartDeflect *pd = object->pd; ModifierData *md = modifiers_findByType(object, eModifierType_Surface); @@ -978,7 +1014,7 @@ void ED_object_check_force_modifiers(Main *bmain, Scene *scene, Object *object) if (!md) { if (pd && (pd->shape == PFIELD_SHAPE_SURFACE) && !ELEM(pd->forcefield, 0, PFIELD_GUIDE, PFIELD_TEXTURE)) { if (ELEM(object->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVE)) { - ED_object_modifier_add(NULL, bmain, scene, object, NULL, eModifierType_Surface); + ED_object_modifier_add(NULL, bmain, scene, object, object_mode, NULL, eModifierType_Surface); } } } @@ -999,8 +1035,9 @@ static int forcefield_toggle_exec(bContext *C, wmOperator *UNUSED(op)) ob->pd->forcefield = PFIELD_FORCE; else ob->pd->forcefield = 0; - - ED_object_check_force_modifiers(CTX_data_main(C), CTX_data_scene(C), ob); + + const WorkSpace *workspace = CTX_wm_workspace(C); + ED_object_check_force_modifiers(CTX_data_main(C), CTX_data_scene(C), ob, workspace->object_mode); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); @@ -1334,7 +1371,7 @@ void OBJECT_OT_shade_smooth(wmOperatorType *ot) /* ********************** */ -static void UNUSED_FUNCTION(image_aspect) (Scene *scene, ViewLayer *view_layer) +static void UNUSED_FUNCTION(image_aspect) (Scene *scene, ViewLayer *view_layer, Object *obedit) { /* all selected objects with an image map: scale in image aspect */ Base *base; @@ -1344,7 +1381,7 @@ static void UNUSED_FUNCTION(image_aspect) (Scene *scene, ViewLayer *view_layer) float x, y, space; int a, b, done; - if (scene->obedit) return; // XXX get from context + if (obedit) return; if (ID_IS_LINKED(scene)) return; for (base = FIRSTBASE(view_layer); base; base = base->next) { @@ -1446,7 +1483,7 @@ static const EnumPropertyItem *object_mode_set_itemsf( return item; } -static const char *object_mode_op_string(int mode) +static const char *object_mode_op_string(eObjectMode mode) { if (mode & OB_MODE_EDIT) return "OBJECT_OT_editmode_toggle"; @@ -1512,18 +1549,14 @@ static bool object_mode_compat_test(Object *ob, eObjectMode mode) * * This is so each mode's exec function can call */ -bool ED_object_mode_compat_set(bContext *C, Object *ob, int mode, ReportList *reports) +bool ED_object_mode_compat_set(bContext *C, WorkSpace *workspace, eObjectMode mode, ReportList *reports) { bool ok; - if (!ELEM(ob->mode, mode, OB_MODE_OBJECT)) { - const char *opstring = object_mode_op_string(ob->mode); + if (!ELEM(workspace->object_mode, mode, OB_MODE_OBJECT)) { + const char *opstring = object_mode_op_string(workspace->object_mode); WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, NULL); -#ifdef USE_WORKSPACE_MODE - BKE_workspace_object_mode_set(CTX_wm_workspace(C), CTX_data_scene(C), ob->mode); -#endif - - ok = ELEM(ob->mode, mode, OB_MODE_OBJECT); + ok = ELEM(workspace->object_mode, mode, OB_MODE_OBJECT); if (!ok) { wmOperatorType *ot = WM_operatortype_find(opstring, false); BKE_reportf(reports, RPT_ERROR, "Unable to execute '%s', error changing modes", ot->name); @@ -1551,10 +1584,11 @@ static int object_mode_set_poll(bContext *C) static int object_mode_set_exec(bContext *C, wmOperator *op) { + WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = CTX_data_active_object(C); bGPdata *gpd = CTX_data_gpencil_data(C); eObjectMode mode = RNA_enum_get(op->ptr, "mode"); - eObjectMode restore_mode = (ob) ? ob->mode : OB_MODE_OBJECT; + eObjectMode restore_mode = workspace->object_mode; const bool toggle = RNA_boolean_get(op->ptr, "toggle"); if (gpd) { @@ -1578,28 +1612,31 @@ static int object_mode_set_exec(bContext *C, wmOperator *op) if (!ob || !object_mode_compat_test(ob, mode)) return OPERATOR_PASS_THROUGH; - if (ob->mode != mode) { + if (workspace->object_mode != mode) { /* we should be able to remove this call, each operator calls */ - ED_object_mode_compat_set(C, ob, mode, op->reports); + ED_object_mode_compat_set(C, workspace, mode, op->reports); } /* Exit current mode if it's not the mode we're setting */ - if (mode != OB_MODE_OBJECT && (ob->mode != mode || toggle)) { + if (mode != OB_MODE_OBJECT && (workspace->object_mode != mode || toggle)) { /* Enter new mode */ ED_object_toggle_modes(C, mode); } if (toggle) { /* Special case for Object mode! */ - if (mode == OB_MODE_OBJECT && restore_mode == OB_MODE_OBJECT && ob->restore_mode != OB_MODE_OBJECT) { - ED_object_toggle_modes(C, ob->restore_mode); + if ((mode == OB_MODE_OBJECT) && + (restore_mode == OB_MODE_OBJECT) && + (workspace->object_mode_restore != OB_MODE_OBJECT)) + { + ED_object_toggle_modes(C, workspace->object_mode_restore); } - else if (ob->mode == mode) { + else if (workspace->object_mode == mode) { /* For toggling, store old mode so we know what to go back to */ - ob->restore_mode = restore_mode; + workspace->object_mode_restore = restore_mode; } - else if (ob->restore_mode != OB_MODE_OBJECT && ob->restore_mode != mode) { - ED_object_toggle_modes(C, ob->restore_mode); + else if (!ELEM(workspace->object_mode_restore, mode, OB_MODE_OBJECT)) { + ED_object_toggle_modes(C, workspace->object_mode_restore); } } @@ -1631,24 +1668,13 @@ void OBJECT_OT_mode_set(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } - -void ED_object_toggle_modes(bContext *C, int mode) +void ED_object_toggle_modes(bContext *C, eObjectMode mode) { if (mode != OB_MODE_OBJECT) { const char *opstring = object_mode_op_string(mode); if (opstring) { -#ifdef USE_WORKSPACE_MODE - WorkSpace *workspace = CTX_wm_workspace(C); -#endif WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, NULL); - -#ifdef USE_WORKSPACE_MODE - Object *ob = CTX_data_active_object(C); - if (ob) { - BKE_workspace_object_mode_set(workspace, CTX_data_scene(C), ob->mode); - } -#endif } } } diff --git a/source/blender/editors/object/object_facemap_ops.c b/source/blender/editors/object/object_facemap_ops.c index 857446ac6b0..c865b45889a 100644 --- a/source/blender/editors/object/object_facemap_ops.c +++ b/source/blender/editors/object/object_facemap_ops.c @@ -35,6 +35,7 @@ #include "DNA_object_types.h" #include "DNA_mesh_types.h" +#include "DNA_workspace_types.h" #include "BKE_context.h" #include "BKE_customdata.h" @@ -173,7 +174,13 @@ static int face_map_supported_edit_mode_poll(bContext *C) { Object *ob = ED_object_context(C); ID *data = (ob) ? ob->data : NULL; - return (ob && !ob->id.lib && ob->type == OB_MESH && data && !data->lib && ob->mode == OB_MODE_EDIT); + if (ob && !ob->id.lib && ob->type == OB_MESH && data && !data->lib) { + const WorkSpace *workspace = CTX_wm_workspace(C); + if (workspace->object_mode == OB_MODE_EDIT) { + return true; + } + } + return false; } static int face_map_add_exec(bContext *C, wmOperator *UNUSED(op)) diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index ca58a60806c..9d1792e9f16 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -40,7 +40,7 @@ #include "DNA_key_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_scene_types.h" #include "BLI_bitmap.h" @@ -95,7 +95,10 @@ static void modifier_skin_customdata_delete(struct Object *ob); /******************************** API ****************************/ -ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type) +ModifierData *ED_object_modifier_add( + ReportList *reports, + Main *bmain, Scene *scene, + Object *ob, eObjectMode object_mode, const char *name, int type) { ModifierData *md = NULL, *new_md = NULL; const ModifierTypeInfo *mti = modifierType_getInfo(type); @@ -162,7 +165,7 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc /* set totlvl from existing MDISPS layer if object already had it */ multiresModifier_set_levels_from_disps((MultiresModifierData *)new_md, ob); - if (ob->mode & OB_MODE_SCULPT) { + if (object_mode & OB_MODE_SCULPT) { /* ensure that grid paint mask layer is created */ BKE_sculpt_mask_layers_ensure(ob, (MultiresModifierData *)new_md); } @@ -202,9 +205,11 @@ static bool object_has_modifier(const Object *ob, const ModifierData *exclude, * If the callback ever returns true, iteration will stop and the * function value will be true. Otherwise the function returns false. */ -bool ED_object_iter_other(Main *bmain, Object *orig_ob, const bool include_orig, - bool (*callback)(Object *ob, void *callback_data), - void *callback_data) +bool ED_object_iter_other( + const EvaluationContext *eval_ctx, + Main *bmain, Object *orig_ob, const bool include_orig, + bool (*callback)(const EvaluationContext *eval_ctx, Object *ob, void *callback_data), + void *callback_data) { ID *ob_data_id = orig_ob->data; int users = ob_data_id->us; @@ -223,7 +228,7 @@ bool ED_object_iter_other(Main *bmain, Object *orig_ob, const bool include_orig, if (((ob != orig_ob) || include_orig) && (ob->data == orig_ob->data)) { - if (callback(ob, callback_data)) + if (callback(eval_ctx, ob, callback_data)) return true; totfound++; @@ -231,13 +236,15 @@ bool ED_object_iter_other(Main *bmain, Object *orig_ob, const bool include_orig, } } else if (include_orig) { - return callback(orig_ob, callback_data); + return callback(eval_ctx, orig_ob, callback_data); } return false; } -static bool object_has_modifier_cb(Object *ob, void *data) +static bool object_has_modifier_cb( + const EvaluationContext *UNUSED(eval_ctx), + Object *ob, void *data) { ModifierType type = *((ModifierType *)data); @@ -247,14 +254,16 @@ static bool object_has_modifier_cb(Object *ob, void *data) /* Use with ED_object_iter_other(). Sets the total number of levels * for any multires modifiers on the object to the int pointed to by * callback_data. */ -bool ED_object_multires_update_totlevels_cb(Object *ob, void *totlevel_v) +bool ED_object_multires_update_totlevels_cb( + const struct EvaluationContext *eval_ctx, + Object *ob, void *totlevel_v) { ModifierData *md; int totlevel = *((char *)totlevel_v); for (md = ob->modifiers.first; md; md = md->next) { if (md->type == eModifierType_Multires) { - multires_set_tot_level(ob, (MultiresModifierData *)md, totlevel); + multires_set_tot_level((MultiresModifierData *)md, totlevel, eval_ctx->object_mode); DEG_id_tag_update(&ob->id, OB_RECALC_DATA); } } @@ -267,7 +276,7 @@ static bool object_modifier_safe_to_delete(Main *bmain, Object *ob, ModifierType type) { return (!object_has_modifier(ob, exclude, type) && - !ED_object_iter_other(bmain, ob, false, + !ED_object_iter_other(NULL, bmain, ob, false, object_has_modifier_cb, &type)); } @@ -316,11 +325,13 @@ static bool object_modifier_remove(Main *bmain, Object *ob, ModifierData *md, modifier_skin_customdata_delete(ob); } +#if 0 /* not needed now modes are in workspace */ if (ELEM(md->type, eModifierType_Softbody, eModifierType_Cloth) && BLI_listbase_is_empty(&ob->particlesystem)) { ob->mode &= ~OB_MODE_PARTICLE_EDIT; } +#endif DEG_relations_tag_update(bmain); @@ -413,7 +424,9 @@ int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData * return 1; } -int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *scene, ViewLayer *view_layer, Object *ob, ModifierData *md) +int ED_object_modifier_convert( + ReportList *UNUSED(reports), Main *bmain, Scene *scene, + ViewLayer *view_layer, Object *UNUSED(ob), eObjectMode object_mode, ModifierData *md) { Object *obn; ParticleSystem *psys; @@ -427,7 +440,7 @@ int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene * int totpart = 0, totchild = 0; if (md->type != eModifierType_ParticleSystem) return 0; - if (ob && ob->mode & OB_MODE_PARTICLE_EDIT) return 0; + if (object_mode & OB_MODE_PARTICLE_EDIT) return 0; psys = ((ParticleSystemModifierData *)md)->psys; part = psys->part; @@ -677,9 +690,10 @@ static int modifier_apply_obdata(ReportList *reports, const bContext *C, Scene * int ED_object_modifier_apply(ReportList *reports, const bContext *C, Scene *scene, Object *ob, ModifierData *md, int mode) { + const WorkSpace *workspace = CTX_wm_workspace(C); int prev_mode; - if (scene->obedit) { + if (BKE_object_is_in_editmode(ob)) { BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in edit mode"); return 0; } @@ -687,7 +701,7 @@ int ED_object_modifier_apply(ReportList *reports, const bContext *C, Scene *scen BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data"); return 0; } - else if ((ob->mode & OB_MODE_SCULPT) && + else if ((workspace->object_mode & OB_MODE_SCULPT) && (find_multires_modifier_before(scene, md)) && (modifier_isSameTopology(md) == false)) { @@ -739,12 +753,13 @@ int ED_object_modifier_copy(ReportList *UNUSED(reports), Object *ob, ModifierDat static int modifier_add_exec(bContext *C, wmOperator *op) { + const WorkSpace *workspace = CTX_wm_workspace(C); Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Object *ob = ED_object_active_context(C); int type = RNA_enum_get(op->ptr, "type"); - if (!ED_object_modifier_add(op->reports, bmain, scene, ob, NULL, type)) + if (!ED_object_modifier_add(op->reports, bmain, scene, ob, workspace->object_mode, NULL, type)) return OPERATOR_CANCELLED; WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); @@ -881,11 +896,12 @@ ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type) static int modifier_remove_exec(bContext *C, wmOperator *op) { + const WorkSpace *workspace = CTX_wm_workspace(C); Main *bmain = CTX_data_main(C); ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob = ED_object_active_context(C); ModifierData *md = edit_modifier_property_get(op, ob, 0); - int mode_orig = ob->mode; + int mode_orig = workspace->object_mode; if (!md || !ED_object_modifier_remove(op->reports, bmain, ob, md)) return OPERATOR_CANCELLED; @@ -893,11 +909,13 @@ static int modifier_remove_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); /* if cloth/softbody was removed, particle mode could be cleared */ - if (mode_orig & OB_MODE_PARTICLE_EDIT) - if ((ob->mode & OB_MODE_PARTICLE_EDIT) == 0) - if (view_layer->basact && view_layer->basact->object == ob) + if (mode_orig & OB_MODE_PARTICLE_EDIT) { + if ((workspace->object_mode & OB_MODE_PARTICLE_EDIT) == 0) { + if (view_layer->basact && view_layer->basact->object == ob) { WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL); - + } + } + } return OPERATOR_FINISHED; } @@ -1056,14 +1074,16 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot) static int modifier_convert_exec(bContext *C, wmOperator *op) { + const WorkSpace *workspace = CTX_wm_workspace(C); Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob = ED_object_active_context(C); ModifierData *md = edit_modifier_property_get(op, ob, 0); - - if (!md || !ED_object_modifier_convert(op->reports, bmain, scene, view_layer, ob, md)) + + if (!md || !ED_object_modifier_convert(op->reports, bmain, scene, view_layer, ob, workspace->object_mode, md)) { return OPERATOR_CANCELLED; + } DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); @@ -1147,10 +1167,13 @@ static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op) if (!mmd) return OPERATOR_CANCELLED; - - multiresModifier_del_levels(mmd, ob, 1); - ED_object_iter_other(CTX_data_main(C), ob, true, + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + + multiresModifier_del_levels(mmd, ob, 1, eval_ctx.object_mode); + + ED_object_iter_other(&eval_ctx, CTX_data_main(C), ob, true, ED_object_multires_update_totlevels_cb, &mmd->totlvl); @@ -1191,17 +1214,20 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op) if (!mmd) return OPERATOR_CANCELLED; - - multiresModifier_subdivide(mmd, ob, 0, mmd->simple); - ED_object_iter_other(CTX_data_main(C), ob, true, - ED_object_multires_update_totlevels_cb, - &mmd->totlvl); + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + multiresModifier_subdivide(mmd, ob, 0, mmd->simple, eval_ctx.object_mode); + + ED_object_iter_other( + &eval_ctx, CTX_data_main(C), ob, true, + ED_object_multires_update_totlevels_cb, + &mmd->totlvl); DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); - if (ob->mode & OB_MODE_SCULPT) { + if (eval_ctx.mode & OB_MODE_SCULPT) { /* ensure that grid paint mask layer is created */ BKE_sculpt_mask_layers_ensure(ob, mmd); } @@ -1415,8 +1441,9 @@ static int multires_base_apply_exec(bContext *C, wmOperator *op) if (!mmd) return OPERATOR_CANCELLED; - - multiresModifier_base_apply(mmd, ob); + + const WorkSpace *workspace = CTX_wm_workspace(C); + multiresModifier_base_apply(mmd, ob, workspace->object_mode); DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 9c321f5cb79..ba3541b428a 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -47,6 +47,8 @@ #include "ED_screen.h" #include "ED_object.h" +#include "DEG_depsgraph.h" + #include "object_intern.h" @@ -290,8 +292,9 @@ void ED_operatormacros_object(void) static int object_mode_poll(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = CTX_data_active_object(C); - return (!ob || ob->mode == OB_MODE_OBJECT); + return (!ob || workspace->object_mode == OB_MODE_OBJECT); } void ED_keymap_object(wmKeyConfig *keyconf) diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index d73e3aabaf0..9e6a5778490 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -717,7 +717,8 @@ bool ED_object_parent_set(ReportList *reports, const bContext *C, Scene *scene, switch (partype) { case PAR_CURVE: /* curve deform */ if (modifiers_isDeformedByCurve(ob) != par) { - md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Curve); + md = ED_object_modifier_add( + reports, bmain, scene, ob, eval_ctx.object_mode, NULL, eModifierType_Curve); if (md) { ((CurveModifierData *)md)->object = par; } @@ -728,7 +729,8 @@ bool ED_object_parent_set(ReportList *reports, const bContext *C, Scene *scene, break; case PAR_LATTICE: /* lattice deform */ if (modifiers_isDeformedByLattice(ob) != par) { - md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Lattice); + md = ED_object_modifier_add( + reports, bmain, scene, ob, eval_ctx.object_mode, NULL, eModifierType_Lattice); if (md) { ((LatticeModifierData *)md)->object = par; } @@ -736,7 +738,8 @@ bool ED_object_parent_set(ReportList *reports, const bContext *C, Scene *scene, break; default: /* armature deform */ if (modifiers_isDeformedByArmature(ob) != par) { - md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Armature); + md = ED_object_modifier_add( + reports, bmain, scene, ob, eval_ctx.object_mode, NULL, eModifierType_Armature); if (md) { ((ArmatureModifierData *)md)->object = par; } @@ -1425,6 +1428,7 @@ static bool allow_make_links_data(const int type, Object *ob_src, Object *ob_dst static int make_links_data_exec(bContext *C, wmOperator *op) { + const WorkSpace *workspace = CTX_wm_workspace(C); Main *bmain = CTX_data_main(C); const int type = RNA_enum_get(op->ptr, "type"); Object *ob_src; @@ -1509,7 +1513,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op) } break; case MAKE_LINKS_MODIFIERS: - BKE_object_link_modifiers(ob_dst, ob_src); + BKE_object_link_modifiers(ob_dst, ob_src, workspace->object_mode); DEG_id_tag_update(&ob_dst->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); break; case MAKE_LINKS_FONTS: @@ -2411,7 +2415,6 @@ static int make_override_static_exec(bContext *C, wmOperator *op) bool success = false; if (!ID_IS_LINKED(obact) && obact->dup_group != NULL && ID_IS_LINKED(obact->dup_group)) { -#if 0 /* Not working yet! */ Base *base = BLI_findlink(&obact->dup_group->view_layer->object_bases, RNA_enum_get(op->ptr, "object")); Object *obgroup = obact; obact = base->object; @@ -2424,7 +2427,7 @@ static int make_override_static_exec(bContext *C, wmOperator *op) FOREACH_GROUP_OBJECT(obgroup->dup_group, ob) { - make_override_tag_object(obact, ob); + make_override_static_tag_object(obact, ob); } FOREACH_GROUP_OBJECT_END; @@ -2435,7 +2438,7 @@ static int make_override_static_exec(bContext *C, wmOperator *op) ViewLayer *view_layer = CTX_data_view_layer(C); Object *new_obact = (Object *)obact->id.newid; if (new_obact != NULL && (base = BKE_view_layer_base_find(view_layer, new_obact)) == NULL) { - BKE_collection_object_add_from(scene, obact, new_obact); + BKE_collection_object_add_from(scene, obgroup, new_obact); base = BKE_view_layer_base_find(view_layer, new_obact); BKE_view_layer_base_select(view_layer, base); } @@ -2453,9 +2456,6 @@ static int make_override_static_exec(bContext *C, wmOperator *op) /* Cleanup. */ BKE_main_id_clear_newpoins(bmain); BKE_main_id_tag_listbase(&bmain->object, LIB_TAG_DOIT, false); -#else - UNUSED_VARS(op); -#endif } /* Else, poll func ensures us that ID_IS_LINKED(obact) is true. */ else if (obact->type == OB_ARMATURE) { @@ -2512,8 +2512,8 @@ void OBJECT_OT_make_override_static(wmOperatorType *ot) /* properties */ PropertyRNA *prop; - prop = RNA_def_enum(ot->srna, "object", DummyRNA_DEFAULT_items, 0, "Proxy Object", - "Name of lib-linked/grouped object to make a proxy for"); + prop = RNA_def_enum(ot->srna, "object", DummyRNA_DEFAULT_items, 0, "Override Object", + "Name of lib-linked/group object to make an override from"); RNA_def_enum_funcs(prop, proxy_group_object_itemf); RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE); ot->prop = prop; diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index b20fe9a004c..8a62438dc80 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -56,7 +56,9 @@ #include "BKE_layer.h" #include "BKE_main.h" #include "BKE_material.h" +#include "BKE_object.h" #include "BKE_particle.h" +#include "BKE_paint.h" #include "BKE_property.h" #include "BKE_report.h" #include "BKE_scene.h" @@ -64,6 +66,8 @@ #include "BKE_library.h" #include "BKE_deform.h" +#include "DEG_depsgraph.h" + #include "WM_api.h" #include "WM_types.h" @@ -119,12 +123,82 @@ void ED_object_base_select(Base *base, eObjectSelect_Mode mode) void ED_object_base_activate(bContext *C, Base *base) { ViewLayer *view_layer = CTX_data_view_layer(C); + + WorkSpace *workspace = CTX_wm_workspace(C); + + bool reset = true; + if (base) { + Object *ob_prev = OBACT(view_layer); + Object *ob_curr = base->object; + if (ob_prev != NULL) { + if (ob_prev->type == ob_curr->type) { + reset = false; + } + } + } + + eObjectMode object_mode = workspace->object_mode; + + { + Scene *scene = CTX_data_scene(C); + /* We don't know the previous active object in update. + * + * Not correct because it's possible other work-spaces use these. + * although that's a corner case. */ + if (workspace->object_mode & OB_MODE_EDIT) { + FOREACH_OBJECT(view_layer, ob) { + if (ob != base->object) { + if (BKE_object_is_in_editmode(ob)) { + ED_object_editmode_exit_ex(NULL, workspace, scene, ob, EM_FREEDATA); + } + } + } + FOREACH_OBJECT_END; + } + else if (workspace->object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_SCULPT)) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + FOREACH_OBJECT(view_layer, ob) { + if (ob != base->object) { + if (ob->sculpt) { + switch (ob->sculpt->mode_type) { + case OB_MODE_VERTEX_PAINT: + { + ED_object_vpaintmode_exit_ex(workspace, ob); + break; + } + case OB_MODE_WEIGHT_PAINT: + { + ED_object_wpaintmode_exit_ex(workspace, ob); + break; + } + case OB_MODE_SCULPT: + { + ED_object_sculptmode_exit_ex(&eval_ctx, workspace, scene, ob); + break; + } + } + } + } + } + FOREACH_OBJECT_END; + } + } + + workspace->object_mode = OB_MODE_OBJECT; + view_layer->basact = base; + if (reset == false) { + wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_mode_set", false); + PointerRNA ptr; + WM_operator_properties_create_ptr(&ptr, ot); + RNA_enum_set(&ptr, "mode", object_mode); + WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr); + WM_operator_properties_free(&ptr); + } + if (base) { -#ifdef USE_WORKSPACE_MODE - BKE_workspace_object_mode_set(CTX_wm_workspace(C), CTX_data_scene(C), base->object->mode); -#endif WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, view_layer); } else { @@ -138,13 +212,14 @@ static int objects_selectable_poll(bContext *C) { /* we don't check for linked scenes here, selection is * still allowed then for inspection of scene */ - Object *obact = CTX_data_active_object(C); - - if (CTX_data_edit_object(C)) + if (CTX_data_edit_object(C)) { return 0; - if (obact && obact->mode) + } + + const WorkSpace *workspace = CTX_wm_workspace(C); + if (workspace->object_mode != OB_MODE_OBJECT) { return 0; - + } return 1; } diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index 1f80cb5f0bc..bd3bd8fd0a5 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -49,6 +49,7 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" +#include "DNA_workspace_types.h" #include "BKE_context.h" #include "BKE_key.h" @@ -225,18 +226,20 @@ static bool object_shape_key_mirror(bContext *C, Object *ob, static int shape_key_mode_poll(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = ED_object_context(C); ID *data = (ob) ? ob->data : NULL; - return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && ob->mode != OB_MODE_EDIT); + return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && (workspace->object_mode != OB_MODE_EDIT)); } static int shape_key_mode_exists_poll(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = ED_object_context(C); ID *data = (ob) ? ob->data : NULL; /* same as shape_key_mode_poll */ - return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && ob->mode != OB_MODE_EDIT) && + return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && (workspace->object_mode != OB_MODE_EDIT)) && /* check a keyblock exists */ (BKE_keyblock_from_object(ob) != NULL); } @@ -244,12 +247,13 @@ static int shape_key_mode_exists_poll(bContext *C) static int shape_key_move_poll(bContext *C) { /* Same as shape_key_mode_exists_poll above, but ensure we have at least two shapes! */ + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = ED_object_context(C); ID *data = (ob) ? ob->data : NULL; Key *key = BKE_key_from_object(ob); return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && - ob->mode != OB_MODE_EDIT && key && key->totkey > 1); + (workspace->object_mode != OB_MODE_EDIT) && key && key->totkey > 1); } static int shape_key_poll(bContext *C) diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 100b9018d00..b336b560ef2 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -245,6 +245,7 @@ static int object_clear_transform_generic_exec(bContext *C, wmOperator *op, void (*clear_func)(Object *, const bool), const char default_ksName[]) { + const WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene = CTX_data_scene(C); KeyingSet *ks; const bool clear_delta = RNA_boolean_get(op->ptr, "clear_delta"); @@ -263,7 +264,7 @@ static int object_clear_transform_generic_exec(bContext *C, wmOperator *op, */ CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { - if (!(ob->mode & OB_MODE_WEIGHT_PAINT)) { + if (!(workspace->object_mode & OB_MODE_WEIGHT_PAINT)) { /* run provided clearing function */ clear_func(ob, clear_delta); @@ -982,7 +983,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) /* Function to recenter armatures in editarmature.c * Bone + object locations are handled there. */ - ED_armature_origin_set(scene, ob, cursor, centermode, around); + ED_armature_origin_set(ob, cursor, centermode, around); tot_change++; arm->id.tag |= LIB_TAG_DOIT; diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index bf2da284591..8c6ccb7e8f0 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -43,6 +43,7 @@ #include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_workspace_types.h" #include "BLI_alloca.h" #include "BLI_array.h" @@ -84,9 +85,9 @@ #include "object_intern.h" /************************ Exported Functions **********************/ -static bool vertex_group_use_vert_sel(Object *ob) +static bool vertex_group_use_vert_sel(const Object *ob) { - if (ob->mode == OB_MODE_EDIT) { + if (BKE_object_is_in_editmode(ob)) { return true; } else if (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_VERT_SEL) { @@ -107,13 +108,15 @@ static Lattice *vgroup_edit_lattice(Object *ob) bool ED_vgroup_sync_from_pose(Object *ob) { Object *armobj = BKE_object_pose_armature_get(ob); - if (armobj && (armobj->mode & OB_MODE_POSE)) { + if (armobj) { struct bArmature *arm = armobj->data; - if (arm->act_bone) { - int def_num = defgroup_name_index(ob, arm->act_bone->name); - if (def_num != -1) { - ob->actdef = def_num + 1; - return true; + if (arm->flag & ARM_POSEMODE) { + if (arm->act_bone) { + int def_num = defgroup_name_index(ob, arm->act_bone->name); + if (def_num != -1) { + ob->actdef = def_num + 1; + return true; + } } } } @@ -255,9 +258,10 @@ bool ED_vgroup_parray_alloc(ID *id, MDeformVert ***dvert_arr, int *dvert_tot, co * * \note \a dvert_array has mirrored weights filled in, incase cleanup operations are needed on both. */ -void ED_vgroup_parray_mirror_sync(Object *ob, - MDeformVert **dvert_array, const int dvert_tot, - const bool *vgroup_validmap, const int vgroup_tot) +void ED_vgroup_parray_mirror_sync( + Object *ob, + MDeformVert **dvert_array, const int dvert_tot, + const bool *vgroup_validmap, const int vgroup_tot) { BMEditMesh *em = BKE_editmesh_from_object(ob); MDeformVert **dvert_array_all = NULL; @@ -300,8 +304,9 @@ void ED_vgroup_parray_mirror_sync(Object *ob, * * similar to #ED_vgroup_parray_mirror_sync but only fill in mirror points. */ -void ED_vgroup_parray_mirror_assign(Object *ob, - MDeformVert **dvert_array, const int dvert_tot) +void ED_vgroup_parray_mirror_assign( + Object *ob, + MDeformVert **dvert_array, const int dvert_tot) { BMEditMesh *em = BKE_editmesh_from_object(ob); MDeformVert **dvert_array_all = NULL; @@ -332,9 +337,10 @@ void ED_vgroup_parray_mirror_assign(Object *ob, MEM_freeN(dvert_array_all); } -void ED_vgroup_parray_remove_zero(MDeformVert **dvert_array, const int dvert_tot, - const bool *vgroup_validmap, const int vgroup_tot, - const float epsilon, const bool keep_single) +void ED_vgroup_parray_remove_zero( + MDeformVert **dvert_array, const int dvert_tot, + const bool *vgroup_validmap, const int vgroup_tot, + const float epsilon, const bool keep_single) { MDeformVert *dv; int i; @@ -484,9 +490,10 @@ void ED_vgroup_parray_from_weight_array( /* TODO, cache flip data to speedup calls within a loop. */ -static void mesh_defvert_mirror_update_internal(Object *ob, - MDeformVert *dvert_dst, MDeformVert *dvert_src, - const int def_nr) +static void mesh_defvert_mirror_update_internal( + Object *ob, + MDeformVert *dvert_dst, MDeformVert *dvert_src, + const int def_nr) { if (def_nr == -1) { /* all vgroups, add groups where neded */ @@ -504,8 +511,9 @@ static void mesh_defvert_mirror_update_internal(Object *ob, } } -static void ED_mesh_defvert_mirror_update_em(Object *ob, BMVert *eve, int def_nr, int vidx, - const int cd_dvert_offset) +static void ED_mesh_defvert_mirror_update_em( + Object *ob, BMVert *eve, int def_nr, int vidx, + const int cd_dvert_offset) { Mesh *me = ob->data; BMEditMesh *em = me->edit_btmesh; @@ -713,26 +721,30 @@ const EnumPropertyItem *ED_object_vgroup_selection_itemf_helper( return item; } -static const EnumPropertyItem *rna_vertex_group_with_single_itemf(bContext *C, PointerRNA *ptr, - PropertyRNA *prop, bool *r_free) +static const EnumPropertyItem *rna_vertex_group_with_single_itemf( + bContext *C, PointerRNA *ptr, + PropertyRNA *prop, bool *r_free) { return ED_object_vgroup_selection_itemf_helper(C, ptr, prop, r_free, WT_VGROUP_MASK_ALL); } -static const EnumPropertyItem *rna_vertex_group_select_itemf(bContext *C, PointerRNA *ptr, - PropertyRNA *prop, bool *r_free) +static const EnumPropertyItem *rna_vertex_group_select_itemf( + bContext *C, PointerRNA *ptr, + PropertyRNA *prop, bool *r_free) { - return ED_object_vgroup_selection_itemf_helper(C, ptr, prop, r_free, WT_VGROUP_MASK_ALL & ~(1 << WT_VGROUP_ACTIVE)); + return ED_object_vgroup_selection_itemf_helper( + C, ptr, prop, r_free, WT_VGROUP_MASK_ALL & ~(1 << WT_VGROUP_ACTIVE)); } static void vgroup_operator_subset_select_props(wmOperatorType *ot, bool use_active) { PropertyRNA *prop; - prop = RNA_def_enum(ot->srna, - "group_select_mode", DummyRNA_NULL_items, - use_active ? WT_VGROUP_ACTIVE : WT_VGROUP_ALL, "Subset", - "Define which subset of Groups shall be used"); + prop = RNA_def_enum( + ot->srna, + "group_select_mode", DummyRNA_NULL_items, + use_active ? WT_VGROUP_ACTIVE : WT_VGROUP_ALL, "Subset", + "Define which subset of Groups shall be used"); if (use_active) { RNA_def_enum_funcs(prop, rna_vertex_group_with_single_itemf); @@ -749,9 +761,10 @@ static void vgroup_operator_subset_select_props(wmOperatorType *ot, bool use_act /* for Mesh in Object mode */ /* allows editmode for Lattice */ -static void ED_vgroup_nr_vert_add(Object *ob, - const int def_nr, const int vertnum, - const float weight, const int assignmode) +static void ED_vgroup_nr_vert_add( + Object *ob, + const int def_nr, const int vertnum, + const float weight, const int assignmode) { /* add the vert to the deform group with the * specified number @@ -1222,9 +1235,10 @@ static void getSingleCoordinate(MVert *points, int count, float coord[3]) * compute the amount of vertical distance relative to the plane and store it in dists, * then get the horizontal and vertical change and store them in changes */ -static void getVerticalAndHorizontalChange(const float norm[3], float d, const float coord[3], - const float start[3], float distToStart, - float *end, float (*changes)[2], float *dists, int index) +static void getVerticalAndHorizontalChange( + const float norm[3], float d, const float coord[3], + const float start[3], float distToStart, + float *end, float (*changes)[2], float *dists, int index) { /* A = Q - ((Q - P).N)N * D = (a * x0 + b * y0 +c * z0 + d) */ @@ -1275,8 +1289,9 @@ static DerivedMesh *dm_deform_recalc(EvaluationContext *eval_ctx, Scene *scene, * norm and d are the plane's properties for the equation: ax + by + cz + d = 0 * coord is a point on the plane */ -static void moveCloserToDistanceFromPlane(EvaluationContext *eval_ctx, Scene *scene, Object *ob, Mesh *me, int index, float norm[3], - float coord[3], float d, float distToBe, float strength, float cp) +static void moveCloserToDistanceFromPlane( + EvaluationContext *eval_ctx, Scene *scene, Object *ob, Mesh *me, int index, float norm[3], + float coord[3], float d, float distToBe, float strength, float cp) { DerivedMesh *dm; MDeformWeight *dw; @@ -1499,9 +1514,10 @@ static void vgroup_fix(const bContext *C, Scene *scene, Object *ob, float distTo } } -static void vgroup_levels_subset(Object *ob, const bool *vgroup_validmap, const int vgroup_tot, - const int UNUSED(subset_count), - const float offset, const float gain) +static void vgroup_levels_subset( + Object *ob, const bool *vgroup_validmap, const int vgroup_tot, + const int UNUSED(subset_count), + const float offset, const float gain) { MDeformWeight *dw; MDeformVert *dv, **dvert_array = NULL; @@ -1536,8 +1552,9 @@ static void vgroup_levels_subset(Object *ob, const bool *vgroup_validmap, const } if (use_mirror && use_vert_sel) { - ED_vgroup_parray_mirror_sync(ob, dvert_array, dvert_tot, - vgroup_validmap, vgroup_tot); + ED_vgroup_parray_mirror_sync( + ob, dvert_array, dvert_tot, + vgroup_validmap, vgroup_tot); } MEM_freeN(dvert_array); @@ -1594,12 +1611,14 @@ static bool vgroup_normalize_all( /* in case its not selected */ if ((dv = dvert_array[i])) { if (lock_flags) { - defvert_normalize_lock_map(dv, vgroup_validmap, vgroup_tot, - lock_flags, defbase_tot); + defvert_normalize_lock_map( + dv, vgroup_validmap, vgroup_tot, + lock_flags, defbase_tot); } else if (lock_active) { - defvert_normalize_lock_single(dv, vgroup_validmap, vgroup_tot, - def_nr); + defvert_normalize_lock_single( + dv, vgroup_validmap, vgroup_tot, + def_nr); } else { defvert_normalize_subset(dv, vgroup_validmap, vgroup_tot); @@ -1666,9 +1685,10 @@ static void vgroup_lock_all(Object *ob, int action) } } -static void vgroup_invert_subset(Object *ob, - const bool *vgroup_validmap, const int vgroup_tot, - const int UNUSED(subset_count), const bool auto_assign, const bool auto_remove) +static void vgroup_invert_subset( + Object *ob, + const bool *vgroup_validmap, const int vgroup_tot, + const int UNUSED(subset_count), const bool auto_assign, const bool auto_remove) { MDeformWeight *dw; MDeformVert *dv, **dvert_array = NULL; @@ -1707,14 +1727,16 @@ static void vgroup_invert_subset(Object *ob, } if (use_mirror && use_vert_sel) { - ED_vgroup_parray_mirror_sync(ob, dvert_array, dvert_tot, - vgroup_validmap, vgroup_tot); + ED_vgroup_parray_mirror_sync( + ob, dvert_array, dvert_tot, + vgroup_validmap, vgroup_tot); } if (auto_remove) { - ED_vgroup_parray_remove_zero(dvert_array, dvert_tot, - vgroup_validmap, vgroup_tot, - 0.0f, false); + ED_vgroup_parray_remove_zero( + dvert_array, dvert_tot, + vgroup_validmap, vgroup_tot, + 0.0f, false); } MEM_freeN(dvert_array); @@ -1934,8 +1956,9 @@ static void vgroup_smooth_subset( /* not so efficient to get 'dvert_array' again just so unselected verts are NULL'd */ if (use_mirror) { ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, true); - ED_vgroup_parray_mirror_sync(ob, dvert_array, dvert_tot, - vgroup_validmap, vgroup_tot); + ED_vgroup_parray_mirror_sync( + ob, dvert_array, dvert_tot, + vgroup_validmap, vgroup_tot); if (dvert_array) MEM_freeN(dvert_array); } @@ -1959,11 +1982,12 @@ static int inv_cmp_mdef_vert_weights(const void *a1, const void *a2) /* Used for limiting the number of influencing bones per vertex when exporting * skinned meshes. if all_deform_weights is True, limit all deform modifiers * to max_weights regardless of type, otherwise, only limit the number of influencing bones per vertex*/ -static int vgroup_limit_total_subset(Object *ob, - const bool *vgroup_validmap, - const int vgroup_tot, - const int subset_count, - const int max_weights) +static int vgroup_limit_total_subset( + Object *ob, + const bool *vgroup_validmap, + const int vgroup_tot, + const int subset_count, + const int max_weights) { MDeformVert *dv, **dvert_array = NULL; int i, dvert_tot = 0; @@ -2030,8 +2054,9 @@ static int vgroup_limit_total_subset(Object *ob, } -static void vgroup_clean_subset(Object *ob, const bool *vgroup_validmap, const int vgroup_tot, const int UNUSED(subset_count), - const float epsilon, const bool keep_single) +static void vgroup_clean_subset( + Object *ob, const bool *vgroup_validmap, const int vgroup_tot, const int UNUSED(subset_count), + const float epsilon, const bool keep_single) { MDeformVert **dvert_array = NULL; int dvert_tot = 0; @@ -2048,16 +2073,18 @@ static void vgroup_clean_subset(Object *ob, const bool *vgroup_validmap, const i ED_vgroup_parray_mirror_assign(ob, dvert_array, dvert_tot); } - ED_vgroup_parray_remove_zero(dvert_array, dvert_tot, - vgroup_validmap, vgroup_tot, - epsilon, keep_single); + ED_vgroup_parray_remove_zero( + dvert_array, dvert_tot, + vgroup_validmap, vgroup_tot, + epsilon, keep_single); MEM_freeN(dvert_array); } } -static void vgroup_quantize_subset(Object *ob, const bool *vgroup_validmap, const int vgroup_tot, const int UNUSED(subset_count), - const int steps) +static void vgroup_quantize_subset( + Object *ob, const bool *vgroup_validmap, const int vgroup_tot, const int UNUSED(subset_count), + const int steps) { MDeformVert **dvert_array = NULL; int dvert_tot = 0; @@ -2095,11 +2122,12 @@ static void vgroup_quantize_subset(Object *ob, const bool *vgroup_validmap, cons } } -static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr, - const char sel, const char sel_mirr, - const int *flip_map, const int flip_map_len, - const bool mirror_weights, const bool flip_vgroups, const bool all_vgroups, - const int act_vgroup) +static void dvert_mirror_op( + MDeformVert *dvert, MDeformVert *dvert_mirr, + const char sel, const char sel_mirr, + const int *flip_map, const int flip_map_len, + const bool mirror_weights, const bool flip_vgroups, const bool all_vgroups, + const int act_vgroup) { BLI_assert(sel || sel_mirr); @@ -2158,10 +2186,11 @@ static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr, /* TODO, vgroup locking */ /* TODO, face masking */ -void ED_vgroup_mirror(Object *ob, - const bool mirror_weights, const bool flip_vgroups, - const bool all_vgroups, const bool use_topology, - int *r_totmirr, int *r_totfail) +void ED_vgroup_mirror( + Object *ob, + const bool mirror_weights, const bool flip_vgroups, + const bool all_vgroups, const bool use_topology, + int *r_totmirr, int *r_totfail) { #define VGROUP_MIRR_OP \ @@ -2521,12 +2550,13 @@ static int vertex_group_vert_poll_ex(bContext *C, const bool needs_select, const return false; } + const WorkSpace *workspace = CTX_wm_workspace(C); if (BKE_object_is_in_editmode_vgroup(ob)) { return true; } - else if (ob->mode & OB_MODE_WEIGHT_PAINT) { + else if (workspace->object_mode & OB_MODE_WEIGHT_PAINT) { if (needs_select) { - if (BKE_object_is_in_wpaint_select_vert(ob)) { + if (BKE_object_is_in_wpaint_select_vert(ob, workspace->object_mode)) { return true; } else { @@ -2578,8 +2608,9 @@ static int vertex_group_vert_select_unlocked_poll(bContext *C) if (!(ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data))) return 0; + const WorkSpace *workspace = CTX_wm_workspace(C); if (!(BKE_object_is_in_editmode_vgroup(ob) || - BKE_object_is_in_wpaint_select_vert(ob))) + BKE_object_is_in_wpaint_select_vert(ob, workspace->object_mode))) { return 0; } @@ -2605,8 +2636,9 @@ static int vertex_group_vert_select_mesh_poll(bContext *C) if (ob->type != OB_MESH) return 0; + const WorkSpace *workspace = CTX_wm_workspace(C); return (BKE_object_is_in_editmode_vgroup(ob) || - BKE_object_is_in_wpaint_select_vert(ob)); + BKE_object_is_in_wpaint_select_vert(ob, workspace->object_mode)); } static int vertex_group_add_exec(bContext *C, wmOperator *UNUSED(op)) @@ -3282,12 +3314,13 @@ static int vertex_group_mirror_exec(bContext *C, wmOperator *op) Object *ob = ED_object_context(C); int totmirr = 0, totfail = 0; - ED_vgroup_mirror(ob, - RNA_boolean_get(op->ptr, "mirror_weights"), - RNA_boolean_get(op->ptr, "flip_group_names"), - RNA_boolean_get(op->ptr, "all_groups"), - RNA_boolean_get(op->ptr, "use_topology"), - &totmirr, &totfail); + ED_vgroup_mirror( + ob, + RNA_boolean_get(op->ptr, "mirror_weights"), + RNA_boolean_get(op->ptr, "flip_group_names"), + RNA_boolean_get(op->ptr, "all_groups"), + RNA_boolean_get(op->ptr, "use_topology"), + &totmirr, &totfail); ED_mesh_report_mirror(op, totmirr, totfail); @@ -3489,7 +3522,8 @@ static char *vgroup_init_remap(Object *ob) return name_array; } -static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op) +static int vgroup_do_remap( + const EvaluationContext *eval_ctx, Object *ob, const char *name_array, wmOperator *op) { MDeformVert *dvert = NULL; bDeformGroup *def; @@ -3510,7 +3544,7 @@ static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op) BLI_assert(sort_map[i] != -1); } - if (ob->mode == OB_MODE_EDIT) { + if (eval_ctx->object_mode == OB_MODE_EDIT) { if (ob->type == OB_MESH) { BMEditMesh *em = BKE_editmesh_from_object(ob); const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); @@ -3608,6 +3642,8 @@ enum { static int vertex_group_sort_exec(bContext *C, wmOperator *op) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Object *ob = ED_object_context(C); char *name_array; int ret; @@ -3627,7 +3663,7 @@ static int vertex_group_sort_exec(bContext *C, wmOperator *op) } /*remap vgroup data to map to correct names*/ - ret = vgroup_do_remap(ob, name_array, op); + ret = vgroup_do_remap(&eval_ctx, ob, name_array, op); if (ret != OPERATOR_CANCELLED) { DEG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -3663,6 +3699,8 @@ void OBJECT_OT_vertex_group_sort(wmOperatorType *ot) static int vgroup_move_exec(bContext *C, wmOperator *op) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Object *ob = ED_object_context(C); bDeformGroup *def; char *name_array; @@ -3677,7 +3715,7 @@ static int vgroup_move_exec(bContext *C, wmOperator *op) name_array = vgroup_init_remap(ob); if (BLI_listbase_link_move(&ob->defbase, def, dir)) { - ret = vgroup_do_remap(ob, name_array, op); + ret = vgroup_do_remap(&eval_ctx, ob, name_array, op); if (ret != OPERATOR_CANCELLED) { DEG_id_tag_update(&ob->id, OB_RECALC_DATA); diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 89dd46681cb..376e4659b92 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -43,9 +43,10 @@ #include "DNA_view3d_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" +#include "DNA_workspace_types.h" #include "BLI_math.h" -#include "BLI_lasso.h" +#include "BLI_lasso_2d.h" #include "BLI_listbase.h" #include "BLI_string.h" #include "BLI_kdtree.h" @@ -113,26 +114,28 @@ void update_world_cos(Object *ob, PTCacheEdit *edit); int PE_poll(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene= CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob= CTX_data_active_object(C); - if (!scene || !view_layer || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT)) + if (!scene || !view_layer || !ob || !(workspace->object_mode & OB_MODE_PARTICLE_EDIT)) { return 0; - + } return (PE_get_current(scene, view_layer, ob) != NULL); } int PE_hair_poll(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene= CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob= CTX_data_active_object(C); PTCacheEdit *edit; - if (!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT)) + if (!scene || !ob || !(workspace->object_mode & OB_MODE_PARTICLE_EDIT)) { return 0; - + } edit= PE_get_current(scene, view_layer, ob); return (edit && edit->psys); @@ -312,12 +315,12 @@ PTCacheEdit *PE_get_current(Scene *scene, ViewLayer *view_layer, Object *ob) PTCacheEdit *PE_create_current(const EvaluationContext *eval_ctx, Scene *scene, Object *ob) { - return pe_get_current(eval_ctx, scene, NULL, ob, 1); + return pe_get_current(eval_ctx, scene, eval_ctx->view_layer, ob, 1); } void PE_current_changed(const EvaluationContext *eval_ctx, Scene *scene, Object *ob) { - if (ob->mode == OB_MODE_PARTICLE_EDIT) { + if (eval_ctx->object_mode == OB_MODE_PARTICLE_EDIT) { PE_create_current(eval_ctx, scene, ob); } } @@ -1312,6 +1315,8 @@ void PE_update_object(const EvaluationContext *eval_ctx, Scene *scene, ViewLayer if (edit->psys) edit->psys->flag &= ~PSYS_HAIR_UPDATED; + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); } /************************************************/ @@ -2840,7 +2845,8 @@ void PARTICLE_OT_delete(wmOperatorType *ot) /*************************** mirror operator **************************/ -static void PE_mirror_x(Scene *scene, ViewLayer *view_layer, Object *ob, int tagged) +static void PE_mirror_x( + Scene *scene, ViewLayer *view_layer, Object *ob, int tagged) { Mesh *me= (Mesh *)(ob->data); ParticleSystemModifierData *psmd; @@ -3865,6 +3871,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) (sqrtf(dx * dx + dy * dy) > pset->brush[PE_BRUSH_ADD].step) : (dx != 0 || dy != 0)) || bedit->first) { PEData data= bedit->data; + data.context = C; // TODO(mai): why isnt this set in bedit->data? view3d_operator_needs_opengl(C); selected= (short)count_selected_keys(scene, edit); @@ -4779,26 +4786,24 @@ static int particle_edit_toggle_poll(bContext *C) static int particle_edit_toggle_exec(bContext *C, wmOperator *op) { + struct WorkSpace *workspace = CTX_wm_workspace(C); + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); const int mode_flag = OB_MODE_PARTICLE_EDIT; - const bool is_mode_set = (ob->mode & mode_flag) != 0; - - BKE_report(op->reports, RPT_INFO, "Particles are changing, editing is not possible"); - return OPERATOR_CANCELLED; + const bool is_mode_set = (eval_ctx.object_mode & mode_flag) != 0; if (!is_mode_set) { - if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) { + if (!ED_object_mode_compat_set(C, workspace, mode_flag, op->reports)) { return OPERATOR_CANCELLED; } } if (!is_mode_set) { PTCacheEdit *edit; - EvaluationContext eval_ctx; - CTX_data_eval_ctx(C, &eval_ctx); - ob->mode |= mode_flag; + workspace->object_mode |= mode_flag; edit= PE_create_current(&eval_ctx, scene, ob); /* mesh may have changed since last entering editmode. @@ -4810,7 +4815,7 @@ static int particle_edit_toggle_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_PARTICLE, NULL); } else { - ob->mode &= ~mode_flag; + workspace->object_mode &= ~mode_flag; toggle_particle_cursor(C, 0); WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL); } diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index 1536c15525f..7a22a0d81d9 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -133,23 +133,25 @@ void OBJECT_OT_particle_system_add(wmOperatorType *ot) static int particle_system_remove_exec(bContext *C, wmOperator *UNUSED(op)) { + WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = ED_object_context(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - int mode_orig; + eObjectMode mode_orig; if (!scene || !ob) return OPERATOR_CANCELLED; - mode_orig = ob->mode; + mode_orig = workspace->object_mode; object_remove_particle_system(scene, ob); /* possible this isn't the active object * object_remove_particle_system() clears the mode on the last psys */ if (mode_orig & OB_MODE_PARTICLE_EDIT) { - if ((ob->mode & OB_MODE_PARTICLE_EDIT) == 0) { + if ((workspace->object_mode & OB_MODE_PARTICLE_EDIT) == 0) { if (view_layer->basact && view_layer->basact->object == ob) { + workspace->object_mode &= ~OB_MODE_PARTICLE_EDIT; WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL); } } diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c index 12e01228e1e..d9a7d288f9c 100644 --- a/source/blender/editors/physics/physics_fluid.c +++ b/source/blender/editors/physics/physics_fluid.c @@ -39,7 +39,7 @@ /* types */ #include "DNA_action_types.h" #include "DNA_object_types.h" -#include "DNA_object_fluidsim.h" +#include "DNA_object_fluidsim_types.h" #include "BLI_blenlib.h" #include "BLI_math.h" diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 3be890f2c36..0130b93babf 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -339,12 +339,12 @@ static int screen_render_exec(bContext *C, wmOperator *op) RE_SetReports(re, op->reports); - BLI_begin_threaded_malloc(); + BLI_threaded_malloc_begin(); if (is_animation) RE_BlenderAnim(re, mainp, scene, camera_override, lay_override, scene->r.sfra, scene->r.efra, scene->r.frame_step); else RE_BlenderFrame(re, mainp, scene, view_layer, camera_override, lay_override, scene->r.cfra, is_write_still); - BLI_end_threaded_malloc(); + BLI_threaded_malloc_end(); RE_SetReports(re, NULL); @@ -873,6 +873,8 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even * This is a problem for animation rendering since you cannot abort them. * This also does not open an image editor space. */ if (RE_engine_is_opengl(re_type)) { + /* ensure at least 1 area shows result */ + render_view_open(C, event->x, event->y, op->reports); return screen_render_exec(C, op); } @@ -1442,8 +1444,10 @@ static bool render_view3d_flag_changed(RenderEngine *engine, const bContext *C) job_update_flag |= PR_UPDATE_DATABASE; /* load editmesh */ - if (scene->obedit) - ED_object_editmode_load(scene->obedit); + Object *obedit = CTX_data_edit_object(C); + if (obedit) { + ED_object_editmode_load(obedit); + } } engine->update_flag = 0; diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 6e969067985..8eb9283790b 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -652,7 +652,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) sizey = (scene->r.size * scene->r.ysch) / 100; /* corrects render size with actual size, not every card supports non-power-of-two dimensions */ - ofs = GPU_offscreen_create(sizex, sizey, full_samples ? 0 : samples, true, err_out); + ofs = GPU_offscreen_create(sizex, sizey, full_samples ? 0 : samples, true, true, err_out); if (!ofs) { BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer, %s", err_out); diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 2e3091268a9..c76a6aa175a 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -455,9 +455,18 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty } else { /* use current scene world to light sphere */ - if (mat->pr_type == MA_SPHERE_A) { + if (mat->pr_type == MA_SPHERE_A && sp->pr_method == PR_BUTS_RENDER) { + /* Use current scene world to light sphere. */ sce->world = preview_get_localized_world(sp, scene->world); } + else if (sce->world) { + /* Use a default world color. Using the current + * scene world can be slow if it has big textures. */ + sce->world->use_nodes = false; + sce->world->horr = 0.5f; + sce->world->horg = 0.5f; + sce->world->horb = 0.5f; + } } if (sp->pr_method == PR_ICON_RENDER) { @@ -466,10 +475,6 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty } else { set_preview_layer(view_layer, MA_SPHERE_A); - - /* same as above, use current scene world to light sphere */ - if (BKE_scene_use_new_shading_nodes(scene)) - sce->world = preview_get_localized_world(sp, scene->world); } } else { @@ -569,6 +574,14 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty } else { set_preview_layer(view_layer, MA_LAMP); + + if (sce->world) { + /* Only use lighting from the lamp. */ + sce->world->use_nodes = false; + sce->world->horr = 0.0f; + sce->world->horg = 0.0f; + sce->world->horb = 0.0f; + } } for (Base *base = view_layer->object_bases.first; base; base = base->next) { diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 270ba2a7947..222e0e20dff 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -99,6 +99,7 @@ static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op)) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = ED_object_context(C); if (!ob) @@ -106,7 +107,7 @@ static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op)) BKE_object_material_slot_add(ob); - if (ob->mode & OB_MODE_TEXTURE_PAINT) { + if (workspace->object_mode & OB_MODE_TEXTURE_PAINT) { Scene *scene = CTX_data_scene(C); BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL); @@ -136,6 +137,7 @@ void OBJECT_OT_material_slot_add(wmOperatorType *ot) static int material_slot_remove_exec(bContext *C, wmOperator *op) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = ED_object_context(C); if (!ob) @@ -149,7 +151,7 @@ static int material_slot_remove_exec(bContext *C, wmOperator *op) BKE_object_material_slot_remove(ob); - if (ob->mode & OB_MODE_TEXTURE_PAINT) { + if (workspace->object_mode & OB_MODE_TEXTURE_PAINT) { Scene *scene = CTX_data_scene(C); BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL); diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index 4943222f038..7b2fcc15649 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -202,7 +202,7 @@ void ED_render_engine_changed(Main *bmain) update_ctx.bmain = bmain; for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { update_ctx.scene = scene; - BLI_LISTBASE_FOREACH(ViewLayer *, view_layer, &scene->view_layers) { + LISTBASE_FOREACH(ViewLayer *, view_layer, &scene->view_layers) { /* TDODO(sergey): Iterate over depsgraphs instead? */ update_ctx.depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true); update_ctx.view_layer = view_layer; @@ -401,10 +401,12 @@ static void texture_changed(Main *bmain, Tex *tex) /* icons */ BKE_icon_changed(BKE_icon_id_ensure(&tex->id)); + const eObjectMode object_mode = WM_windows_object_mode_get(bmain->wm.first); + /* paint overlays */ for (scene = bmain->scene.first; scene; scene = scene->id.next) { for (view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) { - BKE_paint_invalidate_overlay_tex(scene, view_layer, tex); + BKE_paint_invalidate_overlay_tex(scene, view_layer, tex, object_mode); } } @@ -524,8 +526,18 @@ static void scene_changed(Main *bmain, Scene *scene) Object *ob; /* glsl */ - for (ob = bmain->object.first; ob; ob = ob->id.next) { - if (ob->mode & OB_MODE_TEXTURE_PAINT) { + bool has_texture_mode = false; + wmWindowManager *wm = bmain->wm.first; + for (wmWindow *win = wm->windows.first; win; win = win->next) { + WorkSpace *workspace = WM_window_get_active_workspace(win); + if (workspace->object_mode & OB_MODE_TEXTURE_PAINT) { + has_texture_mode = true; + break; + } + } + + if (has_texture_mode) { + for (ob = bmain->object.first; ob; ob = ob->id.next) { BKE_texpaint_slots_refresh_object(scene, ob); BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); GPU_drawobject_free(ob->derivedFinal); @@ -558,8 +570,10 @@ void ED_render_id_flush_update(const DEGEditorUpdateContext *update_ctx, ID *id) lamp_changed(bmain, (Lamp *)id); break; case ID_IM: + { image_changed(bmain, (Image *)id); break; + } case ID_SCE: scene_changed(bmain, (Scene *)id); render_engine_flag_changed(bmain, RE_ENGINE_UPDATE_OTHER); diff --git a/source/blender/editors/scene/scene_edit.c b/source/blender/editors/scene/scene_edit.c index 812f9a736bf..d0077df73e4 100644 --- a/source/blender/editors/scene/scene_edit.c +++ b/source/blender/editors/scene/scene_edit.c @@ -186,13 +186,15 @@ bool ED_scene_view_layer_delete( return false; } + /* We need to unset nodetrees before removing the layer, otherwise its index will be -1. */ + view_layer_remove_unset_nodetrees(bmain, scene, layer); + BLI_remlink(&scene->view_layers, layer); BLI_assert(BLI_listbase_is_empty(&scene->view_layers) == false); scene->active_view_layer = 0; ED_workspace_view_layer_unset(bmain, scene, layer, scene->view_layers.first); BKE_workspace_view_layer_remove_references(bmain, layer); - view_layer_remove_unset_nodetrees(bmain, scene, layer); BKE_view_layer_free(layer); diff --git a/source/blender/editors/screen/CMakeLists.txt b/source/blender/editors/screen/CMakeLists.txt index 02584a4611b..29b9971eabb 100644 --- a/source/blender/editors/screen/CMakeLists.txt +++ b/source/blender/editors/screen/CMakeLists.txt @@ -26,6 +26,7 @@ set(INC ../../blenloader ../../blentranslation ../../bmesh + ../../depsgraph ../../gpu ../../imbuf ../../makesdna diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index f886a6ad613..397090388ff 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -52,7 +52,6 @@ #include "WM_api.h" #include "WM_types.h" #include "WM_message.h" -#include "wm_subwindow.h" #include "ED_screen.h" #include "ED_screen_types.h" @@ -91,7 +90,7 @@ static void region_draw_emboss(const ARegion *ar, const rcti *scirct) /* set transp line */ glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); Gwn_VertFormat *format = immVertexFormat(); unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); @@ -450,7 +449,7 @@ static void region_draw_azones(ScrArea *sa, ARegion *ar) glLineWidth(1.0f); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); gpuPushMatrix(); gpuTranslate2f(-ar->winrct.xmin, -ar->winrct.ymin); @@ -495,23 +494,6 @@ static void region_draw_azones(ScrArea *sa, ARegion *ar) glDisable(GL_BLEND); } -/* only exported for WM */ -/* makes region ready for drawing, sets pixelspace */ -void ED_region_set(const bContext *C, ARegion *ar) -{ - wmWindow *win = CTX_wm_window(C); - ScrArea *sa = CTX_wm_area(C); - - ar->drawrct = ar->winrct; - - /* note; this sets state, so we can use wmOrtho and friends */ - wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct, true); - - UI_SetTheme(sa ? sa->spacetype : 0, ar->type ? ar->type->regionid : 0); - - ED_region_pixelspace(ar); -} - /* Follow wmMsgNotifyFn spec */ void ED_region_do_msg_notify_tag_redraw( bContext *UNUSED(C), wmMsgSubscribeKey *UNUSED(msg_key), wmMsgSubscribeValue *msg_val) @@ -546,27 +528,15 @@ void ED_region_do_draw(bContext *C, ARegion *ar) wmWindow *win = CTX_wm_window(C); ScrArea *sa = CTX_wm_area(C); ARegionType *at = ar->type; - bool scissor_pad; /* see BKE_spacedata_draw_locks() */ if (at->do_lock) return; - /* if no partial draw rect set, full rect */ - if (ar->drawrct.xmin == ar->drawrct.xmax) { - ar->drawrct = ar->winrct; - scissor_pad = true; - } - else { - /* extra clip for safety */ - BLI_rcti_isect(&ar->winrct, &ar->drawrct, &ar->drawrct); - scissor_pad = false; - } - ar->do_draw |= RGN_DRAWING; - /* note; this sets state, so we can use wmOrtho and friends */ - wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct, scissor_pad); + /* Set viewport, scissor, ortho and ar->drawrct. */ + wmPartialViewport(&ar->drawrct, &ar->winrct, &ar->drawrct); wmOrtho2_region_pixelspace(ar); @@ -1470,24 +1440,14 @@ static void area_calc_totrct(ScrArea *sa, int window_size_x, int window_size_y) /* used for area initialize below */ -static void region_subwindow(wmWindow *win, ARegion *ar, bool activate) +static void region_subwindow(ARegion *ar) { bool hidden = (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) != 0; if ((ar->alignment & RGN_SPLIT_PREV) && ar->prev) hidden = hidden || (ar->prev->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)); - if (hidden) { - if (ar->swinid) - wm_subwindow_close(win, ar->swinid); - ar->swinid = 0; - } - else if (ar->swinid == 0) { - ar->swinid = wm_subwindow_open(win, &ar->winrct, activate); - } - else { - wm_subwindow_position(win, ar->swinid, &ar->winrct, activate); - } + ar->visible = !hidden; } static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ListBase *handlers, int flag) @@ -1570,7 +1530,7 @@ void screen_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea region_rect_recursive(win, area, area->regionbase.first, &rect, 0, false); for (ARegion *ar = area->regionbase.first; ar; ar = ar->next) { - region_subwindow(win, ar, false); + region_subwindow(ar); /* region size may have changed, init does necessary adjustments */ if (ar->type->init) { @@ -1620,9 +1580,9 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa) /* region windows, default and own handlers */ for (ar = sa->regionbase.first; ar; ar = ar->next) { - region_subwindow(win, ar, false); + region_subwindow(ar); - if (ar->swinid) { + if (ar->visible) { /* default region handlers */ ed_default_handlers(wm, sa, &ar->handlers, ar->type->keymapflag); /* own handlers */ @@ -1649,22 +1609,16 @@ static void region_update_rect(ARegion *ar) /** * Call to move a popup window (keep OpenGL context free!) */ -void ED_region_update_rect(bContext *C, ARegion *ar) +void ED_region_update_rect(bContext *UNUSED(C), ARegion *ar) { - wmWindow *win = CTX_wm_window(C); - - wm_subwindow_rect_set(win, ar->swinid, &ar->winrct); - region_update_rect(ar); } /* externally called for floating regions like menus */ -void ED_region_init(bContext *C, ARegion *ar) +void ED_region_init(bContext *UNUSED(C), ARegion *ar) { -// ARegionType *at = ar->type; - /* refresh can be called before window opened */ - region_subwindow(CTX_wm_window(C), ar, false); + region_subwindow(ar); region_update_rect(ar); } @@ -2327,7 +2281,7 @@ void ED_region_info_draw_multiline(ARegion *ar, const char *text_array[], float BLI_rcti_size_x(&rect) + 1, BLI_rcti_size_y(&rect) + 1); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); Gwn_VertFormat *format = immVertexFormat(); unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index 7ce16efdb97..cd53655a0bb 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -354,142 +354,6 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state, clip_min_x, clip_min_y, clip_max_x, clip_max_y, xzoom, yzoom, color); } -/* 2D Drawing Assistance */ - -void glaDefine2DArea(rcti *screen_rect) -{ - const int sc_w = BLI_rcti_size_x(screen_rect) + 1; - const int sc_h = BLI_rcti_size_y(screen_rect) + 1; - - glViewport(screen_rect->xmin, screen_rect->ymin, sc_w, sc_h); - glScissor(screen_rect->xmin, screen_rect->ymin, sc_w, sc_h); - - /* The GLA_PIXEL_OFS magic number is to shift the matrix so that - * both raster and vertex integer coordinates fall at pixel - * centers properly. For a longer discussion see the OpenGL - * Programming Guide, Appendix H, Correctness Tips. - */ - - gpuOrtho2D(GLA_PIXEL_OFS, sc_w + GLA_PIXEL_OFS, GLA_PIXEL_OFS, sc_h + GLA_PIXEL_OFS); - gpuLoadIdentity(); -} - -/* TODO(merwin): put the following 2D code to use, or build new 2D code inspired & informd by it */ - -#if 0 /* UNUSED */ - -struct gla2DDrawInfo { - int orig_vp[4], orig_sc[4]; - float orig_projmat[16], orig_viewmat[16]; - - rcti screen_rect; - rctf world_rect; - - float wo_to_sc[2]; -}; - -void gla2DGetMap(gla2DDrawInfo *di, rctf *rect) -{ - *rect = di->world_rect; -} - -void gla2DSetMap(gla2DDrawInfo *di, rctf *rect) -{ - int sc_w, sc_h; - float wo_w, wo_h; - - di->world_rect = *rect; - - sc_w = BLI_rcti_size_x(&di->screen_rect); - sc_h = BLI_rcti_size_y(&di->screen_rect); - wo_w = BLI_rcti_size_x(&di->world_rect); - wo_h = BLI_rcti_size_y(&di->world_rect); - - di->wo_to_sc[0] = sc_w / wo_w; - di->wo_to_sc[1] = sc_h / wo_h; -} - -/** Save the current OpenGL state and initialize OpenGL for 2D - * rendering. glaEnd2DDraw should be called on the returned structure - * to free it and to return OpenGL to its previous state. The - * scissor rectangle is set to match the viewport. - * - * See glaDefine2DArea for an explanation of why this function uses integers. - * - * \param screen_rect The screen rectangle to be used for 2D drawing. - * \param world_rect The world rectangle that the 2D area represented - * by \a screen_rect is supposed to represent. If NULL it is assumed the - * world has a 1 to 1 mapping to the screen. - */ -gla2DDrawInfo *glaBegin2DDraw(rcti *screen_rect, rctf *world_rect) -{ - gla2DDrawInfo *di = MEM_mallocN(sizeof(*di), "gla2DDrawInfo"); - int sc_w, sc_h; - float wo_w, wo_h; - - glGetIntegerv(GL_VIEWPORT, (GLint *)di->orig_vp); - glGetIntegerv(GL_SCISSOR_BOX, (GLint *)di->orig_sc); - gpuGetProjectionMatrix(di->orig_projmat); - gpuGetModelViewMatrix(di->orig_viewmat); - - di->screen_rect = *screen_rect; - if (world_rect) { - di->world_rect = *world_rect; - } - else { - di->world_rect.xmin = di->screen_rect.xmin; - di->world_rect.ymin = di->screen_rect.ymin; - di->world_rect.xmax = di->screen_rect.xmax; - di->world_rect.ymax = di->screen_rect.ymax; - } - - sc_w = BLI_rcti_size_x(&di->screen_rect); - sc_h = BLI_rcti_size_y(&di->screen_rect); - wo_w = BLI_rcti_size_x(&di->world_rect); - wo_h = BLI_rcti_size_y(&di->world_rect); - - di->wo_to_sc[0] = sc_w / wo_w; - di->wo_to_sc[1] = sc_h / wo_h; - - glaDefine2DArea(&di->screen_rect); - - return di; -} - -/** - * Translate the (\a wo_x, \a wo_y) point from world coordinates into screen space. - */ -void gla2DDrawTranslatePt(gla2DDrawInfo *di, float wo_x, float wo_y, int *r_sc_x, int *r_sc_y) -{ - *r_sc_x = (wo_x - di->world_rect.xmin) * di->wo_to_sc[0]; - *r_sc_y = (wo_y - di->world_rect.ymin) * di->wo_to_sc[1]; -} - -/** - * Translate the \a world point from world coordinates into screen space. - */ -void gla2DDrawTranslatePtv(gla2DDrawInfo *di, float world[2], int r_screen[2]) -{ - screen_r[0] = (world[0] - di->world_rect.xmin) * di->wo_to_sc[0]; - screen_r[1] = (world[1] - di->world_rect.ymin) * di->wo_to_sc[1]; -} - -/** - * Restores the previous OpenGL state and frees the auxiliary gla data. - */ -void glaEnd2DDraw(gla2DDrawInfo *di) -{ - glViewport(di->orig_vp[0], di->orig_vp[1], di->orig_vp[2], di->orig_vp[3]); - glScissor(di->orig_vp[0], di->orig_vp[1], di->orig_vp[2], di->orig_vp[3]); - gpuLoadProjectionMatrix(di->orig_projmat); - gpuLoadMatrix(di->orig_viewmat); - - MEM_freeN(di); -} - -#endif /* UNUSED */ - - /* *************** glPolygonOffset hack ************* */ /** diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 4c62253bef6..2a48ae46b12 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -53,6 +53,8 @@ #include "BKE_sequencer.h" #include "BKE_workspace.h" +#include "DEG_depsgraph.h" + #include "RNA_access.h" #include "ED_armature.h" @@ -90,8 +92,8 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult Scene *scene = WM_window_get_active_scene(win); WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); ViewLayer *view_layer = BKE_view_layer_from_workspace_get(scene, workspace); - Object *obedit = scene->obedit; Object *obact = (view_layer && view_layer->basact) ? view_layer->basact->object : NULL; + Object *obedit = BKE_workspace_edit_object(workspace, scene); if (CTX_data_dir(member)) { CTX_data_dir_set(result, screen_context_dir); @@ -371,31 +373,31 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult return 1; } else if (CTX_data_equals(member, "sculpt_object")) { - if (obact && (obact->mode & OB_MODE_SCULPT)) + if (obact && (workspace->object_mode & OB_MODE_SCULPT)) { CTX_data_id_pointer_set(result, &obact->id); - + } return 1; } else if (CTX_data_equals(member, "vertex_paint_object")) { - if (obact && (obact->mode & OB_MODE_VERTEX_PAINT)) + if (obact && (workspace->object_mode & OB_MODE_VERTEX_PAINT)) CTX_data_id_pointer_set(result, &obact->id); return 1; } else if (CTX_data_equals(member, "weight_paint_object")) { - if (obact && (obact->mode & OB_MODE_WEIGHT_PAINT)) + if (obact && (workspace->object_mode & OB_MODE_WEIGHT_PAINT)) CTX_data_id_pointer_set(result, &obact->id); return 1; } else if (CTX_data_equals(member, "image_paint_object")) { - if (obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) + if (obact && (workspace->object_mode & OB_MODE_TEXTURE_PAINT)) CTX_data_id_pointer_set(result, &obact->id); return 1; } else if (CTX_data_equals(member, "particle_edit_object")) { - if (obact && (obact->mode & OB_MODE_PARTICLE_EDIT)) + if (obact && (workspace->object_mode & OB_MODE_PARTICLE_EDIT)) CTX_data_id_pointer_set(result, &obact->id); return 1; diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c index 2e4e9127ed6..c749d77869f 100644 --- a/source/blender/editors/screen/screen_draw.c +++ b/source/blender/editors/screen/screen_draw.c @@ -213,7 +213,7 @@ static void draw_join_shape(ScrArea *sa, char dir, unsigned int pos) */ static void scrarea_draw_shape_dark(ScrArea *sa, char dir, unsigned int pos) { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); immUniformColor4ub(0, 0, 0, 50); draw_join_shape(sa, dir, pos); @@ -298,7 +298,7 @@ void ED_screen_draw_edges(wmWindow *win) ScrArea *sa; - wmSubWindowSet(win, screen->mainwin); + wmWindowViewport(win); unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -499,7 +499,7 @@ static void screen_preview_draw(const bScreen *screen, int size_x, int size_y) void ED_screen_preview_render(const bScreen *screen, int size_x, int size_y, unsigned int *r_rect) { char err_out[256] = "unknown"; - GPUOffScreen *offscreen = GPU_offscreen_create(size_x, size_y, 0, false, err_out); + GPUOffScreen *offscreen = GPU_offscreen_create(size_x, size_y, 0, true, false, err_out); GPU_offscreen_bind(offscreen, true); glClearColor(0.0, 0.0, 0.0, 0.0); diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 57f45bf95ce..2e738d71a91 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -68,9 +68,6 @@ #include "WM_message.h" -/* XXX actually should be not here... solve later */ -#include "wm_subwindow.h" - #include "screen_intern.h" /* own module include */ @@ -699,14 +696,14 @@ static void screen_vertices_scale( /* ****************** EXPORTED API TO OTHER MODULES *************************** */ -/* screen sets cursor based on swinid */ -static void region_cursor_set(wmWindow *win, int swinid, int swin_changed) +/* screen sets cursor based on active region */ +static void region_cursor_set(wmWindow *win, bool swin_changed) { bScreen *screen = WM_window_get_active_screen(win); for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->swinid == swinid) { + if (ar == screen->active_region) { if (swin_changed || (ar->type && ar->type->event_cursor)) { if (ar->manipulator_map != NULL) { if (WM_manipulatormap_cursor_set(ar->manipulator_map, win)) { @@ -741,7 +738,7 @@ void ED_screen_do_listen(bContext *C, wmNotifier *note) break; case NC_SCENE: if (note->data == ND_MODE) - region_cursor_set(win, note->swinid, true); + region_cursor_set(win, true); break; } } @@ -770,12 +767,6 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win) const int window_size_y = WM_window_pixels_y(win); const int screen_size_x = WM_window_screen_pixels_x(win); const int screen_size_y = WM_window_screen_pixels_y(win); - rcti window_rect; - - window_rect.xmin = 0; - window_rect.xmax = window_size_x - 1; - window_rect.ymin = 0; - window_rect.ymax = window_size_y - 1; /* header size depends on DPI, let's verify */ WM_window_set_dpi(win); @@ -783,13 +774,6 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win) screen_vertices_scale(win, screen, window_size_x, window_size_y, screen_size_x, screen_size_y); - if (screen->mainwin == 0) { - screen->mainwin = wm_subwindow_open(win, &window_rect, false); - } - else { - wm_subwindow_position(win, screen->mainwin, &window_rect, false); - } - ED_screen_areas_iter(win, screen, area) { /* set spacetype and region callbacks, calls init() */ /* sets subwindows for regions, adds handlers */ @@ -881,10 +865,7 @@ void ED_region_exit(bContext *C, ARegion *ar) WM_event_remove_handlers(C, &ar->handlers); WM_event_modal_handler_region_replace(win, ar, NULL); - if (ar->swinid) { - wm_subwindow_close(win, ar->swinid); - ar->swinid = 0; - } + ar->visible = 0; if (ar->headerstr) { MEM_freeN(ar->headerstr); @@ -936,10 +917,7 @@ void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen) screen->animtimer = NULL; screen->scrubbing = false; - if (screen->mainwin) - wm_subwindow_close(window, screen->mainwin); - screen->mainwin = 0; - screen->subwinactive = 0; + screen->active_region = NULL; for (ar = screen->regionbase.first; ar; ar = ar->next) { ED_region_exit(C, ar); @@ -1008,7 +986,7 @@ static void screen_cursor_set(wmWindow *win, const wmEvent *event) /* called in wm_event_system.c. sets state vars in screen, cursors */ /* event type is mouse move */ -void ED_screen_set_subwinactive(bContext *C, const wmEvent *event) +void ED_screen_set_active_region(bContext *C, const wmEvent *event) { wmWindow *win = CTX_wm_window(C); bScreen *scr = WM_window_get_active_screen(win); @@ -1016,7 +994,7 @@ void ED_screen_set_subwinactive(bContext *C, const wmEvent *event) if (scr) { ScrArea *sa = NULL; ARegion *ar; - int oldswin = scr->subwinactive; + ARegion *old_ar = scr->active_region; ED_screen_areas_iter(win, scr, area_iter) { if (event->x > area_iter->totrct.xmin && event->x < area_iter->totrct.xmax) { @@ -1032,22 +1010,22 @@ void ED_screen_set_subwinactive(bContext *C, const wmEvent *event) /* make overlap active when mouse over */ for (ar = sa->regionbase.first; ar; ar = ar->next) { if (BLI_rcti_isect_pt_v(&ar->winrct, &event->x)) { - scr->subwinactive = ar->swinid; + scr->active_region = ar; break; } } } else - scr->subwinactive = scr->mainwin; + scr->active_region = NULL; /* check for redraw headers */ - if (oldswin != scr->subwinactive) { + if (old_ar != scr->active_region) { ED_screen_areas_iter(win, scr, area_iter) { bool do_draw = false; for (ar = area_iter->regionbase.first; ar; ar = ar->next) { - if (ar->swinid == oldswin || ar->swinid == scr->subwinactive) { + if (ar == old_ar || ar == scr->active_region) { do_draw = true; } } @@ -1063,13 +1041,13 @@ void ED_screen_set_subwinactive(bContext *C, const wmEvent *event) } /* cursors, for time being set always on edges, otherwise aregion doesnt switch */ - if (scr->subwinactive == scr->mainwin) { + if (scr->active_region == NULL) { screen_cursor_set(win, event); } else { /* notifier invokes freeing the buttons... causing a bit too much redraws */ - if (oldswin != scr->subwinactive) { - region_cursor_set(win, scr->subwinactive, true); + if (old_ar != scr->active_region) { + region_cursor_set(win, true); /* this used to be a notifier, but needs to be done immediate * because it can undo setting the right button as active due @@ -1077,7 +1055,7 @@ void ED_screen_set_subwinactive(bContext *C, const wmEvent *event) UI_screen_free_active_but(C, scr); } else - region_cursor_set(win, scr->subwinactive, false); + region_cursor_set(win, false); } } } @@ -1096,7 +1074,7 @@ int ED_screen_area_active(const bContext *C) return 1; for (ar = sa->regionbase.first; ar; ar = ar->next) - if (ar->swinid == sc->subwinactive) + if (ar == sc->active_region) return 1; } return 0; @@ -1114,7 +1092,7 @@ void ED_screen_global_topbar_area_create(const bContext *C, wmWindow *win, const sa->v2 = MEM_callocN(sizeof(*sa->v2), __func__); sa->v3 = MEM_callocN(sizeof(*sa->v3), __func__); sa->v4 = MEM_callocN(sizeof(*sa->v4), __func__); - /* Actual coordinates of area verts are set later (screen_test_scale) */ + /* Actual coordinates of area verts are set later (screen_vertices_scale) */ sa->spacetype = sa->butspacetype = SPACE_TOPBAR; sa->fixed_height = size_y; @@ -1755,10 +1733,14 @@ bool ED_screen_stereo3d_required(const bScreen *screen, const Scene *scene) * Find the scene displayed in \a screen. * \note Assumes \a screen to be visible/active! */ -Scene *ED_screen_scene_find(const bScreen *screen, const wmWindowManager *wm) + +Scene *ED_screen_scene_find_with_window(const bScreen *screen, const wmWindowManager *wm, struct wmWindow **r_window) { for (wmWindow *win = wm->windows.first; win; win = win->next) { if (WM_window_get_active_screen(win) == screen) { + if (r_window) { + *r_window = win; + } return WM_window_get_active_scene(win); } } @@ -1766,3 +1748,20 @@ Scene *ED_screen_scene_find(const bScreen *screen, const wmWindowManager *wm) BLI_assert(0); return NULL; } + + +Scene *ED_screen_scene_find(const bScreen *screen, const wmWindowManager *wm) +{ + return ED_screen_scene_find_with_window(screen, wm, NULL); +} + + +wmWindow *ED_screen_window_find(const bScreen *screen, const wmWindowManager *wm) +{ + for (wmWindow *win = wm->windows.first; win; win = win->next) { + if (WM_window_get_active_screen(win) == screen) { + return win; + } + } + return NULL; +} diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 09af0d86f84..4596c2e5cf1 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -68,6 +68,8 @@ #include "WM_api.h" #include "WM_types.h" +#include "DEG_depsgraph.h" + #include "ED_armature.h" #include "ED_clip.h" #include "ED_image.h" @@ -136,7 +138,7 @@ int ED_operator_screen_mainwinactive(bContext *C) if (CTX_wm_window(C) == NULL) return 0; screen = CTX_wm_screen(C); if (screen == NULL) return 0; - if (screen->subwinactive != screen->mainwin) return 0; + if (screen->active_region != NULL) return 0; return 1; } @@ -150,6 +152,7 @@ int ED_operator_scene_editable(bContext *C) int ED_operator_objectmode(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene = CTX_data_scene(C); Object *obact = CTX_data_active_object(C); @@ -159,7 +162,7 @@ int ED_operator_objectmode(bContext *C) return 0; /* add a check for ob->mode too? */ - if (obact && (obact->mode != OB_MODE_OBJECT)) + if (obact && (workspace->object_mode != OB_MODE_OBJECT)) return 0; return 1; @@ -301,35 +304,39 @@ int ED_operator_console_active(bContext *C) return ed_spacetype_test(C, SPACE_CONSOLE); } -static int ed_object_hidden(Object *ob) +static int ed_object_hidden(Object *ob, eObjectMode object_mode) { /* if hidden but in edit mode, we still display, can happen with animation */ - return ((ob->restrictflag & OB_RESTRICT_VIEW) && !(ob->mode & OB_MODE_EDIT)); + return ((ob->restrictflag & OB_RESTRICT_VIEW) && !(object_mode & OB_MODE_EDIT)); } int ED_operator_object_active(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = ED_object_active_context(C); - return ((ob != NULL) && !ed_object_hidden(ob)); + return ((ob != NULL) && !ed_object_hidden(ob, workspace->object_mode)); } int ED_operator_object_active_editable(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = ED_object_active_context(C); - return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob)); + return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob, workspace->object_mode)); } int ED_operator_object_active_editable_mesh(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = ED_object_active_context(C); - return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob) && + return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob, workspace->object_mode) && (ob->type == OB_MESH) && !ID_IS_LINKED(ob->data)); } int ED_operator_object_active_editable_font(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = ED_object_active_context(C); - return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob) && + return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob, workspace->object_mode) && (ob->type == OB_FONT)); } @@ -374,11 +381,14 @@ int ED_operator_posemode_exclusive(bContext *C) { Object *obact = CTX_data_active_object(C); - if (obact && !(obact->mode & OB_MODE_EDIT)) { - Object *obpose; - if ((obpose = BKE_object_pose_armature_get(obact))) { - if (obact == obpose) { - return 1; + if (obact) { + const WorkSpace *workspace = CTX_wm_workspace(C); + if ((workspace->object_mode & OB_MODE_EDIT) == 0) { + Object *obpose; + if ((obpose = BKE_object_pose_armature_get(obact))) { + if (obact == obpose) { + return 1; + } } } } @@ -392,9 +402,15 @@ int ED_operator_posemode_context(bContext *C) { Object *obpose = ED_pose_object_from_context(C); - if (obpose && !(obpose->mode & OB_MODE_EDIT)) { - if (BKE_object_pose_context_check(obpose)) { - return 1; + if (obpose) { + const WorkSpace *workspace = CTX_wm_workspace(C); + /* TODO, should we allow this out of pose mode? */ + if (workspace->object_mode & OB_MODE_POSE) { + // if ((workspace->object_mode & OB_MODE_EDIT) == 0) { + if (BKE_object_pose_context_check(obpose)) { + return 1; + } + // } } } @@ -405,11 +421,17 @@ int ED_operator_posemode(bContext *C) { Object *obact = CTX_data_active_object(C); - if (obact && !(obact->mode & OB_MODE_EDIT)) { - Object *obpose; - if ((obpose = BKE_object_pose_armature_get(obact))) { - if ((obact == obpose) || (obact->mode & OB_MODE_WEIGHT_PAINT)) { - return 1; + + if (obact) { + const WorkSpace *workspace = CTX_wm_workspace(C); + if ((workspace->object_mode & OB_MODE_EDIT) == 0) { + Object *obpose; + if ((obpose = BKE_object_pose_armature_get(obact))) { + if (((workspace->object_mode & OB_MODE_POSE) && (obact == obpose)) || + (workspace->object_mode & OB_MODE_WEIGHT_PAINT)) + { + return 1; + } } } } @@ -545,9 +567,10 @@ int ED_operator_mask(bContext *C) } case SPACE_IMAGE: { + WorkSpace *workspace = CTX_wm_workspace(C); SpaceImage *sima = sa->spacedata.first; ViewLayer *view_layer = CTX_data_view_layer(C); - return ED_space_image_check_show_maskedit(view_layer, sima); + return ED_space_image_check_show_maskedit(sima, workspace, view_layer); } } } diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c index da9cb69b528..6ec1ac2e239 100644 --- a/source/blender/editors/screen/workspace_edit.c +++ b/source/blender/editors/screen/workspace_edit.c @@ -79,33 +79,9 @@ WorkSpace *ED_workspace_add( BKE_workspace_view_layer_set(workspace, act_view_layer, scene); BKE_viewrender_copy(&workspace->view_render, view_render); -#ifdef USE_WORKSPACE_MODE - BKE_workspace_object_mode_set(workspace, scene, OB_MODE_OBJECT); -#endif - return workspace; } -#ifdef USE_WORKSPACE_MODE -/** - * Changes the object mode (if needed) to the one set in \a workspace_new. - * Object mode is still stored on object level. In future it should all be workspace level instead. - */ -static void workspace_change_update_mode( - const WorkSpace *workspace_old, const WorkSpace *workspace_new, - bContext *C, Object *ob_act, ReportList *reports) -{ - const Scene *scene = CTX_data_scene(C); - eObjectMode mode_old = BKE_workspace_object_mode_get(workspace_old, scene); - eObjectMode mode_new = BKE_workspace_object_mode_get(workspace_new, scene); - - if (mode_old != mode_new) { - ED_object_mode_compat_set(C, ob_act, mode_new, reports); - ED_object_toggle_modes(C, mode_new); - } -} -#endif - static void workspace_change_update_view_layer( WorkSpace *workspace_new, const WorkSpace *workspace_old, Scene *scene) @@ -117,15 +93,10 @@ static void workspace_change_update_view_layer( static void workspace_change_update( WorkSpace *workspace_new, const WorkSpace *workspace_old, - bContext *C, wmWindowManager *wm) + bContext *C) { /* needs to be done before changing mode! (to ensure right context) */ workspace_change_update_view_layer(workspace_new, workspace_old, CTX_data_scene(C)); -#ifdef USE_WORKSPACE_MODE - workspace_change_update_mode(workspace_old, workspace_new, C, CTX_data_active_object(C), &wm->reports); -#else - UNUSED_VARS(C, wm); -#endif } static bool workspace_change_find_new_layout_cb(const WorkSpaceLayout *layout, void *UNUSED(arg)) @@ -177,7 +148,7 @@ static WorkSpaceLayout *workspace_change_get_new_layout( * \returns if workspace changing was successful. */ bool ED_workspace_change( - WorkSpace *workspace_new, bContext *C, wmWindowManager *wm, wmWindow *win) + WorkSpace *workspace_new, bContext *C, wmWindow *win) { Main *bmain = CTX_data_main(C); WorkSpace *workspace_old = WM_window_get_active_workspace(win); @@ -200,7 +171,7 @@ bool ED_workspace_change( /* update screen *after* changing workspace - which also causes the actual screen change */ screen_changed_update(C, win, screen_new); - workspace_change_update(workspace_new, workspace_old, C, wm); + workspace_change_update(workspace_new, workspace_old, C); BLI_assert(BKE_workspace_view_layer_get(workspace_new, CTX_data_scene(C)) != NULL); BLI_assert(CTX_wm_workspace(C) == workspace_new); @@ -231,9 +202,6 @@ WorkSpace *ED_workspace_duplicate( ListBase *transform_orientations_old = BKE_workspace_transform_orientations_get(workspace_old); ListBase *transform_orientations_new = BKE_workspace_transform_orientations_get(workspace_new); -#ifdef USE_WORKSPACE_MODE - BKE_workspace_object_mode_set(workspace_new, scene, BKE_workspace_object_mode_get(workspace_old, scene)); -#endif BLI_duplicatelist(transform_orientations_new, transform_orientations_old); workspace_new->tool = workspace_old->tool; @@ -264,7 +232,7 @@ bool ED_workspace_delete( WorkSpace *prev = workspace_id->prev; WorkSpace *next = workspace_id->next; - ED_workspace_change((prev != NULL) ? prev : next, C, wm, win); + ED_workspace_change((prev != NULL) ? prev : next, C, win); } BKE_libblock_free(bmain, workspace_id); diff --git a/source/blender/editors/sculpt_paint/paint_curve.c b/source/blender/editors/sculpt_paint/paint_curve.c index 337f7a1ef2b..c9ad4a46a13 100644 --- a/source/blender/editors/sculpt_paint/paint_curve.c +++ b/source/blender/editors/sculpt_paint/paint_curve.c @@ -32,6 +32,7 @@ #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_view3d_types.h" +#include "DNA_workspace_types.h" #include "BLI_math_vector.h" #include "BLI_string.h" @@ -40,6 +41,8 @@ #include "BKE_main.h" #include "BKE_paint.h" +#include "DEG_depsgraph.h" + #include "ED_paint.h" #include "ED_view3d.h" @@ -59,12 +62,13 @@ int paint_curve_poll(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = CTX_data_active_object(C); Paint *p; RegionView3D *rv3d = CTX_wm_region_view3d(C); SpaceImage *sima; - if (rv3d && !(ob && ((ob->mode & OB_MODE_ALL_PAINT) != 0))) + if (rv3d && !(ob && ((workspace->object_mode & OB_MODE_ALL_PAINT) != 0))) return false; sima = CTX_wm_space_image(C); diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c index 8377b22756e..b175a33934a 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.c @@ -384,7 +384,7 @@ static int hide_show_exec(bContext *C, wmOperator *op) clip_planes_from_rect(C, clip_planes, &rect); dm = mesh_get_derived_final(&eval_ctx, CTX_data_scene(C), ob, CD_MASK_BAREMESH); - pbvh = dm->getPBVH(ob, dm); + pbvh = dm->getPBVH(ob, dm, eval_ctx.object_mode); ob->sculpt->pbvh = pbvh; get_pbvh_nodes(pbvh, &nodes, &totnode, clip_planes, area); @@ -418,7 +418,7 @@ static int hide_show_exec(bContext *C, wmOperator *op) MEM_freeN(nodes); /* end undo */ - sculpt_undo_push_end(C); + sculpt_undo_push_end(); /* ensure that edges and faces get hidden as well (not used by * sculpt but it looks wrong when entering editmode otherwise) */ diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index aebd0c10e9c..1cb37fc10cd 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -590,11 +590,13 @@ static int image_paint_poll(bContext *C) { Object *obact; - if (!image_paint_brush(C)) + if (!image_paint_brush(C)) { return 0; + } + const WorkSpace *workspace = CTX_wm_workspace(C); obact = CTX_data_active_object(C); - if ((obact && obact->mode & OB_MODE_TEXTURE_PAINT) && CTX_wm_region_view3d(C)) { + if ((obact && workspace->object_mode & OB_MODE_TEXTURE_PAINT) && CTX_wm_region_view3d(C)) { return 1; } else { @@ -1374,19 +1376,20 @@ static int texture_paint_toggle_poll(bContext *C) static int texture_paint_toggle_exec(bContext *C, wmOperator *op) { + WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); const int mode_flag = OB_MODE_TEXTURE_PAINT; - const bool is_mode_set = (ob->mode & mode_flag) != 0; + const bool is_mode_set = (workspace->object_mode & mode_flag) != 0; if (!is_mode_set) { - if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) { + if (!ED_object_mode_compat_set(C, workspace, mode_flag, op->reports)) { return OPERATOR_CANCELLED; } } - if (ob->mode & mode_flag) { - ob->mode &= ~mode_flag; + if (workspace->object_mode & mode_flag) { + workspace->object_mode &= ~mode_flag; if (U.glreslimit != 0) GPU_free_images(); @@ -1426,15 +1429,17 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op) if (sl->spacetype == SPACE_IMAGE) { SpaceImage *sima = (SpaceImage *)sl; - if (!sima->pin) - ED_space_image_set(sima, scene, scene->obedit, ima); + if (!sima->pin) { + Object *obedit = CTX_data_edit_object(C); + ED_space_image_set(sima, scene, obedit, ima); + } } } } } } - ob->mode |= mode_flag; + workspace->object_mode |= mode_flag; BKE_paint_init(scene, ePaintTextureProjective, PAINT_CURSOR_TEXTURE_PAINT); @@ -1471,9 +1476,10 @@ static int brush_colors_flip_exec(bContext *C, wmOperator *UNUSED(op)) { UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings; - Brush *br; + WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = CTX_data_active_object(C); - if (!(ob && (ob->mode & OB_MODE_VERTEX_PAINT))) { + Brush *br; + if (!(ob && (workspace->object_mode & OB_MODE_VERTEX_PAINT))) { br = image_paint_brush(C); } else { @@ -1504,8 +1510,11 @@ static int brush_colors_flip_poll(bContext *C) } else { Object *ob = CTX_data_active_object(C); - if (ob && (ob->mode & OB_MODE_VERTEX_PAINT)) { - return 1; + if (ob) { + WorkSpace *workspace = CTX_wm_workspace(C); + if (workspace->object_mode & OB_MODE_VERTEX_PAINT) { + return 1; + } } } return 0; @@ -1545,10 +1554,12 @@ void ED_imapaint_bucket_fill(struct bContext *C, float color[3], wmOperator *op) static int texture_paint_poll(bContext *C) { - if (texture_paint_toggle_poll(C)) - if (CTX_data_active_object(C)->mode & OB_MODE_TEXTURE_PAINT) + if (texture_paint_toggle_poll(C)) { + WorkSpace *workspace = CTX_wm_workspace(C); + if (workspace->object_mode & OB_MODE_TEXTURE_PAINT) { return 1; - + } + } return 0; } @@ -1559,16 +1570,19 @@ int image_texture_paint_poll(bContext *C) int facemask_paint_poll(bContext *C) { - return BKE_paint_select_face_test(CTX_data_active_object(C)); + const WorkSpace *workspace = CTX_wm_workspace(C); + return BKE_paint_select_face_test(CTX_data_active_object(C), workspace->object_mode); } int vert_paint_poll(bContext *C) { - return BKE_paint_select_vert_test(CTX_data_active_object(C)); + const WorkSpace *workspace = CTX_wm_workspace(C); + return BKE_paint_select_vert_test(CTX_data_active_object(C), workspace->object_mode); } int mask_paint_poll(bContext *C) { - return BKE_paint_select_elem_test(CTX_data_active_object(C)); + const WorkSpace *workspace = CTX_wm_workspace(C); + return BKE_paint_select_elem_test(CTX_data_active_object(C), workspace->object_mode); } diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 4a14e985827..ae5b825e4ae 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -2694,7 +2694,7 @@ static void project_paint_face_init( int face_seam_flag; if (threaded) - BLI_lock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */ + BLI_thread_lock(LOCK_CUSTOM1); /* Other threads could be modifying these vars */ face_seam_flag = ps->faceSeamFlags[tri_index]; @@ -2711,7 +2711,7 @@ static void project_paint_face_init( if ((face_seam_flag & (PROJ_FACE_SEAM1 | PROJ_FACE_SEAM2 | PROJ_FACE_SEAM3)) == 0) { if (threaded) - BLI_unlock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */ + BLI_thread_unlock(LOCK_CUSTOM1); /* Other threads could be modifying these vars */ } else { @@ -2737,7 +2737,7 @@ static void project_paint_face_init( /* ps->faceSeamUVs cant be modified when threading, now this is done we can unlock */ if (threaded) - BLI_unlock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */ + BLI_thread_unlock(LOCK_CUSTOM1); /* Other threads could be modifying these vars */ vCoSS[0] = ps->screenCoords[lt_vtri[0]]; vCoSS[1] = ps->screenCoords[lt_vtri[1]]; @@ -4138,7 +4138,7 @@ static bool project_bucket_iter_next( const int diameter = 2 * ps->brush_size; if (ps->thread_tot > 1) - BLI_lock_thread(LOCK_CUSTOM1); + BLI_thread_lock(LOCK_CUSTOM1); //printf("%d %d\n", ps->context_bucket_x, ps->context_bucket_y); @@ -4155,7 +4155,7 @@ static bool project_bucket_iter_next( ps->context_bucket_x++; if (ps->thread_tot > 1) - BLI_unlock_thread(LOCK_CUSTOM1); + BLI_thread_unlock(LOCK_CUSTOM1); return 1; } @@ -4164,7 +4164,7 @@ static bool project_bucket_iter_next( } if (ps->thread_tot > 1) - BLI_unlock_thread(LOCK_CUSTOM1); + BLI_thread_unlock(LOCK_CUSTOM1); return 0; } @@ -4883,7 +4883,7 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po } if (ps->thread_tot > 1) - BLI_init_threads(&threads, do_projectpaint_thread, ps->thread_tot); + BLI_threadpool_init(&threads, do_projectpaint_thread, ps->thread_tot); pool = BKE_image_pool_new(); @@ -4913,11 +4913,11 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po handles[a].pool = pool; if (ps->thread_tot > 1) - BLI_insert_thread(&threads, &handles[a]); + BLI_threadpool_insert(&threads, &handles[a]); } if (ps->thread_tot > 1) /* wait for everything to be done */ - BLI_end_threads(&threads); + BLI_threadpool_end(&threads); else do_projectpaint_thread(&handles[0]); @@ -5941,11 +5941,11 @@ static int add_simple_uvs_exec(bContext *C, wmOperator *UNUSED(op)) static int add_simple_uvs_poll(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = CTX_data_active_object(C); - - if (!ob || ob->type != OB_MESH || ob->mode != OB_MODE_TEXTURE_PAINT) + if (!ob || (ob->type != OB_MESH) || (workspace->object_mode != OB_MODE_TEXTURE_PAINT)) { return false; - + } return true; } diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index ff261a808da..64969075d89 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -39,7 +39,7 @@ #include "BLI_math_matrix.h" #include "BLI_math_geom.h" #include "BLI_utildefines.h" -#include "BLI_lasso.h" +#include "BLI_lasso_2d.h" #include "BLI_task.h" #include "BKE_pbvh.h" @@ -171,7 +171,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op) if (multires) multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED); - sculpt_undo_push_end(C); + sculpt_undo_push_end(); if (nodes) MEM_freeN(nodes); @@ -327,7 +327,7 @@ int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *r if (multires) multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED); - sculpt_undo_push_end(C); + sculpt_undo_push_end(); ED_region_tag_redraw(ar); @@ -514,7 +514,7 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op) if (multires) multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED); - sculpt_undo_push_end(C); + sculpt_undo_push_end(); ED_region_tag_redraw(vc.ar); MEM_freeN((void *)mcords); diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 004d2757a71..c031a733630 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -40,6 +40,8 @@ #include "BKE_paint.h" #include "BKE_main.h" +#include "DEG_depsgraph.h" + #include "ED_paint.h" #include "ED_screen.h" #include "ED_image.h" @@ -260,7 +262,9 @@ static void PALETTE_OT_color_delete(wmOperatorType *ot) } static int brush_reset_exec(bContext *C, wmOperator *UNUSED(op)) + { + const WorkSpace *workspace = CTX_wm_workspace(C); Paint *paint = BKE_paint_get_active_from_context(C); Brush *brush = BKE_paint_brush(paint); Object *ob = CTX_data_active_object(C); @@ -268,7 +272,7 @@ static int brush_reset_exec(bContext *C, wmOperator *UNUSED(op)) if (!ob || !brush) return OPERATOR_CANCELLED; /* TODO: other modes */ - if (ob->mode & OB_MODE_SCULPT) { + if (workspace->object_mode & OB_MODE_SCULPT) { BKE_brush_sculpt_reset(brush); } else { @@ -401,6 +405,7 @@ static int brush_generic_tool_set(Main *bmain, Paint *paint, const int tool, static int brush_select_exec(bContext *C, wmOperator *op) { + WorkSpace *workspace = CTX_wm_workspace(C); Main *bmain = CTX_data_main(C); ToolSettings *toolsettings = CTX_data_tool_settings(C); Paint *paint = NULL; @@ -414,7 +419,7 @@ static int brush_select_exec(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); if (ob) { /* select current paint mode */ - paint_mode = ob->mode & OB_MODE_ALL_PAINT; + paint_mode = workspace->object_mode & OB_MODE_ALL_PAINT; } else { return OPERATOR_CANCELLED; diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 1ec1e052d43..6b14f97d80c 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -566,10 +566,11 @@ static int brush_curve_preset_exec(bContext *C, wmOperator *op) Brush *br = BKE_paint_brush(BKE_paint_get_active_from_context(C)); if (br) { + const WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); BKE_brush_curve_preset(br, RNA_enum_get(op->ptr, "shape")); - BKE_paint_invalidate_cursor_overlay(scene, view_layer, br->curve); + BKE_paint_invalidate_cursor_overlay(scene, view_layer, br->curve, workspace->object_mode); } return OPERATOR_FINISHED; diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 0c1df71b1aa..8ce0af068d6 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -199,9 +199,12 @@ static void paint_last_stroke_update(Scene *scene, ARegion *ar, const float mval /* Returns true if vertex paint mode is active */ int vertex_paint_mode_poll(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = CTX_data_active_object(C); - - return ob && ob->mode == OB_MODE_VERTEX_PAINT && ((Mesh *)ob->data)->totpoly; + return (ob && + (ob->type == OB_MESH) && + ((Mesh *)ob->data)->totpoly && + (workspace->object_mode & OB_MODE_VERTEX_PAINT)); } int vertex_paint_poll(bContext *C) @@ -221,18 +224,22 @@ int vertex_paint_poll(bContext *C) int weight_paint_mode_poll(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = CTX_data_active_object(C); - - return ob && ob->mode == OB_MODE_WEIGHT_PAINT && ((Mesh *)ob->data)->totpoly; + return (ob && + (ob->type == OB_MESH) && + ((Mesh *)ob->data)->totpoly && + (workspace->object_mode == OB_MODE_WEIGHT_PAINT)); } int weight_paint_poll(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = CTX_data_active_object(C); ScrArea *sa; if ((ob != NULL) && - (ob->mode & OB_MODE_WEIGHT_PAINT) && + (workspace->object_mode & OB_MODE_WEIGHT_PAINT) && (BKE_paint_brush(&CTX_data_tool_settings(C)->wpaint->paint) != NULL) && (sa = CTX_wm_area(C)) && (sa->spacetype == SPACE_VIEW3D)) @@ -940,23 +947,27 @@ static void do_weight_paint_vertex( /* Toggle operator for turning vertex paint mode on or off (copied from sculpt.c) */ static void vertex_paint_init_session(const EvaluationContext *eval_ctx, Scene *scene, Object *ob) { + /* Create persistent sculpt mode data */ + BKE_sculpt_toolsettings_data_ensure(scene); + if (ob->sculpt == NULL) { ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session"); BKE_sculpt_update_mesh_elements(eval_ctx, scene, scene->toolsettings->sculpt, ob, 0, false); } } -static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) +static void vertex_paint_init_session_data( + const EvaluationContext *eval_ctx, const ToolSettings *ts, Object *ob) { /* Create maps */ struct SculptVertexPaintGeomMap *gmap = NULL; const Brush *brush = NULL; - if (ob->mode == OB_MODE_VERTEX_PAINT) { + if (eval_ctx->object_mode == OB_MODE_VERTEX_PAINT) { gmap = &ob->sculpt->mode.vpaint.gmap; brush = BKE_paint_brush(&ts->vpaint->paint); ob->sculpt->mode_type = OB_MODE_VERTEX_PAINT; } - else if (ob->mode == OB_MODE_WEIGHT_PAINT) { + else if (eval_ctx->object_mode == OB_MODE_WEIGHT_PAINT) { gmap = &ob->sculpt->mode.wpaint.gmap; brush = BKE_paint_brush(&ts->wpaint->paint); ob->sculpt->mode_type = OB_MODE_WEIGHT_PAINT; @@ -985,7 +996,7 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) } /* Create average brush arrays */ - if (ob->mode == OB_MODE_VERTEX_PAINT) { + if (eval_ctx->object_mode == OB_MODE_VERTEX_PAINT) { if (!brush_use_accumulate(brush)) { if (ob->sculpt->mode.vpaint.previous_color == NULL) { ob->sculpt->mode.vpaint.previous_color = @@ -996,7 +1007,7 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) MEM_SAFE_FREE(ob->sculpt->mode.vpaint.previous_color); } } - else if (ob->mode == OB_MODE_WEIGHT_PAINT) { + else if (eval_ctx->object_mode == OB_MODE_WEIGHT_PAINT) { if (!brush_use_accumulate(brush)) { if (ob->sculpt->mode.wpaint.alpha_weight == NULL) { ob->sculpt->mode.wpaint.alpha_weight = @@ -1024,75 +1035,200 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) } -/* *************** set wpaint operator ****************** */ +/* -------------------------------------------------------------------- */ +/** \name Enter Vertex/Weight Paint Mode + * \{ */ -/** - * \note Keep in sync with #vpaint_mode_toggle_exec - */ -static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op) +static void ed_vwpaintmode_enter_generic( + const EvaluationContext *eval_ctx, + wmWindowManager *wm, + WorkSpace *workspace, Scene *scene, + Object *ob, const eObjectMode mode_flag) { - Object *ob = CTX_data_active_object(C); - const int mode_flag = OB_MODE_WEIGHT_PAINT; - const bool is_mode_set = (ob->mode & mode_flag) != 0; - Scene *scene = CTX_data_scene(C); - VPaint *wp = scene->toolsettings->wpaint; - Mesh *me; + workspace->object_mode |= mode_flag; + Mesh *me = BKE_mesh_from_object(ob); - if (!is_mode_set) { - if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) { - return OPERATOR_CANCELLED; - } - } + if (mode_flag == OB_MODE_VERTEX_PAINT) { + const ePaintMode paint_mode = ePaintVertex; + ED_mesh_color_ensure(me, NULL); - me = BKE_mesh_from_object(ob); + if (scene->toolsettings->vpaint == NULL) { + scene->toolsettings->vpaint = new_vpaint(); + } - if (ob->mode & mode_flag) { - ob->mode &= ~mode_flag; + Paint *paint = BKE_paint_get_active_from_paintmode(scene, paint_mode); + paint_cursor_start_explicit(paint, wm, vertex_paint_poll); + BKE_paint_init(scene, paint_mode, PAINT_CURSOR_VERTEX_PAINT); + } + else if (mode_flag == OB_MODE_WEIGHT_PAINT) { + const ePaintMode paint_mode = ePaintWeight; - if (me->editflag & ME_EDIT_PAINT_VERT_SEL) { - BKE_mesh_flush_select_from_verts(me); - } - else if (me->editflag & ME_EDIT_PAINT_FACE_SEL) { - BKE_mesh_flush_select_from_polys(me); + if (scene->toolsettings->wpaint == NULL) { + scene->toolsettings->wpaint = new_vpaint(); } + Paint *paint = BKE_paint_get_active_from_paintmode(scene, paint_mode); + paint_cursor_start_explicit(paint, wm, weight_paint_poll); + BKE_paint_init(scene, paint_mode, PAINT_CURSOR_WEIGHT_PAINT); + /* weight paint specific */ - ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e'); - ED_mesh_mirror_topo_table(NULL, NULL, 'e'); + ED_mesh_mirror_spatial_table(ob, NULL, NULL, NULL, 's'); + ED_vgroup_sync_from_pose(ob); + } + else { + BLI_assert(0); + } - /* If the cache is not released by a cancel or a done, free it now. */ + /* Create vertex/weight paint mode session data */ + if (ob->sculpt) { if (ob->sculpt->cache) { sculpt_cache_free(ob->sculpt->cache); ob->sculpt->cache = NULL; } - BKE_sculptsession_free(ob); + } + + vertex_paint_init_session(eval_ctx, scene, ob); +} + +void ED_object_vpaintmode_enter_ex( + const EvaluationContext *eval_ctx, wmWindowManager *wm, + WorkSpace *workspace, Scene *scene, Object *ob) +{ + ed_vwpaintmode_enter_generic( + eval_ctx, wm, workspace, scene, ob, OB_MODE_VERTEX_PAINT); +} +void ED_object_vpaintmode_enter(struct bContext *C) +{ + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + wmWindowManager *wm = CTX_wm_manager(C); + WorkSpace *workspace = CTX_wm_workspace(C); + Scene *scene = CTX_data_scene(C); + Object *ob = CTX_data_active_object(C); + ED_object_vpaintmode_enter_ex(&eval_ctx, wm, workspace, scene, ob); +} + +void ED_object_wpaintmode_enter_ex( + const EvaluationContext *eval_ctx, wmWindowManager *wm, + WorkSpace *workspace, Scene *scene, Object *ob) +{ + ed_vwpaintmode_enter_generic( + eval_ctx, wm, workspace, scene, ob, OB_MODE_WEIGHT_PAINT); +} +void ED_object_wpaintmode_enter(struct bContext *C) +{ + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + wmWindowManager *wm = CTX_wm_manager(C); + WorkSpace *workspace = CTX_wm_workspace(C); + Scene *scene = CTX_data_scene(C); + Object *ob = CTX_data_active_object(C); + ED_object_wpaintmode_enter_ex(&eval_ctx, wm, workspace, scene, ob); +} - paint_cursor_delete_textures(); +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Exit Vertex/Weight Paint Mode + * \{ */ + +static void ed_vwpaintmode_exit_generic( + WorkSpace *workspace, + Object *ob, const eObjectMode mode_flag) +{ + Mesh *me = BKE_mesh_from_object(ob); + workspace->object_mode &= ~mode_flag; + + if (mode_flag == OB_MODE_VERTEX_PAINT) { + if (me->editflag & ME_EDIT_PAINT_FACE_SEL) { + BKE_mesh_flush_select_from_polys(me); + } + else if (me->editflag & ME_EDIT_PAINT_VERT_SEL) { + BKE_mesh_flush_select_from_verts(me); + } + } + else if (mode_flag == OB_MODE_WEIGHT_PAINT) { + if (me->editflag & ME_EDIT_PAINT_VERT_SEL) { + BKE_mesh_flush_select_from_verts(me); + } + else if (me->editflag & ME_EDIT_PAINT_FACE_SEL) { + BKE_mesh_flush_select_from_polys(me); + } } else { - EvaluationContext eval_ctx; + BLI_assert(0); + } - CTX_data_eval_ctx(C, &eval_ctx); + /* If the cache is not released by a cancel or a done, free it now. */ + if (ob->sculpt->cache) { + sculpt_cache_free(ob->sculpt->cache); + ob->sculpt->cache = NULL; + } - ob->mode |= mode_flag; + BKE_sculptsession_free(ob); - if (wp == NULL) - wp = scene->toolsettings->wpaint = new_vpaint(); + paint_cursor_delete_textures(); - paint_cursor_start(C, weight_paint_poll); + if (mode_flag == OB_MODE_WEIGHT_PAINT) { + ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e'); + ED_mesh_mirror_topo_table(NULL, NULL, 'e'); + } +} - BKE_paint_init(scene, ePaintWeight, PAINT_CURSOR_WEIGHT_PAINT); +void ED_object_vpaintmode_exit_ex(WorkSpace *workspace, Object *ob) +{ + ed_vwpaintmode_exit_generic(workspace, ob, OB_MODE_VERTEX_PAINT); +} +void ED_object_vpaintmode_exit(struct bContext *C) +{ + WorkSpace *workspace = CTX_wm_workspace(C); + Object *ob = CTX_data_active_object(C); + ED_object_vpaintmode_exit_ex(workspace, ob); +} - /* weight paint specific */ - ED_mesh_mirror_spatial_table(ob, NULL, NULL, NULL, 's'); - ED_vgroup_sync_from_pose(ob); +void ED_object_wpaintmode_exit_ex(WorkSpace *workspace, Object *ob) +{ + ed_vwpaintmode_exit_generic(workspace, ob, OB_MODE_WEIGHT_PAINT); +} +void ED_object_wpaintmode_exit(struct bContext *C) +{ + WorkSpace *workspace = CTX_wm_workspace(C); + Object *ob = CTX_data_active_object(C); + ED_object_wpaintmode_exit_ex(workspace, ob); +} - /* Create vertex/weight paint mode session data */ - if (ob->sculpt) { - BKE_sculptsession_free(ob); +/** \} */ + +/* *************** set wpaint operator ****************** */ + +/** + * \note Keep in sync with #vpaint_mode_toggle_exec + */ +static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op) +{ + WorkSpace *workspace = CTX_wm_workspace(C); + Object *ob = CTX_data_active_object(C); + const int mode_flag = OB_MODE_WEIGHT_PAINT; + const bool is_mode_set = (workspace->object_mode & mode_flag) != 0; + Scene *scene = CTX_data_scene(C); + + if (!is_mode_set) { + if (!ED_object_mode_compat_set(C, workspace, mode_flag, op->reports)) { + return OPERATOR_CANCELLED; } - vertex_paint_init_session(&eval_ctx, scene, ob); + } + + Mesh *me = BKE_mesh_from_object(ob); + + if (is_mode_set) { + ED_object_wpaintmode_exit_ex(workspace, ob); + } + else { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + wmWindowManager *wm = CTX_wm_manager(C); + ED_object_wpaintmode_enter_ex(&eval_ctx, wm, workspace, scene, ob); } BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL); @@ -1393,7 +1529,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo /* If not previously created, create vertex/weight paint mode session data */ vertex_paint_init_session(&eval_ctx, scene, ob); vwpaint_update_cache_invariants(C, vp, ss, op, mouse); - vertex_paint_init_session_data(ts, ob); + vertex_paint_init_session_data(&eval_ctx, ts, ob); if (ob->sculpt->mode.wpaint.dvert_prev != NULL) { MDeformVert *dv = ob->sculpt->mode.wpaint.dvert_prev; @@ -1832,7 +1968,8 @@ static void wpaint_paint_leaves( /* threaded loop over nodes */ SculptThreadedTaskData data = { - .sd = sd, .ob = ob, .brush = brush, .nodes = nodes, .vp = vp, .wpd = wpd, .wpi = wpi, .me = me, .C = C, + .C = C, .sd = sd, .ob = ob, .brush = brush, .nodes = nodes, + .vp = vp, .wpd = wpd, .wpi = wpi, .me = me, }; /* Use this so average can modify its weight without touching the brush. */ @@ -2208,67 +2345,29 @@ void PAINT_OT_weight_paint(wmOperatorType *ot) */ static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op) { + WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = CTX_data_active_object(C); const int mode_flag = OB_MODE_VERTEX_PAINT; - const bool is_mode_set = (ob->mode & mode_flag) != 0; + const bool is_mode_set = (workspace->object_mode & mode_flag) != 0; Scene *scene = CTX_data_scene(C); - VPaint *vp = scene->toolsettings->vpaint; - Mesh *me; if (!is_mode_set) { - if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) { + if (!ED_object_mode_compat_set(C, workspace, mode_flag, op->reports)) { return OPERATOR_CANCELLED; } } - me = BKE_mesh_from_object(ob); + Mesh *me = BKE_mesh_from_object(ob); /* toggle: end vpaint */ if (is_mode_set) { - ob->mode &= ~mode_flag; - - if (me->editflag & ME_EDIT_PAINT_FACE_SEL) { - BKE_mesh_flush_select_from_polys(me); - } - else if (me->editflag & ME_EDIT_PAINT_VERT_SEL) { - BKE_mesh_flush_select_from_verts(me); - } - - /* If the cache is not released by a cancel or a done, free it now. */ - if (ob->sculpt->cache) { - sculpt_cache_free(ob->sculpt->cache); - ob->sculpt->cache = NULL; - } - - BKE_sculptsession_free(ob); - - paint_cursor_delete_textures(); + ED_object_vpaintmode_exit_ex(workspace, ob); } else { EvaluationContext eval_ctx; - CTX_data_eval_ctx(C, &eval_ctx); - - ob->mode |= mode_flag; - - ED_mesh_color_ensure(me, NULL); - - if (vp == NULL) - vp = scene->toolsettings->vpaint = new_vpaint(); - - paint_cursor_start(C, vertex_paint_poll); - - BKE_paint_init(scene, ePaintVertex, PAINT_CURSOR_VERTEX_PAINT); - - /* Create vertex/weight paint mode session data */ - if (ob->sculpt) { - if (ob->sculpt->cache) { - sculpt_cache_free(ob->sculpt->cache); - ob->sculpt->cache = NULL; - } - BKE_sculptsession_free(ob); - } - vertex_paint_init_session(&eval_ctx, scene, ob); + wmWindowManager *wm = CTX_wm_manager(C); + ED_object_vpaintmode_enter_ex(&eval_ctx, wm, workspace, scene, ob); } BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL); @@ -2417,7 +2516,7 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f /* If not previously created, create vertex/weight paint mode session data */ vertex_paint_init_session(&eval_ctx, scene, ob); vwpaint_update_cache_invariants(C, vp, ss, op, mouse); - vertex_paint_init_session_data(ts, ob); + vertex_paint_init_session_data(&eval_ctx, ts, ob); if (ob->sculpt->mode.vpaint.previous_color != NULL) { memset(ob->sculpt->mode.vpaint.previous_color, 0, sizeof(uint) * me->totloop); @@ -2871,8 +2970,8 @@ static void vpaint_paint_leaves( const Brush *brush = ob->sculpt->cache->brush; SculptThreadedTaskData data = { - .sd = sd, .ob = ob, .brush = brush, .nodes = nodes, .vp = vp, .vpd = vpd, - .lcol = (uint *)me->mloopcol, .me = me, .C = C, + .C = C, .sd = sd, .ob = ob, .brush = brush, .nodes = nodes, .vp = vp, .vpd = vpd, + .lcol = (uint *)me->mloopcol, .me = me, }; ParallelRangeSettings settings; BLI_parallel_range_settings_defaults(&settings); diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c index d7668a48139..f442c12cbe9 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c @@ -28,6 +28,7 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_workspace_types.h" #include "BLI_math_base.h" #include "BLI_math_color.h" @@ -51,9 +52,10 @@ static int vertex_weight_paint_mode_poll(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = CTX_data_active_object(C); Mesh *me = BKE_mesh_from_object(ob); - return (ob && (ob->mode == OB_MODE_VERTEX_PAINT || ob->mode == OB_MODE_WEIGHT_PAINT)) && + return (ob && ELEM(workspace->object_mode, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT)) && (me && me->totpoly && me->dvert); } diff --git a/source/blender/editors/sculpt_paint/paint_vertex_proj.c b/source/blender/editors/sculpt_paint/paint_vertex_proj.c index 999c9dc7880..336f851d4c1 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_proj.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_proj.c @@ -78,8 +78,9 @@ struct VertProjUpdate { /* -------------------------------------------------------------------- */ /* Internal Init */ -static void vpaint_proj_dm_map_cosnos_init__map_cb(void *userData, int index, const float co[3], - const float no_f[3], const short no_s[3]) +static void vpaint_proj_dm_map_cosnos_init__map_cb( + void *userData, int index, const float co[3], + const float no_f[3], const short no_s[3]) { struct VertProjHandle *vp_handle = userData; DMCoNo *co_no = &vp_handle->vcosnos[index]; @@ -131,8 +132,9 @@ static void vpaint_proj_dm_map_cosnos_init( /* Same as init but take mouse location into account */ -static void vpaint_proj_dm_map_cosnos_update__map_cb(void *userData, int index, const float co[3], - const float no_f[3], const short no_s[3]) +static void vpaint_proj_dm_map_cosnos_update__map_cb( + void *userData, int index, const float co[3], + const float no_f[3], const short no_s[3]) { struct VertProjUpdate *vp_update = userData; struct VertProjHandle *vp_handle = vp_update->vp_handle; @@ -144,9 +146,10 @@ static void vpaint_proj_dm_map_cosnos_update__map_cb(void *userData, int index, /* first find distance to this vertex */ float co_ss[2]; /* screenspace */ - if (ED_view3d_project_float_object(vp_update->ar, - co, co_ss, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) + if (ED_view3d_project_float_object( + vp_update->ar, + co, co_ss, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) { const float dist_sq = len_squared_v2v2(vp_update->mval_fl, co_ss); if (dist_sq > vp_handle->dists_sq[index]) { diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c index 1348847167c..72e2e7b323d 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c @@ -118,9 +118,10 @@ static void wpaint_prev_destroy(struct WPaintPrev *wpp) static int weight_from_bones_poll(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = CTX_data_active_object(C); - return (ob && (ob->mode & OB_MODE_WEIGHT_PAINT) && modifiers_isDeformedByArmature(ob)); + return (ob && (workspace->object_mode & OB_MODE_WEIGHT_PAINT) && modifiers_isDeformedByArmature(ob)); } static int weight_from_bones_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c index 4d70d82d5c6..51cd759b260 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c @@ -43,6 +43,7 @@ #include "BKE_modifier.h" #include "BKE_object_deform.h" #include "BKE_report.h" +#include "BKE_object.h" #include "WM_api.h" #include "WM_types.h" @@ -58,7 +59,6 @@ bool ED_wpaint_ensure_data( bContext *C, struct ReportList *reports, enum eWPaintFlag flag, struct WPaintVGroupIndex *vgroup_index) { - Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); Mesh *me = BKE_mesh_from_object(ob); @@ -67,7 +67,7 @@ bool ED_wpaint_ensure_data( vgroup_index->mirror = -1; } - if (scene->obedit) { + if (BKE_object_is_in_editmode(ob)) { return false; } @@ -308,4 +308,4 @@ float ED_wpaint_blend_tool( } } -/** \} */
\ No newline at end of file +/** \} */ diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index c9d550aa4bd..8df3d4e9f90 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -37,7 +37,7 @@ #include "BLI_math.h" #include "BLI_blenlib.h" -#include "BLI_dial.h" +#include "BLI_dial_2d.h" #include "BLI_task.h" #include "BLI_utildefines.h" #include "BLI_ghash.h" @@ -4082,8 +4082,9 @@ static void sculpt_update_tex(const Scene *scene, Sculpt *sd, SculptSession *ss) int sculpt_mode_poll(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = CTX_data_active_object(C); - return ob && ob->mode & OB_MODE_SCULPT; + return ob && workspace->object_mode & OB_MODE_SCULPT; } int sculpt_mode_poll_view3d(bContext *C) @@ -4595,19 +4596,17 @@ static bool sculpt_any_smooth_mode(const Brush *brush, (brush->mask_tool == BRUSH_MASK_SMOOTH))); } -static void sculpt_stroke_modifiers_check(const bContext *C, Object *ob) +static void sculpt_stroke_modifiers_check(const bContext *C, Object *ob, const Brush *brush) { SculptSession *ss = ob->sculpt; if (ss->kb || ss->modifiers_active) { EvaluationContext eval_ctx; - Sculpt *sd = CTX_data_tool_settings(C)->sculpt; - Brush *brush = BKE_paint_brush(&sd->paint); - CTX_data_eval_ctx(C, &eval_ctx); - - BKE_sculpt_update_mesh_elements(&eval_ctx, CTX_data_scene(C), sd, ob, - sculpt_any_smooth_mode(brush, ss->cache, 0), false); + Scene *scene = CTX_data_scene(C); + Sculpt *sd = scene->toolsettings->sculpt; + bool need_pmap = sculpt_any_smooth_mode(brush, ss->cache, 0); + BKE_sculpt_update_mesh_elements(&eval_ctx, scene, sd, ob, need_pmap, false); } } @@ -4736,7 +4735,9 @@ bool sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]) cache = ss->cache; original = (cache) ? cache->original : 0; - sculpt_stroke_modifiers_check(C, ob); + const Brush *brush = BKE_paint_brush(BKE_paint_get_active_from_context(C)); + + sculpt_stroke_modifiers_check(C, ob, brush); depth = sculpt_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, original); @@ -4762,7 +4763,6 @@ bool sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]) } if (hit == false) { - const Brush *brush = BKE_paint_brush(BKE_paint_get_active_from_context(C)); if (ELEM(brush->falloff_shape, PAINT_FALLOFF_SHAPE_TUBE)) { SculptFindNearestToRayData srd = { .original = original, @@ -4953,7 +4953,7 @@ static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *UNUSED(st SculptSession *ss = ob->sculpt; const Brush *brush = BKE_paint_brush(&sd->paint); - sculpt_stroke_modifiers_check(C, ob); + sculpt_stroke_modifiers_check(C, ob, brush); sculpt_update_cache_variants(C, sd, ob, itemptr); sculpt_restore_mesh(sd, ob); @@ -5028,7 +5028,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str BLI_assert(brush == ss->cache->brush); /* const, so we shouldn't change. */ ups->draw_inverted = false; - sculpt_stroke_modifiers_check(C, ob); + sculpt_stroke_modifiers_check(C, ob, brush); /* Alt-Smooth */ if (ss->cache->alt_smooth) { @@ -5047,7 +5047,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str sculpt_cache_free(ss->cache); ss->cache = NULL; - sculpt_undo_push_end(C); + sculpt_undo_push_end(); BKE_pbvh_update(ss->pbvh, PBVH_UpdateOriginalBB, NULL); @@ -5219,7 +5219,7 @@ void sculpt_pbvh_clear(Object *ob) BKE_pbvh_free(ss->pbvh); ss->pbvh = NULL; if (dm) - dm->getPBVH(NULL, dm); + dm->getPBVH(NULL, dm, OB_MODE_OBJECT); BKE_object_free_derived_caches(ob); } @@ -5255,24 +5255,21 @@ void sculpt_dyntopo_node_layers_add(SculptSession *ss) } -void sculpt_update_after_dynamic_topology_toggle(bContext *C) +void sculpt_update_after_dynamic_topology_toggle( + const EvaluationContext *eval_ctx, + Scene *scene, Object *ob) { - Scene *scene = CTX_data_scene(C); - Object *ob = CTX_data_active_object(C); - EvaluationContext eval_ctx; Sculpt *sd = scene->toolsettings->sculpt; - CTX_data_eval_ctx(C, &eval_ctx); - /* Create the PBVH */ - BKE_sculpt_update_mesh_elements(&eval_ctx, scene, sd, ob, false, false); - WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); + BKE_sculpt_update_mesh_elements(eval_ctx, scene, sd, ob, false, false); + WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob); } -void sculpt_dynamic_topology_enable(bContext *C) +void sculpt_dynamic_topology_enable_ex( + const EvaluationContext *eval_ctx, + Scene *scene, Object *ob) { - Scene *scene = CTX_data_scene(C); - Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; Mesh *me = ob->data; const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(me); @@ -5308,17 +5305,17 @@ void sculpt_dynamic_topology_enable(bContext *C) ss->bm_log = BM_log_create(ss->bm); /* Refresh */ - sculpt_update_after_dynamic_topology_toggle(C); + sculpt_update_after_dynamic_topology_toggle(eval_ctx, scene, ob); } /* Free the sculpt BMesh and BMLog * * If 'unode' is given, the BMesh's data is copied out to the unode * before the BMesh is deleted so that it can be restored from */ -void sculpt_dynamic_topology_disable(bContext *C, - SculptUndoNode *unode) +void sculpt_dynamic_topology_disable_ex( + const EvaluationContext *eval_ctx, + Scene *scene, Object *ob, SculptUndoNode *unode) { - Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; Mesh *me = ob->data; @@ -5367,28 +5364,59 @@ void sculpt_dynamic_topology_disable(bContext *C, } /* Refresh */ - sculpt_update_after_dynamic_topology_toggle(C); + sculpt_update_after_dynamic_topology_toggle(eval_ctx, scene, ob); +} + +void sculpt_dynamic_topology_disable(bContext *C, SculptUndoNode *unode) +{ + Scene *scene = CTX_data_scene(C); + Object *ob = CTX_data_active_object(C); + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + sculpt_dynamic_topology_disable_ex(&eval_ctx, scene, ob, unode); +} + +static void sculpt_dynamic_topology_disable_with_undo( + const EvaluationContext *eval_ctx, Scene *scene, Object *ob) +{ + SculptSession *ss = ob->sculpt; + if (ss->bm) { + sculpt_undo_push_begin("Dynamic topology disable"); + sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_END); + sculpt_dynamic_topology_disable_ex(eval_ctx, scene, ob, NULL); + sculpt_undo_push_end(); + } } +static void sculpt_dynamic_topology_enable_with_undo( + const EvaluationContext *eval_ctx, + Scene *scene, Object *ob) +{ + SculptSession *ss = ob->sculpt; + if (ss->bm == NULL) { + sculpt_undo_push_begin("Dynamic topology enable"); + sculpt_dynamic_topology_enable_ex(eval_ctx, scene, ob); + sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN); + sculpt_undo_push_end(); + } +} static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { + Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); WM_cursor_wait(1); if (ss->bm) { - sculpt_undo_push_begin("Dynamic topology disable"); - sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_END); - sculpt_dynamic_topology_disable(C, NULL); + sculpt_dynamic_topology_disable_with_undo(&eval_ctx, scene, ob); } else { - sculpt_undo_push_begin("Dynamic topology enable"); - sculpt_dynamic_topology_enable(C); - sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN); + sculpt_dynamic_topology_enable_with_undo(&eval_ctx, scene, ob); } - sculpt_undo_push_end(C); WM_cursor_wait(0); @@ -5576,7 +5604,7 @@ static int sculpt_symmetrize_exec(bContext *C, wmOperator *UNUSED(op)) /* Finish undo */ BM_log_all_added(ss->bm, ss->bm_log); - sculpt_undo_push_end(C); + sculpt_undo_push_end(); /* Redraw */ sculpt_pbvh_clear(ob); @@ -5599,31 +5627,81 @@ static void SCULPT_OT_symmetrize(wmOperatorType *ot) /**** Toggle operator for turning sculpt mode on or off ****/ -static void sculpt_init_session(const bContext *C, Scene *scene, Object *ob) +static void sculpt_init_session(const EvaluationContext *eval_ctx, Scene *scene, Object *ob) { - EvaluationContext eval_ctx; - - CTX_data_eval_ctx(C, &eval_ctx); + /* Create persistent sculpt mode data */ + BKE_sculpt_toolsettings_data_ensure(scene); ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session"); + ob->sculpt->mode_type = OB_MODE_SCULPT; + BKE_sculpt_update_mesh_elements(eval_ctx, scene, scene->toolsettings->sculpt, ob, 0, false); +} + +void ED_object_sculptmode_exit_ex( + const EvaluationContext *eval_ctx, + WorkSpace *workspace, Scene *scene, Object *ob) +{ + const int mode_flag = OB_MODE_SCULPT; + Mesh *me = BKE_mesh_from_object(ob); - BKE_sculpt_update_mesh_elements(&eval_ctx, scene, scene->toolsettings->sculpt, ob, 0, false); + MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob); + if (mmd) { + multires_force_update(ob); + } + + /* Always for now, so leaving sculpt mode always ensures scene is in + * a consistent state. + */ + if (true || /* flush_recalc || */ (ob->sculpt && ob->sculpt->bm)) { + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + } + + if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) { + /* Dynamic topology must be disabled before exiting sculpt + * mode to ensure the undo stack stays in a consistent + * state */ + sculpt_dynamic_topology_disable_with_undo(eval_ctx, scene, ob); + + /* store so we know to re-enable when entering sculpt mode */ + me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY; + } + + /* Leave sculptmode */ + workspace->object_mode &= ~mode_flag; + + BKE_sculptsession_free(ob); + + paint_cursor_delete_textures(); + + /* VBO no longer valid */ + if (ob->derivedFinal) { + GPU_drawobject_free(ob->derivedFinal); + } } +void ED_object_sculptmode_exit(bContext *C) +{ + WorkSpace *workspace = CTX_wm_workspace(C); + Scene *scene = CTX_data_scene(C); + Object *ob = CTX_data_active_object(C); + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + ED_object_sculptmode_exit_ex(&eval_ctx, workspace, scene, ob); +} static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) { + WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene = CTX_data_scene(C); - ToolSettings *ts = CTX_data_tool_settings(C); Object *ob = CTX_data_active_object(C); const int mode_flag = OB_MODE_SCULPT; - const bool is_mode_set = (ob->mode & mode_flag) != 0; + const bool is_mode_set = (workspace->object_mode & mode_flag) != 0; Mesh *me; MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob); int flush_recalc = 0; if (!is_mode_set) { - if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) { + if (!ED_object_mode_compat_set(C, workspace, mode_flag, op->reports)) { return OPERATOR_CANCELLED; } } @@ -5636,70 +5714,25 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) flush_recalc |= sculpt_has_active_modifiers(scene, ob); if (is_mode_set) { - if (mmd) - multires_force_update(ob); - - /* Always for now, so leaving sculpt mode always ensures scene is in - * a consistent state. - */ - if (true || flush_recalc || (ob->sculpt && ob->sculpt->bm)) { - DEG_id_tag_update(&ob->id, OB_RECALC_DATA); - } - - if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) { - /* Dynamic topology must be disabled before exiting sculpt - * mode to ensure the undo stack stays in a consistent - * state */ - sculpt_dynamic_topology_toggle_exec(C, NULL); - - /* store so we know to re-enable when entering sculpt mode */ - me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY; - } - - /* Leave sculptmode */ - ob->mode &= ~mode_flag; - - BKE_sculptsession_free(ob); - - paint_cursor_delete_textures(); + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + ED_object_sculptmode_exit_ex(&eval_ctx, workspace, scene, ob); } else { /* Enter sculptmode */ - ob->mode |= mode_flag; + workspace->object_mode |= mode_flag; if (flush_recalc) DEG_id_tag_update(&ob->id, OB_RECALC_DATA); - /* Create persistent sculpt mode data */ - if (!ts->sculpt) { - ts->sculpt = MEM_callocN(sizeof(Sculpt), "sculpt mode data"); - - /* Turn on X plane mirror symmetry by default */ - ts->sculpt->paint.symmetry_flags |= PAINT_SYMM_X; - ts->sculpt->paint.flags |= PAINT_SHOW_BRUSH; - - /* Make sure at least dyntopo subdivision is enabled */ - ts->sculpt->flags |= SCULPT_DYNTOPO_SUBDIVIDE | SCULPT_DYNTOPO_COLLAPSE; - } - - if (!ts->sculpt->detail_size) - ts->sculpt->detail_size = 12; - if (!ts->sculpt->detail_percent) - ts->sculpt->detail_percent = 25; - if (ts->sculpt->constant_detail == 0.0f) - ts->sculpt->constant_detail = 3.0f; - - /* Set sane default tiling offsets */ - if (!ts->sculpt->paint.tile_offset[0]) ts->sculpt->paint.tile_offset[0] = 1.0f; - if (!ts->sculpt->paint.tile_offset[1]) ts->sculpt->paint.tile_offset[1] = 1.0f; - if (!ts->sculpt->paint.tile_offset[2]) ts->sculpt->paint.tile_offset[2] = 1.0f; - - /* Create sculpt mode session data */ - if (ob->sculpt) + if (ob->sculpt) { BKE_sculptsession_free(ob); + } - sculpt_init_session(C, scene, ob); + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + sculpt_init_session(&eval_ctx, scene, ob); /* Mask layer is required */ if (mmd) { @@ -5756,7 +5789,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) if (message_unsupported == NULL) { /* undo push is needed to prevent memory leak */ sculpt_undo_push_begin("Dynamic topology enable"); - sculpt_dynamic_topology_enable(C); + sculpt_dynamic_topology_enable_ex(&eval_ctx, scene, ob); sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN); } else { @@ -5766,10 +5799,12 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) me->flag &= ~ME_SCULPT_DYNAMIC_TOPOLOGY; } } - } - if (ob->derivedFinal) /* VBO no longer valid */ - GPU_drawobject_free(ob->derivedFinal); + /* VBO no longer valid */ + if (ob->derivedFinal) { + GPU_drawobject_free(ob->derivedFinal); + } + } WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene); @@ -5839,7 +5874,7 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *UNUSED(op)) } MEM_freeN(nodes); - sculpt_undo_push_end(C); + sculpt_undo_push_end(); /* force rebuild of pbvh for better BB placement */ sculpt_pbvh_clear(ob); @@ -5876,7 +5911,9 @@ static void sample_detail(bContext *C, int ss_co[2]) sd = CTX_data_tool_settings(C)->sculpt; ob = vc.obact; - sculpt_stroke_modifiers_check(C, ob); + Brush *brush = BKE_paint_brush(&sd->paint); + + sculpt_stroke_modifiers_check(C, ob, brush); depth = sculpt_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, false); diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 5fb9eee805f..54cdbb18693 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -60,10 +60,19 @@ bool sculpt_stroke_get_location(struct bContext *C, float out[3], const float mo /* Dynamic topology */ void sculpt_pbvh_clear(Object *ob); void sculpt_dyntopo_node_layers_add(struct SculptSession *ss); -void sculpt_update_after_dynamic_topology_toggle(struct bContext *C); -void sculpt_dynamic_topology_enable(struct bContext *C); -void sculpt_dynamic_topology_disable(struct bContext *C, - struct SculptUndoNode *unode); +void sculpt_update_after_dynamic_topology_toggle( + const struct EvaluationContext *eval_ctx, + struct Scene *scene, struct Object *ob); +void sculpt_dynamic_topology_enable_ex( + const struct EvaluationContext *eval_ctx, + struct Scene *scene, struct Object *ob); +void sculpt_dynamic_topology_enable(bContext *C); + +void sculpt_dynamic_topology_disable_ex( + const struct EvaluationContext *eval_ctx, + struct Scene *scene, struct Object *ob, + struct SculptUndoNode *unode); +void sculpt_dynamic_topology_disable(bContext *C, struct SculptUndoNode *unode); /* Undo */ @@ -342,7 +351,7 @@ void sculpt_cache_free(StrokeCache *cache); SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType type); SculptUndoNode *sculpt_undo_get_node(PBVHNode *node); void sculpt_undo_push_begin(const char *name); -void sculpt_undo_push_end(const struct bContext *C); +void sculpt_undo_push_end(void); void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]); diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index 63017a0e576..55950a51fba 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -368,8 +368,8 @@ static void sculpt_undo_bmesh_restore_generic(bContext *C, } /* Create empty sculpt BMesh and enable logging */ -static void sculpt_undo_bmesh_enable(Object *ob, - SculptUndoNode *unode) +static void sculpt_undo_bmesh_enable( + Object *ob, SculptUndoNode *unode) { SculptSession *ss = ob->sculpt; Mesh *me = ob->data; @@ -896,7 +896,7 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node, SculptUndoNode *unode; /* list is manipulated by multiple threads, so we lock */ - BLI_lock_thread(LOCK_CUSTOM1); + BLI_thread_lock(LOCK_CUSTOM1); if (ss->bm || ELEM(type, @@ -906,17 +906,17 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node, /* Dynamic topology stores only one undo node per stroke, * regardless of the number of PBVH nodes modified */ unode = sculpt_undo_bmesh_push(ob, node, type); - BLI_unlock_thread(LOCK_CUSTOM1); + BLI_thread_unlock(LOCK_CUSTOM1); return unode; } else if ((unode = sculpt_undo_get_node(node))) { - BLI_unlock_thread(LOCK_CUSTOM1); + BLI_thread_unlock(LOCK_CUSTOM1); return unode; } unode = sculpt_undo_alloc_node(ob, node, type); - BLI_unlock_thread(LOCK_CUSTOM1); + BLI_thread_unlock(LOCK_CUSTOM1); /* copy threaded, hopefully this is the performance critical part */ @@ -964,7 +964,7 @@ void sculpt_undo_push_begin(const char *name) sculpt_undo_restore, sculpt_undo_free, sculpt_undo_cleanup); } -void sculpt_undo_push_end(const bContext *C) +void sculpt_undo_push_end(void) { ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_MESH); SculptUndoNode *unode; @@ -982,5 +982,5 @@ void sculpt_undo_push_end(const bContext *C) ED_undo_paint_push_end(UNDO_PAINT_MESH); - WM_file_tag_modified(C); + WM_file_tag_modified(); } diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c index c9453f94e61..700b0969277 100644 --- a/source/blender/editors/sculpt_paint/sculpt_uv.c +++ b/source/blender/editors/sculpt_paint/sculpt_uv.c @@ -652,7 +652,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm UvElement *element; NearestHit hit; Image *ima = CTX_data_edit_image(C); - uv_find_nearest_vert(scene, ima, em, co, NULL, &hit); + uv_find_nearest_vert(scene, ima, obedit, em, co, NULL, &hit); element = BM_uv_element_get(data->elementMap, hit.efa, hit.l); island_index = element->island; @@ -759,7 +759,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm MEM_freeN(uniqueUv); /* Allocate connectivity data, we allocate edges once */ - data->uvedges = MEM_mallocN(sizeof(*data->uvedges) * BLI_ghash_size(edgeHash), "uv_brush_edge_connectivity_data"); + data->uvedges = MEM_mallocN(sizeof(*data->uvedges) * BLI_ghash_len(edgeHash), "uv_brush_edge_connectivity_data"); if (!data->uvedges) { BLI_ghash_free(edgeHash, NULL, NULL); MEM_freeN(edges); @@ -772,7 +772,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm GHASH_ITER (gh_iter, edgeHash) { data->uvedges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(&gh_iter)); } - data->totalUvEdges = BLI_ghash_size(edgeHash); + data->totalUvEdges = BLI_ghash_len(edgeHash); /* cleanup temporary stuff */ BLI_ghash_free(edgeHash, NULL, NULL); diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index 110c4d1789d..3c3a71d00fd 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -36,7 +36,7 @@ #include "BLI_blenlib.h" #include "BLI_dlrbTree.h" -#include "BLI_lasso.h" +#include "BLI_lasso_2d.h" #include "BLI_utildefines.h" #include "DNA_anim_types.h" diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt index 397d79e1dbe..ec866780122 100644 --- a/source/blender/editors/space_buttons/CMakeLists.txt +++ b/source/blender/editors/space_buttons/CMakeLists.txt @@ -23,6 +23,7 @@ set(INC ../../blenkernel ../../blenlib ../../blentranslation + ../../depsgraph ../../gpu ../../makesdna ../../makesrna diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 8866c6b6c40..ebb14d3caeb 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -62,6 +62,8 @@ #include "RNA_access.h" +#include "DEG_depsgraph.h" + #include "ED_buttons.h" #include "ED_armature.h" #include "ED_screen.h" @@ -423,8 +425,9 @@ static int buttons_context_path_brush(const bContext *C, ButsContextPath *path) scene = path->ptr[path->len - 1].data; if (scene) { + const WorkSpace *workspace = CTX_wm_workspace(C); ViewLayer *view_layer = CTX_data_view_layer(C); - br = BKE_paint_brush(BKE_paint_get_active(scene, view_layer)); + br = BKE_paint_brush(BKE_paint_get_active(scene, view_layer, workspace->object_mode)); } if (br) { diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c index 036db87e846..d0e69a3dd7e 100644 --- a/source/blender/editors/space_buttons/buttons_texture.c +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -45,7 +45,7 @@ #include "DNA_material_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_particle_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 09d225fc1b8..96968a14883 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -157,7 +157,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* cache background */ ED_region_cache_draw_background(ar); @@ -314,7 +314,7 @@ static void draw_movieclip_buffer(const bContext *C, SpaceClip *sc, ARegion *ar, /* checkerboard for case alpha */ if (ibuf->planes == 32) { glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); imm_draw_box_checker_2d(x, y, x + zoomx * ibuf->x, y + zoomy * ibuf->y); } @@ -1126,7 +1126,7 @@ static void draw_plane_marker_image(Scene *scene, if (plane_track->image_opacity != 1.0f || ibuf->planes == 32) { transparent = true; glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } glGenTextures(1, (GLuint *)&texid); diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c index 7f9d9bf577c..9f79e8ffd6b 100644 --- a/source/blender/editors/space_clip/clip_utils.c +++ b/source/blender/editors/space_clip/clip_utils.c @@ -302,7 +302,7 @@ void clip_draw_sfra_efra(View2D *v2d, Scene *scene) UI_view2d_view_ortho(v2d); /* currently clip editor supposes that editing clip length is equal to scene frame range */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c index 4ee85ace271..ecbc1f5ae1e 100644 --- a/source/blender/editors/space_clip/tracking_select.c +++ b/source/blender/editors/space_clip/tracking_select.c @@ -37,7 +37,7 @@ #include "BLI_utildefines.h" #include "BLI_math.h" #include "BLI_rect.h" -#include "BLI_lasso.h" +#include "BLI_lasso_2d.h" #include "BKE_context.h" #include "BKE_tracking.h" diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index c1e298c426f..4bf377ddc1a 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -375,7 +375,7 @@ static void file_draw_preview( xco = sx + (int)dx; yco = sy - layout->prv_h + (int)dy; - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* shadow */ if (use_dropshadow) { diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 3c90f2957df..0fe51ea1c70 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -189,6 +189,9 @@ static SpaceLink *file_duplicate(SpaceLink *sl) /* clear or remove stuff from old */ sfilen->op = NULL; /* file window doesn't own operators */ + sfilen->previews_timer = NULL; + sfilen->smoothscroll_timer = NULL; + if (sfileo->params) { sfilen->files = filelist_new(sfileo->params->type); sfilen->params = MEM_dupallocN(sfileo->params); diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index d917e3b85a2..74349d52169 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -1232,7 +1232,7 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar) y = (float)ACHANNEL_FIRST(ac); /* set blending again, as may not be set in previous step */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); for (ale = anim_data.first, i = 0; ale; ale = ale->next, i++) { diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index 392db4ef4b5..0b7ce7d7310 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -37,7 +37,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_lasso.h" +#include "BLI_lasso_2d.h" #include "DNA_anim_types.h" #include "DNA_screen_types.h" diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 23c4fbbe45e..43d5348da3e 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -170,7 +170,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d float hue = 0, sat = 0, val = 0, lum = 0, u = 0, v = 0; float col[4], finalcol[4]; - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); @@ -482,8 +482,6 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar, { int x, y; - glaDefine2DArea(&ar->winrct); - /* find window pixel coordinates of origin */ UI_view2d_view_to_region(&ar->v2d, fx, fy, &x, &y); @@ -506,7 +504,7 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar, imm_draw_box_checker_2d(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } /* If RGBA display with color management */ @@ -733,7 +731,7 @@ static void draw_image_paint_helpers(const bContext *C, ARegion *ar, Scene *scen } glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); immDrawPixelsTex(&state, x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer, zoomx, zoomy, col); @@ -794,7 +792,7 @@ void draw_image_main(const bContext *C, ARegion *ar) * other images are not modifying in such a way so they does not require * lock (sergey) */ - BLI_lock_thread(LOCK_DRAW_IMAGE); + BLI_thread_lock(LOCK_DRAW_IMAGE); } if (show_stereo3d) { @@ -838,7 +836,7 @@ void draw_image_main(const bContext *C, ARegion *ar) draw_image_paint_helpers(C, ar, scene, zoomx, zoomy); if (show_viewer) { - BLI_unlock_thread(LOCK_DRAW_IMAGE); + BLI_thread_unlock(LOCK_DRAW_IMAGE); } /* render info */ @@ -879,7 +877,7 @@ void draw_image_cache(const bContext *C, ARegion *ar) } glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* Draw cache background. */ ED_region_cache_draw_background(ar); diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c index 587689eda78..95ed8967380 100644 --- a/source/blender/editors/space_image/image_edit.c +++ b/source/blender/editors/space_image/image_edit.c @@ -44,6 +44,8 @@ #include "IMB_imbuf_types.h" +#include "DEG_depsgraph.h" + #include "ED_image.h" /* own include */ #include "ED_mesh.h" #include "ED_screen.h" @@ -321,15 +323,16 @@ bool ED_image_slot_cycle(struct Image *image, int direction) void ED_space_image_scopes_update(const struct bContext *C, struct SpaceImage *sima, struct ImBuf *ibuf, bool use_view_settings) { + const WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); - + /* scope update can be expensive, don't update during paint modes */ if (sima->mode == SI_MODE_PAINT) return; - if (ob && ((ob->mode & (OB_MODE_TEXTURE_PAINT | OB_MODE_EDIT)) != 0)) + if (ob && ((workspace->object_mode & (OB_MODE_TEXTURE_PAINT | OB_MODE_EDIT)) != 0)) { return; - + } /* We also don't update scopes of render result during render. */ if (G.is_rendering) { const Image *image = sima->image; @@ -374,11 +377,12 @@ bool ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit) } /* matches clip function */ -bool ED_space_image_check_show_maskedit(ViewLayer *view_layer, SpaceImage *sima) +bool ED_space_image_check_show_maskedit( + SpaceImage *sima, const WorkSpace *workspace, ViewLayer *view_layer) { /* check editmode - this is reserved for UV editing */ Object *ob = OBACT(view_layer); - if (ob && ob->mode & OB_MODE_EDIT && ED_space_image_show_uvedit(sima, ob)) { + if (ob && (workspace->object_mode & OB_MODE_EDIT) && ED_space_image_show_uvedit(sima, ob)) { return false; } @@ -388,10 +392,10 @@ bool ED_space_image_check_show_maskedit(ViewLayer *view_layer, SpaceImage *sima) int ED_space_image_maskedit_poll(bContext *C) { SpaceImage *sima = CTX_wm_space_image(C); - if (sima) { + WorkSpace *workspace = CTX_wm_workspace(C); ViewLayer *view_layer = CTX_data_view_layer(C); - return ED_space_image_check_show_maskedit(view_layer, sima); + return ED_space_image_check_show_maskedit(sima, workspace, view_layer); } return false; diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index de158f84a4d..84179eb3b3a 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -275,12 +275,14 @@ int space_image_main_region_poll(bContext *C) /* For IMAGE_OT_curves_point_set to avoid sampling when in uv smooth mode or editmode */ static int space_image_main_area_not_uv_brush_poll(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); SpaceImage *sima = CTX_wm_space_image(C); Scene *scene = CTX_data_scene(C); ToolSettings *toolsettings = scene->toolsettings; - if (sima && !toolsettings->uvsculpt && !scene->obedit) + if (sima && !toolsettings->uvsculpt && ((workspace->object_mode & OB_MODE_EDIT) == 0)) { return 1; + } return 0; } @@ -791,6 +793,7 @@ void IMAGE_OT_view_all(wmOperatorType *ot) static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op)) { + WorkSpace *workspace = CTX_wm_workspace(C); SpaceImage *sima; ARegion *ar; Scene *scene; @@ -814,7 +817,7 @@ static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_CANCELLED; } } - else if (ED_space_image_check_show_maskedit(view_layer, sima)) { + else if (ED_space_image_check_show_maskedit(sima, workspace, view_layer)) { if (!ED_mask_selected_minmax(C, min, max)) { return OPERATOR_CANCELLED; } @@ -2458,7 +2461,7 @@ static int image_new_exec(bContext *C, wmOperator *op) SpaceImage *sima_other = (SpaceImage *)sl; if (!sima_other->pin) { - ED_space_image_set(sima_other, scene, scene->obedit, ima); + ED_space_image_set(sima_other, scene, obedit, ima); } } } diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index a89ae2b869a..c66d588c50d 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -551,7 +551,7 @@ static void image_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Sc { ViewLayer *view_layer = BKE_view_layer_from_workspace_get(scene, workspace); Object *ob = OBACT(view_layer); - if (ob && (ob == wmn->reference) && (ob->mode & OB_MODE_EDIT)) { + if (ob && (ob == wmn->reference) && (workspace->object_mode & OB_MODE_EDIT)) { if (sima->lock && (sima->flag & SI_DRAWSHADOW)) { ED_area_tag_refresh(sa); ED_area_tag_redraw(sa); @@ -725,6 +725,9 @@ static void image_main_region_init(wmWindowManager *wm, ARegion *ar) static void image_main_region_draw(const bContext *C, ARegion *ar) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + /* draw entirely, view changes should be handled here */ SpaceImage *sima = CTX_wm_space_image(C); Object *obact = CTX_data_active_object(C); @@ -759,7 +762,7 @@ static void image_main_region_draw(const bContext *C, ARegion *ar) ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW); - ED_uvedit_draw_main(sima, ar, scene, view_layer, obedit, obact, depsgraph); + ED_uvedit_draw_main(sima, &eval_ctx, ar, scene, view_layer, obedit, obact, depsgraph); /* check for mask (delay draw) */ if (ED_space_image_show_uvedit(sima, obedit)) { @@ -800,14 +803,14 @@ static void image_main_region_draw(const bContext *C, ARegion *ar) /* ED_space_image_get* will acquire image buffer which requires * lock here by the same reason why lock is needed in draw_image_main */ - BLI_lock_thread(LOCK_DRAW_IMAGE); + BLI_thread_lock(LOCK_DRAW_IMAGE); } ED_space_image_get_size(sima, &width, &height); ED_space_image_get_aspect(sima, &aspx, &aspy); if (show_viewer) - BLI_unlock_thread(LOCK_DRAW_IMAGE); + BLI_thread_unlock(LOCK_DRAW_IMAGE); ED_mask_draw_region(mask, ar, sima->mask_info.draw_flag, diff --git a/source/blender/editors/space_info/info_report.c b/source/blender/editors/space_info/info_report.c index 31df9b199ea..a6b3dad239c 100644 --- a/source/blender/editors/space_info/info_report.c +++ b/source/blender/editors/space_info/info_report.c @@ -133,9 +133,6 @@ static int select_report_pick_invoke(bContext *C, wmOperator *op, const wmEvent ReportList *reports = CTX_wm_reports(C); Report *report; - /* uses opengl */ - wmSubWindowSet(CTX_wm_window(C), ar->swinid); - report = info_text_pick(sinfo, ar, reports, event->mval[1]); RNA_int_set(op->ptr, "report_index", BLI_findindex(&reports->list, report)); diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c index 3cf833756ef..800560c380c 100644 --- a/source/blender/editors/space_info/info_stats.c +++ b/source/blender/editors/space_info/info_stats.c @@ -36,6 +36,7 @@ #include "DNA_lattice_types.h" #include "DNA_meta_types.h" #include "DNA_scene_types.h" +#include "DNA_workspace_types.h" #include "BLI_math.h" #include "BLI_string.h" @@ -53,6 +54,7 @@ #include "BKE_paint.h" #include "BKE_particle.h" #include "BKE_editmesh.h" +#include "BKE_object.h" #include "ED_info.h" #include "ED_armature.h" @@ -365,28 +367,29 @@ static void stats_dupli_object(Base *base, Object *ob, SceneStats *stats) } } -static bool stats_is_object_dynamic_topology_sculpt(Object *ob) +static bool stats_is_object_dynamic_topology_sculpt(Object *ob, const eObjectMode object_mode) { - return (ob && (ob->mode & OB_MODE_SCULPT) && + return (ob && + (object_mode & OB_MODE_SCULPT) && ob->sculpt && ob->sculpt->bm); } /* Statistics displayed in info header. Called regularly on scene changes. */ -static void stats_update(Scene *scene, ViewLayer *view_layer) +static void stats_update(ViewLayer *view_layer, Object *obedit, const eObjectMode object_mode) { SceneStats stats = {0}; Object *ob = (view_layer->basact) ? view_layer->basact->object : NULL; Base *base; - - if (scene->obedit) { + + if (obedit) { /* Edit Mode */ - stats_object_edit(scene->obedit, &stats); + stats_object_edit(ob, &stats); } - else if (ob && (ob->mode & OB_MODE_POSE)) { + else if (ob && (object_mode & OB_MODE_POSE)) { /* Pose Mode */ stats_object_pose(ob, &stats); } - else if (stats_is_object_dynamic_topology_sculpt(ob)) { + else if (stats_is_object_dynamic_topology_sculpt(ob, object_mode)) { /* Dynamic-topology sculpt mode */ stats_object_sculpt_dynamic_topology(ob, &stats); } @@ -405,7 +408,7 @@ static void stats_update(Scene *scene, ViewLayer *view_layer) *(view_layer->stats) = stats; } -static void stats_string(Scene *scene, ViewLayer *view_layer) +static void stats_string(ViewLayer *view_layer, Object *obedit, const eObjectMode object_mode) { #define MAX_INFO_MEM_LEN 64 SceneStats *stats = view_layer->stats; @@ -471,17 +474,17 @@ static void stats_string(Scene *scene, ViewLayer *view_layer) ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, "%s | ", versionstr); - if (scene->obedit) { - if (BKE_keyblock_from_object(scene->obedit)) + if (obedit) { + if (BKE_keyblock_from_object(obedit)) ofs += BLI_strncpy_rlen(s + ofs, IFACE_("(Key) "), MAX_INFO_LEN - ofs); - if (scene->obedit->type == OB_MESH) { + if (obedit->type == OB_MESH) { ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Verts:%s/%s | Edges:%s/%s | Faces:%s/%s | Tris:%s"), stats_fmt.totvertsel, stats_fmt.totvert, stats_fmt.totedgesel, stats_fmt.totedge, stats_fmt.totfacesel, stats_fmt.totface, stats_fmt.tottri); } - else if (scene->obedit->type == OB_ARMATURE) { + else if (obedit->type == OB_ARMATURE) { ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Verts:%s/%s | Bones:%s/%s"), stats_fmt.totvertsel, stats_fmt.totvert, stats_fmt.totbonesel, stats_fmt.totbone); } @@ -493,11 +496,11 @@ static void stats_string(Scene *scene, ViewLayer *view_layer) ofs += BLI_strncpy_rlen(s + ofs, memstr, MAX_INFO_LEN - ofs); ofs += BLI_strncpy_rlen(s + ofs, gpumemstr, MAX_INFO_LEN - ofs); } - else if (ob && (ob->mode & OB_MODE_POSE)) { + else if (ob && (object_mode & OB_MODE_POSE)) { ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Bones:%s/%s %s%s"), stats_fmt.totbonesel, stats_fmt.totbone, memstr, gpumemstr); } - else if (stats_is_object_dynamic_topology_sculpt(ob)) { + else if (stats_is_object_dynamic_topology_sculpt(ob, object_mode)) { ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Verts:%s | Tris:%s%s"), stats_fmt.totvert, stats_fmt.tottri, gpumemstr); } @@ -525,12 +528,16 @@ void ED_info_stats_clear(ViewLayer *view_layer) } } -const char *ED_info_stats_string(Scene *scene, ViewLayer *view_layer) +const char *ED_info_stats_string(Scene *UNUSED(scene), WorkSpace *workspace, ViewLayer *view_layer) { + Object *obact = (view_layer->basact) ? view_layer->basact->object : NULL; + Object *obedit = (obact && (workspace->object_mode & OB_MODE_EDIT) && + BKE_object_is_in_editmode(obact)) ? obact : NULL; + if (!view_layer->stats) { - stats_update(scene, view_layer); + stats_update(view_layer, obedit, workspace->object_mode); } - stats_string(scene, view_layer); + stats_string(view_layer, obedit, workspace->object_mode); return view_layer->stats->infostr; } diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c index 3eb0158e7b5..3f35cadd820 100644 --- a/source/blender/editors/space_info/textview.c +++ b/source/blender/editors/space_info/textview.c @@ -82,7 +82,7 @@ static void console_draw_sel(const char *str, const int sel[2], const int xy[2], const int end = txt_utf8_offset_to_column(str, min_ii(sel[1], str_len_draw)); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); Gwn_VertFormat *format = immVertexFormat(); unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index cb20b76a3ee..a18a692c0a3 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -408,7 +408,7 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri */ if ((strip->extendmode != NLASTRIP_EXTEND_NOTHING) && (non_solo == 0)) { /* enable transparency... */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); switch (strip->extendmode) { @@ -709,7 +709,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar) /* just draw a semi-shaded rect spanning the width of the viewable area if there's data, * and a second darker rect within which we draw keyframe indicator dots if there's data */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); /* get colors for drawing */ @@ -826,7 +826,7 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar) y = (float)(-NLACHANNEL_HEIGHT(snla)); /* set blending again, as may not be set in previous step */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); /* loop through channels, and set up drawing depending on their type */ diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 1bee2716e65..68934ebedd6 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -986,7 +986,7 @@ static void node_shader_buts_normal_map(uiLayout *layout, bContext *C, PointerRN { uiItemR(layout, ptr, "space", 0, "", 0); - if (RNA_enum_get(ptr, "space") == SHD_NORMAL_MAP_TANGENT) { + if (RNA_enum_get(ptr, "space") == SHD_SPACE_TANGENT) { PointerRNA obptr = CTX_data_pointer_get(C, "active_object"); if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) { @@ -998,6 +998,11 @@ static void node_shader_buts_normal_map(uiLayout *layout, bContext *C, PointerRN } } +static void node_shader_buts_displacement(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "space", 0, "", 0); +} + static void node_shader_buts_tangent(uiLayout *layout, bContext *C, PointerRNA *ptr) { uiLayout *split, *row; @@ -1027,6 +1032,12 @@ static void node_shader_buts_glossy(uiLayout *layout, bContext *UNUSED(C), Point uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE); } +static void node_shader_buts_principled(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE); + uiItemR(layout, ptr, "subsurface_method", 0, "", ICON_NONE); +} + static void node_shader_buts_anisotropic(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE); @@ -1189,15 +1200,21 @@ static void node_shader_set_butfunc(bNodeType *ntype) case SH_NODE_NORMAL_MAP: ntype->draw_buttons = node_shader_buts_normal_map; break; + case SH_NODE_DISPLACEMENT: + case SH_NODE_VECTOR_DISPLACEMENT: + ntype->draw_buttons = node_shader_buts_displacement; + break; case SH_NODE_TANGENT: ntype->draw_buttons = node_shader_buts_tangent; break; case SH_NODE_BSDF_GLOSSY: case SH_NODE_BSDF_GLASS: case SH_NODE_BSDF_REFRACTION: - case SH_NODE_BSDF_PRINCIPLED: ntype->draw_buttons = node_shader_buts_glossy; break; + case SH_NODE_BSDF_PRINCIPLED: + ntype->draw_buttons = node_shader_buts_principled; + break; case SH_NODE_BSDF_ANISOTROPIC: ntype->draw_buttons = node_shader_buts_anisotropic; break; @@ -3205,8 +3222,6 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b gpuPushMatrix(); /* somehow the offset has to be calculated inverse */ - - glaDefine2DArea(&ar->winrct); wmOrtho2_region_pixelspace(ar); x = (ar->winx - snode->zoom * ibuf->x) / 2 + snode->xof; @@ -3239,7 +3254,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b } else if (snode->flag & SNODE_USE_ALPHA) { glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST, snode->zoom, snode->zoom); diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 231039b2e22..94bd752cf81 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -705,7 +705,7 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv) node_draw_preview_background(BLI_rctf_size_x(prv) / 10.0f, &draw_rect); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* premul graphics */ + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* premul graphics */ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); immDrawPixelsTex(&state, draw_rect.xmin, draw_rect.ymin, preview->xsize, preview->ysize, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, preview->rect, @@ -1336,7 +1336,7 @@ void drawnodespace(const bContext *C, ARegion *ar) ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW); /* only set once */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* nodes */ snode_set_context(C); @@ -1404,7 +1404,6 @@ void drawnodespace(const bContext *C, ARegion *ar) gpuPushMatrix(); gpuLoadIdentity(); - glaDefine2DArea(&ar->winrct); wmOrtho2_pixelspace(ar->winx, ar->winy); WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_2D); diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index dc7863bb354..4b4add0e698 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -34,7 +34,7 @@ #include "BLI_utildefines.h" #include "BLI_rect.h" -#include "BLI_lasso.h" +#include "BLI_lasso_2d.h" #include "BLI_math.h" #include "BLI_string.h" #include "BLI_string_utf8.h" diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c index 8999555521a..efc28eea917 100644 --- a/source/blender/editors/space_outliner/outliner_collections.c +++ b/source/blender/editors/space_outliner/outliner_collections.c @@ -37,6 +37,7 @@ #include "DEG_depsgraph_build.h" #include "DNA_group_types.h" +#include "DNA_object_types.h" #include "ED_screen.h" @@ -91,6 +92,30 @@ static int view_layer_editor_poll(bContext *C) return (so != NULL) && (so->outlinevis == SO_VIEW_LAYER); } +static int outliner_either_collection_editor_poll(bContext *C) +{ + SpaceOops *so = CTX_wm_space_outliner(C); + return (so != NULL) && (ELEM(so->outlinevis, SO_VIEW_LAYER, SO_COLLECTIONS)); +} + +static int outliner_objects_collection_poll(bContext *C) +{ + SpaceOops *so = CTX_wm_space_outliner(C); + if (so == NULL) { + return 0; + } + + /* Groups don't support filtering. */ + if ((so->outlinevis != SO_GROUPS) && + ((so->filter & (SO_FILTER_ENABLE | SO_FILTER_NO_COLLECTION)) == + (SO_FILTER_ENABLE | SO_FILTER_NO_COLLECTION))) + { + return 0; + } + + return ELEM(so->outlinevis, SO_VIEW_LAYER, SO_COLLECTIONS, SO_GROUPS); +} + /* -------------------------------------------------------------------- */ /* collection manager operators */ @@ -317,7 +342,8 @@ static int collection_new_exec(bContext *C, wmOperator *UNUSED(op)) Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - SceneCollection *scene_collection = BKE_collection_add(&scene->id, NULL, COLLECTION_TYPE_NONE, NULL); + SceneCollection *scene_collection_parent = BKE_collection_master(&scene->id); + SceneCollection *scene_collection = BKE_collection_add(&scene->id, scene_collection_parent, COLLECTION_TYPE_NONE, NULL); BKE_collection_link(view_layer, scene_collection); DEG_relations_tag_update(bmain); @@ -468,7 +494,7 @@ static int collection_objects_add_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN (C, struct Object *, ob, selected_objects) { - BLI_LISTBASE_FOREACH (LinkData *, link, &data.scene_collections_array) { + LISTBASE_FOREACH (LinkData *, link, &data.scene_collections_array) { SceneCollection *scene_collection = link->data; BKE_collection_object_add( &scene->id, @@ -523,7 +549,7 @@ static int collection_objects_remove_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN (C, struct Object *, ob, selected_objects) { - BLI_LISTBASE_FOREACH (LinkData *, link, &data.scene_collections_array) { + LISTBASE_FOREACH (LinkData *, link, &data.scene_collections_array) { SceneCollection *scene_collection = link->data; BKE_collection_object_remove( bmain, @@ -557,6 +583,139 @@ void OUTLINER_OT_collection_objects_remove(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static TreeElement *outliner_collection_parent_element_get(TreeElement *te) +{ + TreeElement *te_parent = te; + while ((te_parent = te_parent->parent)) { + if (outliner_scene_collection_from_tree_element(te->parent)) { + return te_parent; + } + } + return NULL; +} + +static int object_collection_remove_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceOops *soops = CTX_wm_space_outliner(C); + Main *bmain = CTX_data_main(C); + + struct ObjectsSelectedData data = { + .objects_selected_array = {NULL, NULL}, + }; + + outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &data); + + LISTBASE_FOREACH (LinkData *, link, &data.objects_selected_array) { + TreeElement *te = (TreeElement *)link->data; + Object *ob = (Object *)TREESTORE(te)->id; + SceneCollection *scene_collection = NULL; + + TreeElement *te_parent = outliner_collection_parent_element_get(te); + if (te_parent != NULL) { + scene_collection = outliner_scene_collection_from_tree_element(te_parent); + ID *owner_id = TREESTORE(te_parent)->id; + BKE_collection_object_remove(bmain, owner_id, scene_collection, ob, true); + DEG_id_tag_update(owner_id, DEG_TAG_BASE_FLAGS_UPDATE); + } + } + + BLI_freelistN(&data.objects_selected_array); + + outliner_cleanup_tree(soops); + DEG_relations_tag_update(bmain); + + WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); + WM_main_add_notifier(NC_SCENE | ND_OB_ACTIVE, NULL); + WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, NULL); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_object_remove_from_collection(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Object from Collection"; + ot->idname = "OUTLINER_OT_object_remove_from_collection"; + ot->description = "Remove selected objects from their respective collection"; + + /* api callbacks */ + ot->exec = object_collection_remove_exec; + ot->poll = outliner_objects_collection_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int object_add_to_new_collection_exec(bContext *C, wmOperator *op) +{ + int operator_result = OPERATOR_CANCELLED; + + SpaceOops *soops = CTX_wm_space_outliner(C); + Main *bmain = CTX_data_main(C); + + SceneCollection *scene_collection_parent, *scene_collection_new; + TreeElement *te_active, *te_parent; + + struct ObjectsSelectedData data = {NULL}, active = {NULL}; + + outliner_tree_traverse(soops, &soops->tree, 0, TSE_HIGHLIGHTED, outliner_find_selected_objects, &active); + if (BLI_listbase_is_empty(&active.objects_selected_array)) { + BKE_report(op->reports, RPT_ERROR, "No object is selected"); + goto cleanup; + } + + outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &data); + if (BLI_listbase_is_empty(&data.objects_selected_array)) { + BKE_report(op->reports, RPT_ERROR, "No objects are selected"); + goto cleanup; + } + + /* Heuristic to get the "active" / "last object" */ + te_active = ((LinkData *)active.objects_selected_array.first)->data; + te_parent = outliner_collection_parent_element_get(te_active); + + if (te_parent == NULL) { + BKE_reportf(op->reports, RPT_ERROR, "Couldn't find collection of \"%s\" object", te_active->name); + goto cleanup; + } + + ID *owner_id = TREESTORE(te_parent)->id; + scene_collection_parent = outliner_scene_collection_from_tree_element(te_parent); + scene_collection_new = BKE_collection_add(owner_id, scene_collection_parent, scene_collection_parent->type, NULL); + + LISTBASE_FOREACH (LinkData *, link, &data.objects_selected_array) { + TreeElement *te = (TreeElement *)link->data; + Object *ob = (Object *)TREESTORE(te)->id; + BKE_collection_object_add(owner_id, scene_collection_new, ob); + } + + outliner_cleanup_tree(soops); + DEG_relations_tag_update(bmain); + + WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); + + operator_result = OPERATOR_FINISHED; +cleanup: + BLI_freelistN(&active.objects_selected_array); + BLI_freelistN(&data.objects_selected_array); + return operator_result; +} + +void OUTLINER_OT_object_add_to_new_collection(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Objects to New Collection"; + ot->idname = "OUTLINER_OT_object_add_to_new_collection"; + ot->description = "Add objects to a new collection"; + + /* api callbacks */ + ot->exec = object_add_to_new_collection_exec; + ot->poll = outliner_objects_collection_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + struct CollectionDeleteData { Scene *scene; SpaceOops *soops; @@ -757,3 +916,139 @@ void OUTLINER_OT_collection_toggle(wmOperatorType *ot) #undef ACTION_TOGGLE #undef ACTION_ENABLE #undef ACTION_DISABLE + +struct CollectionObjectsSelectData { + bool error; + LayerCollection *layer_collection; +}; + +static TreeTraversalAction outliner_find_first_selected_layer_collection(TreeElement *te, void *customdata) +{ + struct CollectionObjectsSelectData *data = customdata; + TreeStoreElem *tselem = TREESTORE(te); + + switch (tselem->type) { + case TSE_LAYER_COLLECTION: + data->layer_collection = te->directdata; + return TRAVERSE_BREAK; + case TSE_LAYER_COLLECTION_BASE: + return TRAVERSE_CONTINUE; + default: + return TRAVERSE_SKIP_CHILDS; + } +} + +static LayerCollection *outliner_active_layer_collection(bContext *C) +{ + SpaceOops *soops = CTX_wm_space_outliner(C); + + struct CollectionObjectsSelectData data = { + .layer_collection = NULL, + }; + + outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_first_selected_layer_collection, &data); + return data.layer_collection; +} + +static int collection_objects_select_exec(bContext *C, wmOperator *UNUSED(op)) +{ + LayerCollection *layer_collection = outliner_active_layer_collection(C); + + if (layer_collection == NULL) { + return OPERATOR_CANCELLED; + } + + BKE_layer_collection_objects_select(layer_collection); + WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, CTX_data_scene(C)); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_collection_objects_select(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Objects"; + ot->idname = "OUTLINER_OT_collection_objects_select"; + ot->description = "Select all the collection objects"; + + /* api callbacks */ + ot->exec = collection_objects_select_exec; + ot->poll = view_layer_editor_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +struct CollectionDuplicateData { + TreeElement *te; +}; + +static TreeTraversalAction outliner_find_first_selected_collection(TreeElement *te, void *customdata) +{ + struct CollectionDuplicateData *data = customdata; + TreeStoreElem *tselem = TREESTORE(te); + + switch (tselem->type) { + case TSE_LAYER_COLLECTION: + case TSE_SCENE_COLLECTION: + data->te = te; + return TRAVERSE_BREAK; + case TSE_LAYER_COLLECTION_BASE: + default: + return TRAVERSE_CONTINUE; + } +} + +static TreeElement *outliner_active_collection(bContext *C) +{ + SpaceOops *soops = CTX_wm_space_outliner(C); + + struct CollectionDuplicateData data = { + .te = NULL, + }; + + outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_first_selected_collection, &data); + return data.te; +} + +static int collection_duplicate_exec(bContext *C, wmOperator *op) +{ + SpaceOops *soops = CTX_wm_space_outliner(C); + TreeElement *te = outliner_active_collection(C); + + BLI_assert(te != NULL); + if (BKE_collection_master(TREESTORE(te)->id) == outliner_scene_collection_from_tree_element(te)) { + BKE_report(op->reports, RPT_ERROR, "You can't duplicate the master collection"); + return OPERATOR_CANCELLED; + } + + switch (soops->outlinevis) { + case SO_COLLECTIONS: + BKE_collection_duplicate(TREESTORE(te)->id, (SceneCollection *)te->directdata); + break; + case SO_VIEW_LAYER: + case SO_GROUPS: + BKE_layer_collection_duplicate(TREESTORE(te)->id, (LayerCollection *)te->directdata); + break; + } + + DEG_relations_tag_update(CTX_data_main(C)); + WM_main_add_notifier(NC_SCENE | ND_LAYER, CTX_data_scene(C)); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_collection_duplicate(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Duplicate Collection"; + ot->idname = "OUTLINER_OT_collection_duplicate"; + ot->description = "Duplicate collection"; + + /* api callbacks */ + ot->exec = collection_duplicate_exec; + ot->poll = outliner_either_collection_editor_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 1478792b38b..90e59a677ac 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -409,7 +409,8 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname) case TSE_LAYER_COLLECTION: { SceneCollection *sc = outliner_scene_collection_from_tree_element(te); - BKE_collection_rename(scene, sc, te->name); + BKE_collection_rename(tselem->id, sc, te->name); + WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene); break; } } @@ -671,7 +672,7 @@ static void outliner_draw_userbuts(uiBlock *block, ARegion *ar, SpaceOops *soops } } -static void UNUSED_FUNCTION(outliner_draw_rnacols)(ARegion *ar, int sizex) +static void outliner_draw_rnacols(ARegion *ar, int sizex) { View2D *v2d = &ar->v2d; @@ -697,7 +698,6 @@ static void UNUSED_FUNCTION(outliner_draw_rnacols)(ARegion *ar, int sizex) immUnbindProgram(); } -#if 0 static void outliner_draw_rnabuts(uiBlock *block, ARegion *ar, SpaceOops *soops, int sizex, ListBase *lb) { TreeElement *te; @@ -742,7 +742,6 @@ static void outliner_draw_rnabuts(uiBlock *block, ARegion *ar, SpaceOops *soops, UI_block_emboss_set(block, UI_EMBOSS); } -#endif static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, TreeElement *te) { @@ -1236,8 +1235,9 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto #undef ICON_DRAW } -static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, ViewLayer *view_layer, SpaceOops *soops, - ListBase *lb, int level, int xmax, int *offsx, int ys, float alpha_fac) +static void outliner_draw_iconrow( + bContext *C, uiBlock *block, Scene *scene, ViewLayer *view_layer, Object *obedit, SpaceOops *soops, + ListBase *lb, int level, int xmax, int *offsx, int ys, float alpha_fac) { TreeElement *te; TreeStoreElem *tselem; @@ -1258,7 +1258,7 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Vie if (te->idcode == ID_OB) { active = (OBACT(view_layer) == (Object *)tselem->id) ? OL_DRAWSEL_NORMAL : OL_DRAWSEL_NONE; } - else if (scene->obedit && scene->obedit->data == tselem->id) { + else if (obedit && obedit->data == tselem->id) { active = OL_DRAWSEL_NORMAL; } else { @@ -1298,7 +1298,9 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Vie /* this tree element always has same amount of branches, so don't draw */ if (tselem->type != TSE_R_LAYER) - outliner_draw_iconrow(C, block, scene, view_layer, soops, &te->subtree, level + 1, xmax, offsx, ys, alpha_fac); + outliner_draw_iconrow( + C, block, scene, view_layer, obedit, soops, + &te->subtree, level + 1, xmax, offsx, ys, alpha_fac); } } @@ -1322,7 +1324,7 @@ static void outliner_set_coord_tree_element(TreeElement *te, int startx, int sta static void outliner_draw_tree_element( - bContext *C, uiBlock *block, const uiFontStyle *fstyle, Scene *scene, ViewLayer *view_layer, + bContext *C, uiBlock *block, const uiFontStyle *fstyle, Scene *scene, ViewLayer *view_layer, Object *obedit, ARegion *ar, SpaceOops *soops, TreeElement *te, bool draw_grayed_out, int startx, int *starty, TreeElement **te_edit, TreeElement **te_floating) { @@ -1386,7 +1388,7 @@ static void outliner_draw_tree_element( } } - else if (scene->obedit && scene->obedit->data == tselem->id) { + else if (obedit && obedit->data == tselem->id) { rgba_float_args_set(color, 1.0f, 1.0f, 1.0f, alpha); active = OL_DRAWSEL_ACTIVE; } @@ -1516,8 +1518,9 @@ static void outliner_draw_tree_element( immUnbindProgram(); } - outliner_draw_iconrow(C, block, scene, view_layer, soops, &te->subtree, 0, xmax, &tempx, - *starty, alpha_fac); + outliner_draw_iconrow( + C, block, scene, view_layer, obedit, soops, &te->subtree, 0, xmax, &tempx, + *starty, alpha_fac); glDisable(GL_BLEND); } @@ -1536,8 +1539,10 @@ static void outliner_draw_tree_element( /* check if element needs to be drawn grayed out, but also gray out * childs of a grayed out parent (pass on draw_grayed_out to childs) */ bool draw_childs_grayed_out = draw_grayed_out || (ten->drag_data != NULL); - outliner_draw_tree_element(C, block, fstyle, scene, view_layer, ar, soops, ten, draw_childs_grayed_out, - startx + UI_UNIT_X, starty, te_edit, te_floating); + outliner_draw_tree_element( + C, block, fstyle, scene, view_layer, obedit, + ar, soops, ten, draw_childs_grayed_out, + startx + UI_UNIT_X, starty, te_edit, te_floating); } } else { @@ -1776,15 +1781,15 @@ static void outliner_draw_highlights(ARegion *ar, SpaceOops *soops, int startx, } static void outliner_draw_tree( - bContext *C, uiBlock *block, Scene *scene, ViewLayer *view_layer, ARegion *ar, - SpaceOops *soops, const bool has_restrict_icons, + bContext *C, uiBlock *block, Scene *scene, ViewLayer *view_layer, Object *obedit, + ARegion *ar, SpaceOops *soops, const bool has_restrict_icons, TreeElement **te_edit) { const uiFontStyle *fstyle = UI_FSTYLE_WIDGET; TreeElement *te_floating = NULL; int starty, startx; - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // only once + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // only once if (soops->outlinevis == SO_DATABLOCKS) { /* struct marks */ @@ -1817,8 +1822,10 @@ static void outliner_draw_tree( starty = (int)ar->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET; startx = 0; for (TreeElement *te = soops->tree.first; te; te = te->next) { - outliner_draw_tree_element(C, block, fstyle, scene, view_layer, ar, soops, te, te->drag_data != NULL, - startx, &starty, te_edit, &te_floating); + outliner_draw_tree_element( + C, block, fstyle, scene, view_layer, obedit, + ar, soops, te, te->drag_data != NULL, + startx, &starty, te_edit, &te_floating); } if (te_floating && te_floating->drag_data->insert_handle) { outliner_draw_tree_element_floating(ar, te_floating); @@ -1893,6 +1900,9 @@ static void outliner_draw_restrictcols(ARegion *ar) void draw_outliner(const bContext *C) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + Object *obedit = OBEDIT_FROM_EVAL_CTX(&eval_ctx); Main *mainvar = CTX_data_main(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); @@ -1904,7 +1914,7 @@ void draw_outliner(const bContext *C) TreeElement *te_edit = NULL; bool has_restrict_icons; - outliner_build_tree(mainvar, scene, view_layer, soops, ar); // always + outliner_build_tree(mainvar, &eval_ctx, scene, view_layer, soops, ar); // always /* get extents of data */ outliner_height(soops, &soops->tree, &sizey); @@ -1955,9 +1965,16 @@ void draw_outliner(const bContext *C) /* draw outliner stuff (background, hierarchy lines and names) */ outliner_back(ar); block = UI_block_begin(C, ar, __func__, UI_EMBOSS); - outliner_draw_tree((bContext *)C, block, scene, view_layer, ar, soops, has_restrict_icons, &te_edit); + outliner_draw_tree( + (bContext *)C, block, scene, view_layer, obedit, + ar, soops, has_restrict_icons, &te_edit); - if ((soops->outlinevis == SO_ID_ORPHANS) && has_restrict_icons) { + if (soops->outlinevis == SO_DATABLOCKS) { + /* draw rna buttons */ + outliner_draw_rnacols(ar, sizex_rna); + outliner_draw_rnabuts(block, ar, soops, sizex_rna, &soops->tree); + } + else if ((soops->outlinevis == SO_ID_ORPHANS) && has_restrict_icons) { /* draw user toggle columns */ outliner_draw_restrictcols(ar); outliner_draw_userbuts(block, ar, soops, &soops->tree); diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index fc0e30c78ce..6bbec6a1a48 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -64,6 +64,7 @@ #include "BKE_material.h" #include "BKE_group.h" +#include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" #include "../blenloader/BLO_readfile.h" @@ -977,6 +978,7 @@ static int outliner_open_back(TreeElement *te) static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op)) { + const WorkSpace *workspace = CTX_wm_workspace(C); SpaceOops *so = CTX_wm_space_outliner(C); ViewLayer *view_layer = CTX_data_view_layer(C); ARegion *ar = CTX_wm_region(C); @@ -997,13 +999,13 @@ static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op)) /* traverse down the bone hierarchy in case of armature */ TreeElement *te_obact = te; - if (obact->mode & OB_MODE_POSE) { + if (workspace->object_mode & OB_MODE_POSE) { bPoseChannel *pchan = CTX_data_active_pose_bone(C); if (pchan) { te = outliner_find_posechannel(&te_obact->subtree, pchan); } } - else if (obact->mode & OB_MODE_EDIT) { + else if (workspace->object_mode & OB_MODE_EDIT) { EditBone *ebone = CTX_data_active_bone(C); if (ebone) { te = outliner_find_editbone(&te_obact->subtree, ebone); diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index b06c9b85eb8..148af52050d 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -37,6 +37,7 @@ /* internal exports only */ struct ARegion; +struct ListBase; struct wmOperatorType; struct TreeElement; struct TreeStoreElem; @@ -50,7 +51,7 @@ struct bPoseChannel; struct EditBone; struct wmEvent; struct wmKeyConfig; - +struct EvaluationContext; typedef enum TreeElementInsertType { TE_INSERT_BEFORE, @@ -191,8 +192,16 @@ void outliner_cleanup_tree(struct SpaceOops *soops); void outliner_free_tree_element(TreeElement *element, ListBase *parent_subtree); void outliner_remove_treestore_element(struct SpaceOops *soops, TreeStoreElem *tselem); -void outliner_build_tree(struct Main *mainvar, struct Scene *scene, struct ViewLayer *view_layer, - struct SpaceOops *soops, struct ARegion *ar); +void outliner_build_tree( + struct Main *mainvar, const struct EvaluationContext *eval_ctx, + struct Scene *scene, struct ViewLayer *view_layer, + struct SpaceOops *soops, struct ARegion *ar); + +typedef struct ObjectsSelectedData { + struct ListBase objects_selected_array; +} ObjectsSelectedData; + +TreeTraversalAction outliner_find_selected_objects(struct TreeElement *te, void *customdata); /* outliner_draw.c ---------------------------------------------- */ @@ -344,7 +353,11 @@ void OUTLINER_OT_collection_toggle(struct wmOperatorType *ot); void OUTLINER_OT_collection_link(struct wmOperatorType *ot); void OUTLINER_OT_collection_unlink(struct wmOperatorType *ot); void OUTLINER_OT_collection_new(struct wmOperatorType *ot); +void OUTLINER_OT_collection_duplicate(struct wmOperatorType *ot); void OUTLINER_OT_collection_objects_remove(struct wmOperatorType *ot); +void OUTLINER_OT_collection_objects_select(struct wmOperatorType *ot); +void OUTLINER_OT_object_add_to_new_collection(struct wmOperatorType *ot); +void OUTLINER_OT_object_remove_from_collection(struct wmOperatorType *ot); void OUTLINER_OT_collection_objects_add(struct wmOperatorType *ot); void OUTLINER_OT_collection_nested_new(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c index 52f27b9708e..ba501ac7db5 100644 --- a/source/blender/editors/space_outliner/outliner_ops.c +++ b/source/blender/editors/space_outliner/outliner_ops.c @@ -474,11 +474,15 @@ void outliner_operatortypes(void) WM_operatortype_append(OUTLINER_OT_collection_link); WM_operatortype_append(OUTLINER_OT_collection_unlink); WM_operatortype_append(OUTLINER_OT_collection_new); + WM_operatortype_append(OUTLINER_OT_collection_duplicate); WM_operatortype_append(OUTLINER_OT_collection_nested_new); WM_operatortype_append(OUTLINER_OT_collection_delete_selected); WM_operatortype_append(OUTLINER_OT_collection_objects_add); WM_operatortype_append(OUTLINER_OT_collection_objects_remove); + WM_operatortype_append(OUTLINER_OT_collection_objects_select); + WM_operatortype_append(OUTLINER_OT_object_add_to_new_collection); + WM_operatortype_append(OUTLINER_OT_object_remove_from_collection); } static wmKeyMap *outliner_item_drag_drop_modal_keymap(wmKeyConfig *keyconf) diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index b9222e62bb0..16f3aeaf110 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -193,10 +193,10 @@ static eOLDrawState tree_element_set_active_object( WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); } } - - if (ob != scene->obedit) + + if (CTX_data_edit_object(C)) { ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); - + } return OL_DRAWSEL_NORMAL; } @@ -547,7 +547,7 @@ static eOLDrawState tree_element_active_bone( /* ebones only draw in editmode armature */ -static void tree_element_active_ebone__sel(bContext *C, Scene *scene, bArmature *arm, EditBone *ebone, short sel) +static void tree_element_active_ebone__sel(bContext *C, Object *obedit, bArmature *arm, EditBone *ebone, short sel) { if (sel) { ebone->flag |= BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL; @@ -561,34 +561,34 @@ static void tree_element_active_ebone__sel(bContext *C, Scene *scene, bArmature if (ebone->parent && (ebone->flag & BONE_CONNECTED)) ebone->parent->flag &= ~BONE_TIPSEL; } - WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, scene->obedit); + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, obedit); } static eOLDrawState tree_element_active_ebone( - bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tselem), const eOLSetState set, bool recursive) + bContext *C, TreeElement *te, TreeStoreElem *UNUSED(tselem), const eOLSetState set, bool recursive) { - BLI_assert(scene->obedit != NULL); - - bArmature *arm = scene->obedit->data; + Object *obedit = CTX_data_edit_object(C); + BLI_assert(obedit != NULL); + bArmature *arm = obedit->data; EditBone *ebone = te->directdata; eOLDrawState status = OL_DRAWSEL_NONE; if (set != OL_SETSEL_NONE) { if (set == OL_SETSEL_NORMAL) { if (!(ebone->flag & BONE_HIDDEN_A)) { - ED_armature_deselect_all(scene->obedit); - tree_element_active_ebone__sel(C, scene, arm, ebone, true); + ED_armature_deselect_all(obedit); + tree_element_active_ebone__sel(C, obedit, arm, ebone, true); status = OL_DRAWSEL_NORMAL; } } else if (set == OL_SETSEL_EXTEND) { if (!(ebone->flag & BONE_HIDDEN_A)) { if (!(ebone->flag & BONE_SELECTED)) { - tree_element_active_ebone__sel(C, scene, arm, ebone, true); + tree_element_active_ebone__sel(C, obedit, arm, ebone, true); status = OL_DRAWSEL_NORMAL; } else { /* entirely selected, so de-select */ - tree_element_active_ebone__sel(C, scene, arm, ebone, false); + tree_element_active_ebone__sel(C, obedit, arm, ebone, false); status = OL_DRAWSEL_NONE; } } @@ -656,8 +656,9 @@ static eOLDrawState tree_element_active_text( } static eOLDrawState tree_element_active_pose( - bContext *C, Scene *scene, ViewLayer *view_layer, TreeElement *UNUSED(te), TreeStoreElem *tselem, const eOLSetState set) + bContext *C, ViewLayer *view_layer, TreeElement *UNUSED(te), TreeStoreElem *tselem, const eOLSetState set) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = (Object *)tselem->id; Base *base = BKE_view_layer_base_find(view_layer, ob); @@ -667,16 +668,18 @@ static eOLDrawState tree_element_active_pose( } if (set != OL_SETSEL_NONE) { - if (scene->obedit) + if (workspace->object_mode & OB_MODE_EDIT) { ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); - - if (ob->mode & OB_MODE_POSE) + } + if (workspace->object_mode & OB_MODE_POSE) { ED_armature_exit_posemode(C, base); - else + } + else { ED_armature_enter_posemode(C, base); + } } else { - if (ob->mode & OB_MODE_POSE) { + if (workspace->object_mode & OB_MODE_POSE) { return OL_DRAWSEL_NORMAL; } } @@ -847,7 +850,7 @@ eOLDrawState tree_element_type_active( case TSE_BONE: return tree_element_active_bone(C, view_layer, te, tselem, set, recursive); case TSE_EBONE: - return tree_element_active_ebone(C, scene, te, tselem, set, recursive); + return tree_element_active_ebone(C, te, tselem, set, recursive); case TSE_MODIFIER: return tree_element_active_modifier(C, scene, view_layer, te, tselem, set); case TSE_LINKED_OB: @@ -861,7 +864,7 @@ eOLDrawState tree_element_type_active( case TSE_LINKED_PSYS: return tree_element_active_psys(C, scene, te, tselem, set); case TSE_POSE_BASE: - return tree_element_active_pose(C, scene, view_layer, te, tselem, set); + return tree_element_active_pose(C, view_layer, te, tselem, set); case TSE_POSE_CHANNEL: return tree_element_active_posechannel(C, scene, view_layer, te, tselem, set, recursive); case TSE_CONSTRAINT: diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 9f0165d1272..b97046d1470 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -419,9 +419,9 @@ static void object_delete_cb( } // check also library later - if (scene->obedit == ob) + if (ob == CTX_data_edit_object(C)) { ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); - + } ED_object_base_free_and_unlink(CTX_data_main(C), scene, ob); /* leave for ED_outliner_id_unref to handle */ #if 0 @@ -675,7 +675,9 @@ typedef enum eOutliner_PropModifierOps { typedef enum eOutliner_PropCollectionOps { OL_COLLECTION_OP_OBJECTS_ADD = 1, OL_COLLECTION_OP_OBJECTS_REMOVE, + OL_COLLECTION_OP_OBJECTS_SELECT, OL_COLLECTION_OP_COLLECTION_NEW, + OL_COLLECTION_OP_COLLECTION_COPY, OL_COLLECTION_OP_COLLECTION_DEL, OL_COLLECTION_OP_COLLECTION_UNLINK, OL_COLLECTION_OP_GROUP_CREATE, @@ -860,6 +862,10 @@ static void collection_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tsel WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene); te->store_elem->flag &= ~TSE_SELECTED; } + else if (event == OL_COLLECTION_OP_OBJECTS_SELECT) { + BKE_layer_collection_objects_select(lc); + WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene); + } else if (event == OL_COLLECTION_OP_COLLECTION_NEW) { if (GS(id->name) == ID_GR) { BKE_collection_add(id, sc, COLLECTION_TYPE_GROUP_INTERNAL, NULL); @@ -870,6 +876,11 @@ static void collection_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tsel } WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene); } + else if (event == OL_COLLECTION_OP_COLLECTION_COPY) { + BKE_layer_collection_duplicate(id, lc); + DEG_relations_tag_update(CTX_data_main(C)); + WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene); + } else if (event == OL_COLLECTION_OP_COLLECTION_UNLINK) { ViewLayer *view_layer = CTX_data_view_layer(C); @@ -969,7 +980,7 @@ static void object_delete_hierarchy_cb( { ViewLayer *view_layer = CTX_data_view_layer(C); Base *base = (Base *)te->directdata; - Object *obedit = scene->obedit; + Object *obedit = CTX_data_edit_object(C); if (!base) { base = BKE_view_layer_base_find(view_layer, (Object *)tselem->id); @@ -1841,39 +1852,18 @@ void OUTLINER_OT_modifier_operation(wmOperatorType *ot) /* ******************** */ -static EnumPropertyItem prop_collection_op_none_types[] = { +static EnumPropertyItem prop_collection_op_types[] = { {OL_COLLECTION_OP_OBJECTS_ADD, "OBJECTS_ADD", ICON_ZOOMIN, "Add Selected", "Add selected objects to collection"}, {OL_COLLECTION_OP_OBJECTS_REMOVE, "OBJECTS_REMOVE", ICON_X, "Remove Selected", "Remove selected objects from collection"}, + {OL_COLLECTION_OP_OBJECTS_SELECT, "OBJECTS_SELECT", ICON_RESTRICT_SELECT_OFF, "Select Objects", "Selected collection objects"}, {OL_COLLECTION_OP_COLLECTION_NEW, "COLLECTION_NEW", ICON_NEW, "New Collection", "Add a new nested collection"}, + {OL_COLLECTION_OP_COLLECTION_COPY, "COLLECTION_DUPLI", ICON_NONE, "Duplicate Collection", "Duplicate the collection"}, {OL_COLLECTION_OP_COLLECTION_UNLINK, "COLLECTION_UNLINK", ICON_UNLINKED, "Unlink", "Unlink collection"}, {OL_COLLECTION_OP_COLLECTION_DEL, "COLLECTION_DEL", ICON_X, "Delete Collection", "Delete the collection"}, {OL_COLLECTION_OP_GROUP_CREATE, "GROUP_CREATE", ICON_GROUP, "Create Group", "Turn the collection into a group collection"}, {0, NULL, 0, NULL, NULL} }; -static EnumPropertyItem prop_collection_op_group_internal_types[] = { - {OL_COLLECTION_OP_OBJECTS_ADD, "OBJECTS_ADD", ICON_ZOOMIN, "Add Selected", "Add selected objects to collection"}, - {OL_COLLECTION_OP_OBJECTS_REMOVE, "OBJECTS_REMOVE", ICON_X, "Remove Selected", "Remove selected objects from collection"}, - {OL_COLLECTION_OP_COLLECTION_NEW, "COLLECTION_NEW", ICON_NEW, "New Collection", "Add a new nested collection"}, - {OL_COLLECTION_OP_COLLECTION_DEL, "COLLECTION_DEL", ICON_X, "Delete Collection", "Delete the collection"}, - {0, NULL, 0, NULL, NULL} -}; - -static const EnumPropertyItem *outliner_collection_operation_type_itemf( - bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) -{ - *r_free = false; - SpaceOops *soops = CTX_wm_space_outliner(C); - - switch (soops->outlinevis) { - case SO_GROUPS: - return prop_collection_op_group_internal_types; - case SO_VIEW_LAYER: - return prop_collection_op_none_types; - } - return NULL; -} - static int outliner_collection_operation_exec(bContext *C, wmOperator *op) { SpaceOops *soops = CTX_wm_space_outliner(C); @@ -1892,6 +1882,31 @@ static int outliner_collection_operation_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int outliner_collection_operation_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + SpaceOops *soops = CTX_wm_space_outliner(C); + wmOperatorType *ot = op->type; + EnumPropertyItem *prop = &prop_collection_op_types[0]; + + uiPopupMenu *pup = UI_popup_menu_begin(C, "Collection", ICON_NONE); + uiLayout *layout = UI_popup_menu_layout(pup); + + for (int i = 0; i < (ARRAY_SIZE(prop_collection_op_types) - 1); i++, prop++) { + if (soops->outlinevis != SO_GROUPS || + !ELEM(prop->value, + OL_COLLECTION_OP_OBJECTS_SELECT, + OL_COLLECTION_OP_COLLECTION_UNLINK, + OL_COLLECTION_OP_GROUP_CREATE)) + { + uiItemEnumO_ptr(layout, ot, NULL, prop->icon, "type", prop->value); + } + } + + UI_popup_menu_end(C, pup); + + return OPERATOR_INTERFACE; +} + void OUTLINER_OT_collection_operation(wmOperatorType *ot) { PropertyRNA *prop; @@ -1902,14 +1917,13 @@ void OUTLINER_OT_collection_operation(wmOperatorType *ot) ot->description = ""; /* callbacks */ - ot->invoke = WM_menu_invoke; + ot->invoke = outliner_collection_operation_invoke; ot->exec = outliner_collection_operation_exec; ot->poll = ED_operator_outliner_active; ot->flag = 0; - prop = RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, 0, "Collection Operation", ""); - RNA_def_enum_funcs(prop, outliner_collection_operation_type_itemf); + prop = RNA_def_enum(ot->srna, "type", prop_collection_op_types, OL_COLLECTION_OP_OBJECTS_ADD, "Collection Operation", ""); RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE); ot->prop = prop; } diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 06b3319935d..00eb4efde02 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -92,10 +92,12 @@ /* prototypes */ static void outliner_add_layer_collections_recursive( - SpaceOops *soops, ListBase *tree, ID *id, ListBase *layer_collections, TreeElement *parent_ten, + SpaceOops *soops, const EvaluationContext *eval_ctx, + ListBase *tree, ID *id, ListBase *layer_collections, TreeElement *parent_ten, const bool show_objects); static void outliner_add_view_layer( - SpaceOops *soops, ListBase *tree, TreeElement *parent, + SpaceOops *soops, const EvaluationContext *eval_ctx, + ListBase *tree, TreeElement *parent, Scene *scene, ViewLayer *layer, const bool show_objects); static void outliner_make_hierarchy(ListBase *lb); @@ -129,7 +131,7 @@ static void outliner_storage_cleanup(SpaceOops *soops) } if (unused) { - if (BLI_mempool_count(ts) == unused) { + if (BLI_mempool_len(ts) == unused) { BLI_mempool_destroy(ts); soops->treestore = NULL; if (soops->treehash) { @@ -139,7 +141,7 @@ static void outliner_storage_cleanup(SpaceOops *soops) } else { TreeStoreElem *tsenew; - BLI_mempool *new_ts = BLI_mempool_create(sizeof(TreeStoreElem), BLI_mempool_count(ts) - unused, + BLI_mempool *new_ts = BLI_mempool_create(sizeof(TreeStoreElem), BLI_mempool_len(ts) - unused, 512, BLI_MEMPOOL_ALLOW_ITER); BLI_mempool_iternew(ts, &iter); while ((tselem = BLI_mempool_iterstep(&iter))) { @@ -233,23 +235,25 @@ void outliner_free_tree_element(TreeElement *element, ListBase *parent_subtree) /* ********************************************************* */ /* Prototype, see functions below */ -static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *idv, - TreeElement *parent, short type, short index); +static TreeElement *outliner_add_element( + SpaceOops *soops, const EvaluationContext *eval_ctx, + ListBase *lb, void *idv, TreeElement *parent, short type, short index); /* -------------------------------------------------------- */ /* special handling of hierarchical non-lib data */ -static void outliner_add_bone(SpaceOops *soops, ListBase *lb, ID *id, Bone *curBone, - TreeElement *parent, int *a) +static void outliner_add_bone( + SpaceOops *soops, const EvaluationContext *eval_ctx, + ListBase *lb, ID *id, Bone *curBone, TreeElement *parent, int *a) { - TreeElement *te = outliner_add_element(soops, lb, id, parent, TSE_BONE, *a); + TreeElement *te = outliner_add_element(soops, eval_ctx, lb, id, parent, TSE_BONE, *a); (*a)++; te->name = curBone->name; te->directdata = curBone; for (curBone = curBone->childbase.first; curBone; curBone = curBone->next) { - outliner_add_bone(soops, &te->subtree, id, curBone, te, a); + outliner_add_bone(soops, eval_ctx, &te->subtree, id, curBone, te, a); } } @@ -257,7 +261,9 @@ static void outliner_add_bone(SpaceOops *soops, ListBase *lb, ID *id, Bone *curB #define LOG2I(x) (int)(log(x) / M_LN2) -static void outliner_add_passes(SpaceOops *soops, TreeElement *tenla, ID *id, ViewLayer *view_layer) +static void outliner_add_passes( + SpaceOops *soops, const EvaluationContext *eval_ctx, + TreeElement *tenla, ID *id, ViewLayer *view_layer) { TreeStoreElem *tselem = NULL; TreeElement *te = NULL; @@ -265,7 +271,7 @@ static void outliner_add_passes(SpaceOops *soops, TreeElement *tenla, ID *id, Vi /* log stuff is to convert bitflags (powers of 2) to small integers, * in order to not overflow short tselem->nr */ - te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_COMBINED)); + te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_COMBINED)); te->name = IFACE_("Combined"); te->directdata = &view_layer->passflag; @@ -274,71 +280,71 @@ static void outliner_add_passes(SpaceOops *soops, TreeElement *tenla, ID *id, Vi if (tselem->flag & TSE_CLOSED) return; - te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_Z)); + te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_Z)); te->name = IFACE_("Z"); te->directdata = &view_layer->passflag; - te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_VECTOR)); + te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_VECTOR)); te->name = IFACE_("Vector"); te->directdata = &view_layer->passflag; - te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_NORMAL)); + te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_NORMAL)); te->name = IFACE_("Normal"); te->directdata = &view_layer->passflag; - te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_UV)); + te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_UV)); te->name = IFACE_("UV"); te->directdata = &view_layer->passflag; - te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_MIST)); + te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_MIST)); te->name = IFACE_("Mist"); te->directdata = &view_layer->passflag; - te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDEXOB)); + te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDEXOB)); te->name = IFACE_("Index Object"); te->directdata = &view_layer->passflag; - te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDEXMA)); + te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDEXMA)); te->name = IFACE_("Index Material"); te->directdata = &view_layer->passflag; - te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_RGBA)); + te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_RGBA)); te->name = IFACE_("Color"); te->directdata = &view_layer->passflag; - te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_DIFFUSE)); + te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_DIFFUSE)); te->name = IFACE_("Diffuse"); te->directdata = &view_layer->passflag; - te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_SPEC)); + te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_SPEC)); te->name = IFACE_("Specular"); te->directdata = &view_layer->passflag; - te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_SHADOW)); + te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_SHADOW)); te->name = IFACE_("Shadow"); te->directdata = &view_layer->passflag; - te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_AO)); + te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_AO)); te->name = IFACE_("AO"); te->directdata = &view_layer->passflag; - te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_REFLECT)); + te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_REFLECT)); te->name = IFACE_("Reflection"); te->directdata = &view_layer->passflag; - te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_REFRACT)); + te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_REFRACT)); te->name = IFACE_("Refraction"); te->directdata = &view_layer->passflag; - te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDIRECT)); + te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDIRECT)); te->name = IFACE_("Indirect"); te->directdata = &view_layer->passflag; - te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_ENVIRONMENT)); + te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_ENVIRONMENT)); te->name = IFACE_("Environment"); te->directdata = &view_layer->passflag; - te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_EMIT)); + te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_EMIT)); te->name = IFACE_("Emit"); te->directdata = &view_layer->passflag; } @@ -373,41 +379,43 @@ static void outliner_add_line_styles(SpaceOops *soops, ListBase *lb, Scene *sce, if (!(linestyle->id.tag & LIB_TAG_DOIT)) continue; linestyle->id.tag &= ~LIB_TAG_DOIT; - outliner_add_element(soops, lb, linestyle, te, 0, 0); + outliner_add_element(soops, eval_ctx, lb, linestyle, te, 0, 0); } } } } #endif -static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *sce, TreeElement *te) +static void outliner_add_scene_contents( + SpaceOops *soops, const EvaluationContext *eval_ctx, + ListBase *lb, Scene *sce, TreeElement *te) { ViewLayer *view_layer; - TreeElement *tenla = outliner_add_element(soops, lb, sce, te, TSE_R_LAYER_BASE, 0); + TreeElement *tenla = outliner_add_element(soops, eval_ctx, lb, sce, te, TSE_R_LAYER_BASE, 0); int a; tenla->name = IFACE_("View Layers"); for (a = 0, view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next, a++) { - TreeElement *tenlay = outliner_add_element(soops, &tenla->subtree, sce, te, TSE_R_LAYER, a); + TreeElement *tenlay = outliner_add_element(soops, eval_ctx, &tenla->subtree, sce, te, TSE_R_LAYER, a); tenlay->name = view_layer->name; tenlay->directdata = &view_layer->flag; TreeElement *te_view_layers; - te_view_layers = outliner_add_element(soops, &tenlay->subtree, sce, tenlay, TSE_LAYER_COLLECTION_BASE, 0); + te_view_layers = outliner_add_element(soops, eval_ctx, &tenlay->subtree, sce, tenlay, TSE_LAYER_COLLECTION_BASE, 0); te_view_layers->name = IFACE_("Collections"); - outliner_add_view_layer(soops, &te_view_layers->subtree, te_view_layers, sce, view_layer, false); + outliner_add_view_layer(soops, eval_ctx, &te_view_layers->subtree, te_view_layers, sce, view_layer, false); TreeElement *te_passes; - te_passes = outliner_add_element(soops, &tenlay->subtree, sce, tenlay, TSE_LAYER_COLLECTION_BASE, 0); + te_passes = outliner_add_element(soops, eval_ctx, &tenlay->subtree, sce, tenlay, TSE_LAYER_COLLECTION_BASE, 0); te_passes->name = IFACE_("Passes"); - outliner_add_passes(soops, te_passes, &sce->id, view_layer); + outliner_add_passes(soops, eval_ctx, te_passes, &sce->id, view_layer); } // TODO: move this to the front? if (outliner_animdata_test(sce->adt)) - outliner_add_element(soops, lb, sce, te, TSE_ANIM_DATA, 0); + outliner_add_element(soops, eval_ctx, lb, sce, te, TSE_ANIM_DATA, 0); - outliner_add_element(soops, lb, sce->gpd, te, 0, 0); + outliner_add_element(soops, eval_ctx, lb, sce->gpd, te, 0, 0); #ifdef WITH_FREESTYLE if (STREQ(sce->view_render->engine_id, RE_engine_id_BLENDER_RENDER) && (sce->r.mode & R_EDGE_FRS)) @@ -415,11 +423,7 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s #endif } -struct ObjectsSelectedData { - ListBase objects_selected_array; -}; - -static TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *customdata) +TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *customdata) { struct ObjectsSelectedData *data = customdata; TreeStoreElem *tselem = TREESTORE(te); @@ -465,7 +469,7 @@ static void outliner_object_reorder( TREESTORE(insert_element)->flag |= TSE_SELECTED; outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &data); - BLI_LISTBASE_FOREACH (LinkData *, link, &data.objects_selected_array) { + LISTBASE_FOREACH (LinkData *, link, &data.objects_selected_array) { TreeElement *ten_selected = (TreeElement *)link->data; Object *ob = (Object *)TREESTORE(ten_selected)->id; @@ -516,37 +520,41 @@ static bool outliner_object_reorder_poll( } // can be inlined if necessary -static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, Object *ob) +static void outliner_add_object_contents( + SpaceOops *soops, const EvaluationContext *eval_ctx, + TreeElement *te, TreeStoreElem *tselem, Object *ob) { te->reinsert = outliner_object_reorder; te->reinsert_poll = outliner_object_reorder_poll; if (outliner_animdata_test(ob->adt)) - outliner_add_element(soops, &te->subtree, ob, te, TSE_ANIM_DATA, 0); + outliner_add_element(soops, eval_ctx, &te->subtree, ob, te, TSE_ANIM_DATA, 0); - outliner_add_element(soops, &te->subtree, ob->poselib, te, 0, 0); // XXX FIXME.. add a special type for this + outliner_add_element(soops, eval_ctx, &te->subtree, ob->poselib, te, 0, 0); // XXX FIXME.. add a special type for this if (ob->proxy && !ID_IS_LINKED(ob)) - outliner_add_element(soops, &te->subtree, ob->proxy, te, TSE_PROXY, 0); + outliner_add_element(soops, eval_ctx, &te->subtree, ob->proxy, te, TSE_PROXY, 0); - outliner_add_element(soops, &te->subtree, ob->gpd, te, 0, 0); + outliner_add_element(soops, eval_ctx, &te->subtree, ob->gpd, te, 0, 0); - outliner_add_element(soops, &te->subtree, ob->data, te, 0, 0); + outliner_add_element(soops, eval_ctx, &te->subtree, ob->data, te, 0, 0); if (ob->pose) { bArmature *arm = ob->data; bPoseChannel *pchan; - TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_POSE_BASE, 0); + TreeElement *tenla = outliner_add_element( + soops, eval_ctx, &te->subtree, ob, te, TSE_POSE_BASE, 0); tenla->name = IFACE_("Pose"); /* channels undefined in editmode, but we want the 'tenla' pose icon itself */ - if ((arm->edbo == NULL) && (ob->mode & OB_MODE_POSE)) { + if ((arm->edbo == NULL) && (eval_ctx->object_mode & OB_MODE_POSE)) { TreeElement *ten; int a = 0, const_index = 1000; /* ensure unique id for bone constraints */ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next, a++) { - ten = outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_POSE_CHANNEL, a); + ten = outliner_add_element( + soops, eval_ctx, &tenla->subtree, ob, tenla, TSE_POSE_CHANNEL, a); ten->name = pchan->name; ten->directdata = pchan; pchan->temp = (void *)ten; @@ -555,12 +563,14 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree //Object *target; bConstraint *con; TreeElement *ten1; - TreeElement *tenla1 = outliner_add_element(soops, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0); + TreeElement *tenla1 = outliner_add_element( + soops, eval_ctx, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0); //char *str; tenla1->name = IFACE_("Constraints"); for (con = pchan->constraints.first; con; con = con->next, const_index++) { - ten1 = outliner_add_element(soops, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, const_index); + ten1 = outliner_add_element( + soops, eval_ctx, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, const_index); #if 0 /* disabled as it needs to be reworked for recoded constraints system */ target = get_constraint_target(con, &str); if (str && str[0]) ten1->name = str; @@ -594,13 +604,15 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree /* Pose Groups */ if (ob->pose->agroups.first) { bActionGroup *agrp; - TreeElement *ten_bonegrp = outliner_add_element(soops, &te->subtree, ob, te, TSE_POSEGRP_BASE, 0); + TreeElement *ten_bonegrp = outliner_add_element( + soops, eval_ctx, &te->subtree, ob, te, TSE_POSEGRP_BASE, 0); int a = 0; ten_bonegrp->name = IFACE_("Bone Groups"); for (agrp = ob->pose->agroups.first; agrp; agrp = agrp->next, a++) { TreeElement *ten; - ten = outliner_add_element(soops, &ten_bonegrp->subtree, ob, ten_bonegrp, TSE_POSEGRP, a); + ten = outliner_add_element( + soops, eval_ctx, &ten_bonegrp->subtree, ob, ten_bonegrp, TSE_POSEGRP, a); ten->name = agrp->name; ten->directdata = agrp; } @@ -608,20 +620,21 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree } for (int a = 0; a < ob->totcol; a++) { - outliner_add_element(soops, &te->subtree, ob->mat[a], te, 0, a); + outliner_add_element( + soops, eval_ctx, &te->subtree, ob->mat[a], te, 0, a); } if (ob->constraints.first) { //Object *target; bConstraint *con; TreeElement *ten; - TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0); + TreeElement *tenla = outliner_add_element(soops, eval_ctx, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0); //char *str; int a; tenla->name = IFACE_("Constraints"); for (con = ob->constraints.first, a = 0; con; con = con->next, a++) { - ten = outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, a); + ten = outliner_add_element(soops, eval_ctx, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, a); #if 0 /* disabled due to constraints system targets recode... code here needs review */ target = get_constraint_target(con, &str); if (str && str[0]) ten->name = str; @@ -636,32 +649,38 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree if (ob->modifiers.first) { ModifierData *md; - TreeElement *ten_mod = outliner_add_element(soops, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0); + TreeElement *ten_mod = outliner_add_element(soops, eval_ctx, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0); int index; ten_mod->name = IFACE_("Modifiers"); for (index = 0, md = ob->modifiers.first; md; index++, md = md->next) { - TreeElement *ten = outliner_add_element(soops, &ten_mod->subtree, ob, ten_mod, TSE_MODIFIER, index); + TreeElement *ten = outliner_add_element( + soops, eval_ctx, &ten_mod->subtree, ob, ten_mod, TSE_MODIFIER, index); ten->name = md->name; ten->directdata = md; if (md->type == eModifierType_Lattice) { - outliner_add_element(soops, &ten->subtree, ((LatticeModifierData *) md)->object, ten, TSE_LINKED_OB, 0); + outliner_add_element( + soops, eval_ctx, &ten->subtree, ((LatticeModifierData *) md)->object, ten, TSE_LINKED_OB, 0); } else if (md->type == eModifierType_Curve) { - outliner_add_element(soops, &ten->subtree, ((CurveModifierData *) md)->object, ten, TSE_LINKED_OB, 0); + outliner_add_element( + soops, eval_ctx, &ten->subtree, ((CurveModifierData *) md)->object, ten, TSE_LINKED_OB, 0); } else if (md->type == eModifierType_Armature) { - outliner_add_element(soops, &ten->subtree, ((ArmatureModifierData *) md)->object, ten, TSE_LINKED_OB, 0); + outliner_add_element( + soops, eval_ctx, &ten->subtree, ((ArmatureModifierData *) md)->object, ten, TSE_LINKED_OB, 0); } else if (md->type == eModifierType_Hook) { - outliner_add_element(soops, &ten->subtree, ((HookModifierData *) md)->object, ten, TSE_LINKED_OB, 0); + outliner_add_element( + soops, eval_ctx, &ten->subtree, ((HookModifierData *) md)->object, ten, TSE_LINKED_OB, 0); } else if (md->type == eModifierType_ParticleSystem) { ParticleSystem *psys = ((ParticleSystemModifierData *) md)->psys; TreeElement *ten_psys; - ten_psys = outliner_add_element(soops, &ten->subtree, ob, te, TSE_LINKED_PSYS, 0); + ten_psys = outliner_add_element( + soops, eval_ctx, &ten->subtree, ob, te, TSE_LINKED_PSYS, 0); ten_psys->directdata = psys; ten_psys->name = psys->part->id.name + 2; } @@ -672,25 +691,29 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree if (ob->defbase.first) { bDeformGroup *defgroup; TreeElement *ten; - TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0); + TreeElement *tenla = outliner_add_element( + soops, eval_ctx, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0); int a; tenla->name = IFACE_("Vertex Groups"); for (defgroup = ob->defbase.first, a = 0; defgroup; defgroup = defgroup->next, a++) { - ten = outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_DEFGROUP, a); + ten = outliner_add_element(soops, eval_ctx, &tenla->subtree, ob, tenla, TSE_DEFGROUP, a); ten->name = defgroup->name; ten->directdata = defgroup; } } /* duplicated group */ - if (ob->dup_group) - outliner_add_element(soops, &te->subtree, ob->dup_group, te, 0, 0); + if (ob->dup_group) { + outliner_add_element(soops, eval_ctx, &te->subtree, ob->dup_group, te, 0, 0); + } } // can be inlined if necessary -static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, ID *id) +static void outliner_add_id_contents( + SpaceOops *soops, const EvaluationContext *eval_ctx, + TreeElement *te, TreeStoreElem *tselem, ID *id) { /* tuck pointer back in object, to construct hierarchy */ if (GS(id->name) == ID_OB) id->newid = (ID *)te; @@ -704,25 +727,26 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor } case ID_SCE: { - outliner_add_scene_contents(soops, &te->subtree, (Scene *)id, te); + outliner_add_scene_contents(soops, eval_ctx, &te->subtree, (Scene *)id, te); break; } case ID_OB: { - outliner_add_object_contents(soops, te, tselem, (Object *)id); + outliner_add_object_contents(soops, eval_ctx, te, tselem, (Object *)id); break; } case ID_ME: { Mesh *me = (Mesh *)id; int a; - - if (outliner_animdata_test(me->adt)) - outliner_add_element(soops, &te->subtree, me, te, TSE_ANIM_DATA, 0); - - outliner_add_element(soops, &te->subtree, me->key, te, 0, 0); + + if (outliner_animdata_test(me->adt)) { + outliner_add_element(soops, eval_ctx, &te->subtree, me, te, TSE_ANIM_DATA, 0); + } + + outliner_add_element(soops, eval_ctx, &te->subtree, me->key, te, 0, 0); for (a = 0; a < me->totcol; a++) - outliner_add_element(soops, &te->subtree, me->mat[a], te, 0, a); + outliner_add_element(soops, eval_ctx, &te->subtree, me->mat[a], te, 0, a); /* could do tfaces with image links, but the images are not grouped nicely. * would require going over all tfaces, sort images in use. etc... */ break; @@ -733,10 +757,10 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor int a; if (outliner_animdata_test(cu->adt)) - outliner_add_element(soops, &te->subtree, cu, te, TSE_ANIM_DATA, 0); + outliner_add_element(soops, eval_ctx, &te->subtree, cu, te, TSE_ANIM_DATA, 0); for (a = 0; a < cu->totcol; a++) - outliner_add_element(soops, &te->subtree, cu->mat[a], te, 0, a); + outliner_add_element(soops, eval_ctx, &te->subtree, cu->mat[a], te, 0, a); break; } case ID_MB: @@ -745,10 +769,10 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor int a; if (outliner_animdata_test(mb->adt)) - outliner_add_element(soops, &te->subtree, mb, te, TSE_ANIM_DATA, 0); + outliner_add_element(soops, eval_ctx, &te->subtree, mb, te, TSE_ANIM_DATA, 0); for (a = 0; a < mb->totcol; a++) - outliner_add_element(soops, &te->subtree, mb->mat[a], te, 0, a); + outliner_add_element(soops, eval_ctx, &te->subtree, mb->mat[a], te, 0, a); break; } case ID_MA: @@ -756,11 +780,14 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor Material *ma = (Material *)id; int a; - if (outliner_animdata_test(ma->adt)) - outliner_add_element(soops, &te->subtree, ma, te, TSE_ANIM_DATA, 0); + if (outliner_animdata_test(ma->adt)) { + outliner_add_element(soops, eval_ctx, &te->subtree, ma, te, TSE_ANIM_DATA, 0); + } for (a = 0; a < MAX_MTEX; a++) { - if (ma->mtex[a]) outliner_add_element(soops, &te->subtree, ma->mtex[a]->tex, te, 0, a); + if (ma->mtex[a]) { + outliner_add_element(soops, eval_ctx, &te->subtree, ma->mtex[a]->tex, te, 0, a); + } } break; } @@ -768,10 +795,10 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor { Tex *tex = (Tex *)id; - if (outliner_animdata_test(tex->adt)) - outliner_add_element(soops, &te->subtree, tex, te, TSE_ANIM_DATA, 0); - - outliner_add_element(soops, &te->subtree, tex->ima, te, 0, 0); + if (outliner_animdata_test(tex->adt)) { + outliner_add_element(soops, eval_ctx, &te->subtree, tex, te, TSE_ANIM_DATA, 0); + } + outliner_add_element(soops, eval_ctx, &te->subtree, tex->ima, te, 0, 0); break; } case ID_CA: @@ -779,7 +806,7 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor Camera *ca = (Camera *)id; if (outliner_animdata_test(ca->adt)) - outliner_add_element(soops, &te->subtree, ca, te, TSE_ANIM_DATA, 0); + outliner_add_element(soops, eval_ctx, &te->subtree, ca, te, TSE_ANIM_DATA, 0); break; } case ID_CF: @@ -787,7 +814,7 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor CacheFile *cache_file = (CacheFile *)id; if (outliner_animdata_test(cache_file->adt)) { - outliner_add_element(soops, &te->subtree, cache_file, te, TSE_ANIM_DATA, 0); + outliner_add_element(soops, eval_ctx, &te->subtree, cache_file, te, TSE_ANIM_DATA, 0); } break; @@ -798,10 +825,12 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor int a; if (outliner_animdata_test(la->adt)) - outliner_add_element(soops, &te->subtree, la, te, TSE_ANIM_DATA, 0); + outliner_add_element(soops, eval_ctx, &te->subtree, la, te, TSE_ANIM_DATA, 0); for (a = 0; a < MAX_MTEX; a++) { - if (la->mtex[a]) outliner_add_element(soops, &te->subtree, la->mtex[a]->tex, te, 0, a); + if (la->mtex[a]) { + outliner_add_element(soops, eval_ctx, &te->subtree, la->mtex[a]->tex, te, 0, a); + } } break; } @@ -809,16 +838,18 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor { Speaker *spk = (Speaker *)id; - if (outliner_animdata_test(spk->adt)) - outliner_add_element(soops, &te->subtree, spk, te, TSE_ANIM_DATA, 0); + if (outliner_animdata_test(spk->adt)) { + outliner_add_element(soops, eval_ctx, &te->subtree, spk, te, TSE_ANIM_DATA, 0); + } break; } case ID_LP: { LightProbe *prb = (LightProbe *)id; - if (outliner_animdata_test(prb->adt)) - outliner_add_element(soops, &te->subtree, prb, te, TSE_ANIM_DATA, 0); + if (outliner_animdata_test(prb->adt)) { + outliner_add_element(soops, eval_ctx, &te->subtree, prb, te, TSE_ANIM_DATA, 0); + } break; } case ID_WO: @@ -826,11 +857,13 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor World *wrld = (World *)id; int a; - if (outliner_animdata_test(wrld->adt)) - outliner_add_element(soops, &te->subtree, wrld, te, TSE_ANIM_DATA, 0); - + if (outliner_animdata_test(wrld->adt)) { + outliner_add_element(soops, eval_ctx, &te->subtree, wrld, te, TSE_ANIM_DATA, 0); + } for (a = 0; a < MAX_MTEX; a++) { - if (wrld->mtex[a]) outliner_add_element(soops, &te->subtree, wrld->mtex[a]->tex, te, 0, a); + if (wrld->mtex[a]) { + outliner_add_element(soops, eval_ctx, &te->subtree, wrld->mtex[a]->tex, te, 0, a); + } } break; } @@ -838,8 +871,9 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor { Key *key = (Key *)id; - if (outliner_animdata_test(key->adt)) - outliner_add_element(soops, &te->subtree, key, te, TSE_ANIM_DATA, 0); + if (outliner_animdata_test(key->adt)) { + outliner_add_element(soops, eval_ctx, &te->subtree, key, te, TSE_ANIM_DATA, 0); + } break; } case ID_AC: @@ -853,15 +887,15 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor bArmature *arm = (bArmature *)id; int a = 0; - if (outliner_animdata_test(arm->adt)) - outliner_add_element(soops, &te->subtree, arm, te, TSE_ANIM_DATA, 0); - + if (outliner_animdata_test(arm->adt)) { + outliner_add_element(soops, eval_ctx, &te->subtree, arm, te, TSE_ANIM_DATA, 0); + } if (arm->edbo) { EditBone *ebone; TreeElement *ten; for (ebone = arm->edbo->first; ebone; ebone = ebone->next, a++) { - ten = outliner_add_element(soops, &te->subtree, id, te, TSE_EBONE, a); + ten = outliner_add_element(soops, eval_ctx, &te->subtree, id, te, TSE_EBONE, a); ten->directdata = ebone; ten->name = ebone->name; ebone->temp.p = ten; @@ -883,13 +917,17 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor else { /* do not extend Armature when we have posemode */ tselem = TREESTORE(te->parent); - if (GS(tselem->id->name) == ID_OB && ((Object *)tselem->id)->mode & OB_MODE_POSE) { + if (GS(tselem->id->name) == ID_OB && + (eval_ctx->object_mode & OB_MODE_POSE) + /* (((Object *)tselem->id)->mode & OB_MODE_POSE) */ + ) + { /* pass */ } else { Bone *curBone; for (curBone = arm->bonebase.first; curBone; curBone = curBone->next) { - outliner_add_bone(soops, &te->subtree, id, curBone, te, &a); + outliner_add_bone(soops, eval_ctx, &te->subtree, id, curBone, te, &a); } } } @@ -899,13 +937,14 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor { FreestyleLineStyle *linestyle = (FreestyleLineStyle *)id; int a; - - if (outliner_animdata_test(linestyle->adt)) - outliner_add_element(soops, &te->subtree, linestyle, te, TSE_ANIM_DATA, 0); + + if (outliner_animdata_test(linestyle->adt)) { + outliner_add_element(soops, eval_ctx, &te->subtree, linestyle, te, TSE_ANIM_DATA, 0); + } for (a = 0; a < MAX_MTEX; a++) { if (linestyle->mtex[a]) - outliner_add_element(soops, &te->subtree, linestyle->mtex[a]->tex, te, 0, a); + outliner_add_element(soops, eval_ctx, &te->subtree, linestyle->mtex[a]->tex, te, 0, a); } break; } @@ -916,11 +955,11 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor int a = 0; if (outliner_animdata_test(gpd->adt)) - outliner_add_element(soops, &te->subtree, gpd, te, TSE_ANIM_DATA, 0); + outliner_add_element(soops, eval_ctx, &te->subtree, gpd, te, TSE_ANIM_DATA, 0); // TODO: base element for layers? for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { - outliner_add_element(soops, &te->subtree, gpl, te, TSE_GP_LAYER, a); + outliner_add_element(soops, eval_ctx, &te->subtree, gpl, te, TSE_GP_LAYER, a); a++; } break; @@ -932,8 +971,9 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor // TODO: this function needs to be split up! It's getting a bit too large... // Note: "ID" is not always a real ID -static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *idv, - TreeElement *parent, short type, short index) +static TreeElement *outliner_add_element( + SpaceOops *soops, const EvaluationContext *eval_ctx, + ListBase *lb, void *idv, TreeElement *parent, short type, short index) { TreeElement *te; TreeStoreElem *tselem; @@ -1006,7 +1046,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i /* ID datablock */ if (tsepar == NULL || tsepar->type != TSE_ID_BASE) - outliner_add_id_contents(soops, te, tselem, id); + outliner_add_id_contents(soops, eval_ctx, te, tselem, id); } else if (type == TSE_ANIM_DATA) { IdAdtTemplate *iat = (IdAdtTemplate *)idv; @@ -1017,11 +1057,11 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i te->directdata = adt; /* Action */ - outliner_add_element(soops, &te->subtree, adt->action, te, 0, 0); + outliner_add_element(soops, eval_ctx, &te->subtree, adt->action, te, 0, 0); /* Drivers */ if (adt->drivers.first) { - TreeElement *ted = outliner_add_element(soops, &te->subtree, adt, te, TSE_DRIVER_BASE, 0); + TreeElement *ted = outliner_add_element(soops, eval_ctx, &te->subtree, adt, te, TSE_DRIVER_BASE, 0); ID *lastadded = NULL; FCurve *fcu; @@ -1038,7 +1078,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i { if (lastadded != dtar->id) { // XXX this lastadded check is rather lame, and also fails quite badly... - outliner_add_element(soops, &ted->subtree, dtar->id, ted, TSE_LINKED_OB, 0); + outliner_add_element(soops, eval_ctx, &ted->subtree, dtar->id, ted, TSE_LINKED_OB, 0); lastadded = dtar->id; } } @@ -1050,14 +1090,14 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i /* NLA Data */ if (adt->nla_tracks.first) { - TreeElement *tenla = outliner_add_element(soops, &te->subtree, adt, te, TSE_NLA, 0); + TreeElement *tenla = outliner_add_element(soops, eval_ctx, &te->subtree, adt, te, TSE_NLA, 0); NlaTrack *nlt; int a = 0; tenla->name = IFACE_("NLA Tracks"); for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) { - TreeElement *tenlt = outliner_add_element(soops, &tenla->subtree, nlt, tenla, TSE_NLA_TRACK, a); + TreeElement *tenlt = outliner_add_element(soops, eval_ctx, &tenla->subtree, nlt, tenla, TSE_NLA_TRACK, a); NlaStrip *strip; TreeElement *ten; int b = 0; @@ -1065,7 +1105,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i tenlt->name = nlt->name; for (strip = nlt->strips.first; strip; strip = strip->next, b++) { - ten = outliner_add_element(soops, &tenlt->subtree, strip->act, tenlt, TSE_NLA_ACTION, b); + ten = outliner_add_element(soops, eval_ctx, &tenlt->subtree, strip->act, tenlt, TSE_NLA_ACTION, b); if (ten) ten->directdata = strip; } } @@ -1100,12 +1140,12 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i if (seq->type == SEQ_TYPE_META) { p = seq->seqbase.first; while (p) { - outliner_add_element(soops, &te->subtree, (void *)p, te, TSE_SEQUENCE, index); + outliner_add_element(soops, eval_ctx, &te->subtree, (void *)p, te, TSE_SEQUENCE, index); p = p->next; } } else - outliner_add_element(soops, &te->subtree, (void *)seq->strip, te, TSE_SEQ_STRIP, index); + outliner_add_element(soops, eval_ctx, &te->subtree, (void *)seq->strip, te, TSE_SEQ_STRIP, index); } } else if (type == TSE_SEQ_STRIP) { @@ -1166,7 +1206,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i for (a = 0; a < tot; a++) { RNA_property_collection_lookup_int(ptr, iterprop, a, &propptr); if (!(RNA_property_flag(propptr.data) & PROP_HIDDEN)) { - outliner_add_element(soops, &te->subtree, (void *)ptr, te, TSE_RNA_PROPERTY, a); + outliner_add_element(soops, eval_ctx, &te->subtree, (void *)ptr, te, TSE_RNA_PROPERTY, a); } } } @@ -1195,7 +1235,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i if (pptr.data) { if (TSELEM_OPEN(tselem, soops)) - outliner_add_element(soops, &te->subtree, (void *)&pptr, te, TSE_RNA_STRUCT, -1); + outliner_add_element(soops, eval_ctx, &te->subtree, (void *)&pptr, te, TSE_RNA_STRUCT, -1); else te->flag |= TE_LAZY_CLOSED; } @@ -1207,7 +1247,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i if (TSELEM_OPEN(tselem, soops)) { for (a = 0; a < tot; a++) { RNA_property_collection_lookup_int(ptr, prop, a, &pptr); - outliner_add_element(soops, &te->subtree, (void *)&pptr, te, TSE_RNA_STRUCT, a); + outliner_add_element(soops, eval_ctx, &te->subtree, (void *)&pptr, te, TSE_RNA_STRUCT, a); } } else if (tot) @@ -1219,7 +1259,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i if (TSELEM_OPEN(tselem, soops)) { for (a = 0; a < tot; a++) - outliner_add_element(soops, &te->subtree, (void *)ptr, te, TSE_RNA_ARRAY_ELEM, a); + outliner_add_element(soops, eval_ctx, &te->subtree, (void *)ptr, te, TSE_RNA_ARRAY_ELEM, a); } else if (tot) te->flag |= TE_LAZY_CLOSED; @@ -1267,7 +1307,8 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i } if (ot || kmi->propvalue) { - TreeElement *ten = outliner_add_element(soops, &te->subtree, kmi, te, TSE_KEYMAP_ITEM, a); + TreeElement *ten = outliner_add_element( + soops, eval_ctx, &te->subtree, kmi, te, TSE_KEYMAP_ITEM, a); ten->directdata = kmi; @@ -1289,7 +1330,8 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i if ((type != TSE_LAYER_COLLECTION) && (te->idcode == ID_GR)) { Group *group = (Group *)id; - outliner_add_layer_collections_recursive(soops, &te->subtree, id, &group->view_layer->layer_collections, NULL, true); + outliner_add_layer_collections_recursive( + soops, eval_ctx, &te->subtree, id, &group->view_layer->layer_collections, NULL, true); } return te; @@ -1345,7 +1387,9 @@ static int need_add_seq_dup(Sequence *seq) return(1); } -static void outliner_add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *te, short index) +static void outliner_add_seq_dup( + SpaceOops *soops, const EvaluationContext *eval_ctx, + Sequence *seq, TreeElement *te, short index) { /* TreeElement *ch; */ /* UNUSED */ Sequence *p; @@ -1358,7 +1402,8 @@ static void outliner_add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *t } if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) - /* ch = */ /* UNUSED */ outliner_add_element(soops, &te->subtree, (void *)p, te, TSE_SEQUENCE, index); + /* ch = */ /* UNUSED */ outliner_add_element( + soops, eval_ctx, &te->subtree, (void *)p, te, TSE_SEQUENCE, index); p = p->next; } } @@ -1367,7 +1412,9 @@ static void outliner_add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *t /* ----------------------------------------------- */ -static void outliner_add_library_contents(Main *mainvar, SpaceOops *soops, TreeElement *te, Library *lib) +static void outliner_add_library_contents( + Main *mainvar, SpaceOops *soops, const EvaluationContext *eval_ctx, + TreeElement *te, Library *lib) { TreeElement *ten; ListBase *lbarray[MAX_LIBARRAY]; @@ -1384,7 +1431,7 @@ static void outliner_add_library_contents(Main *mainvar, SpaceOops *soops, TreeE break; if (id) { - ten = outliner_add_element(soops, &te->subtree, lbarray[a], NULL, TSE_ID_BASE, 0); + ten = outliner_add_element(soops, eval_ctx, &te->subtree, lbarray[a], NULL, TSE_ID_BASE, 0); ten->directdata = lbarray[a]; ten->name = BKE_idcode_to_name_plural(GS(id->name)); @@ -1393,7 +1440,7 @@ static void outliner_add_library_contents(Main *mainvar, SpaceOops *soops, TreeE for (id = lbarray[a]->first; id; id = id->next) { if (id->lib == lib) - outliner_add_element(soops, &ten->subtree, id, ten, 0, 0); + outliner_add_element(soops, eval_ctx, &ten->subtree, id, ten, 0, 0); } } } @@ -1401,7 +1448,7 @@ static void outliner_add_library_contents(Main *mainvar, SpaceOops *soops, TreeE } -static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops) +static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops, const EvaluationContext *eval_ctx) { TreeElement *ten; ListBase *lbarray[MAX_LIBARRAY]; @@ -1424,7 +1471,7 @@ static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops) * - Add a parameter to BKE_idcode_to_name_plural to get a sane "user-visible" name instead? * - Ensure that this uses nice icons for the datablock type involved instead of the dot? */ - ten = outliner_add_element(soops, &soops->tree, lbarray[a], NULL, TSE_ID_BASE, 0); + ten = outliner_add_element(soops, eval_ctx, &soops->tree, lbarray[a], NULL, TSE_ID_BASE, 0); ten->directdata = lbarray[a]; ten->name = BKE_idcode_to_name_plural(GS(id->name)); @@ -1434,7 +1481,7 @@ static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops) /* add the orphaned datablocks - these will not be added with any subtrees attached */ for (id = lbarray[a]->first; id; id = id->next) { if (ID_REAL_USERS(id) <= 0) - outliner_add_element(soops, &ten->subtree, id, ten, 0, 0); + outliner_add_element(soops, eval_ctx, &ten->subtree, id, ten, 0, 0); } } } @@ -1480,22 +1527,24 @@ static bool outliner_layer_collections_reorder_poll( } static void outliner_add_layer_collections_recursive( - SpaceOops *soops, ListBase *tree, ID *id, ListBase *layer_collections, TreeElement *parent_ten, + SpaceOops *soops, const EvaluationContext *eval_ctx, + ListBase *tree, ID *id, ListBase *layer_collections, TreeElement *parent_ten, const bool show_objects) { for (LayerCollection *collection = layer_collections->first; collection; collection = collection->next) { - TreeElement *ten = outliner_add_element(soops, tree, id, parent_ten, TSE_LAYER_COLLECTION, 0); + TreeElement *ten = outliner_add_element(soops, eval_ctx, tree, id, parent_ten, TSE_LAYER_COLLECTION, 0); ten->name = collection->scene_collection->name; ten->directdata = collection; ten->reinsert = outliner_layer_collections_reorder; ten->reinsert_poll = outliner_layer_collections_reorder_poll; - outliner_add_layer_collections_recursive(soops, &ten->subtree, id, &collection->layer_collections, ten, show_objects); + outliner_add_layer_collections_recursive( + soops, eval_ctx, &ten->subtree, id, &collection->layer_collections, ten, show_objects); if (show_objects) { for (LinkData *link = collection->object_bases.first; link; link = link->next) { Base *base = (Base *)link->data; - TreeElement *te_object = outliner_add_element(soops, &ten->subtree, base->object, ten, 0, 0); + TreeElement *te_object = outliner_add_element(soops, eval_ctx, &ten->subtree, base->object, ten, 0, 0); te_object->directdata = base; } } @@ -1503,10 +1552,13 @@ static void outliner_add_layer_collections_recursive( } } -static void outliner_add_view_layer(SpaceOops *soops, ListBase *tree, TreeElement *parent, - Scene *scene, ViewLayer *layer, const bool show_objects) +static void outliner_add_view_layer( + SpaceOops *soops, const EvaluationContext *eval_ctx, + ListBase *tree, TreeElement *parent, + Scene *scene, ViewLayer *layer, const bool show_objects) { - outliner_add_layer_collections_recursive(soops, tree, &scene->id, &layer->layer_collections, parent, show_objects); + outliner_add_layer_collections_recursive( + soops, eval_ctx, tree, &scene->id, &layer->layer_collections, parent, show_objects); } static void outliner_scene_collections_reorder( @@ -1577,35 +1629,40 @@ BLI_INLINE void outliner_add_scene_collection_init(TreeElement *te, SceneCollect } BLI_INLINE void outliner_add_scene_collection_objects( - SpaceOops *soops, ListBase *tree, SceneCollection *collection, TreeElement *parent) + SpaceOops *soops, const EvaluationContext *eval_ctx, + ListBase *tree, SceneCollection *collection, TreeElement *parent) { for (LinkData *link = collection->objects.first; link; link = link->next) { - outliner_add_element(soops, tree, link->data, parent, 0, 0); + outliner_add_element(soops, eval_ctx, tree, link->data, parent, 0, 0); } } static TreeElement *outliner_add_scene_collection_recursive( - SpaceOops *soops, ListBase *tree, ID *id, SceneCollection *scene_collection, TreeElement *parent_ten) + SpaceOops *soops, const EvaluationContext *eval_ctx, + ListBase *tree, ID *id, SceneCollection *scene_collection, TreeElement *parent_ten) { - TreeElement *ten = outliner_add_element(soops, tree, id, parent_ten, TSE_SCENE_COLLECTION, 0); + TreeElement *ten = outliner_add_element(soops, eval_ctx, tree, id, parent_ten, TSE_SCENE_COLLECTION, 0); outliner_add_scene_collection_init(ten, scene_collection); - outliner_add_scene_collection_objects(soops, &ten->subtree, scene_collection, ten); + outliner_add_scene_collection_objects(soops, eval_ctx, &ten->subtree, scene_collection, ten); for (SceneCollection *scene_collection_nested = scene_collection->scene_collections.first; scene_collection_nested != NULL; scene_collection_nested = scene_collection_nested->next) { - outliner_add_scene_collection_recursive(soops, &ten->subtree, id, scene_collection_nested, ten); + outliner_add_scene_collection_recursive( + soops, eval_ctx, &ten->subtree, id, scene_collection_nested, ten); } outliner_make_hierarchy(&ten->subtree); return ten; } -static void outliner_add_collections(SpaceOops *soops, Scene *scene) +static void outliner_add_collections( + SpaceOops *soops, const EvaluationContext *eval_ctx, Scene *scene) { SceneCollection *master_collection = BKE_collection_master(&scene->id); - TreeElement *ten = outliner_add_scene_collection_recursive(soops, &soops->tree, &scene->id, master_collection, NULL); + TreeElement *ten = outliner_add_scene_collection_recursive( + soops, eval_ctx, &soops->tree, &scene->id, master_collection, NULL); /* Master Collection should always be expanded. */ TREESTORE(ten)->flag &= ~TSE_CLOSED; } @@ -2170,11 +2227,13 @@ static void outliner_filter_tree(SpaceOops *soops, ViewLayer *view_layer) /* Main entry point for building the tree data-structure that the outliner represents */ // TODO: split each mode into its own function? -void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, SpaceOops *soops, ARegion *ar) +void outliner_build_tree( + Main *mainvar, const EvaluationContext *eval_ctx, Scene *scene, + ViewLayer *view_layer, SpaceOops *soops, ARegion *ar) { TreeElement *te = NULL, *ten; TreeStoreElem *tselem; - int show_opened = !soops->treestore || !BLI_mempool_count(soops->treestore); /* on first view, we open scenes */ + int show_opened = !soops->treestore || !BLI_mempool_len(soops->treestore); /* on first view, we open scenes */ /* Are we looking for something - we want to tag parents to filter child matches * - NOT in datablocks view - searching all datablocks takes way too long to be useful @@ -2203,20 +2262,20 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa Library *lib; /* current file first - mainvar provides tselem with unique pointer - not used */ - ten = outliner_add_element(soops, &soops->tree, mainvar, NULL, TSE_ID_BASE, 0); + ten = outliner_add_element(soops, eval_ctx, &soops->tree, mainvar, NULL, TSE_ID_BASE, 0); ten->name = IFACE_("Current File"); tselem = TREESTORE(ten); if (!tselem->used) tselem->flag &= ~TSE_CLOSED; - outliner_add_library_contents(mainvar, soops, ten, NULL); + outliner_add_library_contents(mainvar, soops, eval_ctx, ten, NULL); for (lib = mainvar->library.first; lib; lib = lib->id.next) { - ten = outliner_add_element(soops, &soops->tree, lib, NULL, 0, 0); + ten = outliner_add_element(soops, eval_ctx, &soops->tree, lib, NULL, 0, 0); lib->id.newid = (ID *)ten; - outliner_add_library_contents(mainvar, soops, ten, lib); + outliner_add_library_contents(mainvar, soops, eval_ctx, ten, lib); } /* make hierarchy */ @@ -2236,8 +2295,8 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa } else { /* Else, make a new copy of the libtree for our parent. */ - TreeElement *dupten = outliner_add_element(soops, &par->subtree, lib, NULL, 0, 0); - outliner_add_library_contents(mainvar, soops, dupten, lib); + TreeElement *dupten = outliner_add_element(soops, eval_ctx, &par->subtree, lib, NULL, 0, 0); + outliner_add_library_contents(mainvar, soops, eval_ctx, dupten, lib); dupten->parent = par; } } @@ -2251,7 +2310,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa else if (soops->outlinevis == SO_SCENES) { Scene *sce; for (sce = mainvar->scene.first; sce; sce = sce->id.next) { - te = outliner_add_element(soops, &soops->tree, sce, NULL, 0, 0); + te = outliner_add_element(soops, eval_ctx, &soops->tree, sce, NULL, 0, 0); tselem = TREESTORE(te); if (sce == scene && show_opened) { @@ -2264,7 +2323,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa else if (soops->outlinevis == SO_GROUPS) { Group *group; for (group = mainvar->group.first; group; group = group->id.next) { - te = outliner_add_element(soops, &soops->tree, group, NULL, 0, 0); + te = outliner_add_element(soops, eval_ctx, &soops->tree, group, NULL, 0, 0); outliner_make_hierarchy(&te->subtree); } } @@ -2283,11 +2342,11 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa while (seq) { op = need_add_seq_dup(seq); if (op == 1) { - /* ten = */ outliner_add_element(soops, &soops->tree, (void *)seq, NULL, TSE_SEQUENCE, 0); + /* ten = */ outliner_add_element(soops, eval_ctx, &soops->tree, (void *)seq, NULL, TSE_SEQUENCE, 0); } else if (op == 0) { - ten = outliner_add_element(soops, &soops->tree, (void *)seq, NULL, TSE_SEQUENCE_DUP, 0); - outliner_add_seq_dup(soops, seq, ten, 0); + ten = outliner_add_element(soops, eval_ctx, &soops->tree, (void *)seq, NULL, TSE_SEQUENCE_DUP, 0); + outliner_add_seq_dup(soops, eval_ctx, seq, ten, 0); } seq = seq->next; } @@ -2297,7 +2356,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa RNA_main_pointer_create(mainvar, &mainptr); - ten = outliner_add_element(soops, &soops->tree, (void *)&mainptr, NULL, TSE_RNA_STRUCT, -1); + ten = outliner_add_element(soops, eval_ctx, &soops->tree, (void *)&mainptr, NULL, TSE_RNA_STRUCT, -1); if (show_opened) { tselem = TREESTORE(ten); @@ -2305,36 +2364,36 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa } } else if (soops->outlinevis == SO_ID_ORPHANS) { - outliner_add_orphaned_datablocks(mainvar, soops); + outliner_add_orphaned_datablocks(mainvar, soops, eval_ctx); } else if (soops->outlinevis == SO_VIEW_LAYER) { if ((soops->filter & SO_FILTER_ENABLE) && (soops->filter & SO_FILTER_NO_COLLECTION)) { for (Base *base = view_layer->object_bases.first; base; base = base->next) { - TreeElement *te_object = outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); + TreeElement *te_object = outliner_add_element(soops, eval_ctx, &soops->tree, base->object, NULL, 0, 0); te_object->directdata = base; } outliner_make_hierarchy(&soops->tree); } else { - outliner_add_view_layer(soops, &soops->tree, NULL, scene, view_layer, true); + outliner_add_view_layer(soops, eval_ctx, &soops->tree, NULL, scene, view_layer, true); } } else if (soops->outlinevis == SO_COLLECTIONS) { if ((soops->filter & SO_FILTER_ENABLE) && (soops->filter & SO_FILTER_NO_COLLECTION)) { FOREACH_SCENE_OBJECT(scene, ob) { - outliner_add_element(soops, &soops->tree, ob, NULL, 0, 0); + outliner_add_element(soops, eval_ctx, &soops->tree, ob, NULL, 0, 0); } FOREACH_SCENE_OBJECT_END outliner_make_hierarchy(&soops->tree); } else { - outliner_add_collections(soops, scene); + outliner_add_collections(soops, eval_ctx, scene); } } else { if (BASACT(view_layer)) { - ten = outliner_add_element(soops, &soops->tree, OBACT(view_layer), NULL, 0, 0); + ten = outliner_add_element(soops, eval_ctx, &soops->tree, OBACT(view_layer), NULL, 0, 0); ten->directdata = BASACT(view_layer); } } diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 04dbab0b853..db0593ef2d1 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -330,7 +330,7 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, } glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); for (seq = seqbase->first; seq; seq = seq->next) { chan_min = min_ii(chan_min, seq->machine); @@ -435,7 +435,7 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_cla { glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); if (seq->flag & whichsel) { immUniformColor4ub(0, 0, 0, 80); @@ -620,7 +620,7 @@ static void draw_sequence_extensions(Scene *scene, ARegion *ar, Sequence *seq, u if (seq->startofs || seq->endofs) { glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); color3ubv_from_seq(scene, seq, col); @@ -664,7 +664,7 @@ static void draw_sequence_extensions(Scene *scene, ARegion *ar, Sequence *seq, u if (seq->startstill || seq->endstill) { glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); color3ubv_from_seq(scene, seq, col); UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.5f, 60); @@ -730,7 +730,7 @@ static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, AReg background_col[3] = 128; glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } else { background_col[3] = 255; @@ -842,7 +842,7 @@ static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, AReg col[3] = 96; glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); immUniformColor4ubv(col); } @@ -1226,7 +1226,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) { glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } /* Format needs to be created prior to any immBindProgram call. diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index cb0c5bd3717..e1163fd3207 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2785,7 +2785,7 @@ static int sequencer_view_zoom_ratio_exec(bContext *C, wmOperator *op) float facx = BLI_rcti_size_x(&v2d->mask) / winx; float facy = BLI_rcti_size_y(&v2d->mask) / winy; - BLI_rctf_resize(&v2d->cur, floorf(winx * facx / ratio + 0.5f), floorf(winy * facy / ratio + 0.5f)); + BLI_rctf_resize(&v2d->cur, ceilf(winx * facx / ratio + 0.5f), ceilf(winy * facy / ratio + 0.5f)); ED_region_tag_redraw(CTX_wm_region(C)); diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index 62fde49cade..3949aa928c9 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -1207,7 +1207,7 @@ static void draw_text_decoration(SpaceText *st, ARegion *ar) immUniformColor4ub(255, 255, 255, 32); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); immRecti(pos, x1 - 4, y1, x2, y2); glDisable(GL_BLEND); diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c index 283dbf3b4e2..9a736ae977f 100644 --- a/source/blender/editors/space_time/space_time.c +++ b/source/blender/editors/space_time/space_time.c @@ -83,7 +83,7 @@ static void time_draw_sfra_efra(Scene *scene, View2D *v2d) /* draw darkened area outside of active timeline * frame range used is preview range or scene range */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); Gwn_VertFormat *format = immVertexFormat(); @@ -402,6 +402,7 @@ static void time_draw_caches_keyframes(Main *bmain, ViewLayer *view_layer, View2 /* draw keyframe lines for timeline */ static void time_draw_keyframes(const bContext *C, ARegion *ar) { + WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob = CTX_data_active_object(C); @@ -443,7 +444,7 @@ static void time_draw_keyframes(const bContext *C, ARegion *ar) */ UI_GetThemeColor3ubv(TH_TIME_KEYFRAME, color); - if (ob && ((ob->mode == OB_MODE_POSE) || onlysel)) { + if (ob && ((workspace->object_mode == OB_MODE_POSE) || onlysel)) { /* draw keyframes for active object only */ time_draw_idblock_keyframes(v2d, (ID *)ob, onlysel, color); } diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index 77cd64be7c1..f0adf307bda 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -2667,8 +2667,10 @@ static void ghost_poses_tag_unselected(Object *ob, short unset) * note: object should be in posemode */ static void draw_ghost_poses_range( - const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, View3D *v3d, ARegion *ar, Base *base) + const EvaluationContext *eval_ctx_init, + Scene *scene, ViewLayer *view_layer, View3D *v3d, ARegion *ar, Base *base) { + EvaluationContext eval_ctx = *eval_ctx_init; Object *ob = base->object; AnimData *adt = BKE_animdata_from_id(&ob->id); bArmature *arm = ob->data; @@ -2690,7 +2692,7 @@ static void draw_ghost_poses_range( range = (float)(end - start); /* store values */ - ob->mode &= ~OB_MODE_POSE; + eval_ctx.object_mode &= ~OB_MODE_POSE; cfrao = CFRA; flago = arm->flag; arm->flag &= ~(ARM_DRAWNAMES | ARM_DRAWAXES); @@ -2711,8 +2713,8 @@ static void draw_ghost_poses_range( UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col); BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - BKE_pose_where_is(eval_ctx, scene, ob); - draw_pose_bones(eval_ctx, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false); + BKE_pose_where_is(&eval_ctx, scene, ob); + draw_pose_bones(&eval_ctx, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false); } glDisable(GL_BLEND); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); @@ -2728,16 +2730,17 @@ static void draw_ghost_poses_range( CFRA = cfrao; ob->pose = poseo; arm->flag = flago; - ob->mode |= OB_MODE_POSE; + eval_ctx.object_mode |= OB_MODE_POSE; } /* draw ghosts on keyframes in action within range * - object should be in posemode */ static void draw_ghost_poses_keys( - const struct EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, + const struct EvaluationContext *eval_ctx_init, Scene *scene, ViewLayer *view_layer, View3D *v3d, ARegion *ar, Base *base) { + EvaluationContext eval_ctx = *eval_ctx_init; Object *ob = base->object; AnimData *adt = BKE_animdata_from_id(&ob->id); bAction *act = (adt) ? adt->action : NULL; @@ -2771,7 +2774,7 @@ static void draw_ghost_poses_keys( if (range == 0) return; /* store values */ - ob->mode &= ~OB_MODE_POSE; + eval_ctx.object_mode &= ~OB_MODE_POSE; cfrao = CFRA; flago = arm->flag; arm->flag &= ~(ARM_DRAWNAMES | ARM_DRAWAXES); @@ -2794,8 +2797,8 @@ static void draw_ghost_poses_keys( CFRA = (int)ak->cfra; BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - BKE_pose_where_is(eval_ctx, scene, ob); - draw_pose_bones(eval_ctx, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false); + BKE_pose_where_is(&eval_ctx, scene, ob); + draw_pose_bones(&eval_ctx, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false); } glDisable(GL_BLEND); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); @@ -2812,16 +2815,17 @@ static void draw_ghost_poses_keys( CFRA = cfrao; ob->pose = poseo; arm->flag = flago; - ob->mode |= OB_MODE_POSE; + eval_ctx.object_mode |= OB_MODE_POSE; } /* draw ghosts around current frame * - object is supposed to be armature in posemode */ static void draw_ghost_poses( - const struct EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, + const struct EvaluationContext *eval_ctx_init, Scene *scene, ViewLayer *view_layer, View3D *v3d, ARegion *ar, Base *base) { + EvaluationContext eval_ctx = *eval_ctx_init; Object *ob = base->object; AnimData *adt = BKE_animdata_from_id(&ob->id); bArmature *arm = ob->data; @@ -2846,7 +2850,7 @@ static void draw_ghost_poses( range = (float)(arm->ghostep) * stepsize + 0.5f; /* plus half to make the for loop end correct */ /* store values */ - ob->mode &= ~OB_MODE_POSE; + eval_ctx.object_mode &= ~OB_MODE_POSE; cfrao = CFRA; actframe = BKE_nla_tweakedit_remap(adt, (float)CFRA, 0); flago = arm->flag; @@ -2874,8 +2878,8 @@ static void draw_ghost_poses( if (CFRA != cfrao) { BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - BKE_pose_where_is(eval_ctx, scene, ob); - draw_pose_bones(eval_ctx, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false); + BKE_pose_where_is(&eval_ctx, scene, ob); + draw_pose_bones(&eval_ctx, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false); } } @@ -2889,8 +2893,8 @@ static void draw_ghost_poses( if (CFRA != cfrao) { BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - BKE_pose_where_is(eval_ctx, scene, ob); - draw_pose_bones(eval_ctx, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false); + BKE_pose_where_is(&eval_ctx, scene, ob); + draw_pose_bones(&eval_ctx, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false); } } } @@ -2908,7 +2912,7 @@ static void draw_ghost_poses( CFRA = cfrao; ob->pose = poseo; arm->flag = flago; - ob->mode |= OB_MODE_POSE; + eval_ctx.object_mode |= OB_MODE_POSE; } /* ********************************** Armature Drawing - Main ************************* */ @@ -2970,11 +2974,11 @@ bool draw_armature( } else #endif - if (ob->mode & OB_MODE_POSE) { + if (eval_ctx->object_mode & OB_MODE_POSE) { arm->flag |= ARM_POSEMODE; } } - else if (ob->mode & OB_MODE_POSE) { + else if (eval_ctx->object_mode & OB_MODE_POSE) { if (arm->ghosttype == ARM_GHOST_RANGE) { draw_ghost_poses_range(eval_ctx, scene, view_layer, v3d, ar, base); } @@ -2988,7 +2992,7 @@ bool draw_armature( if ((dflag & DRAW_SCENESET) == 0) { if (ob == OBACT(view_layer)) arm->flag |= ARM_POSEMODE; - else if (OBACT(view_layer) && (OBACT(view_layer)->mode & OB_MODE_WEIGHT_PAINT)) { + else if (OBACT(view_layer) && (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT)) { if (ob == modifiers_isDeformedByArmature(OBACT(view_layer))) arm->flag |= ARM_POSEMODE; } diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index f8f2d5598de..c014c2b12a0 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -59,6 +59,8 @@ #include "UI_resources.h" +#include "DEG_depsgraph.h" + #include "GPU_draw.h" #include "GPU_material.h" #include "GPU_basic_shader.h" @@ -177,7 +179,7 @@ void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm, bool d /* Draw Selected Faces */ if (me->drawflag & ME_DRAWFACES) { glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* dull unselected faces so as not to get in the way of seeing color */ glColor4ub(96, 96, 96, 64); dm->drawMappedFaces(dm, draw_mesh_face_select__drawFaceOptsInv, NULL, NULL, (void *)me, DM_DRAW_SKIP_HIDDEN); @@ -325,8 +327,10 @@ void draw_mesh_paint_weight_edges(RegionView3D *rv3d, DerivedMesh *dm, } } -void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d, - Object *ob, DerivedMesh *dm, const int draw_flags) +void draw_mesh_paint( + const EvaluationContext *eval_ctx, + View3D *v3d, RegionView3D *rv3d, + Object *ob, DerivedMesh *dm, const int draw_flags) { DMSetDrawOptions facemask = NULL; Mesh *me = ob->data; @@ -336,21 +340,21 @@ void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d, if (me->editflag & (ME_EDIT_PAINT_VERT_SEL | ME_EDIT_PAINT_FACE_SEL)) facemask = wpaint__setSolidDrawOptions_facemask; - if (ob->mode & OB_MODE_WEIGHT_PAINT) { + if (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) { draw_mesh_paint_weight_faces(dm, use_light, facemask, me); } - else if (ob->mode & OB_MODE_VERTEX_PAINT) { + else if (eval_ctx->object_mode & OB_MODE_VERTEX_PAINT) { draw_mesh_paint_vcolor_faces(dm, use_light, facemask, me, me); } /* draw face selection on top */ if (draw_flags & DRAW_FACE_SELECT) { - bool draw_select_edges = (ob->mode & OB_MODE_TEXTURE_PAINT) == 0; + bool draw_select_edges = (eval_ctx->object_mode & OB_MODE_TEXTURE_PAINT) == 0; draw_mesh_face_select(rv3d, me, dm, draw_select_edges); } else if ((use_light == false) || (ob->dtx & OB_DRAWWIRE)) { - const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) || !(ob->mode & OB_MODE_WEIGHT_PAINT); - const bool use_alpha = (ob->mode & OB_MODE_VERTEX_PAINT) == 0; + const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) || !(eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT); + const bool use_alpha = (eval_ctx->object_mode & OB_MODE_VERTEX_PAINT) == 0; if (use_alpha == false) { set_inverted_drawing(1); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 51dc56bafaf..75c217c4f0c 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -314,13 +314,15 @@ static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt) /* check for glsl drawing */ -bool draw_glsl_material(Scene *scene, ViewLayer *view_layer, Object *ob, View3D *v3d, const char dt) +bool draw_glsl_material( + const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, + Object *ob, View3D *v3d, const char dt) { if (G.f & G_PICKSEL) return false; if (!check_object_draw_texture(scene, v3d, dt)) return false; - if (ob == OBACT(view_layer) && (ob && ob->mode & OB_MODE_WEIGHT_PAINT)) + if (ob == OBACT(view_layer) && (ob && eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT)) return false; if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP) @@ -334,7 +336,7 @@ bool draw_glsl_material(Scene *scene, ViewLayer *view_layer, Object *ob, View3D return false; } -static bool check_alpha_pass(Base *base) +static bool check_alpha_pass(const EvaluationContext *eval_ctx, Base *base) { if (base->flag_legacy & OB_FROMDUPLI) return false; @@ -342,8 +344,9 @@ static bool check_alpha_pass(Base *base) if (G.f & G_PICKSEL) return false; - if (base->object->mode & OB_MODE_ALL_PAINT) + if (eval_ctx->object_mode & OB_MODE_ALL_PAINT) { return false; + } return (base->object->dtx & OB_DRAWTRANSP); } @@ -727,7 +730,7 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char if (use_blend) { glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } Gwn_VertFormat *format = immVertexFormat(); @@ -777,7 +780,7 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char if (!use_blend) { glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } imm_draw_box_wire_2d(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax); @@ -1184,7 +1187,7 @@ static void draw_transp_spot_volume(Lamp *la, float x, float z, unsigned pos) draw_spot_cone(la, x, z, pos); /* restore state */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_BLEND); glDepthMask(GL_TRUE); glDisable(GL_CULL_FACE); @@ -1228,7 +1231,7 @@ static void draw_transp_sun_volume(Lamp *la, unsigned pos) imm_draw_box(box, true, pos); /* restore state */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_BLEND); glDepthMask(GL_TRUE); glDisable(GL_CULL_FACE); @@ -1324,7 +1327,7 @@ void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base, GPU_enable_program_point_size(); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA); immUniform1f("size", lampdot_size); @@ -3892,8 +3895,9 @@ static DMDrawOption draw_em_fancy__setGLSLFaceOpts(void *userData, int index) } } -static void draw_em_fancy(Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, - Object *ob, BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, const char dt) +static void draw_em_fancy( + const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, + Object *ob, BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, const char dt) { RegionView3D *rv3d = ar->regiondata; @@ -3930,7 +3934,7 @@ static void draw_em_fancy(Scene *scene, ViewLayer *view_layer, ARegion *ar, View glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } else if (check_object_draw_texture(scene, v3d, dt)) { - if (draw_glsl_material(scene, view_layer, ob, v3d, dt)) { + if (draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt)) { glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); finalDM->drawMappedFacesGLSL(finalDM, GPU_object_material_bind, @@ -4223,10 +4227,12 @@ static void draw_em_fancy_new(Scene *UNUSED(scene), ARegion *UNUSED(ar), View3D /* Mesh drawing routines */ -void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm, const unsigned char ob_wire_col[4]) /* LEGACY */ +void draw_mesh_object_outline( + const EvaluationContext *eval_ctx, View3D *v3d, + Object *ob, DerivedMesh *dm, const unsigned char ob_wire_col[4]) /* LEGACY */ { if ((v3d->transp == false) && /* not when we draw the transparent pass */ - (ob->mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */ + (eval_ctx->object_mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */ { glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); glDepthMask(GL_FALSE); @@ -4249,10 +4255,12 @@ void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm, const un } } -static void draw_mesh_object_outline_new(View3D *v3d, RegionView3D *rv3d, Object *ob, Mesh *me, const bool is_active) +static void draw_mesh_object_outline_new( + const EvaluationContext *eval_ctx, View3D *v3d, RegionView3D *rv3d, + Mesh *me, const bool is_active) { if ((v3d->transp == false) && /* not when we draw the transparent pass */ - (ob->mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */ + (eval_ctx->object_mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */ { glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); glDepthMask(GL_FALSE); @@ -4302,7 +4310,9 @@ static void draw_mesh_fancy( const char dt, const unsigned char ob_wire_col[4], const short dflag) { #ifdef WITH_GAMEENGINE - Object *ob = (rv3d->rflag & RV3D_IS_GAME_ENGINE) ? BKE_object_lod_meshob_get(base->object, view_layer) : base->object; + Object *ob = ( + (rv3d->rflag & RV3D_IS_GAME_ENGINE) ? + BKE_object_lod_meshob_get(base->object, view_layer, eval_ctx->object_mode) : base->object); #else Object *ob = base->object; #endif @@ -4311,7 +4321,7 @@ static void draw_mesh_fancy( bool /* no_verts,*/ no_edges, no_faces; DerivedMesh *dm = mesh_get_derived_final(eval_ctx, scene, ob, scene->customdata_mask); const bool is_obact = (ob == OBACT(view_layer)); - int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0; + int draw_flags = (is_obact && BKE_paint_select_face_test(ob, eval_ctx->object_mode)) ? DRAW_FACE_SELECT : 0; if (!dm) return; @@ -4349,7 +4359,7 @@ static void draw_mesh_fancy( draw_bounding_volume(ob, ob->boundtype, ob_wire_col); } else if ((no_faces && no_edges) || - ((!is_obact || (ob->mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob))) + ((!is_obact || (eval_ctx->object_mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob))) { glPointSize(1.5f); dm->drawVerts(dm); @@ -4357,7 +4367,7 @@ static void draw_mesh_fancy( else if ((dt == OB_WIRE) || no_faces) { draw_wire = OBDRAW_WIRE_ON; /* draw wire only, no depth buffer stuff */ } - else if (((is_obact && ob->mode & OB_MODE_TEXTURE_PAINT)) || + else if (((is_obact && eval_ctx->object_mode & OB_MODE_TEXTURE_PAINT)) || check_object_draw_texture(scene, v3d, dt)) { bool draw_loose = true; @@ -4368,15 +4378,17 @@ static void draw_mesh_fancy( !(G.f & G_PICKSEL || (draw_flags & DRAW_FACE_SELECT)) && (draw_wire == OBDRAW_WIRE_OFF)) { - draw_mesh_object_outline(v3d, ob, dm, ob_wire_col); + draw_mesh_object_outline(eval_ctx, v3d, ob, dm, ob_wire_col); } - if (draw_glsl_material(scene, view_layer, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) { + if (draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) { Paint *p; glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && (p = BKE_paint_get_active(scene, view_layer))) { + if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && + (p = BKE_paint_get_active(scene, view_layer, eval_ctx->object_mode))) + { GPUVertexAttribs gattribs; float planes[4][4]; float (*fpl)[4] = NULL; @@ -4439,7 +4451,7 @@ static void draw_mesh_fancy( (draw_wire == OBDRAW_WIRE_OFF) && (ob->sculpt == NULL)) { - draw_mesh_object_outline(v3d, ob, dm, ob_wire_col); + draw_mesh_object_outline(eval_ctx, v3d, ob, dm, ob_wire_col); } /* materials arent compatible with vertex colors */ @@ -4463,12 +4475,12 @@ static void draw_mesh_fancy( (draw_wire == OBDRAW_WIRE_OFF) && (ob->sculpt == NULL)) { - draw_mesh_object_outline(v3d, ob, dm, ob_wire_col); + draw_mesh_object_outline(eval_ctx, v3d, ob, dm, ob_wire_col); } glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - if (ob->sculpt && (p = BKE_paint_get_active(scene, view_layer))) { + if (ob->sculpt && (p = BKE_paint_get_active(scene, view_layer, eval_ctx->object_mode))) { float planes[4][4]; float (*fpl)[4] = NULL; const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING); @@ -4500,7 +4512,7 @@ static void draw_mesh_fancy( } } else if (dt == OB_PAINT) { - draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags); + draw_mesh_paint(eval_ctx, v3d, rv3d, ob, dm, draw_flags); /* since we already draw wire as wp guide, don't draw over the top */ draw_wire = OBDRAW_WIRE_OFF; @@ -4515,7 +4527,7 @@ static void draw_mesh_fancy( * with the background. */ if ((dflag & DRAW_CONSTCOLOR) == 0) { - if (is_obact && (ob->mode & OB_MODE_PARTICLE_EDIT)) { + if (is_obact && (eval_ctx->object_mode & OB_MODE_PARTICLE_EDIT)) { float color[3]; ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.15f, color); glColor3fv(color); @@ -4548,7 +4560,7 @@ static void draw_mesh_fancy( } } - if (is_obact && BKE_paint_select_vert_test(ob)) { + if (is_obact && BKE_paint_select_vert_test(ob, eval_ctx->object_mode)) { const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) != 0; glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); @@ -4567,7 +4579,7 @@ static bool draw_mesh_object( const char dt, const unsigned char ob_wire_col[4], const short dflag) { Object *ob = base->object; - Object *obedit = scene->obedit; + Object *obedit = OBEDIT_FROM_EVAL_CTX(eval_ctx); Mesh *me = ob->data; BMEditMesh *em = me->edit_btmesh; bool do_alpha_after = false, drawlinked = false, retval = false; @@ -4617,13 +4629,13 @@ static bool draw_mesh_object( if (use_material) { if (dt > OB_WIRE) { - const bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt); + const bool glsl = draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt); - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, NULL); + GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, eval_ctx->object_mode, NULL); } } - draw_em_fancy(scene, view_layer, ar, v3d, ob, em, cageDM, finalDM, dt); + draw_em_fancy(eval_ctx, scene, view_layer, ar, v3d, ob, em, cageDM, finalDM, dt); if (use_material) { GPU_end_object_materials(); @@ -4636,12 +4648,13 @@ static bool draw_mesh_object( /* ob->bb was set by derived mesh system, do NULL check just to be sure */ if (me->totpoly <= 4 || (!ob->bb || ED_view3d_boundbox_clip(rv3d, ob->bb))) { if (dt > OB_WIRE) { - const bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt); + const bool glsl = draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt); if (dt == OB_SOLID || glsl) { - const bool check_alpha = check_alpha_pass(base); - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, - (check_alpha) ? &do_alpha_after : NULL); + const bool check_alpha = check_alpha_pass(eval_ctx, base); + GPU_begin_object_materials( + v3d, rv3d, scene, view_layer, ob, + glsl, eval_ctx->object_mode, (check_alpha) ? &do_alpha_after : NULL); } } @@ -4707,8 +4720,10 @@ static void make_color_variations(const unsigned char base_ubyte[4], float low[4 high[3] = base[3]; } -static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const unsigned char ob_wire_col[4], const short dflag, const bool other_obedit) +static void draw_mesh_fancy_new( + const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, + ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, + const char dt, const unsigned char ob_wire_col[4], const short dflag, const bool other_obedit) { if (dflag & (DRAW_PICKING | DRAW_CONSTCOLOR)) { /* too complicated! use existing methods */ @@ -4718,7 +4733,9 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewL } #ifdef WITH_GAMEENGINE - Object *ob = (rv3d->rflag & RV3D_IS_GAME_ENGINE) ? BKE_object_lod_meshob_get(base->object, view_layer) : base->object; + Object *ob = ( + (rv3d->rflag & RV3D_IS_GAME_ENGINE) ? + BKE_object_lod_meshob_get(base->object, view_layer, eval_ctx->object_mode) : base->object); #else Object *ob = base->object; #endif @@ -4727,7 +4744,7 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewL bool no_edges, no_faces; DerivedMesh *dm = mesh_get_derived_final(eval_ctx, scene, ob, scene->customdata_mask); const bool is_obact = (ob == OBACT(view_layer)); - int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0; + int draw_flags = (is_obact && BKE_paint_select_face_test(ob, eval_ctx->object_mode)) ? DRAW_FACE_SELECT : 0; if (!dm) return; @@ -4770,7 +4787,7 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewL draw_bounding_volume(ob, ob->boundtype, ob_wire_col); } else if ((no_faces && no_edges) || - ((!is_obact || (ob->mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob))) + ((!is_obact || (eval_ctx->object_mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob))) { glPointSize(1.5f); // dm->drawVerts(dm); @@ -4836,7 +4853,7 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewL GWN_batch_draw(batch); #endif } - else if (((is_obact && ob->mode & OB_MODE_TEXTURE_PAINT)) || + else if (((is_obact && eval_ctx->object_mode & OB_MODE_TEXTURE_PAINT)) || check_object_draw_texture(scene, v3d, dt)) { bool draw_loose = true; @@ -4847,15 +4864,17 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewL !(G.f & G_PICKSEL || (draw_flags & DRAW_FACE_SELECT)) && (draw_wire == OBDRAW_WIRE_OFF)) { - draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT(view_layer))); + draw_mesh_object_outline_new(eval_ctx, v3d, rv3d, me, (ob == OBACT(view_layer))); } - if (draw_glsl_material(scene, view_layer, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) { + if (draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) { Paint *p; glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && (p = BKE_paint_get_active(scene, view_layer))) { + if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && + (p = BKE_paint_get_active(scene, view_layer, eval_ctx->object_mode))) + { GPUVertexAttribs gattribs; float planes[4][4]; float (*fpl)[4] = NULL; @@ -4914,7 +4933,7 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewL (draw_wire == OBDRAW_WIRE_OFF) && (ob->sculpt == NULL)) { - draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT(view_layer))); + draw_mesh_object_outline_new(eval_ctx, v3d, rv3d, me, (ob == OBACT(view_layer))); } /* materials arent compatible with vertex colors */ @@ -4939,12 +4958,12 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewL (ob->sculpt == NULL)) { /* TODO: move this into a separate pass */ - draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT(view_layer))); + draw_mesh_object_outline_new(eval_ctx, v3d, rv3d, me, (ob == OBACT(view_layer))); } glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - if (ob->sculpt && (p = BKE_paint_get_active(scene, view_layer))) { + if (ob->sculpt && (p = BKE_paint_get_active(scene, view_layer, eval_ctx->object_mode))) { float planes[4][4]; float (*fpl)[4] = NULL; const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING); @@ -4976,7 +4995,7 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewL } } else if (dt == OB_PAINT) { - draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags); + draw_mesh_paint(eval_ctx, v3d, rv3d, ob, dm, draw_flags); /* since we already draw wire as wp guide, don't draw over the top */ draw_wire = OBDRAW_WIRE_OFF; @@ -5025,22 +5044,20 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewL dm->release(dm); } -static bool UNUSED_FUNCTION(draw_mesh_object_new)(const bContext *C, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const unsigned char ob_wire_col[4], const short dflag) +static bool UNUSED_FUNCTION(draw_mesh_object_new)( + const EvaluationContext *eval_ctx, Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, + const char dt, const unsigned char ob_wire_col[4], const short dflag) { - EvaluationContext eval_ctx; Object *ob = base->object; - Object *obedit = scene->obedit; Mesh *me = ob->data; BMEditMesh *em = me->edit_btmesh; bool do_alpha_after = false, drawlinked = false, retval = false; - CTX_data_eval_ctx(C, &eval_ctx); - if (v3d->flag2 & V3D_RENDER_SHADOW) { /* TODO: handle shadow pass separately */ return true; } + Object *obedit = OBEDIT_FROM_EVAL_CTX(eval_ctx); if (obedit && ob != obedit && ob->data == obedit->data) { if (BKE_key_from_object(ob) || BKE_key_from_object(obedit)) {} @@ -5066,7 +5083,7 @@ static bool UNUSED_FUNCTION(draw_mesh_object_new)(const bContext *C, Scene *scen } else { cageDM = editbmesh_get_derived_cage_and_final( - &eval_ctx, scene, ob, em, scene->customdata_mask, + eval_ctx, scene, ob, em, scene->customdata_mask, &finalDM); } @@ -5085,9 +5102,9 @@ static bool UNUSED_FUNCTION(draw_mesh_object_new)(const bContext *C, Scene *scen DM_update_materials(cageDM, ob); } - const bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt); + const bool glsl = draw_glsl_material(eval_ctx, scene, eval_ctx->view_layer, ob, v3d, dt); - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, NULL); + GPU_begin_object_materials(v3d, rv3d, scene, eval_ctx->view_layer, ob, glsl, eval_ctx->object_mode, NULL); } draw_em_fancy_new(scene, ar, v3d, ob, me, em, cageDM, finalDM, dt); @@ -5103,18 +5120,19 @@ static bool UNUSED_FUNCTION(draw_mesh_object_new)(const bContext *C, Scene *scen /* ob->bb was set by derived mesh system, do NULL check just to be sure */ if (me->totpoly <= 4 || (!ob->bb || ED_view3d_boundbox_clip(rv3d, ob->bb))) { if (solid) { - const bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt); + const bool glsl = draw_glsl_material(eval_ctx, scene, eval_ctx->view_layer, ob, v3d, dt); if (dt == OB_SOLID || glsl) { - const bool check_alpha = check_alpha_pass(base); - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, - (check_alpha) ? &do_alpha_after : NULL); + const bool check_alpha = check_alpha_pass(eval_ctx, base); + GPU_begin_object_materials( + v3d, rv3d, scene, eval_ctx->view_layer, ob, + eval_ctx->object_mode, glsl, (check_alpha) ? &do_alpha_after : NULL); } } const bool other_obedit = obedit && (obedit != ob); - draw_mesh_fancy_new(&eval_ctx, scene, view_layer, ar, v3d, rv3d, base, dt, ob_wire_col, dflag, other_obedit); + draw_mesh_fancy_new(eval_ctx, scene, eval_ctx->view_layer, ar, v3d, rv3d, base, dt, ob_wire_col, dflag, other_obedit); GPU_end_object_materials(); @@ -5425,7 +5443,9 @@ static void drawCurveDMWired(Object *ob) } /* return true when nothing was drawn */ -static bool drawCurveDerivedMesh(Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, Base *base, const char dt) +static bool drawCurveDerivedMesh( + const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, + Base *base, const char dt) { Object *ob = base->object; DerivedMesh *dm = ob->derivedFinal; @@ -5439,8 +5459,10 @@ static bool drawCurveDerivedMesh(Scene *scene, ViewLayer *view_layer, View3D *v3 glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); if (dt > OB_WIRE && dm->getNumPolys(dm)) { - bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt); - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, NULL); + bool glsl = draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt); + GPU_begin_object_materials( + v3d, rv3d, scene, view_layer, ob, + eval_ctx->object_mode, glsl, NULL); if (!glsl) dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind); @@ -5461,8 +5483,9 @@ static bool drawCurveDerivedMesh(Scene *scene, ViewLayer *view_layer, View3D *v3 * Only called by #drawDispList * \return true when nothing was drawn */ -static bool drawDispList_nobackface(Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const short dflag, const unsigned char ob_wire_col[4]) +static bool drawDispList_nobackface( + const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, + Base *base, const char dt, const short dflag, const unsigned char ob_wire_col[4]) { Object *ob = base->object; ListBase *lb = NULL; @@ -5502,13 +5525,13 @@ static bool drawDispList_nobackface(Scene *scene, ViewLayer *view_layer, View3D /* pass */ } else { - if (draw_glsl_material(scene, view_layer, ob, v3d, dt)) { - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 1, NULL); + if (draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt)) { + GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 1, eval_ctx->object_mode, NULL); drawDispListsolid(lb, ob, dflag, ob_wire_col, true); GPU_end_object_materials(); } else { - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 0, NULL); + GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 0, eval_ctx->object_mode, NULL); drawDispListsolid(lb, ob, dflag, ob_wire_col, false); GPU_end_object_materials(); } @@ -5537,13 +5560,13 @@ static bool drawDispList_nobackface(Scene *scene, ViewLayer *view_layer, View3D if (dl->nors == NULL) BKE_displist_normals_add(lb); - if (draw_glsl_material(scene, view_layer, ob, v3d, dt)) { - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 1, NULL); + if (draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt)) { + GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 1, eval_ctx->object_mode, NULL); drawDispListsolid(lb, ob, dflag, ob_wire_col, true); GPU_end_object_materials(); } else { - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 0, NULL); + GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 0, eval_ctx->object_mode, NULL); drawDispListsolid(lb, ob, dflag, ob_wire_col, false); GPU_end_object_materials(); } @@ -5562,13 +5585,13 @@ static bool drawDispList_nobackface(Scene *scene, ViewLayer *view_layer, View3D if (solid) { - if (draw_glsl_material(scene, view_layer, ob, v3d, dt)) { - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 1, NULL); + if (draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt)) { + GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 1, eval_ctx->object_mode, NULL); drawDispListsolid(lb, ob, dflag, ob_wire_col, true); GPU_end_object_materials(); } else { - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 0, NULL); + GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 0, eval_ctx->object_mode, NULL); drawDispListsolid(lb, ob, dflag, ob_wire_col, false); GPU_end_object_materials(); } @@ -5599,7 +5622,7 @@ static bool drawDispList( ensure_curve_cache(eval_ctx, scene, base->object); #endif - if (drawCurveDerivedMesh(scene, view_layer, v3d, rv3d, base, dt) == false) { + if (drawCurveDerivedMesh(eval_ctx, scene, view_layer, v3d, rv3d, base, dt) == false) { retval = false; } else { @@ -5615,7 +5638,7 @@ static bool drawDispList( glFrontFace(mode); - retval = drawDispList_nobackface(scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col); + retval = drawDispList_nobackface(eval_ctx, scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col); if (mode != GL_CCW) { glFrontFace(GL_CCW); @@ -5939,7 +5962,7 @@ static void draw_new_particle_system( if (pars == NULL) return; /* don't draw normal paths in edit mode */ - if (psys_in_edit_mode(eval_ctx->view_layer, psys) && (pset->flag & PE_DRAW_PART) == 0) + if (psys_in_edit_mode(eval_ctx, eval_ctx->view_layer, psys) && (pset->flag & PE_DRAW_PART) == 0) return; if (part->draw_as == PART_DRAW_REND) @@ -5955,6 +5978,8 @@ static void draw_new_particle_system( curvemapping_changed_all(psys->part->clumpcurve); if ((psys->part->child_flag & PART_CHILD_USE_ROUGH_CURVE) && psys->part->roughcurve) curvemapping_changed_all(psys->part->roughcurve); + if ((psys->part->child_flag & PART_CHILD_USE_TWIST_CURVE) && psys->part->twistcurve) + curvemapping_changed_all(psys->part->twistcurve); /* 2. */ sim.eval_ctx = eval_ctx; @@ -8296,7 +8321,7 @@ static void draw_object_selected_outline( if (has_faces && ED_view3d_boundbox_clip(rv3d, ob->bb)) { glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); if (dm) { - draw_mesh_object_outline(v3d, ob, dm, ob_wire_col); + draw_mesh_object_outline(eval_ctx, v3d, ob, dm, ob_wire_col); } else { /* only draw 'solid' parts of the display list as wire. */ @@ -8313,7 +8338,7 @@ static void draw_object_selected_outline( } } else if (ob->type == OB_ARMATURE) { - if (!(ob->mode & OB_MODE_POSE && base == view_layer->basact)) { + if (!(eval_ctx->object_mode & OB_MODE_POSE && base == view_layer->basact)) { glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); draw_armature(eval_ctx, scene, view_layer, v3d, ar, base, OB_WIRE, 0, ob_wire_col, true); } @@ -8322,7 +8347,8 @@ static void draw_object_selected_outline( glDepthMask(GL_TRUE); } -static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, const unsigned char ob_wire_col[4]) +static void draw_wire_extra( + RegionView3D *rv3d, Object *ob, const bool is_obedit, const unsigned char ob_wire_col[4]) { if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL)) { unsigned char wire_edit_col[4]; @@ -8339,13 +8365,13 @@ static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, const drawCurveDMWired(ob); } else { - drawDispListwire(&ob->curve_cache->disp, ob->type, (scene->obedit == ob) ? wire_edit_col : ob_wire_col); + drawDispListwire(&ob->curve_cache->disp, ob->type, is_obedit ? wire_edit_col : ob_wire_col); } } } else if (ob->type == OB_MBALL) { if (BKE_mball_is_basis(ob)) { - drawDispListwire(&ob->curve_cache->disp, ob->type, (scene->obedit == ob) ? wire_edit_col : ob_wire_col); + drawDispListwire(&ob->curve_cache->disp, ob->type, is_obedit ? wire_edit_col : ob_wire_col); } } @@ -8423,11 +8449,13 @@ static void draw_rigid_body_pivot(bRigidBodyJointConstraint *data, immUnbindProgram(); } -void draw_object_wire_color(Scene *scene, ViewLayer *view_layer, Base *base, unsigned char r_ob_wire_col[4]) +void draw_object_wire_color( + const EvaluationContext *eval_ctx, ViewLayer *view_layer, + Base *base, unsigned char r_ob_wire_col[4]) { Object *ob = base->object; int colindex = 0; - const bool is_edit = (ob->mode & OB_MODE_EDIT) != 0; + const bool is_edit = (eval_ctx->object_mode & OB_MODE_EDIT) != 0; /* confusing logic here, there are 2 methods of setting the color * 'colortab[colindex]' and 'theme_id', colindex overrides theme_id. * @@ -8435,7 +8463,7 @@ void draw_object_wire_color(Scene *scene, ViewLayer *view_layer, Base *base, uns int theme_id = is_edit ? TH_WIRE_EDIT : TH_WIRE; int theme_shade = 0; - if ((scene->obedit == NULL) && + if (((eval_ctx->object_mode & OB_MODE_EDIT) == 0) && (G.moving & G_TRANSFORM_OBJ) && ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL))) { @@ -8489,10 +8517,12 @@ void draw_object_wire_color(Scene *scene, ViewLayer *view_layer, Base *base, uns r_ob_wire_col[3] = 255; } -static void draw_object_matcap_check(View3D *v3d, Object *ob) +static void draw_object_matcap_check( + const EvaluationContext *eval_ctx, View3D *v3d, Object *ob) { /* fixed rule, active object draws as matcap */ - BLI_assert((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) == 0); + BLI_assert((eval_ctx->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) == 0); + UNUSED_VARS_NDEBUG(eval_ctx); (void)ob; if (v3d->defmaterial == NULL) { @@ -8579,13 +8609,15 @@ void draw_object( const unsigned char *ob_wire_col = NULL; /* dont initialize this, use NULL crashes as a way to find invalid use */ bool zbufoff = false, is_paint = false, empty_object = false; const bool is_obact = (ob == OBACT(view_layer)); + /* this could be moved to a 'dflag'. */ + const bool is_obedit = (is_obact && (ob == OBEDIT_FROM_EVAL_CTX(eval_ctx))); const bool render_override = (v3d->flag2 & V3D_RENDER_OVERRIDE) != 0; const bool is_picking = (G.f & G_PICKSEL) != 0; const bool has_particles = (ob->particlesystem.first != NULL); bool skip_object = false; /* Draw particles but not their emitter object. */ SmokeModifierData *smd = NULL; - if (ob != scene->obedit) { + if (is_obedit == false) { if (ob->restrictflag & OB_RESTRICT_VIEW) return; @@ -8604,7 +8636,7 @@ void draw_object( return; } - if (ob->mode == OB_MODE_OBJECT) { + if (eval_ctx->object_mode == OB_MODE_OBJECT) { ParticleSystem *psys; skip_object = render_override; @@ -8644,7 +8676,7 @@ void draw_object( /* xray delay? */ if ((dflag & DRAW_PICKING) == 0 && (base->flag_legacy & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) { /* don't do xray in particle mode, need the z-buffer */ - if (!(ob->mode & OB_MODE_PARTICLE_EDIT)) { + if (!(eval_ctx->object_mode & OB_MODE_PARTICLE_EDIT)) { /* xray and transp are set when it is drawing the 2nd/3rd pass */ if (!v3d->xray && !v3d->transp && (ob->dtx & OB_DRAWXRAY) && !(ob->dtx & OB_DRAWTRANSP)) { ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag); @@ -8666,7 +8698,7 @@ void draw_object( /* no return after this point, otherwise leaks */ /* only once set now, will be removed too, should become a global standard */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* reset here to avoid having to call all over */ glLineWidth(1.0f); @@ -8695,7 +8727,7 @@ void draw_object( ED_view3d_project_base(ar, base); - draw_object_wire_color(scene, view_layer, base, _ob_wire_col); + draw_object_wire_color(eval_ctx, view_layer, base, _ob_wire_col); ob_wire_col = _ob_wire_col; //glColor3ubv(ob_wire_col); @@ -8711,14 +8743,14 @@ void draw_object( /* faceselect exception: also draw solid when (dt == wire), except in editmode */ if (is_obact) { - if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) { + if (eval_ctx->object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) { if (ob->type == OB_MESH) { if (dt < OB_SOLID) { zbufoff = true; dt = OB_SOLID; } - if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) { + if (eval_ctx->object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) { dt = OB_PAINT; } @@ -8734,13 +8766,13 @@ void draw_object( (is_paint == false && is_picking == false) && ((v3d->flag2 & V3D_RENDER_SHADOW) == 0)) { - draw_object_matcap_check(v3d, ob); + draw_object_matcap_check(eval_ctx, v3d, ob); } /* draw-extra supported for boundbox drawmode too */ if (dt >= OB_BOUNDBOX) { dtx = ob->dtx; - if (ob->mode & OB_MODE_EDIT) { + if (eval_ctx->object_mode & OB_MODE_EDIT) { /* the only 2 extra drawtypes alowed in editmode */ dtx = dtx & (OB_DRAWWIRE | OB_TEXSPACE); } @@ -8749,7 +8781,7 @@ void draw_object( if (!skip_object) { /* draw outline for selected objects, mesh does itself */ if ((v3d->flag & V3D_SELECT_OUTLINE) && !render_override && ob->type != OB_MESH) { - if (dt > OB_WIRE && (ob->mode & OB_MODE_EDIT) == 0 && (dflag & DRAW_SCENESET) == 0) { + if (dt > OB_WIRE && (eval_ctx->object_mode & OB_MODE_EDIT) == 0 && (dflag & DRAW_SCENESET) == 0) { if (!(ob->dtx & OB_DRAWWIRE) && (base->flag & BASE_SELECTED) && !(dflag & (DRAW_PICKING | DRAW_CONSTCOLOR))) { draw_object_selected_outline(eval_ctx, scene, view_layer, v3d, ar, base, ob_wire_col); } @@ -8857,7 +8889,7 @@ void draw_object( case OB_LATTICE: if (!render_override) { /* Do not allow boundbox in edit nor pose mode! */ - if ((dt == OB_BOUNDBOX) && (ob->mode & OB_MODE_EDIT)) + if ((dt == OB_BOUNDBOX) && (eval_ctx->object_mode & OB_MODE_EDIT)) dt = OB_WIRE; if (dt == OB_BOUNDBOX) { draw_bounding_volume(ob, ob->boundtype, ob_wire_col); @@ -8873,7 +8905,7 @@ void draw_object( case OB_ARMATURE: if (!render_override) { /* Do not allow boundbox in edit nor pose mode! */ - if ((dt == OB_BOUNDBOX) && (ob->mode & (OB_MODE_EDIT | OB_MODE_POSE))) + if ((dt == OB_BOUNDBOX) && (eval_ctx->object_mode & (OB_MODE_EDIT | OB_MODE_POSE))) dt = OB_WIRE; if (dt == OB_BOUNDBOX) { draw_bounding_volume(ob, ob->boundtype, ob_wire_col); @@ -8929,7 +8961,7 @@ afterdraw: /* code for new particle system */ if ((ob->particlesystem.first) && - (ob != scene->obedit)) + (is_obedit == false)) { ParticleSystem *psys; @@ -8941,7 +8973,7 @@ afterdraw: for (psys = ob->particlesystem.first; psys; psys = psys->next) { /* run this so that possible child particles get cached */ - if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) { + if (eval_ctx->object_mode & OB_MODE_PARTICLE_EDIT && is_obact) { PTCacheEdit *edit = PE_create_current(eval_ctx, scene, ob); if (edit && edit->psys == psys) draw_update_ptcache_edit(eval_ctx, scene, view_layer, ob, edit); @@ -8959,10 +8991,10 @@ afterdraw: /* draw edit particles last so that they can draw over child particles */ if ((dflag & DRAW_PICKING) == 0 && - (!scene->obedit)) + (is_obedit == false)) { - if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) { + if (eval_ctx->object_mode & OB_MODE_PARTICLE_EDIT && is_obact) { PTCacheEdit *edit = PE_create_current(eval_ctx, scene, ob); if (edit) { gpuLoadMatrix(rv3d->viewmat); @@ -9063,7 +9095,7 @@ afterdraw: } } - if ((ob->gameflag & OB_BOUNDS) && (ob->mode == OB_MODE_OBJECT)) { + if ((ob->gameflag & OB_BOUNDS) && (eval_ctx->object_mode == OB_MODE_OBJECT)) { if (ob->boundtype != ob->collision_boundtype || (dtx & OB_DRAWBOUNDOX) == 0) { setlinestyle(2); draw_bounding_volume(ob, ob->collision_boundtype, ob_wire_col); @@ -9108,7 +9140,7 @@ afterdraw: } if ((dtx & OB_DRAWWIRE) && dt >= OB_SOLID) { if ((dflag & DRAW_CONSTCOLOR) == 0) { - draw_wire_extra(scene, rv3d, ob, ob_wire_col); + draw_wire_extra(rv3d, ob, is_obedit, ob_wire_col); } } } @@ -9159,7 +9191,7 @@ afterdraw: } /* object centers, need to be drawn in viewmat space for speed, but OK for picking select */ - if (!is_obact || !(ob->mode & OB_MODE_ALL_PAINT)) { + if (!is_obact || !(eval_ctx->object_mode & OB_MODE_ALL_PAINT)) { int do_draw_center = -1; /* defines below are zero or positive... */ if (render_override) { @@ -9212,11 +9244,11 @@ afterdraw: immUniformColor3ubv(ob_wire_col); /* draw hook center and offset line */ - if (ob != scene->obedit) + if (is_obedit == false) draw_hooks(ob, pos); /* help lines and so */ - if (ob != scene->obedit && ob->parent) { + if ((is_obedit == false) && ob->parent) { const eObjectVisibilityCheck mode = eval_ctx->mode != DAG_EVAL_VIEWPORT ? OB_VISIBILITY_CHECK_FOR_RENDER : OB_VISIBILITY_CHECK_FOR_VIEWPORT; @@ -9759,7 +9791,7 @@ void draw_object_backbufsel( switch (ob->type) { case OB_MESH: - if (ob->mode & OB_MODE_EDIT) { + if (eval_ctx->object_mode & OB_MODE_EDIT) { Mesh *me = ob->data; BMEditMesh *em = me->edit_btmesh; @@ -9805,7 +9837,7 @@ void draw_object_backbufsel( Mesh *me = ob->data; if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) && /* currently vertex select supports weight paint and vertex paint*/ - ((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT))) + ((eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) || (eval_ctx->object_mode & OB_MODE_VERTEX_PAINT))) { bbs_mesh_solid_verts(eval_ctx, scene, ob); } @@ -9834,7 +9866,7 @@ static void draw_object_mesh_instance( Mesh *me = ob->data; DerivedMesh *dm = NULL, *edm = NULL; - if (ob->mode & OB_MODE_EDIT) { + if (eval_ctx->object_mode & OB_MODE_EDIT) { edm = editbmesh_get_derived_base(ob, me->edit_btmesh, CD_MASK_BAREMESH); DM_update_materials(edm, ob); } @@ -9852,11 +9884,11 @@ static void draw_object_mesh_instance( } else { if (outline) - draw_mesh_object_outline(v3d, ob, dm ? dm : edm, ob_wire_col); + draw_mesh_object_outline(eval_ctx, v3d, ob, dm ? dm : edm, ob_wire_col); if (dm) { - bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt); - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, NULL); + bool glsl = draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt); + GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, eval_ctx->object_mode, NULL); } glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); @@ -9960,7 +9992,7 @@ void ED_draw_object_facemap( immUniformColor4fv(col); /* XXX, alpha isn't working yet, not sure why. */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); MVert *mvert; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 6540a1fb234..0eaf1e10086 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -286,7 +286,7 @@ void ED_view3d_stop_render_preview(wmWindowManager *wm, ARegion *ar) } } -void ED_view3d_shade_update(Main *bmain, Scene *scene, View3D *v3d, ScrArea *sa) +void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *sa) { wmWindowManager *wm = bmain->wm.first; @@ -298,10 +298,6 @@ void ED_view3d_shade_update(Main *bmain, Scene *scene, View3D *v3d, ScrArea *sa) ED_view3d_stop_render_preview(wm, ar); } } - else if (scene->obedit != NULL && scene->obedit->type == OB_MESH) { - /* Tag mesh to load edit data. */ - DEG_id_tag_update(scene->obedit->data, 0); - } } /* ******************** default callbacks for view3d space ***************** */ @@ -901,10 +897,10 @@ static void view3d_main_region_listener( case ND_SELECT: { WM_manipulatormap_tag_refresh(mmap); - if (scene->obedit) { - Object *ob = scene->obedit; + Object *obedit = OBEDIT_FROM_WINDOW(wmn->window); + if (obedit) { /* TODO(sergey): Notifiers shouldn't really be doing DEG tags. */ - DEG_id_tag_update((ID *)ob->data, DEG_TAG_SELECT_UPDATE); + DEG_id_tag_update((ID *)obedit->data, DEG_TAG_SELECT_UPDATE); } ATTR_FALLTHROUGH; } @@ -1118,9 +1114,8 @@ static void view3d_main_region_message_subscribe( /* concept is to retrieve cursor type context-less */ static void view3d_main_region_cursor(wmWindow *win, ScrArea *UNUSED(sa), ARegion *UNUSED(ar)) { - const Scene *scene = WM_window_get_active_scene(win); - - if (scene->obedit) { + WorkSpace *workspace = WM_window_get_active_workspace(win); + if (workspace->object_mode & OB_MODE_EDIT) { WM_cursor_set(win, CURSOR_EDIT); } else { @@ -1351,9 +1346,9 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); if (view_layer->basact) { - Object *ob = view_layer->basact->object; + const WorkSpace *workspace = CTX_wm_workspace(C); /* if hidden but in edit mode, we still display, can happen with animation */ - if ((view_layer->basact->flag & BASE_VISIBLED) != 0 || (ob->mode & OB_MODE_EDIT)) { + if ((view_layer->basact->flag & BASE_VISIBLED) != 0 || (workspace->object_mode & OB_MODE_EDIT)) { CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, view_layer->basact); } } @@ -1363,9 +1358,10 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes else if (CTX_data_equals(member, "active_object")) { ViewLayer *view_layer = CTX_data_view_layer(C); if (view_layer->basact) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *ob = view_layer->basact->object; /* if hidden but in edit mode, we still display, can happen with animation */ - if ((view_layer->basact->flag & BASE_VISIBLED) != 0 || (ob->mode & OB_MODE_EDIT) != 0) { + if ((view_layer->basact->flag & BASE_VISIBLED) != 0 || (workspace->object_mode & OB_MODE_EDIT) != 0) { CTX_data_id_pointer_set(result, &ob->id); } } diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 644a6956e54..bd62a4fc3bf 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -787,10 +787,12 @@ static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event) static int view3d_panel_vgroup_poll(const bContext *C, PanelType *UNUSED(pt)) { + const WorkSpace *workspace = CTX_wm_workspace(C); ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob = OBACT(view_layer); + if (ob && (BKE_object_is_in_editmode_vgroup(ob) || - BKE_object_is_in_wpaint_select_vert(ob))) + BKE_object_is_in_wpaint_select_vert(ob, workspace->object_mode))) { MDeformVert *dvert_act = ED_mesh_active_dvert_get_only(ob); if (dvert_act) { @@ -1128,6 +1130,7 @@ static int view3d_panel_transform_poll(const bContext *C, PanelType *UNUSED(pt)) static void view3d_panel_transform(const bContext *C, Panel *pa) { uiBlock *block; + const WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); Object *obedit = CTX_data_edit_object(C); @@ -1152,7 +1155,7 @@ static void view3d_panel_transform(const bContext *C, Panel *pa) v3d_editvertex_buts(col, v3d, ob, lim); } } - else if (ob->mode & OB_MODE_POSE) { + else if (workspace->object_mode & OB_MODE_POSE) { v3d_posearmature_buts(col, ob); } else { diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index f734bb085d0..6e3a0883489 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -35,7 +35,7 @@ #include "BLI_rect.h" #include "BLI_string.h" #include "BLI_threads.h" -#include "BLI_jitter.h" +#include "BLI_jitter_2d.h" #include "BIF_gl.h" #include "BIF_glutil.h" @@ -99,15 +99,15 @@ /* ******************** general functions ***************** */ -static bool use_depth_doit(Scene *scene, View3D *v3d) +static bool use_depth_doit(View3D *v3d, Object *obedit) { if (v3d->drawtype > OB_WIRE) return true; /* special case (depth for wire color) */ if (v3d->drawtype <= OB_WIRE) { - if (scene->obedit && scene->obedit->type == OB_MESH) { - Mesh *me = scene->obedit->data; + if (obedit && obedit->type == OB_MESH) { + Mesh *me = obedit->data; if (me->drawflag & ME_DRAWEIGHT) { return true; } @@ -268,28 +268,28 @@ static void view3d_stereo3d_setup( data = (Camera *)v3d->camera->data; shiftx = data->shiftx; - BLI_lock_thread(LOCK_VIEW3D); + BLI_thread_lock(LOCK_VIEW3D); data->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname); BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat); view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, NULL, rect); data->shiftx = shiftx; - BLI_unlock_thread(LOCK_VIEW3D); + BLI_thread_unlock(LOCK_VIEW3D); } else { /* SCE_VIEWS_FORMAT_MULTIVIEW */ float viewmat[4][4]; Object *view_ob = v3d->camera; Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname); - BLI_lock_thread(LOCK_VIEW3D); + BLI_thread_lock(LOCK_VIEW3D); v3d->camera = camera; BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat); view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, NULL, rect); v3d->camera = view_ob; - BLI_unlock_thread(LOCK_VIEW3D); + BLI_thread_unlock(LOCK_VIEW3D); } } @@ -494,7 +494,7 @@ static void drawviewborder(Scene *scene, const Depsgraph *depsgraph, ARegion *ar float alpha = 1.0f; if (ca->passepartalpha != 1.0f) { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); alpha = ca->passepartalpha; } @@ -752,7 +752,7 @@ void ED_view3d_draw_depth( else #endif /* WITH_OPENGL_LEGACY */ { - DRW_draw_depth_loop(graph, ar, v3d); + DRW_draw_depth_loop(graph, ar, v3d, eval_ctx->object_mode); } if (rv3d->rflag & RV3D_CLIPPING) { @@ -1326,7 +1326,7 @@ float ED_view3d_grid_scale(Scene *scene, View3D *v3d, const char **grid_unit) return v3d->grid * ED_scene_grid_scale(scene, grid_unit); } -static bool is_cursor_visible(Scene *scene, ViewLayer *view_layer) +static bool is_cursor_visible(const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer) { if (U.app_flag & USER_APP_VIEW3D_HIDE_CURSOR) { return false; @@ -1335,16 +1335,16 @@ static bool is_cursor_visible(Scene *scene, ViewLayer *view_layer) Object *ob = OBACT(view_layer); /* don't draw cursor in paint modes, but with a few exceptions */ - if (ob && ob->mode & OB_MODE_ALL_PAINT) { + if (ob && eval_ctx->object_mode & OB_MODE_ALL_PAINT) { /* exception: object is in weight paint and has deforming armature in pose mode */ - if (ob->mode & OB_MODE_WEIGHT_PAINT) { + if (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) { if (BKE_object_pose_armature_get(ob) != NULL) { return true; } } /* exception: object in texture paint mode, clone brush, use_clone_layer disabled */ - else if (ob->mode & OB_MODE_TEXTURE_PAINT) { - const Paint *p = BKE_paint_get_active(scene, view_layer); + else if (eval_ctx->object_mode & OB_MODE_TEXTURE_PAINT) { + const Paint *p = BKE_paint_get_active(scene, view_layer, eval_ctx->object_mode); if (p && p->brush && p->brush->imagepaint_tool == PAINT_TOOL_CLONE) { if ((scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) == 0) { @@ -1422,7 +1422,7 @@ static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d) } } -static void draw_view_axis(RegionView3D *rv3d, rcti *rect) +static void draw_view_axis(RegionView3D *rv3d, const rcti *rect) { const float k = U.rvisize * U.pixelsize; /* axis size */ const int bright = - 20 * (10 - U.rvibright); /* axis alpha offset (rvibright has range 0-10) */ @@ -1455,7 +1455,7 @@ static void draw_view_axis(RegionView3D *rv3d, rcti *rect) glLineWidth(2.0f); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); Gwn_VertFormat *format = immVertexFormat(); unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); @@ -1498,7 +1498,7 @@ static void UNUSED_FUNCTION(draw_rotation_guide)(RegionView3D *rv3d) negate_v3_v3(o, rv3d->ofs); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glDepthMask(GL_FALSE); /* don't overwrite zbuf */ Gwn_VertFormat *format = immVertexFormat(); @@ -1689,7 +1689,7 @@ static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d) return name; } -static void draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect) +static void draw_viewport_name(ARegion *ar, View3D *v3d, const rcti *rect) { RegionView3D *rv3d = ar->regiondata; const char *name = view3d_get_name(v3d, rv3d); @@ -1718,7 +1718,8 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect) * framenum, object name, bone name (if available), marker name (if available) */ -static void draw_selected_name(Scene *scene, Object *ob, rcti *rect) +static void draw_selected_name( + Scene *scene, Object *ob, const eObjectMode object_mode, const rcti *rect) { const int cfra = CFRA; const char *msg_pin = " (Pinned)"; @@ -1760,7 +1761,7 @@ static void draw_selected_name(Scene *scene, Object *ob, rcti *rect) s += BLI_strcpy_rlen(s, arm->act_edbone->name); } } - else if (ob->mode & OB_MODE_POSE) { + else if (object_mode & OB_MODE_POSE) { if (arm->act_bone) { if (arm->act_bone->layer & arm->layer) { @@ -1773,9 +1774,9 @@ static void draw_selected_name(Scene *scene, Object *ob, rcti *rect) else if (ELEM(ob->type, OB_MESH, OB_LATTICE, OB_CURVE)) { /* try to display active bone and active shapekey too (if they exist) */ - if (ob->type == OB_MESH && ob->mode & OB_MODE_WEIGHT_PAINT) { + if (ob->type == OB_MESH && object_mode & OB_MODE_WEIGHT_PAINT) { Object *armobj = BKE_object_pose_armature_get(ob); - if (armobj && armobj->mode & OB_MODE_POSE) { + if (armobj) { bArmature *arm = armobj->data; if (arm->act_bone) { if (arm->act_bone->layer & arm->layer) { @@ -1862,9 +1863,10 @@ void view3d_draw_region_info(const bContext *C, ARegion *ar, const int offset) } if (U.uiflag & USER_DRAWVIEWINFO) { + const WorkSpace *workspace = CTX_wm_workspace(C); ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob = OBACT(view_layer); - draw_selected_name(scene, ob, &rect); + draw_selected_name(scene, ob, workspace->object_mode, &rect); } #if 0 /* TODO */ if (grid_unit) { /* draw below the viewport name */ @@ -1916,6 +1918,10 @@ void view3d_main_region_draw(const bContext *C, ARegion *ar) view3d_draw_view(C, ar); GPU_viewport_unbind(rv3d->viewport); + rcti rect = ar->winrct; + BLI_rcti_translate(&rect, -ar->winrct.xmin, -ar->winrct.ymin); + GPU_viewport_draw_to_screen(rv3d->viewport, &rect); + v3d->flag |= V3D_INVALID_BACKBUF; } @@ -1951,7 +1957,7 @@ void ED_view3d_draw_offscreen_init(const EvaluationContext *eval_ctx, Scene *sce RenderEngineType *engine_type = eval_ctx->engine_type; if (engine_type->flag & RE_USE_LEGACY_PIPELINE) { /* shadow buffers, before we setup matrices */ - if (draw_glsl_material(scene, view_layer, NULL, v3d, v3d->drawtype)) { + if (draw_glsl_material(eval_ctx, scene, view_layer, NULL, v3d, v3d->drawtype)) { VP_deprecated_gpu_update_lamps_shadows_world(eval_ctx, scene, v3d); } } @@ -2076,7 +2082,9 @@ void ED_view3d_draw_offscreen( } } else { - DRW_draw_render_loop_offscreen(depsgraph, eval_ctx->engine_type, ar, v3d, do_sky, ofs, viewport); + DRW_draw_render_loop_offscreen( + eval_ctx->depsgraph, eval_ctx->engine_type, ar, v3d, eval_ctx->object_mode, + do_sky, ofs, viewport); } /* restore size */ @@ -2126,7 +2134,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( if (own_ofs) { /* bind */ - ofs = GPU_offscreen_create(sizex, sizey, use_full_sample ? 0 : samples, false, err_out); + ofs = GPU_offscreen_create(sizex, sizey, use_full_sample ? 0 : samples, true, false, err_out); if (ofs == NULL) { return NULL; } @@ -2352,26 +2360,27 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple( * * \{ */ -void VP_legacy_drawcursor(Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d) +void VP_legacy_drawcursor( + const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d) { - if (is_cursor_visible(scene, view_layer)) { + if (is_cursor_visible(eval_ctx, scene, view_layer)) { drawcursor(scene, ar, v3d); } } -void VP_legacy_draw_view_axis(RegionView3D *rv3d, rcti *rect) +void VP_legacy_draw_view_axis(RegionView3D *rv3d, const rcti *rect) { draw_view_axis(rv3d, rect); } -void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect) +void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, const rcti *rect) { draw_viewport_name(ar, v3d, rect); } -void VP_legacy_draw_selected_name(Scene *scene, Object *ob, rcti *rect) +void VP_legacy_draw_selected_name(Scene *scene, Object *ob, eObjectMode object_mode, const rcti *rect) { - draw_selected_name(scene, ob, rect); + draw_selected_name(scene, ob, object_mode, rect); } void VP_legacy_drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit) @@ -2401,9 +2410,9 @@ void VP_legacy_view3d_stereo3d_setup(const EvaluationContext *eval_ctx, Scene *s view3d_stereo3d_setup(eval_ctx, scene, v3d, ar, NULL); } -bool VP_legacy_use_depth(Scene *scene, View3D *v3d) +bool VP_legacy_use_depth(View3D *v3d, Object *obedit) { - return use_depth_doit(scene, v3d); + return use_depth_doit(v3d, obedit); } void VP_drawviewborder(Scene *scene, const struct Depsgraph *depsgraph, ARegion *ar, View3D *v3d) diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c index 7cb362ffb92..6a746ffe27c 100644 --- a/source/blender/editors/space_view3d/view3d_draw_legacy.c +++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c @@ -48,7 +48,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" -#include "BLI_jitter.h" +#include "BLI_jitter_2d.h" #include "BLI_utildefines.h" #include "BLI_endian_switch.h" #include "BLI_threads.h" @@ -202,7 +202,7 @@ static void draw_view_icon(RegionView3D *rv3d, rcti *rect) else return; glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); UI_icon_draw(5.0 + rect->xmin, 5.0 + rect->ymin, icon); @@ -211,31 +211,32 @@ static void draw_view_icon(RegionView3D *rv3d, rcti *rect) /* *********************** backdraw for selection *************** */ -static void backdrawview3d(const struct EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, wmWindow *win, ARegion *ar, View3D *v3d) +static void backdrawview3d( + const struct EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, + ARegion *ar, View3D *v3d) { RegionView3D *rv3d = ar->regiondata; struct Base *base = view_layer->basact; - int multisample_enabled; BLI_assert(ar->regiontype == RGN_TYPE_WINDOW); - if (base && (base->object->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) || - BKE_paint_select_face_test(base->object))) + if (base && (eval_ctx->object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) || + BKE_paint_select_face_test(base->object, eval_ctx->object_mode))) { /* do nothing */ } /* texture paint mode sampling */ - else if (base && (base->object->mode & OB_MODE_TEXTURE_PAINT) && + else if (base && (eval_ctx->object_mode & OB_MODE_TEXTURE_PAINT) && (v3d->drawtype > OB_WIRE)) { /* do nothing */ } - else if ((base && (base->object->mode & OB_MODE_PARTICLE_EDIT)) && + else if ((base && (eval_ctx->object_mode & OB_MODE_PARTICLE_EDIT)) && V3D_IS_ZBUF(v3d)) { /* do nothing */ } - else if (scene->obedit && + else if ((eval_ctx->object_mode & OB_MODE_EDIT) && V3D_IS_ZBUF(v3d)) { /* do nothing */ @@ -262,14 +263,13 @@ static void backdrawview3d(const struct EvaluationContext *eval_ctx, Scene *scen /* dithering and AA break color coding, so disable */ glDisable(GL_DITHER); - multisample_enabled = glIsEnabled(GL_MULTISAMPLE); - if (multisample_enabled) - glDisable(GL_MULTISAMPLE); - - if (win->multisamples != USER_MULTISAMPLE_NONE) { + if (false) { /* for multisample we use an offscreen FBO. multisample drawing can fail * with color coded selection drawing, and reading back depths from such - * a buffer can also cause a few seconds freeze on OS X / NVidia. */ + * a buffer can also cause a few seconds freeze on OS X / NVidia. + * + * NOTE: code is no longer used now, but offscreen drawing is likely + * what we will always want to do for the new viewport. */ int w = BLI_rcti_size_x(&ar->winrct); int h = BLI_rcti_size_y(&ar->winrct); char error[256]; @@ -284,7 +284,7 @@ static void backdrawview3d(const struct EvaluationContext *eval_ctx, Scene *scen } if (!rv3d->gpuoffscreen) { - rv3d->gpuoffscreen = GPU_offscreen_create(w, h, 0, false, error); + rv3d->gpuoffscreen = GPU_offscreen_create(w, h, 0, true, false, error); if (!rv3d->gpuoffscreen) fprintf(stderr, "Failed to create offscreen selection buffer for multisample: %s\n", error); @@ -325,8 +325,6 @@ static void backdrawview3d(const struct EvaluationContext *eval_ctx, Scene *scen v3d->zbuf = false; glDisable(GL_DEPTH_TEST); glEnable(GL_DITHER); - if (multisample_enabled) - glEnable(GL_MULTISAMPLE); if (rv3d->rflag & RV3D_CLIPPING) ED_view3d_clipping_disable(); @@ -356,7 +354,7 @@ static void view3d_opengl_read_Z_pixels(ARegion *ar, int x, int y, int w, int h, void ED_view3d_backbuf_validate(const struct EvaluationContext *eval_ctx, ViewContext *vc) { if (vc->v3d->flag & V3D_INVALID_BACKBUF) { - backdrawview3d(eval_ctx, vc->scene, vc->view_layer, vc->win, vc->ar, vc->v3d); + backdrawview3d(eval_ctx, vc->scene, vc->view_layer, vc->ar, vc->v3d); } } @@ -734,7 +732,7 @@ static void view3d_draw_bgpic(Scene *scene, const Depsgraph *depsgraph, glDepthMask(GL_FALSE); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); gpuPushProjectionMatrix(); gpuPushMatrix(); @@ -1302,7 +1300,7 @@ void ED_view3d_draw_select_loop( for (base = view_layer->object_bases.first; base; base = base->next) { if ((base->flag & BASE_VISIBLED) != 0) { if (((base->flag & BASE_SELECTABLED) == 0) || - (use_obedit_skip && (scene->obedit->data == base->object->data))) + (use_obedit_skip && (vc->obedit->data == base->object->data))) { base->object->select_color = 0; } @@ -1506,6 +1504,7 @@ static void view3d_draw_objects( Depsgraph *depsgraph = CTX_data_depsgraph(C); RegionView3D *rv3d = ar->regiondata; Base *base; + Object *obedit = OBEDIT_FROM_EVAL_CTX(eval_ctx); const bool do_camera_frame = !draw_offscreen; const bool draw_grids = !draw_offscreen && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0; const bool draw_floor = (rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO); @@ -1522,7 +1521,7 @@ static void view3d_draw_objects( view3d_draw_clipping(rv3d); /* set zbuffer after we draw clipping region */ - v3d->zbuf = VP_legacy_use_depth(scene, v3d); + v3d->zbuf = VP_legacy_use_depth(v3d, obedit); if (v3d->zbuf) { glEnable(GL_DEPTH_TEST); @@ -1599,7 +1598,7 @@ static void view3d_draw_objects( draw_dupli_objects(eval_ctx, scene, view_layer, ar, v3d, base); } if ((base->flag & BASE_SELECTED) == 0) { - if (base->object != scene->obedit) + if (base->object != obedit) draw_object(eval_ctx, scene, view_layer, ar, v3d, base, 0); } } @@ -1611,7 +1610,7 @@ static void view3d_draw_objects( /* draw selected and editmode */ for (base = view_layer->object_bases.first; base; base = base->next) { if ((base->flag & BASE_VISIBLED) != 0) { - if (base->object == scene->obedit || (base->flag & BASE_SELECTED)) { + if (base->object == obedit || (base->flag & BASE_SELECTED)) { draw_object(eval_ctx, scene, view_layer, ar, v3d, base, 0); } } @@ -1946,8 +1945,9 @@ static void update_lods(Scene *scene, float camera_pos[3]) } #endif -static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, ViewLayer *view_layer, View3D *v3d, - ARegion *ar, const char **grid_unit) +static void view3d_main_region_draw_objects( + const bContext *C, Scene *scene, ViewLayer *view_layer, View3D *v3d, + ARegion *ar, const char **grid_unit) { wmWindow *win = CTX_wm_window(C); EvaluationContext eval_ctx; @@ -1960,7 +1960,7 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Vie bool do_compositing = false; /* shadow buffers, before we setup matrices */ - if (draw_glsl_material(scene, view_layer, NULL, v3d, v3d->drawtype)) + if (draw_glsl_material(&eval_ctx, scene, view_layer, NULL, v3d, v3d->drawtype)) gpu_update_lamps_shadows_world(&eval_ctx, scene, v3d); /* reset default OpenGL lights if needed (i.e. after preferences have been altered) */ @@ -2003,11 +2003,6 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Vie do_compositing = GPU_fx_compositor_initialize_passes(rv3d->compositor, &ar->winrct, &ar->drawrct, &fx_settings); } - /* enables anti-aliasing for 3D view drawing */ - if (win->multisamples != USER_MULTISAMPLE_NONE) { - glEnable(GL_MULTISAMPLE); - } - /* main drawing call */ view3d_draw_objects(C, &eval_ctx, scene, v3d, ar, grid_unit, true, false, do_compositing ? rv3d->compositor : NULL); @@ -2016,11 +2011,6 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Vie GPU_fx_do_composite_pass(rv3d->compositor, rv3d->winmat, rv3d->is_persp, scene, NULL); } - /* Disable back anti-aliasing */ - if (win->multisamples != USER_MULTISAMPLE_NONE) { - glDisable(GL_MULTISAMPLE); - } - if (v3d->lay_used != lay_used) { /* happens when loading old files or loading with UI load */ /* find header and force tag redraw */ ScrArea *sa = CTX_wm_area(C); @@ -2033,10 +2023,13 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Vie } } -static void view3d_main_region_draw_info(const bContext *C, Scene *scene, - ARegion *ar, View3D *v3d, - const char *grid_unit, bool render_border) +static void view3d_main_region_draw_info( + const bContext *C, Scene *scene, + ARegion *ar, View3D *v3d, + const char *grid_unit, bool render_border) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); const Depsgraph *depsgraph = CTX_data_depsgraph(C); ViewLayer *view_layer = CTX_data_view_layer(C); wmWindowManager *wm = CTX_wm_manager(C); @@ -2059,7 +2052,7 @@ static void view3d_main_region_draw_info(const bContext *C, Scene *scene, } if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - VP_legacy_drawcursor(scene, view_layer, ar, v3d); /* 3D cursor */ + VP_legacy_drawcursor(&eval_ctx, scene, view_layer, ar, v3d); /* 3D cursor */ if (U.uiflag & USER_SHOW_ROTVIEWICON) VP_legacy_draw_view_axis(rv3d, &rect); @@ -2068,7 +2061,7 @@ static void view3d_main_region_draw_info(const bContext *C, Scene *scene, if (U.uiflag & USER_DRAWVIEWINFO) { Object *ob = OBACT(view_layer); - VP_legacy_draw_selected_name(scene, ob, &rect); + VP_legacy_draw_selected_name(scene, ob, eval_ctx.object_mode, &rect); } } diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 2457a890f71..47778623561 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -244,21 +244,22 @@ void view3d_orbit_apply_dyn_ofs( static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3]) { static float lastofs[3] = {0, 0, 0}; + const WorkSpace *workspace = CTX_wm_workspace(C); bool is_set = false; Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob_act = OBACT(view_layer); - if (ob_act && (ob_act->mode & OB_MODE_ALL_PAINT) && + if (ob_act && (workspace->object_mode & OB_MODE_ALL_PAINT) && /* with weight-paint + pose-mode, fall through to using calculateTransformCenter */ - ((ob_act->mode & OB_MODE_WEIGHT_PAINT) && BKE_object_pose_armature_get(ob_act)) == 0) + ((workspace->object_mode & OB_MODE_WEIGHT_PAINT) && BKE_object_pose_armature_get(ob_act)) == 0) { /* in case of sculpting use last average stroke position as a rotation * center, in other cases it's not clear what rotation center shall be * so just rotate around object origin */ - if (ob_act->mode & (OB_MODE_SCULPT | OB_MODE_TEXTURE_PAINT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) { + if (workspace->object_mode & (OB_MODE_SCULPT | OB_MODE_TEXTURE_PAINT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) { float stroke[3]; BKE_paint_stroke_get_average(scene, ob_act, stroke); copy_v3_v3(lastofs, stroke); @@ -268,7 +269,7 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3]) } is_set = true; } - else if (ob_act && (ob_act->mode & OB_MODE_EDIT) && (ob_act->type == OB_FONT)) { + else if (ob_act && (workspace->object_mode & OB_MODE_EDIT) && (ob_act->type == OB_FONT)) { Curve *cu = ob_act->data; EditFont *ef = cu->editfont; int i; @@ -283,7 +284,7 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3]) is_set = true; } - else if (ob_act == NULL || ob_act->mode == OB_MODE_OBJECT) { + else if (ob_act == NULL || workspace->object_mode == OB_MODE_OBJECT) { /* object mode use boundbox centers */ Base *base; unsigned int tot = 0; @@ -2792,6 +2793,7 @@ void VIEW3D_OT_view_all(wmOperatorType *ot) /* like a localview without local!, was centerview() in 2.4x */ static int viewselected_exec(bContext *C, wmOperator *op) { + const WorkSpace *workspace = CTX_wm_workspace(C); ARegion *ar = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); Scene *scene = CTX_data_scene(C); @@ -2815,22 +2817,13 @@ static int viewselected_exec(bContext *C, wmOperator *op) ob = NULL; } - if (ob && (ob->mode & OB_MODE_WEIGHT_PAINT)) { - /* hard-coded exception, we look for the one selected armature */ - /* this is weak code this way, we should make a generic active/selection callback interface once... */ - Base *base; - for (base = view_layer->object_bases.first; base; base = base->next) { - if (TESTBASELIB(base)) { - if (base->object->type == OB_ARMATURE) - if (base->object->mode & OB_MODE_POSE) - break; - } + if (ob && (workspace->object_mode & OB_MODE_WEIGHT_PAINT)) { + Object *ob_armature = BKE_object_pose_armature_get_visible(ob, view_layer); + if (ob_armature) { + ob = ob_armature; } - if (base) - ob = base->object; } - if (is_gp_edit) { CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) { @@ -2849,17 +2842,17 @@ static int viewselected_exec(bContext *C, wmOperator *op) else if (obedit) { ok = ED_view3d_minmax_verts(obedit, min, max); /* only selected */ } - else if (ob && (ob->mode & OB_MODE_POSE)) { + else if (ob && (workspace->object_mode & OB_MODE_POSE)) { ok = BKE_pose_minmax(ob, min, max, true, true); } - else if (BKE_paint_select_face_test(ob)) { + else if (BKE_paint_select_face_test(ob, workspace->object_mode)) { ok = paintface_minmax(ob, min, max); } - else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) { + else if (ob && (workspace->object_mode & OB_MODE_PARTICLE_EDIT)) { ok = PE_minmax(scene, view_layer, min, max); } else if (ob && - (ob->mode & (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) + (workspace->object_mode & (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) { BKE_paint_stroke_get_average(scene, ob, min); copy_v3_v3(max, min); @@ -2966,13 +2959,13 @@ static int view_lock_to_active_exec(bContext *C, wmOperator *UNUSED(op)) Object *obact = CTX_data_active_object(C); if (v3d) { - ED_view3d_lock_clear(v3d); v3d->ob_centre = obact; /* can be NULL */ if (obact && obact->type == OB_ARMATURE) { - if (obact->mode & OB_MODE_POSE) { + const WorkSpace *workspace = CTX_wm_workspace(C); + if (workspace->object_mode & OB_MODE_POSE) { bPoseChannel *pcham_act = BKE_pose_channel_active(obact); if (pcham_act) { BLI_strncpy(v3d->ob_centre_bone, pcham_act->name, sizeof(v3d->ob_centre_bone)); @@ -4696,7 +4689,7 @@ static int toggle_render_exec(bContext *C, wmOperator *UNUSED(op)) v3d->prev_drawtype = v3d->drawtype; v3d->drawtype = OB_RENDER; } - ED_view3d_shade_update(CTX_data_main(C), CTX_data_scene(C), v3d, CTX_wm_area(C)); + ED_view3d_shade_update(CTX_data_main(C), v3d, CTX_wm_area(C)); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index a1dc2a21477..bf4abf1852d 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -95,14 +95,14 @@ static void handle_view3d_lock(bContext *C) * - uiTemplateLayers in interface/ code for buttons * - ED_view3d_view_layer_set for RNA */ -static void view3d_layers_editmode_ensure(Scene *scene, View3D *v3d) +static void view3d_layers_editmode_ensure(View3D *v3d, Object *obedit) { /* sanity check - when in editmode disallow switching the editmode layer off since its confusing * an alternative would be to always draw the editmode object. */ - if (scene->obedit && (scene->obedit->lay & v3d->lay) == 0) { + if (obedit && (obedit->lay & v3d->lay) == 0) { int bit; for (bit = 0; bit < 32; bit++) { - if (scene->obedit->lay & (1u << bit)) { + if (obedit->lay & (1u << bit)) { v3d->lay |= (1u << bit); break; } @@ -112,9 +112,9 @@ static void view3d_layers_editmode_ensure(Scene *scene, View3D *v3d) static int view3d_layers_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); ScrArea *sa = CTX_wm_area(C); View3D *v3d = sa->spacedata.first; + Object *obedit = CTX_data_edit_object(C); int nr = RNA_int_get(op->ptr, "nr"); const bool toggle = RNA_boolean_get(op->ptr, "toggle"); @@ -130,7 +130,7 @@ static int view3d_layers_exec(bContext *C, wmOperator *op) /* return to active layer only */ v3d->lay = v3d->lay_prev; - view3d_layers_editmode_ensure(scene, v3d); + view3d_layers_editmode_ensure(v3d, obedit); } else { v3d->lay_prev = v3d->lay; @@ -151,7 +151,7 @@ static int view3d_layers_exec(bContext *C, wmOperator *op) v3d->lay = (1 << nr); } - view3d_layers_editmode_ensure(scene, v3d); + view3d_layers_editmode_ensure(v3d, obedit); /* set active layer, ensure to always have one */ if (v3d->lay & (1 << nr)) @@ -276,6 +276,7 @@ void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C) void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); bScreen *screen = CTX_wm_screen(C); ScrArea *sa = CTX_wm_area(C); View3D *v3d = sa->spacedata.first; @@ -288,8 +289,10 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) bGPdata *gpd = CTX_data_gpencil_data(C); uiBlock *block; uiLayout *row; - bool is_paint = ob && !(gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) && - ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT); + bool is_paint = ( + ob && !(gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) && + ELEM(workspace->object_mode, + OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT)); RNA_pointer_create(&screen->id, &RNA_SpaceView3D, v3d, &v3dptr); RNA_pointer_create(&scene->id, &RNA_ToolSettings, ts, &toolsptr); @@ -303,18 +306,18 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) row = uiLayoutRow(layout, true); uiItemR(row, &v3dptr, "pivot_point", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); - if (!ob || ELEM(ob->mode, OB_MODE_OBJECT, OB_MODE_POSE, OB_MODE_WEIGHT_PAINT)) { + if (!ob || ELEM(workspace->object_mode, OB_MODE_OBJECT, OB_MODE_POSE, OB_MODE_WEIGHT_PAINT)) { uiItemR(row, &v3dptr, "use_pivot_point_align", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); } if (obedit == NULL && is_paint) { /* Manipulators aren't used in paint modes */ - if (!ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_PARTICLE_EDIT)) { + if (!ELEM(workspace->object_mode, OB_MODE_SCULPT, OB_MODE_PARTICLE_EDIT)) { /* masks aren't used for sculpt and particle painting */ PointerRNA meshptr; RNA_pointer_create(ob->data, &RNA_Mesh, ob->data, &meshptr); - if (ob->mode & (OB_MODE_TEXTURE_PAINT)) { + if (workspace->object_mode & (OB_MODE_TEXTURE_PAINT)) { uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); } else { diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index d1968166904..b3300e226e0 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -54,6 +54,7 @@ struct wmKeyConfig; struct wmManipulatorGroupType; struct wmManipulatorType; struct wmWindowManager; +struct EvaluationContext; /* drawing flags: */ enum { @@ -154,13 +155,19 @@ void draw_object_select( const struct EvaluationContext *eval_ctx, Scene *scene, struct ViewLayer *view_layer, struct ARegion *ar, View3D *v3d, Base *base, const short dflag); -void draw_mesh_object_outline(View3D *v3d, struct Object *ob, struct DerivedMesh *dm, const unsigned char ob_wire_col[4]); +void draw_mesh_object_outline( + const struct EvaluationContext *eval_ctx, View3D *v3d, + struct Object *ob, struct DerivedMesh *dm, const unsigned char ob_wire_col[4]); -bool draw_glsl_material(Scene *scene, struct ViewLayer *view_layer, struct Object *ob, View3D *v3d, const char dt); +bool draw_glsl_material( + const struct EvaluationContext *eval_ctx, Scene *scene, struct ViewLayer *view_layer, + struct Object *ob, View3D *v3d, const char dt); void draw_object_instance(const struct EvaluationContext *eval_ctx, Scene *scene, struct ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const char dt, int outline, const float wire_col[4]); void draw_object_backbufsel(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob); -void draw_object_wire_color(Scene *scene, struct ViewLayer *, Base *base, unsigned char r_ob_wire_col[4]); +void draw_object_wire_color( + const struct EvaluationContext *eval_ctx, struct ViewLayer *, + Base *base, unsigned char r_ob_wire_col[4]); void drawaxes(const float viewmat_local[4][4], float size, char drawtype, const unsigned char color[4]); void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base, const char dt, const short dflag, const unsigned char ob_wire_col[4], @@ -209,8 +216,10 @@ void draw_mesh_paint_vcolor_faces(struct DerivedMesh *dm, const bool use_light, void draw_mesh_paint_weight_edges(RegionView3D *rv3d, struct DerivedMesh *dm, const bool use_depth, const bool use_alpha, void *edgemask_cb, void *user_data); -void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d, - struct Object *ob, struct DerivedMesh *dm, const int draw_flags); +void draw_mesh_paint( + const struct EvaluationContext *eval_ctx, + View3D *v3d, RegionView3D *rv3d, + struct Object *ob, struct DerivedMesh *dm, const int draw_flags); /* drawsimdebug.c */ void draw_sim_debug_data(Scene *scene, View3D *v3d, ARegion *ar); @@ -366,17 +375,19 @@ extern bool view3d_camera_border_hack_test; #endif /* temporary for legacy viewport to work */ -void VP_legacy_drawcursor(Scene *scene, struct ViewLayer *view_layer, ARegion *ar, View3D *v3d); -void VP_legacy_draw_view_axis(RegionView3D *rv3d, rcti *rect); -void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect); -void VP_legacy_draw_selected_name(Scene *scene, struct Object *ob, rcti *rect); +void VP_legacy_drawcursor( + const struct EvaluationContext *eval_ctx, Scene *scene, + struct ViewLayer *view_layer, ARegion *ar, View3D *v3d); +void VP_legacy_draw_view_axis(RegionView3D *rv3d, const rcti *rect); +void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, const rcti *rect); +void VP_legacy_draw_selected_name(Scene *scene, struct Object *ob, eObjectMode object_mode, const rcti *rect); void VP_legacy_drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit); void VP_legacy_drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth); void VP_legacy_view3d_main_region_setup_view(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]); bool VP_legacy_view3d_stereo3d_active(struct wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d); void VP_legacy_view3d_stereo3d_setup(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar); void draw_dupli_objects(const struct EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, Base *base); -bool VP_legacy_use_depth(Scene *scene, View3D *v3d); +bool VP_legacy_use_depth(View3D *v3d, struct Object *obedit); void VP_drawviewborder(Scene *scene, const struct Depsgraph *depsgraph, ARegion *ar, View3D *v3d); void VP_drawrenderborder(ARegion *ar, View3D *v3d); void VP_view3d_draw_background_none(void); diff --git a/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c b/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c index 6a34f493caf..e76be448be4 100644 --- a/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c +++ b/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c @@ -31,7 +31,7 @@ #include "BKE_object.h" #include "DNA_object_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "ED_screen.h" #include "ED_manipulator_library.h" diff --git a/source/blender/editors/space_view3d/view3d_manipulator_navigate_type.c b/source/blender/editors/space_view3d/view3d_manipulator_navigate_type.c index 424b5dae402..c3f8d92ed7f 100644 --- a/source/blender/editors/space_view3d/view3d_manipulator_navigate_type.c +++ b/source/blender/editors/space_view3d/view3d_manipulator_navigate_type.c @@ -131,7 +131,7 @@ static void axis_geom_draw( glDepthMask(GL_TRUE); glDepthFunc(GL_LEQUAL); glBlendFunc(GL_ONE, GL_ZERO); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 28e15b3bfee..b352a2083a7 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -48,7 +48,7 @@ #include "MEM_guardedalloc.h" #include "BLI_math.h" -#include "BLI_lasso.h" +#include "BLI_lasso_2d.h" #include "BLI_rect.h" #include "BLI_linklist.h" #include "BLI_listbase.h" @@ -209,6 +209,7 @@ static void edbm_backbuf_check_and_select_tfaces(Mesh *me, const bool select) /* *********************** GESTURE AND LASSO ******************* */ typedef struct LassoSelectUserData { + const EvaluationContext *eval_ctx; ViewContext *vc; const rcti *rect; const rctf *rect_fl; @@ -251,14 +252,15 @@ static int view3d_selectable_data(bContext *C) return 0; if (ob) { - if (ob->mode & OB_MODE_EDIT) { + const WorkSpace *workspace = CTX_wm_workspace(C); + if (workspace->object_mode & OB_MODE_EDIT) { if (ob->type == OB_FONT) { return 0; } } else { - if ((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) && - !BKE_paint_select_elem_test(ob)) + if ((workspace->object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) && + !BKE_paint_select_elem_test(ob, workspace->object_mode)) { return 0; } @@ -387,8 +389,10 @@ static void object_deselect_all_visible(ViewLayer *view_layer) } } -static void do_lasso_select_objects(ViewContext *vc, const int mcords[][2], const short moves, - const bool extend, const bool select) +static void do_lasso_select_objects( + const EvaluationContext *eval_ctx, + ViewContext *vc, const int mcords[][2], const short moves, + const bool extend, const bool select) { Base *base; @@ -403,7 +407,7 @@ static void do_lasso_select_objects(ViewContext *vc, const int mcords[][2], cons ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT); } } - if (vc->obact == base->object && (base->object->mode & OB_MODE_POSE)) { + if (vc->obact == base->object && (eval_ctx->object_mode & OB_MODE_POSE)) { do_lasso_select_pose(vc, base->object, mcords, moves, select); } } @@ -810,20 +814,20 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc, CTX_data_eval_ctx(C, &eval_ctx); if (vc->obedit == NULL) { /* Object Mode */ - if (BKE_paint_select_face_test(ob)) { + if (BKE_paint_select_face_test(ob, eval_ctx.object_mode)) { do_lasso_select_paintface(&eval_ctx, vc, mcords, moves, extend, select); } - else if (BKE_paint_select_vert_test(ob)) { + else if (BKE_paint_select_vert_test(ob, eval_ctx.object_mode)) { do_lasso_select_paintvert(&eval_ctx, vc, mcords, moves, extend, select); } - else if (ob && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) { + else if (ob && (eval_ctx.object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) { /* pass */ } - else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) { + else if (ob && (eval_ctx.object_mode & OB_MODE_PARTICLE_EDIT)) { PE_lasso_select(C, mcords, moves, extend, select); } else { - do_lasso_select_objects(vc, mcords, moves, extend, select); + do_lasso_select_objects(&eval_ctx, vc, mcords, moves, extend, select); WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc->scene); } } @@ -1544,7 +1548,10 @@ static bool ed_object_select_pick( } } } - else if (ED_do_pose_selectbuffer(scene, view_layer, basact, buffer, hits, extend, deselect, toggle, do_nearest)) { + else if (ED_do_pose_selectbuffer( + &eval_ctx, view_layer, + basact, buffer, hits, extend, deselect, toggle, do_nearest)) + { /* then bone is found */ /* we make the armature selected: @@ -1557,7 +1564,7 @@ static bool ed_object_select_pick( WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, basact->object); /* in weightpaint, we use selected bone to select vertexgroup, so no switch to new active object */ - if (BASACT(view_layer) && (BASACT(view_layer)->object->mode & OB_MODE_WEIGHT_PAINT)) { + if (BASACT(view_layer) && (eval_ctx.object_mode & OB_MODE_WEIGHT_PAINT)) { /* prevent activating */ basact = NULL; } @@ -2050,7 +2057,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b CTX_data_eval_ctx(C, &eval_ctx); - if ((ob) && (ob->mode & OB_MODE_POSE)) + if ((ob) && (eval_ctx.object_mode & OB_MODE_POSE)) bone_only = 1; else bone_only = 0; @@ -2205,16 +2212,16 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op) } } else { /* no editmode, unified for bones and objects */ - if (vc.obact && vc.obact->mode & OB_MODE_SCULPT) { + if (vc.obact && eval_ctx.object_mode & OB_MODE_SCULPT) { ret = ED_sculpt_mask_box_select(C, &vc, &rect, select, extend); } - else if (vc.obact && BKE_paint_select_face_test(vc.obact)) { + else if (vc.obact && BKE_paint_select_face_test(vc.obact, eval_ctx.object_mode)) { ret = do_paintface_box_select(&eval_ctx, &vc, &rect, select, extend); } - else if (vc.obact && BKE_paint_select_vert_test(vc.obact)) { + else if (vc.obact && BKE_paint_select_vert_test(vc.obact, eval_ctx.object_mode)) { ret = do_paintvert_box_select(&eval_ctx, &vc, &rect, select, extend); } - else if (vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) { + else if (vc.obact && eval_ctx.object_mode & OB_MODE_PARTICLE_EDIT) { ret = PE_border_select(C, &rect, select, extend); } else { /* object mode with none active */ @@ -2300,6 +2307,7 @@ static bool ed_wpaint_vertex_select_pick( static int view3d_select_exec(bContext *C, wmOperator *op) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *obedit = CTX_data_edit_object(C); Object *obact = CTX_data_active_object(C); bool extend = RNA_boolean_get(op->ptr, "extend"); @@ -2311,9 +2319,9 @@ static int view3d_select_exec(bContext *C, wmOperator *op) * or paint-select to allow pose bone select with vert/face select */ bool object = (RNA_boolean_get(op->ptr, "object") && (obedit || - BKE_paint_select_elem_test(obact) || + BKE_paint_select_elem_test(obact, workspace->object_mode) || /* so its possible to select bones in weightpaint mode (LMB select) */ - (obact && (obact->mode & OB_MODE_WEIGHT_PAINT) && BKE_object_pose_armature_get(obact)))); + (obact && (workspace->object_mode & OB_MODE_WEIGHT_PAINT) && BKE_object_pose_armature_get(obact)))); bool retval = false; int location[2]; @@ -2347,11 +2355,11 @@ static int view3d_select_exec(bContext *C, wmOperator *op) retval = ED_curve_editfont_select_pick(C, location, extend, deselect, toggle); } - else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) + else if (obact && workspace->object_mode & OB_MODE_PARTICLE_EDIT) return PE_mouse_particles(C, location, extend, deselect, toggle); - else if (obact && BKE_paint_select_face_test(obact)) + else if (obact && BKE_paint_select_face_test(obact, workspace->object_mode)) retval = paintface_mouse_select(C, obact, location, extend, deselect, toggle); - else if (BKE_paint_select_vert_test(obact)) + else if (BKE_paint_select_vert_test(obact, workspace->object_mode)) retval = ed_wpaint_vertex_select_pick(C, location, extend, deselect, toggle, obact); else retval = ed_object_select_pick(C, location, extend, deselect, toggle, center, enumerate, object); @@ -2856,6 +2864,8 @@ static bool object_circle_select(ViewContext *vc, const bool select, const int m /* not a real operator, only for circle test */ static int view3d_circle_select_exec(bContext *C, wmOperator *op) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Scene *scene = CTX_data_scene(C); Object *obact = CTX_data_active_object(C); const int radius = RNA_int_get(op->ptr, "radius"); @@ -2863,35 +2873,33 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) const int mval[2] = {RNA_int_get(op->ptr, "x"), RNA_int_get(op->ptr, "y")}; - if (CTX_data_edit_object(C) || BKE_paint_select_elem_test(obact) || - (obact && (obact->mode & (OB_MODE_PARTICLE_EDIT | OB_MODE_POSE))) ) + if (CTX_data_edit_object(C) || BKE_paint_select_elem_test(obact, eval_ctx.object_mode) || + (obact && (eval_ctx.object_mode & (OB_MODE_PARTICLE_EDIT | OB_MODE_POSE))) ) { - EvaluationContext eval_ctx; ViewContext vc; - + view3d_operator_needs_opengl(C); - - CTX_data_eval_ctx(C, &eval_ctx); + view3d_set_viewcontext(C, &vc); if (CTX_data_edit_object(C)) { obedit_circle_select(&eval_ctx, &vc, select, mval, (float)radius); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data); } - else if (BKE_paint_select_face_test(obact)) { + else if (BKE_paint_select_face_test(obact, eval_ctx.object_mode)) { paint_facesel_circle_select(&eval_ctx, &vc, select, mval, (float)radius); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data); } - else if (BKE_paint_select_vert_test(obact)) { + else if (BKE_paint_select_vert_test(obact, eval_ctx.object_mode)) { paint_vertsel_circle_select(&eval_ctx, &vc, select, mval, (float)radius); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data); } - else if (obact->mode & OB_MODE_POSE) + else if (eval_ctx.object_mode & OB_MODE_POSE) pose_circle_select(&vc, select, mval, (float)radius); else return PE_circle_select(C, select, mval, (float)radius); } - else if (obact && obact->mode & OB_MODE_SCULPT) { + else if (obact && eval_ctx.object_mode & OB_MODE_SCULPT) { return OPERATOR_CANCELLED; } else { diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 1df29201bf6..40dd2f0f428 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -113,7 +113,7 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { - if (ob->mode & OB_MODE_POSE) { + if (eval_ctx.object_mode & OB_MODE_POSE) { bPoseChannel *pchan; bArmature *arm = ob->data; @@ -272,7 +272,7 @@ static int snap_selected_to_location(bContext *C, const float snap_target_global ED_transverts_update_obedit(&tvs, obedit); ED_transverts_free(&tvs); } - else if (obact && (obact->mode & OB_MODE_POSE)) { + else if (obact && (eval_ctx.object_mode & OB_MODE_POSE)) { struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID); bPoseChannel *pchan; @@ -554,6 +554,8 @@ static void bundle_midpoint(Scene *scene, Object *ob, float vec[3]) static bool snap_curs_to_sel_ex(bContext *C, float cursor[3]) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Object *obedit = CTX_data_edit_object(C); Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); @@ -599,7 +601,7 @@ static bool snap_curs_to_sel_ex(bContext *C, float cursor[3]) else { Object *obact = CTX_data_active_object(C); - if (obact && (obact->mode & OB_MODE_POSE)) { + if (obact && (eval_ctx.object_mode & OB_MODE_POSE)) { bArmature *arm = obact->data; bPoseChannel *pchan; for (pchan = obact->pose->chanbase.first; pchan; pchan = pchan->next) { @@ -701,7 +703,8 @@ static bool snap_calc_active_center(bContext *C, const bool select_only, float r Object *ob = CTX_data_active_object(C); if (ob) { - if (ob->mode & OB_MODE_POSE) { + const WorkSpace *workspace = CTX_wm_workspace(C); + if (workspace->object_mode & OB_MODE_POSE) { bPoseChannel *pchan = BKE_pose_channel_active(ob); if (pchan) { if (!select_only || (pchan->bone->flag & BONE_SELECTED)) { diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c index 7bb3f443ac6..92b3ec19acb 100644 --- a/source/blender/editors/space_view3d/view3d_utils.c +++ b/source/blender/editors/space_view3d/view3d_utils.c @@ -161,7 +161,7 @@ void view3d_operator_needs_opengl(const bContext *C) view3d_region_operator_needs_opengl(win, ar); } -void view3d_region_operator_needs_opengl(wmWindow *win, ARegion *ar) +void view3d_region_operator_needs_opengl(wmWindow *UNUSED(win), ARegion *ar) { /* for debugging purpose, context should always be OK */ if ((ar == NULL) || (ar->regiontype != RGN_TYPE_WINDOW)) { @@ -170,7 +170,7 @@ void view3d_region_operator_needs_opengl(wmWindow *win, ARegion *ar) else { RegionView3D *rv3d = ar->regiondata; - wmSubWindowSet(win, ar->swinid); + wmViewport(&ar->winrct); // TODO: bad gpuLoadProjectionMatrix(rv3d->winmat); gpuLoadMatrix(rv3d->viewmat); } diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 0597f2806b3..4ccf86138e7 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -879,7 +879,7 @@ int view3d_opengl_select( ARegion *ar = vc->ar; rcti rect; int hits; - const bool use_obedit_skip = (scene->obedit != NULL) && (vc->obedit == NULL); + const bool use_obedit_skip = (OBEDIT_FROM_EVAL_CTX(eval_ctx) != NULL) && (vc->obedit == NULL); const bool is_pick_select = (U.gpu_select_pick_deph != 0); const bool do_passes = ( (is_pick_select == false) && @@ -954,7 +954,9 @@ int view3d_opengl_select( else #else { - DRW_draw_select_loop(graph, ar, v3d, use_obedit_skip, use_nearest, &rect); + DRW_draw_select_loop( + graph, ar, v3d, eval_ctx->object_mode, + use_obedit_skip, use_nearest, &rect); } #endif /* WITH_OPENGL_LEGACY */ @@ -971,7 +973,9 @@ int view3d_opengl_select( else #else { - DRW_draw_select_loop(graph, ar, v3d, use_obedit_skip, use_nearest, &rect); + DRW_draw_select_loop( + graph, ar, v3d, eval_ctx->object_mode, + use_obedit_skip, use_nearest, &rect); } #endif /* WITH_OPENGL_LEGACY */ @@ -1054,12 +1058,15 @@ int ED_view3d_view_layer_set(int lay, const int *values, int *active) static ListBase queue_back; static void game_engine_save_state(bContext *C, wmWindow *win) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Object *obact = CTX_data_active_object(C); glPushAttrib(GL_ALL_ATTRIB_BITS); - if (obact && obact->mode & OB_MODE_TEXTURE_PAINT) + if (obact && eval_ctx.object_mode & OB_MODE_TEXTURE_PAINT) { GPU_paint_set_mipmap(1); + } queue_back = win->queue; @@ -1068,11 +1075,13 @@ static void game_engine_save_state(bContext *C, wmWindow *win) static void game_engine_restore_state(bContext *C, wmWindow *win) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Object *obact = CTX_data_active_object(C); - if (obact && obact->mode & OB_MODE_TEXTURE_PAINT) + if (obact && eval_ctx.object_mode & OB_MODE_TEXTURE_PAINT) { GPU_paint_set_mipmap(0); - + } /* check because closing win can set to NULL */ if (win) { win->queue = queue_back; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 9f7b438e338..a4bce5b0f1d 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1890,7 +1890,7 @@ static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar) #endif /* autokey recording icon... */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); xco -= U.widget_unit; @@ -2624,10 +2624,7 @@ static void constraintTransLim(TransInfo *t, TransData *td) if (td->con) { const bConstraintTypeInfo *ctiLoc = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_LOCLIMIT); const bConstraintTypeInfo *ctiDist = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_DISTLIMIT); - EvaluationContext eval_ctx; - CTX_data_eval_ctx(t->context, &eval_ctx); - bConstraintOb cob = {NULL}; bConstraint *con; float ctime = (float)(t->scene->r.cfra); @@ -2676,7 +2673,7 @@ static void constraintTransLim(TransInfo *t, TransData *td) } /* get constraint targets if needed */ - BKE_constraint_targets_for_solving_get(&eval_ctx, con, &cob, &targets, ctime); + BKE_constraint_targets_for_solving_get(&t->eval_ctx, con, &cob, &targets, ctime); /* do constraint */ cti->evaluate_constraint(con, &cob, &targets); @@ -6883,7 +6880,7 @@ static void drawEdgeSlide(TransInfo *t) glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); gpuPushMatrix(); gpuMultMatrix(t->obedit->obmat); @@ -7495,7 +7492,7 @@ static void drawVertSlide(TransInfo *t) glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); gpuPushMatrix(); gpuMultMatrix(t->obedit->obmat); diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 4ad66c0a9a5..b198918b698 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -41,6 +41,8 @@ #include "DNA_listBase.h" +#include "DEG_depsgraph.h" + /* ************************** Types ***************************** */ struct Depsgraph; @@ -66,6 +68,8 @@ struct EditBone; struct RenderEngineType; struct SnapObjectContext; +#include "DNA_object_enums.h" + /* transinfo->redraw */ typedef enum { TREDRAW_NOTHING = 0, @@ -465,6 +469,7 @@ typedef struct TransInfo { bool remove_on_cancel; /* remove elements if operator is canceled */ + EvaluationContext eval_ctx; void *view; struct bContext *context; /* Only valid (non null) during an operator called function. */ struct ScrArea *sa; @@ -649,7 +654,8 @@ void restoreBones(TransInfo *t); #define MANIPULATOR_AXIS_LINE_WIDTH 2.0f -bool gimbal_axis(struct Object *ob, float gmat[3][3]); /* return 0 when no gimbal for selection */ +/* return 0 when no gimbal for selection */ +bool gimbal_axis(struct Object *ob, float gmat[3][3], const eObjectMode object_mode); /*********************** TransData Creation and General Handling *********** */ void createTransData(struct bContext *C, TransInfo *t); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 730ca70547b..96970fa8a0f 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -998,7 +998,7 @@ static short pose_grab_with_ik(Object *ob) Bone *bonec; short tot_ik = 0; - if ((ob == NULL) || (ob->pose == NULL) || (ob->mode & OB_MODE_POSE) == 0) + if ((ob == NULL) || (ob->pose == NULL)) return 0; arm = ob->data; @@ -2049,9 +2049,7 @@ void flushTransParticles(TransInfo *t) point->flag |= PEP_EDIT_RECALC; } - EvaluationContext eval_ctx; - CTX_data_eval_ctx(t->context, &eval_ctx); - PE_update_object(&eval_ctx, scene, view_layer, OBACT(view_layer), 1); + PE_update_object(&t->eval_ctx, scene, view_layer, OBACT(view_layer), 1); } /* ********************* mesh ****************** */ @@ -2463,7 +2461,6 @@ static void createTransEditVerts(TransInfo *t) { TransData *tob = NULL; TransDataExtension *tx = NULL; - EvaluationContext eval_ctx; BMEditMesh *em = BKE_editmesh_from_object(t->obedit); Mesh *me = t->obedit->data; BMesh *bm = em->bm; @@ -2482,10 +2479,6 @@ static void createTransEditVerts(TransInfo *t) int island_info_tot; int *island_vert_map = NULL; - DEG_evaluation_context_init_from_scene(&eval_ctx, - t->scene, t->view_layer, t->engine_type, - DAG_EVAL_VIEWPORT); - /* Even for translation this is needed because of island-orientation, see: T51651. */ const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS); /* Original index of our connected vertex when connected distances are calculated. @@ -2566,10 +2559,10 @@ static void createTransEditVerts(TransInfo *t) /* detect CrazySpace [tm] */ if (modifiers_getCageIndex(t->scene, t->obedit, NULL, 1) != -1) { int totleft = -1; - if (modifiers_isCorrectableDeformed(t->scene, t->obedit)) { + if (modifiers_isCorrectableDeformed(&t->eval_ctx, t->scene, t->obedit)) { /* check if we can use deform matrices for modifier from the * start up to stack, they are more accurate than quats */ - totleft = BKE_crazyspace_get_first_deform_matrices_editbmesh(&eval_ctx, t->scene, t->obedit, em, &defmats, &defcos); + totleft = BKE_crazyspace_get_first_deform_matrices_editbmesh(&t->eval_ctx, t->scene, t->obedit, em, &defmats, &defcos); } /* if we still have more modifiers, also do crazyspace @@ -2582,7 +2575,7 @@ static void createTransEditVerts(TransInfo *t) if (totleft > 0) #endif { - mappedcos = BKE_crazyspace_get_mapped_editverts(&eval_ctx, t->scene, t->obedit); + mappedcos = BKE_crazyspace_get_mapped_editverts(&t->eval_ctx, t->scene, t->obedit); quats = MEM_mallocN(em->bm->totvert * sizeof(*quats), "crazy quats"); BKE_crazyspace_set_quats_editmesh(em, defcos, mappedcos, quats, !prop_mode); if (mappedcos) @@ -2976,7 +2969,7 @@ static void createTransUVs(bContext *C, TransInfo *t) BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BMLoop *l; - if (!uvedit_face_visible_test(scene, ima, efa)) { + if (!uvedit_face_visible_test(scene, t->obedit, ima, efa)) { BM_elem_flag_disable(efa, BM_ELEM_TAG); continue; } @@ -5408,9 +5401,6 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) Scene *scene = t->scene; bool constinv; bool skip_invert = false; - EvaluationContext eval_ctx; - - CTX_data_eval_ctx(t->context, &eval_ctx); if (t->mode != TFM_DUMMY && ob->rigidbody_object) { float rot[3][3], scale[3]; @@ -5458,11 +5448,11 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) if (skip_invert == false && constinv == false) { ob->transflag |= OB_NO_CONSTRAINTS; /* BKE_object_where_is_calc_time checks this */ - BKE_object_where_is_calc(&eval_ctx, t->scene, ob); + BKE_object_where_is_calc(&t->eval_ctx, t->scene, ob); ob->transflag &= ~OB_NO_CONSTRAINTS; } else - BKE_object_where_is_calc(&eval_ctx, t->scene, ob); + BKE_object_where_is_calc(&t->eval_ctx, t->scene, ob); td->ob = ob; @@ -6103,14 +6093,11 @@ static void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t) * */ void special_aftertrans_update(bContext *C, TransInfo *t) { - EvaluationContext eval_ctx; Object *ob; // short redrawipo=0, resetslowpar=1; const bool canceled = (t->state == TRANS_CANCEL); const bool duplicate = (t->mode == TFM_TIME_DUPLICATE); - CTX_data_eval_ctx(C, &eval_ctx); - /* early out when nothing happened */ if (t->total == 0 || t->mode == TFM_DUMMY) return; @@ -6449,7 +6436,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) * we need to update the pose otherwise no updates get called during * transform and the auto-ik is not applied. see [#26164] */ struct Object *pose_ob = t->poseobj; - BKE_pose_where_is(&eval_ctx, t->scene, pose_ob); + BKE_pose_where_is(&t->eval_ctx, t->scene, pose_ob); } /* set BONE_TRANSFORM flags for autokey, manipulator draw might have changed them */ @@ -6493,7 +6480,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) } else if ((t->view_layer->basact) && (ob = t->view_layer->basact->object) && - (ob->mode & OB_MODE_PARTICLE_EDIT) && + (t->eval_ctx.object_mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(t->scene, t->view_layer, ob)) { /* do nothing */ @@ -8231,26 +8218,28 @@ void createTransData(bContext *C, TransInfo *t) t->poseobj = ob; /* <- tsk tsk, this is going to give issues one day */ } } - else if (ob && (ob->mode & OB_MODE_POSE)) { + else if (ob && (t->eval_ctx.object_mode & OB_MODE_POSE)) { // XXX this is currently limited to active armature only... // XXX active-layer checking isn't done as that should probably be checked through context instead createTransPose(t, ob); } - else if (ob && (ob->mode & OB_MODE_WEIGHT_PAINT) && !(t->options & CTX_PAINT_CURVE)) { + else if (ob && (t->eval_ctx.object_mode & OB_MODE_WEIGHT_PAINT) && !(t->options & CTX_PAINT_CURVE)) { /* important that ob_armature can be set even when its not selected [#23412] * lines below just check is also visible */ Object *ob_armature = modifiers_isDeformedByArmature(ob); - if (ob_armature && ob_armature->mode & OB_MODE_POSE) { + if (ob_armature) { +// const bArmature *arm = ob_armature->data; Base *base_arm = BKE_view_layer_base_find(t->view_layer, ob_armature); if (base_arm) { if (BASE_VISIBLE(base_arm)) { createTransPose(t, ob_armature); } } - } } - else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT) && PE_start_edit(PE_get_current(scene, view_layer, ob))) { + else if (ob && (t->eval_ctx.object_mode & OB_MODE_PARTICLE_EDIT) && + PE_start_edit(PE_get_current(scene, view_layer, ob))) + { createTransParticleVerts(C, t); t->flag |= T_POINTS; @@ -8260,7 +8249,7 @@ void createTransData(bContext *C, TransInfo *t) sort_trans_data_dist(t); } } - else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) { + else if (ob && (t->eval_ctx.object_mode & OB_MODE_ALL_PAINT)) { if ((t->options & CTX_PAINT_CURVE) && !ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN)) { t->flag |= T_POINTS | T_2D_EDIT; createTransPaintCurveVerts(C, t); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 1aa4513e99b..fdf5665b6d4 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -715,9 +715,6 @@ static void recalcData_spaceclip(TransInfo *t) static void recalcData_objects(TransInfo *t) { Base *base = t->view_layer->basact; - EvaluationContext eval_ctx; - - CTX_data_eval_ctx(t->context, &eval_ctx); if (t->obedit) { if (ELEM(t->obedit->type, OB_CURVE, OB_SURF)) { @@ -902,9 +899,11 @@ static void recalcData_objects(TransInfo *t) BIK_clear_data(ob->pose); } else - BKE_pose_where_is(&eval_ctx, t->scene, ob); + BKE_pose_where_is(&t->eval_ctx, t->scene, ob); } - else if (base && (base->object->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(t->scene, t->view_layer, base->object)) { + else if (base && (t->eval_ctx.object_mode & OB_MODE_PARTICLE_EDIT) && + PE_get_current(t->scene, t->view_layer, base->object)) + { if (t->state != TRANS_CANCEL) { applyProject(t); } @@ -1115,6 +1114,7 @@ static int initTransInfo_edit_pet_to_flag(const int proportional) */ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *event) { + CTX_data_eval_ctx(C, &t->eval_ctx); Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *sce = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); @@ -1266,7 +1266,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve } } - if (ob && ob->mode & OB_MODE_ALL_PAINT) { + if (ob && t->eval_ctx.object_mode & OB_MODE_ALL_PAINT) { Paint *p = BKE_paint_get_active_from_context(C); if (p && p->brush && (p->brush->flag & BRUSH_CURVE)) { t->options |= CTX_PAINT_CURVE; @@ -1815,7 +1815,7 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3]) } } else if (t->options & CTX_PAINT_CURVE) { - Paint *p = BKE_paint_get_active(t->scene, t->view_layer); + Paint *p = BKE_paint_get_active(t->scene, t->view_layer, t->eval_ctx.object_mode); Brush *br = p->brush; PaintCurve *pc = br->paint_curve; copy_v3_v3(r_center, pc->points[pc->add_index - 1].bez.vec[1]); diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 0643687c29a..1839583015c 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -63,6 +63,8 @@ #include "BIF_gl.h" +#include "DEG_depsgraph.h" + #include "WM_api.h" #include "WM_types.h" #include "WM_message.h" @@ -518,9 +520,9 @@ static bool test_rotmode_euler(short rotmode) return (ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT)) ? 0 : 1; } -bool gimbal_axis(Object *ob, float gmat[3][3]) +bool gimbal_axis(Object *ob, float gmat[3][3], const eObjectMode object_mode) { - if (ob->mode & OB_MODE_POSE) { + if (object_mode & OB_MODE_POSE) { bPoseChannel *pchan = BKE_pose_channel_active(ob); if (pchan) { @@ -589,6 +591,7 @@ static int calc_manipulator_stats( const bContext *C, bool use_only_center, struct TransformBounds *tbounds) { + const WorkSpace *workspace = CTX_wm_workspace(C); ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); @@ -626,7 +629,7 @@ static int calc_manipulator_stats( case V3D_MANIP_GIMBAL: { float mat[3][3]; - if (gimbal_axis(ob, mat)) { + if (gimbal_axis(ob, mat, workspace->object_mode)) { copy_m4_m3(rv3d->twmat, mat); break; } @@ -635,7 +638,7 @@ static int calc_manipulator_stats( } case V3D_MANIP_NORMAL: { - if (obedit || ob->mode & OB_MODE_POSE) { + if (obedit || workspace->object_mode & OB_MODE_POSE) { float mat[3][3]; ED_getTransformOrientationMatrix(C, mat, v3d->around); copy_m4_m3(rv3d->twmat, mat); @@ -646,7 +649,7 @@ static int calc_manipulator_stats( } case V3D_MANIP_LOCAL: { - if (ob->mode & OB_MODE_POSE) { + if (workspace->object_mode & OB_MODE_POSE) { /* each bone moves on its own local axis, but to avoid confusion, * use the active pones axis for display [#33575], this works as expected on a single bone * and users who select many bones will understand whats going on and what local means @@ -688,7 +691,7 @@ static int calc_manipulator_stats( #ifdef USE_AXIS_BOUNDS copy_m3_m4(tbounds->axis, rv3d->twmat); - if (ob && ob->mode & OB_MODE_EDIT) { + if (ob && workspace->object_mode & OB_MODE_EDIT) { float diff_mat[3][3]; copy_m3_m4(diff_mat, ob->obmat); normalize_m3(diff_mat); @@ -931,7 +934,7 @@ static int calc_manipulator_stats( mul_m4_v3(obedit->obmat, tbounds->max); } } - else if (ob && (ob->mode & OB_MODE_POSE)) { + else if (ob && (workspace->object_mode & OB_MODE_POSE)) { bPoseChannel *pchan; int mode = TFM_ROTATION; // mislead counting bones... bah. We don't know the manipulator mode, could be mixed bool ok = false; @@ -969,10 +972,10 @@ static int calc_manipulator_stats( mul_m4_v3(ob->obmat, tbounds->max); } } - else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) { + else if (ob && (workspace->object_mode & OB_MODE_ALL_PAINT)) { /* pass */ } - else if (ob && ob->mode & OB_MODE_PARTICLE_EDIT) { + else if (ob && workspace->object_mode & OB_MODE_PARTICLE_EDIT) { PTCacheEdit *edit = PE_get_current(scene, view_layer, ob); PTCacheEditPoint *point; PTCacheEditKey *ek; @@ -1062,12 +1065,13 @@ static void manipulator_prepare_mat( case V3D_AROUND_CENTER_BOUNDS: case V3D_AROUND_ACTIVE: { + const WorkSpace *workspace = CTX_wm_workspace(C); bGPdata *gpd = CTX_data_gpencil_data(C); Object *ob = OBACT(view_layer); - if (((v3d->around == V3D_AROUND_ACTIVE) && (scene->obedit == NULL)) && + if (((v3d->around == V3D_AROUND_ACTIVE) && ((workspace->object_mode & OB_MODE_EDIT) == 0)) && ((gpd == NULL) || !(gpd->flag & GP_DATA_STROKE_EDITMODE)) && - (!(ob->mode & OB_MODE_POSE))) + (!(workspace->object_mode & OB_MODE_POSE))) { copy_v3_v3(rv3d->twmat[3], ob->obmat[3]); } @@ -1656,10 +1660,10 @@ static void WIDGETGROUP_xform_cage_draw_prepare(const bContext *C, wmManipulator { struct XFormCageWidgetGroup *xmgroup = mgroup->customdata; wmManipulator *mpr = xmgroup->manipulator; - + const WorkSpace *workspace = CTX_wm_workspace(C); ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob = OBACT(view_layer); - if (ob && ob->mode & OB_MODE_EDIT) { + if (ob && workspace->object_mode & OB_MODE_EDIT) { copy_m4_m4(mpr->matrix_space, ob->obmat); } else { diff --git a/source/blender/editors/transform/transform_manipulator2d.c b/source/blender/editors/transform/transform_manipulator2d.c index 6e2d0d8c5c0..9b6dd187c15 100644 --- a/source/blender/editors/transform/transform_manipulator2d.c +++ b/source/blender/editors/transform/transform_manipulator2d.c @@ -368,7 +368,7 @@ bool ED_widgetgroup_manipulator2d_poll(const bContext *C, wmManipulatorGroupType /* check if there's a selected poly */ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index ab0e24671eb..d5d25888ec8 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -316,7 +316,8 @@ static void transformops_loopsel_hack(bContext *C, wmOperator *op) /* still switch if we were originally in face select mode */ if ((ts->selectmode != selectmode_orig) && (selectmode_orig != SCE_SELECT_FACE)) { - BMEditMesh *em = BKE_editmesh_from_object(scene->obedit); + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); em->selectmode = ts->selectmode = selectmode_orig; EDBM_selectmode_set(em); } diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index f8b11a0bcae..63eea11212c 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -55,6 +55,8 @@ #include "BKE_screen.h" #include "BKE_workspace.h" +#include "DEG_depsgraph.h" + #include "BLT_translation.h" #include "ED_armature.h" @@ -296,6 +298,7 @@ void BIF_createTransformOrientation(bContext *C, ReportList *reports, ts = createViewSpace(C, reports, name, overwrite); } else { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *obedit = CTX_data_edit_object(C); Object *ob = CTX_data_active_object(C); if (obedit) { @@ -306,7 +309,7 @@ void BIF_createTransformOrientation(bContext *C, ReportList *reports, else if (obedit->type == OB_CURVE) ts = createCurveSpace(C, reports, name, overwrite); } - else if (ob && (ob->mode & OB_MODE_POSE)) { + else if (ob && (workspace->object_mode & OB_MODE_POSE)) { ts = createBoneSpace(C, reports, name, overwrite); } else { @@ -441,13 +444,13 @@ void initTransformOrientation(bContext *C, TransInfo *t) case V3D_MANIP_GIMBAL: unit_m3(t->spacemtx); - if (ob && gimbal_axis(ob, t->spacemtx)) { + if (ob && gimbal_axis(ob, t->spacemtx, t->eval_ctx.object_mode)) { BLI_strncpy(t->spacename, IFACE_("gimbal"), sizeof(t->spacename)); break; } ATTR_FALLTHROUGH; /* no gimbal fallthrough to normal */ case V3D_MANIP_NORMAL: - if (obedit || (ob && ob->mode & OB_MODE_POSE)) { + if (obedit || (ob && t->eval_ctx.object_mode & OB_MODE_POSE)) { BLI_strncpy(t->spacename, IFACE_("normal"), sizeof(t->spacename)); ED_getTransformOrientationMatrix(C, t->spacemtx, t->around); break; @@ -578,6 +581,7 @@ static unsigned int bm_mesh_faces_select_get_n(BMesh *bm, BMVert **elems, const int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3], const short around) { + const WorkSpace *workspace = CTX_wm_workspace(C); ViewLayer *view_layer = CTX_data_view_layer(C); Object *obedit = CTX_data_edit_object(C); Base *base; @@ -1008,7 +1012,7 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3 mul_m3_v3(mat, plane); } } - else if (ob && (ob->mode & OB_MODE_POSE)) { + else if (ob && (workspace->object_mode & OB_MODE_POSE)) { bArmature *arm = ob->data; bPoseChannel *pchan; float imat[3][3], mat[3][3]; @@ -1048,7 +1052,7 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3 result = ORIENTATION_EDGE; } } - else if (ob && (ob->mode & (OB_MODE_ALL_PAINT | OB_MODE_PARTICLE_EDIT))) { + else if (ob && (workspace->object_mode & (OB_MODE_ALL_PAINT | OB_MODE_PARTICLE_EDIT))) { /* pass */ } else { diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 30aad46843d..9946f1ad546 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -70,6 +70,8 @@ #include "ED_view3d.h" #include "ED_transform_snap_object_context.h" +#include "DEG_depsgraph.h" + #include "UI_resources.h" #include "UI_view2d.h" @@ -542,7 +544,7 @@ static void initSnappingMode(TransInfo *t) } /* Particles edit mode*/ else if (t->tsnap.applySnap != NULL && // A snapping function actually exist - (obedit == NULL && base_act && base_act->object && base_act->object->mode & OB_MODE_PARTICLE_EDIT)) + (obedit == NULL && base_act && base_act->object && t->eval_ctx.object_mode & OB_MODE_PARTICLE_EDIT)) { t->tsnap.modeSelect = SNAP_ALL; } diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index 8f0590eb5b9..14cd4bcc7ac 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -822,7 +822,7 @@ static bool raycastObjects( Object **r_ob, float r_obmat[4][4], ListBase *r_hit_list) { - Object *obedit = use_object_edit_cage ? sctx->scene->obedit : NULL; + Object *obedit = use_object_edit_cage ? OBEDIT_FROM_EVAL_CTX(&sctx->eval_ctx) : NULL; struct RaycastObjUserData data = { .ray_start = ray_start, @@ -1358,7 +1358,7 @@ static bool snapArmature( static bool snapCurve( SnapData *snapdata, - Object *ob, Curve *cu, float obmat[4][4], + Curve *cu, float obmat[4][4], bool use_obedit, /* read/write args */ float *ray_depth, float *dist_px, /* return args */ @@ -1376,12 +1376,12 @@ static bool snapCurve( mul_m4_m4m4(lpmat, snapdata->pmat, obmat); dist_px_sq = SQUARE(*dist_px); - for (Nurb *nu = (ob->mode == OB_MODE_EDIT ? cu->editnurb->nurbs.first : cu->nurb.first); nu; nu = nu->next) { + for (Nurb *nu = (use_obedit ? cu->editnurb->nurbs.first : cu->nurb.first); nu; nu = nu->next) { for (int u = 0; u < nu->pntsu; u++) { switch (snapdata->snap_to) { case SCE_SNAP_MODE_VERTEX: { - if (ob->mode == OB_MODE_EDIT) { + if (use_obedit) { if (nu->bezt) { /* don't snap to selected (moving) or hidden */ if (nu->bezt[u].f2 & SELECT || nu->bezt[u].hide != 0) { @@ -1966,7 +1966,7 @@ static bool snapObject( else if (ob->type == OB_CURVE) { retval = snapCurve( snapdata, - ob, ob->data, obmat, + ob->data, obmat, use_obedit, ray_depth, dist_px, r_loc, r_no); } @@ -2060,7 +2060,7 @@ static bool snapObjectsRay( float r_loc[3], float r_no[3], Object **r_ob, float r_obmat[4][4]) { - Object *obedit = use_object_edit_cage ? sctx->scene->obedit : NULL; + Object *obedit = use_object_edit_cage ? OBEDIT_FROM_EVAL_CTX(&sctx->eval_ctx) : NULL; struct SnapObjUserData data = { .snapdata = snapdata, @@ -2096,7 +2096,8 @@ SnapObjectContext *ED_transform_snap_object_context_create( sctx->bmain = bmain; sctx->scene = scene; - DEG_evaluation_context_init_from_scene(&sctx->eval_ctx, scene, view_layer, engine_type, DAG_EVAL_VIEWPORT); + DEG_evaluation_context_init_from_scene( + &sctx->eval_ctx, scene, view_layer, engine_type, OB_MODE_OBJECT, DAG_EVAL_VIEWPORT); sctx->cache.object_map = BLI_ghash_ptr_new(__func__); sctx->cache.mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index b52cc20f71f..a5a26cf4d57 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -35,12 +35,14 @@ #include "MEM_guardedalloc.h" +#include "DNA_armature_types.h" #include "DNA_mesh_types.h" #include "DNA_object_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_scene_types.h" #include "DNA_packedFile_types.h" +#include "DNA_workspace_types.h" #include "BLI_utildefines.h" #include "BLI_string.h" @@ -70,6 +72,8 @@ #include "ED_space_api.h" #include "ED_util.h" +#include "DEG_depsgraph.h" + #include "GPU_immediate.h" #include "UI_interface.h" @@ -86,11 +90,7 @@ void ED_editors_init(bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); - Main *bmain = CTX_data_main(C); Scene *sce = CTX_data_scene(C); - ViewLayer *view_layer = CTX_data_view_layer(C); - Object *ob, *obact = (view_layer && view_layer->basact) ? view_layer->basact->object : NULL; - ID *data; /* This is called during initialization, so we don't want to store any reports */ ReportList *reports = CTX_wm_reports(C); @@ -98,24 +98,6 @@ void ED_editors_init(bContext *C) SWAP(int, reports->flag, reports_flag_prev); - /* toggle on modes for objects that were saved with these enabled. for - * e.g. linked objects we have to ensure that they are actually the - * active object in this scene. */ - for (ob = bmain->object.first; ob; ob = ob->id.next) { - int mode = ob->mode; - - if (mode == OB_MODE_OBJECT) { - /* pass */ - } - else { - data = ob->data; - ob->mode = OB_MODE_OBJECT; - if ((ob == obact) && !ID_IS_LINKED(ob) && !(data && ID_IS_LINKED(data))) { - ED_object_toggle_modes(C, mode); - } - } - } - /* image editor paint mode */ if (sce) { ED_space_image_paint_update(wm, sce); @@ -128,7 +110,6 @@ void ED_editors_init(bContext *C) void ED_editors_exit(bContext *C) { Main *bmain = CTX_data_main(C); - Scene *sce; if (!bmain) return; @@ -136,23 +117,20 @@ void ED_editors_exit(bContext *C) /* frees all editmode undos */ undo_editmode_clear(); ED_undo_paint_free(); - - for (sce = bmain->scene.first; sce; sce = sce->id.next) { - if (sce->obedit) { - Object *ob = sce->obedit; - - if (ob) { - if (ob->type == OB_MESH) { - Mesh *me = ob->data; - if (me->edit_btmesh) { - EDBM_mesh_free(me->edit_btmesh); - MEM_freeN(me->edit_btmesh); - me->edit_btmesh = NULL; - } - } - else if (ob->type == OB_ARMATURE) { - ED_armature_edit_free(ob->data); - } + + for (Object *ob = bmain->object.first; ob; ob = ob->id.next) { + if (ob->type == OB_MESH) { + Mesh *me = ob->data; + if (me->edit_btmesh) { + EDBM_mesh_free(me->edit_btmesh); + MEM_freeN(me->edit_btmesh); + me->edit_btmesh = NULL; + } + } + else if (ob->type == OB_ARMATURE) { + bArmature *arm = ob->data; + if (arm->edbo) { + ED_armature_edit_free(ob->data); } } } @@ -170,26 +148,35 @@ bool ED_editors_flush_edits(const bContext *C, bool for_render) Object *ob; Main *bmain = CTX_data_main(C); + eObjectMode object_mode = WM_windows_object_mode_get(bmain->wm.first); + if ((object_mode & (OB_MODE_SCULPT | OB_MODE_EDIT)) == 0) { + return has_edited; + } + /* loop through all data to find edit mode or object mode, because during * exiting we might not have a context for edit object and multiple sculpt * objects can exist at the same time */ for (ob = bmain->object.first; ob; ob = ob->id.next) { - if (ob->mode & OB_MODE_SCULPT) { - /* flush multires changes (for sculpt) */ - multires_force_update(ob); - has_edited = true; - - if (for_render) { - /* flush changes from dynamic topology sculpt */ - BKE_sculptsession_bm_to_me_for_render(ob); - } - else { - /* Set reorder=false so that saving the file doesn't reorder - * the BMesh's elements */ - BKE_sculptsession_bm_to_me(ob, false); + if (object_mode & OB_MODE_SCULPT) { + /* Don't allow flushing while in the middle of a stroke (frees data in use). + * Auto-save prevents this from happening but scripts may cause a flush on saving: T53986. */ + if ((ob->sculpt && ob->sculpt->cache) == 0) { + /* flush multires changes (for sculpt) */ + multires_force_update(ob); + has_edited = true; + + if (for_render) { + /* flush changes from dynamic topology sculpt */ + BKE_sculptsession_bm_to_me_for_render(ob); + } + else { + /* Set reorder=false so that saving the file doesn't reorder + * the BMesh's elements */ + BKE_sculptsession_bm_to_me(ob, false); + } } } - else if (ob->mode & OB_MODE_EDIT) { + else if (object_mode & OB_MODE_EDIT) { /* get editmode results */ has_edited = true; ED_object_editmode_load(ob); diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c index dbf1cf46c61..8eaadb97888 100644 --- a/source/blender/editors/util/undo.c +++ b/source/blender/editors/util/undo.c @@ -49,6 +49,8 @@ #include "BKE_main.h" #include "BKE_screen.h" +#include "DEG_depsgraph.h" + #include "ED_armature.h" #include "ED_particle.h" #include "ED_curve.h" @@ -77,6 +79,7 @@ void ED_undo_push(bContext *C, const char *str) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *obedit = CTX_data_edit_object(C); Object *obact = CTX_data_active_object(C); @@ -102,24 +105,25 @@ void ED_undo_push(bContext *C, const char *str) else if (obedit->type == OB_ARMATURE) undo_push_armature(C, str); } - else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) { + else if (obact && workspace->object_mode & OB_MODE_PARTICLE_EDIT) { if (U.undosteps == 0) return; PE_undo_push(CTX_data_scene(C), CTX_data_view_layer(C), str); } - else if (obact && obact->mode & OB_MODE_SCULPT) { + else if (obact && workspace->object_mode & OB_MODE_SCULPT) { /* do nothing for now */ } else { BKE_undo_write(C, str); } - WM_file_tag_modified(C); + WM_file_tag_modified(); } /* note: also check undo_history_exec() in bottom if you change notifiers */ static int ed_undo_step(bContext *C, int step, const char *undoname) { + const WorkSpace *workspace = CTX_wm_workspace(C); wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); Main *bmain = CTX_data_main(C); @@ -143,7 +147,7 @@ static int ed_undo_step(bContext *C, int step, const char *undoname) if (sa && (sa->spacetype == SPACE_IMAGE)) { SpaceImage *sima = (SpaceImage *)sa->spacedata.first; - if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) { + if ((obact && (workspace->object_mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) { if (!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname) && undoname) { if (U.uiflag & USER_GLOBALUNDO) { ED_viewport_render_kill_jobs(wm, bmain, true); @@ -177,13 +181,13 @@ static int ed_undo_step(bContext *C, int step, const char *undoname) * That was inconsistent with editmode, and also makes for * unecessarily tricky interaction with the other undo * systems. */ - if (obact && obact->mode & OB_MODE_TEXTURE_PAINT) { + if (obact && workspace->object_mode & OB_MODE_TEXTURE_PAINT) { ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname); } - else if (obact && obact->mode & OB_MODE_SCULPT) { + else if (obact && workspace->object_mode & OB_MODE_SCULPT) { ED_undo_paint_step(C, UNDO_PAINT_MESH, step, undoname); } - else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) { + else if (obact && workspace->object_mode & OB_MODE_PARTICLE_EDIT) { if (step == 1) PE_undo(scene, view_layer); else @@ -269,6 +273,7 @@ void ED_undo_pop_op(bContext *C, wmOperator *op) /* name optionally, function used to check for operator redo panel */ bool ED_undo_is_valid(const bContext *C, const char *undoname) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *obedit = CTX_data_edit_object(C); Object *obact = CTX_data_active_object(C); ScrArea *sa = CTX_wm_area(C); @@ -276,7 +281,7 @@ bool ED_undo_is_valid(const bContext *C, const char *undoname) if (sa && sa->spacetype == SPACE_IMAGE) { SpaceImage *sima = (SpaceImage *)sa->spacedata.first; - if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) { + if ((obact && (workspace->object_mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) { return 1; } } @@ -293,15 +298,15 @@ bool ED_undo_is_valid(const bContext *C, const char *undoname) /* if below tests fail, global undo gets executed */ - if (obact && obact->mode & OB_MODE_TEXTURE_PAINT) { + if (obact && workspace->object_mode & OB_MODE_TEXTURE_PAINT) { if (ED_undo_paint_is_valid(UNDO_PAINT_IMAGE, undoname)) return 1; } - else if (obact && obact->mode & OB_MODE_SCULPT) { + else if (obact && workspace->object_mode & OB_MODE_SCULPT) { if (ED_undo_paint_is_valid(UNDO_PAINT_MESH, undoname)) return 1; } - else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) { + else if (obact && workspace->object_mode & OB_MODE_PARTICLE_EDIT) { return PE_undo_is_valid(CTX_data_scene(C), CTX_data_view_layer(C)); } @@ -522,6 +527,7 @@ enum { static int get_undo_system(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Object *obact = CTX_data_active_object(C); Object *obedit = CTX_data_edit_object(C); ScrArea *sa = CTX_wm_area(C); @@ -530,7 +536,7 @@ static int get_undo_system(bContext *C) if (sa && (sa->spacetype == SPACE_IMAGE)) { SpaceImage *sima = (SpaceImage *)sa->spacedata.first; - if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) { + if ((obact && (workspace->object_mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) { if (!ED_undo_paint_empty(UNDO_PAINT_IMAGE)) return UNDOSYSTEM_IMAPAINT; } @@ -543,13 +549,13 @@ static int get_undo_system(bContext *C) } else { if (obact) { - if (obact->mode & OB_MODE_PARTICLE_EDIT) + if (workspace->object_mode & OB_MODE_PARTICLE_EDIT) return UNDOSYSTEM_PARTICLE; - else if (obact->mode & OB_MODE_TEXTURE_PAINT) { + else if (workspace->object_mode & OB_MODE_TEXTURE_PAINT) { if (!ED_undo_paint_empty(UNDO_PAINT_IMAGE)) return UNDOSYSTEM_IMAPAINT; } - else if (obact->mode & OB_MODE_SCULPT) { + else if (workspace->object_mode & OB_MODE_SCULPT) { if (!ED_undo_paint_empty(UNDO_PAINT_MESH)) return UNDOSYSTEM_SCULPT; } diff --git a/source/blender/editors/uvedit/uvedit_buttons.c b/source/blender/editors/uvedit/uvedit_buttons.c index 6b4dd0f0210..f037783bd5e 100644 --- a/source/blender/editors/uvedit/uvedit_buttons.c +++ b/source/blender/editors/uvedit/uvedit_buttons.c @@ -61,7 +61,7 @@ /* UV Utilities */ -static int uvedit_center(Scene *scene, BMEditMesh *em, Image *ima, float center[2]) +static int uvedit_center(Scene *scene, Object *obedit, BMEditMesh *em, Image *ima, float center[2]) { BMFace *f; BMLoop *l; @@ -73,7 +73,7 @@ static int uvedit_center(Scene *scene, BMEditMesh *em, Image *ima, float center[ zero_v2(center); BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, f)) + if (!uvedit_face_visible_test(scene, obedit, ima, f)) continue; BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { @@ -93,7 +93,7 @@ static int uvedit_center(Scene *scene, BMEditMesh *em, Image *ima, float center[ return tot; } -static void uvedit_translate(Scene *scene, BMEditMesh *em, Image *ima, float delta[2]) +static void uvedit_translate(Scene *scene, Object *obedit, BMEditMesh *em, Image *ima, float delta[2]) { BMFace *f; BMLoop *l; @@ -103,7 +103,7 @@ static void uvedit_translate(Scene *scene, BMEditMesh *em, Image *ima, float del const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, f)) + if (!uvedit_face_visible_test(scene, obedit, ima, f)) continue; BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { @@ -134,7 +134,7 @@ static void uvedit_vertex_buttons(const bContext *C, uiBlock *block) em = BKE_editmesh_from_object(obedit); - if (uvedit_center(scene, em, ima, center)) { + if (uvedit_center(scene, obedit, em, ima, center)) { float range_xy[2][2] = { {-10.0f, 10.0f}, {-10.0f, 10.0f}, @@ -190,7 +190,7 @@ static void do_uvedit_vertex(bContext *C, void *UNUSED(arg), int event) em = BKE_editmesh_from_object(obedit); ED_space_image_get_size(sima, &imx, &imy); - uvedit_center(scene, em, ima, center); + uvedit_center(scene, obedit, em, ima, center); if (sima->flag & SI_COORDFLOATS) { delta[0] = uvedit_old_center[0] - center[0]; @@ -201,7 +201,7 @@ static void do_uvedit_vertex(bContext *C, void *UNUSED(arg), int event) delta[1] = uvedit_old_center[1] / imy - center[1]; } - uvedit_translate(scene, em, ima, delta); + uvedit_translate(scene, obedit, em, ima, delta); WM_event_add_notifier(C, NC_IMAGE, sima->image); } diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 45fa35766f1..b4d32b3d03a 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -179,7 +179,7 @@ static void draw_uvs_shadow(Object *obedit) immUnbindProgram(); } -static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, const BMFace *efa_act) +static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BMEditMesh *em, const BMFace *efa_act) { BMesh *bm = em->bm; BMFace *efa; @@ -217,7 +217,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, con totarea += BM_face_calc_area(efa); totuvarea += area_poly_v2(tf_uv, efa->len); - if (uvedit_face_visible_test(scene, ima, efa)) { + if (uvedit_face_visible_test(scene, obedit, ima, efa)) { BM_elem_flag_enable(efa, BM_ELEM_TAG); } else { @@ -314,7 +314,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, con immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { - if (uvedit_face_visible_test(scene, ima, efa)) { + if (uvedit_face_visible_test(scene, obedit, ima, efa)) { const int efa_len = efa->len; float (*tf_uv)[2] = (float (*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, efa_len); float (*tf_uvorig)[2] = (float (*)[2])BLI_buffer_reinit_data(&tf_uvorig_buf, vec2f, efa_len); @@ -669,12 +669,12 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje /* 2. draw colored faces */ if (sima->flag & SI_DRAW_STRETCH) { - draw_uvs_stretch(sima, scene, em, efa_act); + draw_uvs_stretch(sima, scene, obedit, em, efa_act); } else { unsigned int tri_count = 0; BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) { - if (uvedit_face_visible_test(scene, ima, efa)) { + if (uvedit_face_visible_test(scene, obedit, ima, efa)) { BM_elem_flag_enable(efa, BM_ELEM_TAG); tri_count += efa->len - 2; } @@ -687,7 +687,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje /* draw transparent faces */ UI_GetThemeColor4ubv(TH_FACE, col1); UI_GetThemeColor4ubv(TH_FACE_SELECT, col2); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); Gwn_VertFormat *format = immVertexFormat(); @@ -722,7 +722,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje glDisable(GL_BLEND); } else { - if (efa_act && !uvedit_face_visible_test(scene, ima, efa_act)) { + if (efa_act && !uvedit_face_visible_test(scene, obedit, ima, efa_act)) { efa_act = NULL; } } @@ -736,7 +736,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje if (sima->flag & SI_SMOOTH_UV) { glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } glLineWidth(1); @@ -1032,7 +1032,9 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje } -static void draw_uv_shadows_get(SpaceImage *sima, Object *ob, Object *obedit, bool *show_shadow, bool *show_texpaint) +static void draw_uv_shadows_get( + SpaceImage *sima, const EvaluationContext *eval_ctx, Object *ob, Object *obedit, + bool *show_shadow, bool *show_texpaint) { *show_shadow = *show_texpaint = false; @@ -1045,16 +1047,18 @@ static void draw_uv_shadows_get(SpaceImage *sima, Object *ob, Object *obedit, bo *show_shadow = EDBM_uv_check(em); } - *show_texpaint = (ob && ob->type == OB_MESH && ob->mode == OB_MODE_TEXTURE_PAINT); + *show_texpaint = (ob && ob->type == OB_MESH && eval_ctx->object_mode == OB_MODE_TEXTURE_PAINT); } -void ED_uvedit_draw_main(SpaceImage *sima, ARegion *ar, Scene *scene, ViewLayer *view_layer, Object *obedit, Object *obact, Depsgraph *depsgraph) +void ED_uvedit_draw_main( + SpaceImage *sima, const EvaluationContext *eval_ctx, + ARegion *ar, Scene *scene, ViewLayer *view_layer, Object *obedit, Object *obact, Depsgraph *depsgraph) { ToolSettings *toolsettings = scene->toolsettings; bool show_uvedit, show_uvshadow, show_texpaint_uvshadow; show_uvedit = ED_space_image_show_uvedit(sima, obedit); - draw_uv_shadows_get(sima, obact, obedit, &show_uvshadow, &show_texpaint_uvshadow); + draw_uv_shadows_get(sima, eval_ctx, obact, obedit, &show_uvshadow, &show_texpaint_uvshadow); if (show_uvedit || show_uvshadow || show_texpaint_uvshadow) { if (show_uvshadow) diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index 6ca46941404..eb92f17544f 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -57,10 +57,12 @@ typedef struct NearestHit { int lindex; /* index of loop within face */ } NearestHit; -void uv_find_nearest_vert(struct Scene *scene, struct Image *ima, struct BMEditMesh *em, - const float co[2], const float penalty[2], struct NearestHit *hit); -void uv_find_nearest_edge(struct Scene *scene, struct Image *ima, struct BMEditMesh *em, - const float co[2], struct NearestHit *hit); +void uv_find_nearest_vert( + struct Scene *scene, struct Image *ima, struct Object *obedit, struct BMEditMesh *em, + const float co[2], const float penalty[2], struct NearestHit *hit); +void uv_find_nearest_edge( + struct Scene *scene, struct Image *ima, struct Object *obedit, struct BMEditMesh *em, + const float co[2], struct NearestHit *hit); /* utility tool functions */ diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 03a5f4dddc8..f66c9ee9951 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -49,7 +49,7 @@ #include "BLI_utildefines.h" #include "BLI_alloca.h" #include "BLI_math.h" -#include "BLI_lasso.h" +#include "BLI_lasso_2d.h" #include "BLI_blenlib.h" #include "BLI_array.h" @@ -89,7 +89,7 @@ #include "uvedit_intern.h" -static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int action); +static void uv_select_all_perform(Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, int action); static void uv_select_flush_from_tag_face(SpaceImage *sima, Scene *scene, Object *obedit, const bool select); static void uv_select_flush_from_tag_loop(SpaceImage *sima, Scene *scene, Object *obedit, const bool select); @@ -230,7 +230,7 @@ void ED_uvedit_assign_image(Main *UNUSED(bmain), Scene *scene, Object *obedit, I /* now assign to all visible faces */ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (uvedit_face_visible_test(scene, previma, efa) && + if (uvedit_face_visible_test(scene, obedit, previma, efa) && (selected == true || uvedit_face_select_test(scene, efa, cd_loop_uv_offset))) { #ifdef USE_SWITCH_ASPECT @@ -296,12 +296,12 @@ bool uvedit_face_visible_nolocal(Scene *scene, BMFace *efa) return (BM_elem_flag_test(efa, BM_ELEM_HIDDEN) == 0 && BM_elem_flag_test(efa, BM_ELEM_SELECT)); } -bool uvedit_face_visible_test(Scene *scene, Image *ima, BMFace *efa) +bool uvedit_face_visible_test(Scene *scene, Object *obedit, Image *ima, BMFace *efa) { ToolSettings *ts = scene->toolsettings; if (ts->uv_flag & UV_SHOW_SAME_IMAGE) { - const Image *face_image = BKE_object_material_edit_image_get(scene->obedit, efa->mat_nr); + const Image *face_image = BKE_object_material_edit_image_get(obedit, efa->mat_nr); return (face_image == ima) ? uvedit_face_visible_nolocal(scene, efa) : false; } else { @@ -607,7 +607,7 @@ bool ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float r_min[2], INIT_MINMAX2(r_min, r_max); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -653,7 +653,7 @@ static bool ED_uvedit_median(Scene *scene, Image *ima, Object *obedit, float co[ zero_v2(co); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -692,7 +692,7 @@ bool ED_uvedit_center(Scene *scene, Image *ima, Object *obedit, float cent[2], c /************************** find nearest ****************************/ -void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, const float co[2], NearestHit *hit) +void uv_find_nearest_edge(Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, const float co[2], NearestHit *hit) { BMFace *efa; BMLoop *l; @@ -709,7 +709,7 @@ void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, const float BM_mesh_elem_index_ensure(em->bm, BM_VERT); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { @@ -732,7 +732,8 @@ void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, const float } } -static void uv_find_nearest_face(Scene *scene, Image *ima, BMEditMesh *em, const float co[2], NearestHit *hit) +static void uv_find_nearest_face( + Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, const float co[2], NearestHit *hit) { BMFace *efa; BMIter iter; @@ -744,12 +745,12 @@ static void uv_find_nearest_face(Scene *scene, Image *ima, BMEditMesh *em, const memset(hit, 0, sizeof(*hit)); /*this will fill in hit.vert1 and hit.vert2*/ - uv_find_nearest_edge(scene, ima, em, co, hit); + uv_find_nearest_edge(scene, ima, obedit, em, co, hit); hit->l = NULL; hit->luv = hit->luv_next = NULL; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; uv_poly_center(efa, cent, cd_loop_uv_offset); @@ -774,8 +775,9 @@ static bool uv_nearest_between(const BMLoop *l, const float co[2], (line_point_side_v2(uv_next, uv_curr, co) <= 0.0f)); } -void uv_find_nearest_vert(Scene *scene, Image *ima, BMEditMesh *em, - float const co[2], const float penalty[2], NearestHit *hit) +void uv_find_nearest_vert( + Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, + float const co[2], const float penalty[2], NearestHit *hit) { BMFace *efa; BMLoop *l; @@ -787,7 +789,7 @@ void uv_find_nearest_vert(Scene *scene, Image *ima, BMEditMesh *em, const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); /*this will fill in hit.vert1 and hit.vert2*/ - uv_find_nearest_edge(scene, ima, em, co, hit); + uv_find_nearest_edge(scene, ima, obedit, em, co, hit); hit->l = NULL; hit->luv = hit->luv_next = NULL; @@ -797,7 +799,7 @@ void uv_find_nearest_vert(Scene *scene, Image *ima, BMEditMesh *em, BM_mesh_elem_index_ensure(em->bm, BM_VERT); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { @@ -842,7 +844,7 @@ bool ED_uvedit_nearest_uv(Scene *scene, Object *obedit, Image *ima, const float copy_v2_v2(r_uv, co); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -946,8 +948,9 @@ static bool uv_select_edgeloop_edge_tag_faces(BMEditMesh *em, UvMapVert *first1, return true; } -static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestHit *hit, - const float limit[2], const bool extend) +static int uv_select_edgeloop( + Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, NearestHit *hit, + const float limit[2], const bool extend) { BMFace *efa; BMIter iter, liter; @@ -967,7 +970,7 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE); if (!extend) { - uv_select_all_perform(scene, ima, em, SEL_DESELECT); + uv_select_all_perform(scene, ima, obedit, em, SEL_DESELECT); } BM_mesh_elem_hflag_disable_all(em->bm, BM_FACE, BM_ELEM_TAG, false); @@ -991,7 +994,7 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH /* find correct valence edges which are not tagged yet, but connect to tagged one */ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!BM_elem_flag_test(efa, BM_ELEM_TAG) && uvedit_face_visible_test(scene, ima, efa)) { + if (!BM_elem_flag_test(efa, BM_ELEM_TAG) && uvedit_face_visible_test(scene, obedit, ima, efa)) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { /* check face not hidden and not tagged */ if (!(iterv_curr = uv_select_edgeloop_vertex_map_get(vmap, efa, l))) @@ -1046,7 +1049,9 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH /*********************** linked select ***********************/ -static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float limit[2], NearestHit *hit, bool extend, bool select_faces) +static void uv_select_linked( + Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, + const float limit[2], NearestHit *hit, bool extend, bool select_faces) { BMFace *efa; BMLoop *l; @@ -1078,7 +1083,7 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo if (!hit) { BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, a) { - if (uvedit_face_visible_test(scene, ima, efa)) { + if (uvedit_face_visible_test(scene, obedit, ima, efa)) { if (select_faces) { if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) { stack[stacksize] = a; @@ -1236,7 +1241,7 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo /* WATCH IT: this returns first selected UV, * not ideal in many cases since there could be multiple */ -static float *uv_sel_co_from_eve(Scene *scene, Image *ima, BMEditMesh *em, BMVert *eve) +static float *uv_sel_co_from_eve(Scene *scene, Object *obedit, Image *ima, BMEditMesh *em, BMVert *eve) { BMIter liter; BMLoop *l; @@ -1244,7 +1249,7 @@ static float *uv_sel_co_from_eve(Scene *scene, Image *ima, BMEditMesh *em, BMVer const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); BM_ITER_ELEM (l, &liter, eve, BM_LOOPS_OF_VERT) { - if (!uvedit_face_visible_test(scene, ima, l->f)) + if (!uvedit_face_visible_test(scene, obedit, ima, l->f)) continue; if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { @@ -1292,7 +1297,7 @@ static int uv_select_more_less(bContext *C, const bool select) /* mark loops to be selected */ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (uvedit_face_visible_test(scene, ima, efa)) { + if (uvedit_face_visible_test(scene, obedit, ima, efa)) { #define IS_SEL 1 #define IS_UNSEL 2 @@ -1335,7 +1340,7 @@ static int uv_select_more_less(bContext *C, const bool select) /* mark loops to be selected */ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (uvedit_face_visible_test(scene, ima, efa)) { + if (uvedit_face_visible_test(scene, obedit, ima, efa)) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); @@ -1418,7 +1423,7 @@ static void uv_weld_align(bContext *C, int tool) BMLoop *l; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -1440,7 +1445,7 @@ static void uv_weld_align(bContext *C, int tool) BMLoop *l; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -1459,7 +1464,7 @@ static void uv_weld_align(bContext *C, int tool) BMLoop *l; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -1487,7 +1492,7 @@ static void uv_weld_align(bContext *C, int tool) /* tag verts with a selected UV */ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { BM_ITER_ELEM (l, &liter, eve, BM_LOOPS_OF_VERT) { - if (!uvedit_face_visible_test(scene, ima, l->f)) + if (!uvedit_face_visible_test(scene, obedit, ima, l->f)) continue; if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { @@ -1554,8 +1559,10 @@ static void uv_weld_align(bContext *C, int tool) if (BLI_array_count(eve_line) > 2) { /* we know the returns from these must be valid */ - const float *uv_start = uv_sel_co_from_eve(scene, ima, em, eve_line[0]); - const float *uv_end = uv_sel_co_from_eve(scene, ima, em, eve_line[BLI_array_count(eve_line) - 1]); + const float *uv_start = uv_sel_co_from_eve( + scene, obedit, ima, em, eve_line[0]); + const float *uv_end = uv_sel_co_from_eve( + scene, obedit, ima, em, eve_line[BLI_array_count(eve_line) - 1]); /* For t & u modes */ float a = 0.0f; @@ -1575,7 +1582,7 @@ static void uv_weld_align(bContext *C, int tool) /* go over all verts except for endpoints */ for (i = 0; i < BLI_array_count(eve_line); i++) { BM_ITER_ELEM (l, &liter, eve_line[i], BM_LOOPS_OF_VERT) { - if (!uvedit_face_visible_test(scene, ima, l->f)) + if (!uvedit_face_visible_test(scene, obedit, ima, l->f)) continue; if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { @@ -1684,7 +1691,7 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op) /* TODO, use qsort as with MESH_OT_remove_doubles, this isn't optimal */ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -1704,7 +1711,7 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op) float uv_min[2]; float uv_max[2]; - BLI_array_empty(loop_arr); + BLI_array_clear(loop_arr); BLI_array_append(loop_arr, vert_arr[uv_a_index].uv_loop); uv_a = vert_arr[uv_a_index].uv_loop->uv; @@ -1746,7 +1753,7 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op) BLI_array_declare(loop_arr_unselected); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -1830,7 +1837,7 @@ static void UV_OT_weld(wmOperatorType *ot) /* ******************** (de)select all operator **************** */ -static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int action) +static void uv_select_all_perform(Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, int action) { ToolSettings *ts = scene->toolsettings; BMFace *efa; @@ -1862,7 +1869,7 @@ static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int if (action == SEL_TOGGLE) { action = SEL_SELECT; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -1878,7 +1885,7 @@ static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -1909,7 +1916,7 @@ static int uv_select_all_exec(bContext *C, wmOperator *op) int action = RNA_enum_get(op->ptr, "action"); - uv_select_all_perform(scene, ima, em, action); + uv_select_all_perform(scene, ima, obedit, em, action); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); @@ -2008,7 +2015,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo /* find nearest element */ if (loop) { /* find edge */ - uv_find_nearest_edge(scene, ima, em, co, &hit); + uv_find_nearest_edge(scene, ima, obedit, em, co, &hit); if (hit.efa == NULL) { return OPERATOR_CANCELLED; } @@ -2017,7 +2024,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo } else if (selectmode == UV_SELECT_VERTEX) { /* find vertex */ - uv_find_nearest_vert(scene, ima, em, co, penalty, &hit); + uv_find_nearest_vert(scene, ima, obedit, em, co, penalty, &hit); if (hit.efa == NULL) { return OPERATOR_CANCELLED; } @@ -2034,7 +2041,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo } else if (selectmode == UV_SELECT_EDGE) { /* find edge */ - uv_find_nearest_edge(scene, ima, em, co, &hit); + uv_find_nearest_edge(scene, ima, obedit, em, co, &hit); if (hit.efa == NULL) { return OPERATOR_CANCELLED; } @@ -2053,7 +2060,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo } else if (selectmode == UV_SELECT_FACE) { /* find face */ - uv_find_nearest_face(scene, ima, em, co, &hit); + uv_find_nearest_face(scene, ima, obedit, em, co, &hit); if (hit.efa == NULL) { return OPERATOR_CANCELLED; } @@ -2074,7 +2081,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo hitlen = hit.efa->len; } else if (selectmode == UV_SELECT_ISLAND) { - uv_find_nearest_edge(scene, ima, em, co, &hit); + uv_find_nearest_edge(scene, ima, obedit, em, co, &hit); if (hit.efa == NULL) { return OPERATOR_CANCELLED; @@ -2089,10 +2096,10 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo /* do selection */ if (loop) { - flush = uv_select_edgeloop(scene, ima, em, &hit, limit, extend); + flush = uv_select_edgeloop(scene, ima, obedit, em, &hit, limit, extend); } else if (selectmode == UV_SELECT_ISLAND) { - uv_select_linked(scene, ima, em, limit, &hit, extend, false); + uv_select_linked(scene, ima, obedit, em, limit, &hit, extend, false); } else if (extend) { if (selectmode == UV_SELECT_VERTEX) { @@ -2127,7 +2134,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo BM_mesh_elem_index_ensure(em->bm, BM_VERT); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -2142,7 +2149,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo } else { /* deselect all */ - uv_select_all_perform(scene, ima, em, SEL_DESELECT); + uv_select_all_perform(scene, ima, obedit, em, SEL_DESELECT); if (selectmode == UV_SELECT_VERTEX) { /* select vertex */ @@ -2162,7 +2169,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo /* select sticky uvs */ if (sticky != SI_STICKY_DISABLE) { BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -2338,11 +2345,11 @@ static int uv_select_linked_internal(bContext *C, wmOperator *op, const wmEvent RNA_float_get_array(op->ptr, "location", co); } - uv_find_nearest_edge(scene, ima, em, co, &hit); + uv_find_nearest_edge(scene, ima, obedit, em, co, &hit); hit_p = &hit; } - uv_select_linked(scene, ima, em, limit, hit_p, extend, select_faces); + uv_select_linked(scene, ima, obedit, em, limit, hit_p, extend, select_faces); DEG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); @@ -2434,7 +2441,7 @@ static int uv_select_split_exec(bContext *C, wmOperator *op) bool is_sel = false; bool is_unsel = false; - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; /* are we all selected? */ @@ -2765,7 +2772,7 @@ static int uv_border_select_exec(bContext *C, wmOperator *op) pinned = RNA_boolean_get(op->ptr, "pinned"); if (!extend) - uv_select_all_perform(scene, ima, em, SEL_DESELECT); + uv_select_all_perform(scene, ima, obedit, em, SEL_DESELECT); /* do actual selection */ if (use_face_center && !pinned) { @@ -2778,7 +2785,7 @@ static int uv_border_select_exec(bContext *C, wmOperator *op) /* assume not touched */ BM_elem_flag_disable(efa, BM_ELEM_TAG); - if (uvedit_face_visible_test(scene, ima, efa)) { + if (uvedit_face_visible_test(scene, obedit, ima, efa)) { uv_poly_center(efa, cent, cd_loop_uv_offset); if (BLI_rctf_isect_pt_v(&rectf, cent)) { BM_elem_flag_enable(efa, BM_ELEM_TAG); @@ -2797,7 +2804,7 @@ static int uv_border_select_exec(bContext *C, wmOperator *op) changed = true; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); @@ -3006,7 +3013,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo BLI_lasso_boundbox(&rect, mcords, moves); if (!extend && select) { - uv_select_all_perform(scene, ima, em, SEL_DESELECT); + uv_select_all_perform(scene, ima, obedit, em, SEL_DESELECT); } if (use_face_center) { /* Face Center Sel */ @@ -3034,7 +3041,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo } else { /* Vert Sel */ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (uvedit_face_visible_test(scene, ima, efa)) { + if (uvedit_face_visible_test(scene, obedit, ima, efa)) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if ((select) != (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))) { MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); @@ -3188,7 +3195,7 @@ static bool uv_snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, cons const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -3215,7 +3222,7 @@ static bool uv_snap_uvs_offset(Scene *scene, Image *ima, Object *obedit, const f const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -3244,7 +3251,7 @@ static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object /* index every vert that has a selected UV using it, but only once so as to * get unique indices and to count how much to malloc */ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { - if (uvedit_face_visible_test(scene, ima, f)) { + if (uvedit_face_visible_test(scene, obedit, ima, f)) { BM_elem_flag_enable(f, BM_ELEM_TAG); BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { BM_elem_flag_set(l, BM_ELEM_TAG, uvedit_uv_select_test(scene, l, cd_loop_uv_offset)); @@ -3304,7 +3311,7 @@ static bool uv_snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit h = (float)height; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -3400,7 +3407,7 @@ static int uv_pin_exec(bContext *C, wmOperator *op) const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -3454,7 +3461,7 @@ static int uv_select_pinned_exec(bContext *C, wmOperator *UNUSED(op)) const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -3534,7 +3541,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op) BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { int hide = 0; - if (!uvedit_face_visible_test(scene, ima, efa)) { + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) { continue; } diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index 29c908ff900..c510c12ae53 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -32,8 +32,8 @@ #include "BLI_math.h" #include "BLI_rand.h" #include "BLI_heap.h" -#include "BLI_boxpack2d.h" -#include "BLI_convexhull2d.h" +#include "BLI_boxpack_2d.h" +#include "BLI_convexhull_2d.h" #include "uvedit_parametrizer.h" @@ -1291,7 +1291,7 @@ static void p_chart_fill_boundary(PChart *chart, PEdge *be, int nedges) while (nedges > 2) { PEdge *ne, *ne1, *ne2; - e = (PEdge *)BLI_heap_popmin(heap); + e = (PEdge *)BLI_heap_pop_min(heap); e1 = p_boundary_edge_prev(e); e2 = p_boundary_edge_next(e); @@ -2185,12 +2185,12 @@ static void p_chart_simplify_compute(PChart *chart) e->u.nextcollapse = NULL; /* pop edge collapse out of heap one by one */ - while (!BLI_heap_empty(heap)) { + while (!BLI_heap_is_empty(heap)) { if (ncollapsed == NCOLLAPSE) break; HeapNode *link = BLI_heap_top(heap); - PEdge *edge = (PEdge *)BLI_heap_popmin(heap), *pair = edge->pair; + PEdge *edge = (PEdge *)BLI_heap_pop_min(heap), *pair = edge->pair; PVert *oldv, *keepv; PEdge *wheele, *nexte; diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index fa936e998fa..9cd34c46874 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -157,6 +157,8 @@ typedef struct StitchState { bool snap_islands; /* stitch at midpoints or at islands */ bool midpoints; + /* object for editmesh */ + Object *obedit; /* editmesh, cached for use in modal handler */ BMEditMesh *em; /* clear seams of stitched edges after stitch */ @@ -1719,6 +1721,7 @@ static int stitch_init(bContext *C, wmOperator *op) /* initialize state */ state->use_limit = RNA_boolean_get(op->ptr, "use_limit"); state->limit_dist = RNA_float_get(op->ptr, "limit"); + state->obedit = obedit; state->em = em; state->snap_islands = RNA_boolean_get(op->ptr, "snap_islands"); state->static_island = RNA_int_get(op->ptr, "static_island"); @@ -1848,7 +1851,7 @@ static int stitch_init(bContext *C, wmOperator *op) } } - total_edges = BLI_ghash_size(edge_hash); + total_edges = BLI_ghash_len(edge_hash); state->edges = edges = MEM_mallocN(sizeof(*edges) * total_edges, "stitch_edges"); /* I assume any system will be able to at least allocate an iterator :p */ @@ -2131,7 +2134,7 @@ static void stitch_select(bContext *C, Scene *scene, const wmEvent *event, Stitc UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]); if (state->mode == STITCH_VERT) { - uv_find_nearest_vert(scene, ima, state->em, co, NULL, &hit); + uv_find_nearest_vert(scene, ima, state->obedit, state->em, co, NULL, &hit); if (hit.efa) { /* Add vertex to selection, deselect all common uv's of vert other @@ -2145,7 +2148,7 @@ static void stitch_select(bContext *C, Scene *scene, const wmEvent *event, Stitc } } else { - uv_find_nearest_edge(scene, ima, state->em, co, &hit); + uv_find_nearest_edge(scene, ima, state->obedit, state->em, co, &hit); if (hit.efa) { UvEdge *edge = uv_edge_get(hit.l, state); diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index 79f17756ca6..977bca66731 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -45,6 +45,7 @@ extern "C" { #include "BKE_collection.h" #include "BKE_customdata.h" +#include "BKE_idprop.h" #include "BKE_global.h" #include "BKE_library.h" /* free_libblock */ #include "BKE_material.h" @@ -117,9 +118,25 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : Str freestyle_scene->r.gauss = old_scene->r.gauss; freestyle_scene->r.dither_intensity = old_scene->r.dither_intensity; BKE_viewrender_copy(&freestyle_scene->view_render, &old_scene->view_render); + if (G.debug & G_DEBUG_FREESTYLE) { + cout << "Stroke rendering engine : " << freestyle_scene->view_render.engine_id << endl; + } freestyle_scene->r.im_format.planes = R_IMF_PLANES_RGBA; freestyle_scene->r.im_format.imtype = R_IMF_IMTYPE_PNG; + // Copy ID properties, including Cycles render properties + if (old_scene->id.properties) { + freestyle_scene->id.properties = IDP_CopyProperty_ex(old_scene->id.properties, 0); + } + + if (STREQ(freestyle_scene->view_render.engine_id, RE_engine_id_CYCLES)) { + /* Render with transparent background. */ + PointerRNA freestyle_scene_ptr; + RNA_id_pointer_create(&freestyle_scene->id, &freestyle_scene_ptr); + PointerRNA freestyle_cycles_ptr = RNA_pointer_get(&freestyle_scene_ptr, "cycles"); + RNA_boolean_set(&freestyle_cycles_ptr, "film_transparent", 1); + } + if (G.debug & G_DEBUG_FREESTYLE) { printf("%s: %d thread(s)\n", __func__, BKE_render_num_threads(&freestyle_scene->r)); } @@ -478,28 +495,6 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const ma = BlenderStrokeRenderer::GetStrokeShader(freestyle_bmain, nt, false); BLI_ghash_insert(_nodetree_hash, nt, ma); } - - if (STREQ(freestyle_scene->view_render.engine_id, RE_engine_id_CYCLES)) { - PointerRNA scene_ptr, freestyle_scene_ptr; - RNA_pointer_create(NULL, &RNA_Scene, old_scene, &scene_ptr); - RNA_pointer_create(NULL, &RNA_Scene, freestyle_scene, &freestyle_scene_ptr); - - PointerRNA cycles_ptr = RNA_pointer_get(&scene_ptr, "cycles"); - PointerRNA freestyle_cycles_ptr = RNA_pointer_get(&freestyle_scene_ptr, "cycles"); - - int flag; - RNA_STRUCT_BEGIN(&freestyle_cycles_ptr, prop) - { - flag = RNA_property_flag(prop); - if (flag & PROP_HIDDEN) - continue; - RNA_property_copy(&freestyle_cycles_ptr, &cycles_ptr, prop, -1); - } - RNA_STRUCT_END; - - RNA_boolean_set(&freestyle_cycles_ptr, "film_transparent", 1); - } - iStrokeRep->setMaterial(ma); } else { diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 0ac842d90a0..189ca8e6a33 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -142,13 +142,13 @@ data_to_c_simple(shaders/gpu_shader_2D_line_dashed_geom.glsl SRC) data_to_c_simple(shaders/gpu_shader_2D_smooth_color_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_2D_smooth_color_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_2D_image_vert.glsl SRC) +data_to_c_simple(shaders/gpu_shader_image_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_linear_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_shuffle_color_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_mask_uniform_color_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_modulate_alpha_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_alpha_color_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_color_frag.glsl SRC) -data_to_c_simple(shaders/gpu_shader_image_rect_modulate_alpha_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_depth_linear_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_interlace_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_3D_image_vert.glsl SRC) @@ -174,7 +174,7 @@ data_to_c_simple(shaders/gpu_shader_instance_edges_variying_color_geom.glsl SRC) data_to_c_simple(shaders/gpu_shader_instance_edges_variying_color_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_instance_bone_envelope_wire_vert.glsl SRC) -data_to_c_simple(shaders/gpu_shader_instance_mball_helpers_vert.glsl SRC) +data_to_c_simple(shaders/gpu_shader_instance_mball_handles_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_3D_groundline_geom.glsl SRC) data_to_c_simple(shaders/gpu_shader_3D_groundpoint_vert.glsl SRC) diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h index 8d29632fc71..e437b4e4f58 100644 --- a/source/blender/gpu/GPU_draw.h +++ b/source/blender/gpu/GPU_draw.h @@ -46,6 +46,9 @@ struct View3D; struct RegionView3D; struct SmokeModifierData; struct DupliObject; +struct EvaluationContext; + +#include "DNA_object_enums.h" /* OpenGL drawing functions related to shading. These are also * shared with the game engine, where there were previously @@ -73,9 +76,10 @@ void GPU_disable_program_point_size(void); * GPU_object_material_bind returns 0 if drawing should be skipped * - after drawing, the material must be disabled again */ -void GPU_begin_object_materials(struct View3D *v3d, struct RegionView3D *rv3d, - struct Scene *scene, struct ViewLayer *view_layer, - struct Object *ob, bool glsl, bool *do_alpha_after); +void GPU_begin_object_materials( + struct View3D *v3d, struct RegionView3D *rv3d, + struct Scene *scene, struct ViewLayer *view_layer, + struct Object *ob, bool glsl, const eObjectMode object_mode, bool *do_alpha_after); void GPU_end_object_materials(void); bool GPU_object_materials_check(void); diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h index d860431b04f..d36b0ea15be 100644 --- a/source/blender/gpu/GPU_extensions.h +++ b/source/blender/gpu/GPU_extensions.h @@ -64,7 +64,6 @@ typedef enum GPUDeviceType { GPU_DEVICE_INTEL = (1 << 2), GPU_DEVICE_SOFTWARE = (1 << 3), GPU_DEVICE_UNKNOWN = (1 << 4), - GPU_DEVICE_AMD_VEGA = (1 << 5), GPU_DEVICE_ANY = (0xff) } GPUDeviceType; diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h index c58d98c201e..31f24aa7c2e 100644 --- a/source/blender/gpu/GPU_framebuffer.h +++ b/source/blender/gpu/GPU_framebuffer.h @@ -83,14 +83,16 @@ void GPU_framebuffer_recursive_downsample( * - wrapper around framebuffer and texture for simple offscreen drawing * - changes size if graphics card can't support it */ -GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, bool high_bitdepth, char err_out[256]); +GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, + bool depth, bool high_bitdepth, char err_out[256]); void GPU_offscreen_free(GPUOffScreen *ofs); void GPU_offscreen_bind(GPUOffScreen *ofs, bool save); void GPU_offscreen_unbind(GPUOffScreen *ofs, bool restore); void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels); +void GPU_offscreen_blit(GPUOffScreen *ofs, int x, int y); int GPU_offscreen_width(const GPUOffScreen *ofs); int GPU_offscreen_height(const GPUOffScreen *ofs); -int GPU_offscreen_color_texture(const GPUOffScreen *ofs); +struct GPUTexture *GPU_offscreen_color_texture(const GPUOffScreen *ofs); void GPU_offscreen_viewport_data_get( GPUOffScreen *ofs, diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 698f3ada2a3..e2f40ff5c54 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -357,10 +357,9 @@ void GPU_zenith_update_color(float color[3]); struct GPUParticleInfo { float scalprops[4]; - float location[3]; + float location[4]; float velocity[3]; float angular_velocity[3]; - int random_id; }; #ifdef WITH_OPENSUBDIV diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index f2119a117e5..ca6e8343401 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -113,8 +113,10 @@ typedef enum GPUBuiltinShader { GPU_SHADER_2D_UNIFORM_COLOR, GPU_SHADER_2D_FLAT_COLOR, GPU_SHADER_2D_SMOOTH_COLOR, + GPU_SHADER_2D_IMAGE, GPU_SHADER_2D_IMAGE_COLOR, GPU_SHADER_2D_IMAGE_ALPHA_COLOR, + GPU_SHADER_2D_IMAGE_ALPHA, GPU_SHADER_2D_CHECKER, GPU_SHADER_2D_DIAG_STRIPES, /* for simple 3D drawing */ @@ -131,7 +133,6 @@ typedef enum GPUBuiltinShader { GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR, GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR, GPU_SHADER_3D_IMAGE_MODULATE_ALPHA, - GPU_SHADER_3D_IMAGE_RECT_MODULATE_ALPHA, GPU_SHADER_3D_IMAGE_DEPTH, /* stereo 3d */ GPU_SHADER_2D_IMAGE_INTERLACE, @@ -173,7 +174,7 @@ typedef enum GPUBuiltinShader { GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_SOLID, GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_WIRE, - GPU_SHADER_3D_INSTANCE_MBALL_HELPERS, + GPU_SHADER_3D_INSTANCE_MBALL_HANDLES, GPU_NUM_BUILTIN_SHADERS /* (not an actual shader) */ } GPUBuiltinShader; diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h index 580ff64befb..dff7e278ae1 100644 --- a/source/blender/gpu/GPU_viewport.h +++ b/source/blender/gpu/GPU_viewport.h @@ -98,6 +98,7 @@ typedef struct ViewportEngineData_Info { GPUViewport *GPU_viewport_create(void); void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect); void GPU_viewport_unbind(GPUViewport *viewport); +void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect); void GPU_viewport_free(GPUViewport *viewport); GPUViewport *GPU_viewport_create_from_offscreen(struct GPUOffScreen *ofs); diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c index 0400fc1025b..332102aca46 100644 --- a/source/blender/gpu/intern/gpu_batch.c +++ b/source/blender/gpu/intern/gpu_batch.c @@ -34,7 +34,7 @@ #include "BLI_utildefines.h" #include "BLI_rect.h" #include "BLI_math.h" -#include "BLI_polyfill2d.h" +#include "BLI_polyfill_2d.h" #include "BLI_sort_utils.h" diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index d0efee79ab0..3043b3ab686 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -1901,7 +1901,7 @@ bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, GSet *bm_faces, } else if (buffers->use_bmesh) { /* due to dynamic nature of dyntopo, only get first material */ - if (BLI_gset_size(bm_faces) > 0) { + if (BLI_gset_len(bm_faces) > 0) { GSetIterator gs_iter; BMFace *f; diff --git a/source/blender/gpu/intern/gpu_compositing.c b/source/blender/gpu/intern/gpu_compositing.c index 3de363cc76e..ca81ca72a32 100644 --- a/source/blender/gpu/intern/gpu_compositing.c +++ b/source/blender/gpu/intern/gpu_compositing.c @@ -1007,7 +1007,7 @@ bool GPU_fx_do_composite_pass( glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); /* the draw call we all waited for, draw a point per pixel, scaled per circle of confusion */ - GWN_batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, 0, NULL, NULL); + // GWN_batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, 0, NULL, NULL); GPU_texture_unbind(fx->dof_half_downsampled_far); GPU_framebuffer_texture_detach(fx->dof_far_blur); @@ -1023,11 +1023,11 @@ bool GPU_fx_do_composite_pass( /* have to clear the buffer unfortunately */ glClear(GL_COLOR_BUFFER_BIT); /* the draw call we all waited for, draw a point per pixel, scaled per circle of confusion */ - GWN_batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, 0, NULL, NULL); + // GWN_batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, 0, NULL, NULL); GWN_batch_program_use_end(fx->point_batch); /* disable bindings */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_BLEND); GPU_framebuffer_texture_detach(fx->dof_near_blur); diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index f9cf3235ac1..fdb5894e9ed 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -39,11 +39,11 @@ #include <string.h> #include "BLI_blenlib.h" +#include "BLI_hash.h" #include "BLI_linklist.h" #include "BLI_math.h" #include "BLI_threads.h" #include "BLI_utildefines.h" -#include "BLI_hash.h" #include "DNA_lamp_types.h" #include "DNA_material_types.h" @@ -398,7 +398,7 @@ static void gpu_set_alpha_blend(GPUBlendMode alphablend) if (alphablend == GPU_BLEND_SOLID) { glDisable(GL_BLEND); glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } else if (alphablend == GPU_BLEND_ADD) { glEnable(GL_BLEND); @@ -1319,9 +1319,9 @@ static LinkNode *image_free_queue = NULL; static void gpu_queue_image_for_free(Image *ima) { - BLI_lock_thread(LOCK_OPENGL); + BLI_thread_lock(LOCK_OPENGL); BLI_linklist_prepend(&image_free_queue, ima); - BLI_unlock_thread(LOCK_OPENGL); + BLI_thread_unlock(LOCK_OPENGL); } void GPU_free_unused_buffers(void) @@ -1329,7 +1329,7 @@ void GPU_free_unused_buffers(void) if (!BLI_thread_is_main()) return; - BLI_lock_thread(LOCK_OPENGL); + BLI_thread_lock(LOCK_OPENGL); /* images */ for (LinkNode *node = image_free_queue; node; node = node->next) { @@ -1346,7 +1346,7 @@ void GPU_free_unused_buffers(void) /* vbo buffers */ GPU_global_buffer_pool_free_unused(); - BLI_unlock_thread(LOCK_OPENGL); + BLI_thread_unlock(LOCK_OPENGL); } void GPU_free_image(Image *ima) @@ -1460,6 +1460,7 @@ static struct GPUMaterialState { Material *gmatbuf_fixed[FIXEDMAT]; Material *gboundmat; Object *gob; + eObjectMode gob_object_mode; DupliObject *dob; Scene *gscene; int glay; @@ -1554,7 +1555,7 @@ void GPU_end_dupli_object(void) void GPU_begin_object_materials( View3D *v3d, RegionView3D *rv3d, Scene *scene, ViewLayer *view_layer, Object *ob, - bool glsl, bool *do_alpha_after) + bool glsl, const eObjectMode object_mode, bool *do_alpha_after) { Material *ma; GPUMaterial *gpumat; @@ -1592,7 +1593,7 @@ void GPU_begin_object_materials( #ifdef WITH_GAMEENGINE if (rv3d->rflag & RV3D_IS_GAME_ENGINE) { - ob = BKE_object_lod_matob_get(ob, view_layer); + ob = BKE_object_lod_matob_get(ob, view_layer, object_mode); } #else UNUSED_VARS(view_layer); @@ -1616,6 +1617,7 @@ void GPU_begin_object_materials( GMS.two_sided_lighting = (((Mesh *)ob->data)->flag & ME_TWOSIDED) != 0; GMS.gob = ob; + GMS.gob_object_mode = object_mode; GMS.gscene = scene; GMS.is_opensubdiv = use_opensubdiv; GMS.totmat = use_matcap ? 1 : ob->totcol + 1; /* materials start from 1, default material is 0 */ @@ -1734,6 +1736,8 @@ static int gpu_get_particle_info(GPUParticleInfo *pi) pi->scalprops[3] = p->size; copy_v3_v3(pi->location, p->state.co); + pi->location[3] = BLI_hash_int_01(ind); + copy_v3_v3(pi->velocity, p->state.vel); copy_v3_v3(pi->angular_velocity, p->state.ave); return 1; @@ -1834,7 +1838,7 @@ int GPU_object_material_bind(int nr, void *attribs) } GPU_material_bind( - gpumat, GMS.gob->lay, GMS.glay, 1.0, !(GMS.gob->mode & OB_MODE_TEXTURE_PAINT), + gpumat, GMS.gob->lay, GMS.glay, 1.0, !(GMS.gob_object_mode & OB_MODE_TEXTURE_PAINT), GMS.gviewmat, GMS.gviewinv, GMS.gviewcamtexcofac); auto_bump_scale = GMS.gob->derivedFinal != NULL ? GMS.gob->derivedFinal->auto_bump_scale : 1.0f; @@ -2093,7 +2097,7 @@ int GPU_scene_object_lights(ViewLayer *view_layer, float viewmat[4][4], int orth return count; } -static void gpu_multisample(bool enable) +static void gpu_disable_multisample(void) { #ifdef __linux__ /* changing multisample from the default (enabled) causes problems on some @@ -2109,16 +2113,10 @@ static void gpu_multisample(bool enable) } if (toggle_ok) { - if (enable) - glEnable(GL_MULTISAMPLE); - else - glDisable(GL_MULTISAMPLE); + glDisable(GL_MULTISAMPLE); } #else - if (enable) - glEnable(GL_MULTISAMPLE); - else - glDisable(GL_MULTISAMPLE); + glDisable(GL_MULTISAMPLE); #endif } @@ -2150,7 +2148,7 @@ void GPU_state_init(void) glCullFace(GL_BACK); glDisable(GL_CULL_FACE); - gpu_multisample(false); + gpu_disable_multisample(); } void GPU_enable_program_point_size(void) diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index 57df877bf18..6bf330179d3 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -178,14 +178,6 @@ void gpu_extensions_init(void) GG.device = GPU_DEVICE_ATI; GG.driver = GPU_DRIVER_OFFICIAL; } - /* XXX : TODO : Remove this once this sampling mipmap problem is gone. - * https://github.com/dfelinto/opengl-sandbox/blob/downsample/README.md */ - else if (strstr(renderer, "AMD VEGA") && - strstr(vendor, "X.Org")) - { - GG.device = GPU_DEVICE_AMD_VEGA; - GG.driver = GPU_DRIVER_OPENSOURCE; - } else if (strstr(vendor, "NVIDIA")) { GG.device = GPU_DEVICE_NVIDIA; GG.driver = GPU_DRIVER_OFFICIAL; diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c index 09013cd29bd..e83eeefe2c5 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.c +++ b/source/blender/gpu/intern/gpu_framebuffer.c @@ -385,6 +385,13 @@ bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256]) glBindFramebuffer(GL_FRAMEBUFFER, fb->object); GG.currentfb = fb->object; + /* On macOS glDrawBuffer must be set when checking completeness, + * otherwise it will return GL_FRAMEBUFFER_UNSUPPORTED when only a + * color buffer without depth is used. */ + if (fb->colortex[0]) { + glDrawBuffer(GL_COLOR_ATTACHMENT0); + } + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { @@ -602,18 +609,9 @@ void GPU_framebuffer_recursive_downsample( current_dim[0] /= 2; current_dim[1] /= 2; - if (GPU_type_matches(GPU_DEVICE_AMD_VEGA, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE)) { - /* NOTE : here 16 is because of a bug on AMD Vega GPU + non-pro drivers, that prevents us - * from sampling mipmaps that are smaller or equal to 16px. (9) */ - if (current_dim[0] <= 16 && current_dim[1] <= 16) { - break; - } - } - else { - if (current_dim[0] <= 2 && current_dim[1] <= 2) { - /* Cannot reduce further. */ - break; - } + if (current_dim[0] <= 2 && current_dim[1] <= 2) { + /* Cannot reduce further. */ + break; } /* ensure that the viewport size is always at least 1x1 */ @@ -650,7 +648,7 @@ struct GPUOffScreen { GPUTexture *depth; }; -GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, bool high_bitdepth, char err_out[256]) +GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, bool depth, bool high_bitdepth, char err_out[256]) { GPUOffScreen *ofs; @@ -672,15 +670,17 @@ GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, bool high } } - ofs->depth = GPU_texture_create_depth_with_stencil_multisample(width, height, samples, err_out); - if (!ofs->depth) { - GPU_offscreen_free(ofs); - return NULL; - } + if (depth) { + ofs->depth = GPU_texture_create_depth_with_stencil_multisample(width, height, samples, err_out); + if (!ofs->depth) { + GPU_offscreen_free(ofs); + return NULL; + } - if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, 0, 0)) { - GPU_offscreen_free(ofs); - return NULL; + if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, 0, 0)) { + GPU_offscreen_free(ofs); + return NULL; + } } if (high_bitdepth) { @@ -740,6 +740,24 @@ void GPU_offscreen_unbind(GPUOffScreen *ofs, bool restore) glEnable(GL_SCISSOR_TEST); } +void GPU_offscreen_blit(GPUOffScreen *ofs, int x, int y) +{ + const int w = GPU_texture_width(ofs->color); + const int h = GPU_texture_height(ofs->color); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, ofs->fb->object); + GLenum status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER); + + if (status == GL_FRAMEBUFFER_COMPLETE) { + glBlitFramebuffer(0, 0, w, h, x, y, x + w, y + h, GL_COLOR_BUFFER_BIT, GL_NEAREST); + } + else { + gpu_print_framebuffer_error(status, NULL); + } + + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); +} + void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels) { const int w = GPU_texture_width(ofs->color); @@ -827,9 +845,9 @@ int GPU_offscreen_height(const GPUOffScreen *ofs) return GPU_texture_height(ofs->color); } -int GPU_offscreen_color_texture(const GPUOffScreen *ofs) +GPUTexture *GPU_offscreen_color_texture(const GPUOffScreen *ofs) { - return GPU_texture_opengl_bindcode(ofs->color); + return ofs->color; } /* only to be used by viewport code! */ diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 2e6c1cbf9df..2d7b9415030 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -417,7 +417,7 @@ void GPU_material_bind_uniforms( GPU_shader_uniform_vector(shader, material->partscalarpropsloc, 4, 1, pi->scalprops); } if (material->builtins & GPU_PARTICLE_LOCATION) { - GPU_shader_uniform_vector(shader, material->partcoloc, 3, 1, pi->location); + GPU_shader_uniform_vector(shader, material->partcoloc, 4, 1, pi->location); } if (material->builtins & GPU_PARTICLE_VELOCITY) { GPU_shader_uniform_vector(shader, material->partvel, 3, 1, pi->velocity); @@ -557,7 +557,9 @@ static float eval_profile(float r, short falloff_type, float sharpness, float pa { r = fabsf(r); - if (falloff_type == SHD_SUBSURFACE_BURLEY) { + if (falloff_type == SHD_SUBSURFACE_BURLEY || + falloff_type == SHD_SUBSURFACE_RANDOM_WALK) + { return burley_profile(r, param) / BURLEY_TRUNCATE_CDF; } else if (falloff_type == SHD_SUBSURFACE_CUBIC) { @@ -598,7 +600,9 @@ static void compute_sss_kernel( /* Christensen-Burley fitting */ float l[3], d[3]; - if (falloff_type == SHD_SUBSURFACE_BURLEY) { + if (falloff_type == SHD_SUBSURFACE_BURLEY || + falloff_type == SHD_SUBSURFACE_RANDOM_WALK) + { mul_v3_v3fl(l, rad, 0.25f * M_1_PI); const float A = 1.0f; const float s = 1.9f - A + 3.5f * (A - 0.8f) * (A - 0.8f); diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 598722d372b..c25d03dff2f 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -68,6 +68,7 @@ extern char datatoc_gpu_shader_2D_smooth_color_frag_glsl[]; extern char datatoc_gpu_shader_2D_image_vert_glsl[]; extern char datatoc_gpu_shader_3D_image_vert_glsl[]; +extern char datatoc_gpu_shader_image_frag_glsl[]; extern char datatoc_gpu_shader_image_linear_frag_glsl[]; extern char datatoc_gpu_shader_image_color_frag_glsl[]; extern char datatoc_gpu_shader_image_alpha_color_frag_glsl[]; @@ -75,7 +76,6 @@ extern char datatoc_gpu_shader_image_shuffle_color_frag_glsl[]; extern char datatoc_gpu_shader_image_interlace_frag_glsl[]; extern char datatoc_gpu_shader_image_mask_uniform_color_frag_glsl[]; extern char datatoc_gpu_shader_image_modulate_alpha_frag_glsl[]; -extern char datatoc_gpu_shader_image_rect_modulate_alpha_frag_glsl[]; extern char datatoc_gpu_shader_image_depth_linear_frag_glsl[]; extern char datatoc_gpu_shader_3D_vert_glsl[]; extern char datatoc_gpu_shader_3D_normal_vert_glsl[]; @@ -98,7 +98,7 @@ extern char datatoc_gpu_shader_instance_edges_variying_color_geom_glsl[]; extern char datatoc_gpu_shader_instance_edges_variying_color_vert_glsl[]; extern char datatoc_gpu_shader_instance_bone_envelope_solid_vert_glsl[]; extern char datatoc_gpu_shader_instance_bone_envelope_wire_vert_glsl[]; -extern char datatoc_gpu_shader_instance_mball_helpers_vert_glsl[]; +extern char datatoc_gpu_shader_instance_mball_handles_vert_glsl[]; extern char datatoc_gpu_shader_3D_groundpoint_vert_glsl[]; extern char datatoc_gpu_shader_3D_groundline_geom_glsl[]; @@ -710,8 +710,6 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader) datatoc_gpu_shader_image_mask_uniform_color_frag_glsl }, [GPU_SHADER_3D_IMAGE_MODULATE_ALPHA] = { datatoc_gpu_shader_3D_image_vert_glsl, datatoc_gpu_shader_image_modulate_alpha_frag_glsl }, - [GPU_SHADER_3D_IMAGE_RECT_MODULATE_ALPHA] = { datatoc_gpu_shader_3D_image_vert_glsl, - datatoc_gpu_shader_image_rect_modulate_alpha_frag_glsl }, [GPU_SHADER_3D_IMAGE_DEPTH] = { datatoc_gpu_shader_3D_image_vert_glsl, datatoc_gpu_shader_image_depth_linear_frag_glsl }, @@ -728,10 +726,14 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader) datatoc_gpu_shader_2D_smooth_color_frag_glsl }, [GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB] = { datatoc_gpu_shader_2D_image_vert_glsl, datatoc_gpu_shader_image_linear_frag_glsl }, + [GPU_SHADER_2D_IMAGE] = { datatoc_gpu_shader_2D_image_vert_glsl, + datatoc_gpu_shader_image_frag_glsl }, [GPU_SHADER_2D_IMAGE_COLOR] = { datatoc_gpu_shader_2D_image_vert_glsl, datatoc_gpu_shader_image_color_frag_glsl }, [GPU_SHADER_2D_IMAGE_ALPHA_COLOR] = { datatoc_gpu_shader_2D_image_vert_glsl, datatoc_gpu_shader_image_alpha_color_frag_glsl }, + [GPU_SHADER_2D_IMAGE_ALPHA] = { datatoc_gpu_shader_2D_image_vert_glsl, + datatoc_gpu_shader_image_modulate_alpha_frag_glsl }, [GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR] = { datatoc_gpu_shader_2D_image_vert_glsl, datatoc_gpu_shader_image_shuffle_color_frag_glsl }, [GPU_SHADER_3D_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl }, @@ -821,7 +823,7 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader) [GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_WIRE] = { datatoc_gpu_shader_instance_bone_envelope_wire_vert_glsl, datatoc_gpu_shader_flat_color_frag_glsl }, - [GPU_SHADER_3D_INSTANCE_MBALL_HELPERS] = { datatoc_gpu_shader_instance_mball_helpers_vert_glsl, + [GPU_SHADER_3D_INSTANCE_MBALL_HANDLES] = { datatoc_gpu_shader_instance_mball_handles_vert_glsl, datatoc_gpu_shader_flat_color_frag_glsl }, }; diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c index 3ef53b3a6c3..fc045805874 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -474,7 +474,7 @@ cleanup: GPU_framebuffer_slots_bind(dfbl->default_fb, 0); } -static void draw_ofs_to_screen(GPUViewport *viewport) +static void draw_ofs_to_screen(GPUViewport *viewport, const rcti *rect) { DefaultTextureList *dtxl = viewport->txl; @@ -483,6 +483,9 @@ static void draw_ofs_to_screen(GPUViewport *viewport) const float w = (float)GPU_texture_width(color); const float h = (float)GPU_texture_height(color); + BLI_assert(w == BLI_rcti_size_x(rect) + 1); + BLI_assert(h == BLI_rcti_size_y(rect) + 1); + Gwn_VertFormat *format = immVertexFormat(); unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); @@ -495,16 +498,16 @@ static void draw_ofs_to_screen(GPUViewport *viewport) immBegin(GWN_PRIM_TRI_STRIP, 4); immAttrib2f(texcoord, 0.0f, 0.0f); - immVertex2f(pos, 0.0f, 0.0f); + immVertex2f(pos, rect->xmin, rect->ymin); immAttrib2f(texcoord, 1.0f, 0.0f); - immVertex2f(pos, w, 0.0f); + immVertex2f(pos, rect->xmin + w, rect->ymin); immAttrib2f(texcoord, 0.0f, 1.0f); - immVertex2f(pos, 0.0f, h); + immVertex2f(pos, rect->xmin, rect->ymin + h); immAttrib2f(texcoord, 1.0f, 1.0f); - immVertex2f(pos, w, h); + immVertex2f(pos, rect->xmin + w, rect->ymin + h); immEnd(); @@ -523,9 +526,16 @@ void GPU_viewport_unbind(GPUViewport *viewport) glEnable(GL_SCISSOR_TEST); glDisable(GL_DEPTH_TEST); + } +} +void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect) +{ + DefaultFramebufferList *dfbl = viewport->fbl; + + if (dfbl->default_fb) { /* This might be bandwidth limiting */ - draw_ofs_to_screen(viewport); + draw_ofs_to_screen(viewport, rect); } } diff --git a/source/blender/gpu/shaders/gpu_shader_image_rect_modulate_alpha_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_frag.glsl index 7d9ce9d2003..6eeab8ca7e8 100644 --- a/source/blender/gpu/shaders/gpu_shader_image_rect_modulate_alpha_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_image_frag.glsl @@ -2,11 +2,9 @@ in vec2 texCoord_interp; out vec4 fragColor; -uniform float alpha; -uniform sampler2DRect image; +uniform sampler2D image; void main() { fragColor = texture(image, texCoord_interp); - fragColor.a *= alpha; } diff --git a/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl index 7f3e7df40ac..d95645f58e5 100644 --- a/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl @@ -8,8 +8,8 @@ in vec2 texCoord_interp; out vec4 fragColor; uniform int interlace_id; -uniform sampler2DRect image_a; -uniform sampler2DRect image_b; +uniform sampler2D image_a; +uniform sampler2D image_b; bool interlace() { diff --git a/source/blender/gpu/shaders/gpu_shader_instance_mball_helpers_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_mball_handles_vert.glsl index 819199c26c7..819199c26c7 100644 --- a/source/blender/gpu/shaders/gpu_shader_instance_mball_helpers_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_instance_mball_handles_vert.glsl diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 780f4f59fb9..7acd9aa1fd5 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -238,16 +238,18 @@ void geom( } void particle_info( - vec4 sprops, vec3 loc, vec3 vel, vec3 avel, - out float index, out float age, out float life_time, out vec3 location, + vec4 sprops, vec4 loc, vec3 vel, vec3 avel, + out float index, out float random, out float age, + out float life_time, out vec3 location, out float size, out vec3 velocity, out vec3 angular_velocity) { index = sprops.x; + random = loc.w; age = sprops.y; life_time = sprops.z; size = sprops.w; - location = loc; + location = loc.xyz; velocity = vel; angular_velocity = avel; } @@ -2533,8 +2535,7 @@ uint hash(int kx, int ky, int kz) float bits_to_01(uint bits) { - float x = float(bits) * (1.0 / float(0xffffffffu)); - return x; + return (float(bits) / 4294967295.0); } float cellnoise(vec3 p) @@ -2979,7 +2980,9 @@ void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Cl color.rgb *= (refractionDepth > 0.0) ? color.rgb : vec3(1.0); /* Simulate 2 absorption event. */ roughness = sqrt(roughness); eevee_closure_refraction(N, roughness, ior, out_refr); + vec3 vN = normalize(mat3(ViewMatrix) * N); result = CLOSURE_DEFAULT; + result.ssr_normal = normal_encode(vN, viewCameraVec); result.radiance = out_refr * color.rgb; result.ssr_id = REFRACT_CLOSURE_FLAG; #else @@ -3004,7 +3007,7 @@ void node_ambient_occlusion(vec4 color, out Closure result) /* emission */ -void node_emission(vec4 color, float strength, vec3 N, out Closure result) +void node_emission(vec4 color, float strength, vec3 vN, out Closure result) { #ifndef VOLUMETRICS color *= strength; @@ -3012,7 +3015,7 @@ void node_emission(vec4 color, float strength, vec3 N, out Closure result) result = CLOSURE_DEFAULT; result.radiance = color.rgb; result.opacity = color.a; - result.ssr_normal = normal_encode(N, viewCameraVec); + result.ssr_normal = normal_encode(vN, viewCameraVec); #else result = Closure(color.rgb, color.a); #endif @@ -3657,17 +3660,29 @@ float noise_perlin(float x, float y, float z) float v = noise_fade(fy); float w = noise_fade(fz); - float result; + float noise_u[2], noise_v[2]; + + noise_u[0] = noise_nerp(u, + noise_grad(hash(X, Y, Z), fx, fy, fz), + noise_grad(hash(X + 1, Y, Z), fx - 1.0, fy, fz)); + + noise_u[1] = noise_nerp(u, + noise_grad(hash(X, Y + 1, Z), fx, fy - 1.0, fz), + noise_grad(hash(X + 1, Y + 1, Z), fx - 1.0, fy - 1.0, fz)); - result = noise_nerp(w, noise_nerp(v, noise_nerp(u, noise_grad(hash(X, Y, Z), fx, fy, fz), - noise_grad(hash(X + 1, Y, Z), fx - 1.0, fy, fz)), - noise_nerp(u, noise_grad(hash(X, Y + 1, Z), fx, fy - 1.0, fz), - noise_grad(hash(X + 1, Y + 1, Z), fx - 1.0, fy - 1.0, fz))), - noise_nerp(v, noise_nerp(u, noise_grad(hash(X, Y, Z + 1), fx, fy, fz - 1.0), - noise_grad(hash(X + 1, Y, Z + 1), fx - 1.0, fy, fz - 1.0)), - noise_nerp(u, noise_grad(hash(X, Y + 1, Z + 1), fx, fy - 1.0, fz - 1.0), - noise_grad(hash(X + 1, Y + 1, Z + 1), fx - 1.0, fy - 1.0, fz - 1.0)))); - return noise_scale3(result); + noise_v[0] = noise_nerp(v, noise_u[0], noise_u[1]); + + noise_u[0] = noise_nerp(u, + noise_grad(hash(X, Y, Z + 1), fx, fy, fz - 1.0), + noise_grad(hash(X + 1, Y, Z + 1), fx - 1.0, fy, fz - 1.0)); + + noise_u[1] = noise_nerp(u, + noise_grad(hash(X, Y + 1, Z + 1), fx, fy - 1.0, fz - 1.0), + noise_grad(hash(X + 1, Y + 1, Z + 1), fx - 1.0, fy - 1.0, fz - 1.0)); + + noise_v[1] = noise_nerp(v, noise_u[0], noise_u[1]); + + return noise_scale3(noise_nerp(w, noise_v[0], noise_v[1])); } float noise(vec3 p) @@ -4135,9 +4150,38 @@ void node_bevel(float radius, vec3 N, out vec3 result) result = N; } -void node_displacement(float height, float dist, vec3 N, out vec3 result) +void node_displacement_object(float height, float midlevel, float scale, vec3 N, mat4 obmat, out vec3 result) +{ + N = (vec4(N, 0.0) * obmat).xyz; + result = (height - midlevel) * scale * normalize(N); + result = (obmat * vec4(result, 0.0)).xyz; +} + +void node_displacement_world(float height, float midlevel, float scale, vec3 N, out vec3 result) +{ + result = (height - midlevel) * scale * normalize(N); +} + +void node_vector_displacement_tangent(vec4 vector, float midlevel, float scale, vec4 tangent, vec3 normal, mat4 obmat, mat4 viewmat, out vec3 result) +{ + vec3 N_object = normalize(((vec4(normal, 0.0) * viewmat) * obmat).xyz); + vec3 T_object = normalize(((vec4(tangent.xyz, 0.0) * viewmat) * obmat).xyz); + vec3 B_object = tangent.w * normalize(cross(N_object, T_object)); + + vec3 offset = (vector.xyz - vec3(midlevel)) * scale; + result = offset.x * T_object + offset.y * N_object + offset.z * B_object; + result = (obmat * vec4(result, 0.0)).xyz; +} + +void node_vector_displacement_object(vec4 vector, float midlevel, float scale, mat4 obmat, out vec3 result) +{ + result = (vector.xyz - vec3(midlevel)) * scale; + result = (obmat * vec4(result, 0.0)).xyz; +} + +void node_vector_displacement_world(vec4 vector, float midlevel, float scale, out vec3 result) { - result = height * dist * N; + result = (vector.xyz - vec3(midlevel)) * scale; } /* output */ diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 863bce125c5..e28c8122006 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -2176,7 +2176,7 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const ColorManagedViewSet BLI_rcti_init(&ibuf->invalid_rect, 0, 0, 0, 0); } - BLI_lock_thread(LOCK_COLORMANAGE); + BLI_thread_lock(LOCK_COLORMANAGE); /* ensure color management bit fields exists */ if (!ibuf->display_buffer_flags) { @@ -2194,7 +2194,7 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const ColorManagedViewSet display_buffer = colormanage_cache_get(ibuf, &cache_view_settings, &cache_display_settings, cache_handle); if (display_buffer) { - BLI_unlock_thread(LOCK_COLORMANAGE); + BLI_thread_unlock(LOCK_COLORMANAGE); return display_buffer; } @@ -2205,7 +2205,7 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const ColorManagedViewSet colormanage_cache_put(ibuf, &cache_view_settings, &cache_display_settings, display_buffer, cache_handle); - BLI_unlock_thread(LOCK_COLORMANAGE); + BLI_thread_unlock(LOCK_COLORMANAGE); return display_buffer; } @@ -2244,11 +2244,11 @@ void IMB_display_buffer_transform_apply(unsigned char *display_buffer, float *li void IMB_display_buffer_release(void *cache_handle) { if (cache_handle) { - BLI_lock_thread(LOCK_COLORMANAGE); + BLI_thread_lock(LOCK_COLORMANAGE); colormanage_cache_handle_release(cache_handle); - BLI_unlock_thread(LOCK_COLORMANAGE); + BLI_thread_unlock(LOCK_COLORMANAGE); } } @@ -2964,7 +2964,7 @@ static void imb_partial_display_buffer_update_ex(ImBuf *ibuf, view_flag = 1 << (cache_view_settings.view - 1); display_index = cache_display_settings.display - 1; - BLI_lock_thread(LOCK_COLORMANAGE); + BLI_thread_lock(LOCK_COLORMANAGE); if ((ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) == 0) { display_buffer = colormanage_cache_get(ibuf, @@ -2983,7 +2983,7 @@ static void imb_partial_display_buffer_update_ex(ImBuf *ibuf, memset(ibuf->display_buffer_flags, 0, global_tot_display * sizeof(unsigned int)); ibuf->display_buffer_flags[display_index] |= view_flag; - BLI_unlock_thread(LOCK_COLORMANAGE); + BLI_thread_unlock(LOCK_COLORMANAGE); } if (display_buffer == NULL) { diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c index 89955711384..daf062f5499 100644 --- a/source/blender/imbuf/intern/moviecache.c +++ b/source/blender/imbuf/intern/moviecache.c @@ -513,7 +513,7 @@ void IMB_moviecache_get_cache_segments(MovieCache *cache, int proxy, int render_ *points_r = cache->points; } else { - int totframe = BLI_ghash_size(cache->hash); + int totframe = BLI_ghash_len(cache->hash); int *frames = MEM_callocN(totframe * sizeof(int), "movieclip cache frames"); int a, totseg = 0; GHashIterator gh_iter; diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c index 8c427dff4a3..ba72decf44d 100644 --- a/source/blender/imbuf/intern/thumbs.c +++ b/source/blender/imbuf/intern/thumbs.c @@ -652,7 +652,7 @@ static struct IMBThumbLocks { void IMB_thumb_locks_acquire(void) { - BLI_lock_thread(LOCK_IMAGE); + BLI_thread_lock(LOCK_IMAGE); if (thumb_locks.lock_counter == 0) { BLI_assert(thumb_locks.locked_paths == NULL); @@ -663,12 +663,12 @@ void IMB_thumb_locks_acquire(void) BLI_assert(thumb_locks.locked_paths != NULL); BLI_assert(thumb_locks.lock_counter > 0); - BLI_unlock_thread(LOCK_IMAGE); + BLI_thread_unlock(LOCK_IMAGE); } void IMB_thumb_locks_release(void) { - BLI_lock_thread(LOCK_IMAGE); + BLI_thread_lock(LOCK_IMAGE); BLI_assert((thumb_locks.locked_paths != NULL) && (thumb_locks.lock_counter > 0)); thumb_locks.lock_counter--; @@ -678,14 +678,14 @@ void IMB_thumb_locks_release(void) BLI_condition_end(&thumb_locks.cond); } - BLI_unlock_thread(LOCK_IMAGE); + BLI_thread_unlock(LOCK_IMAGE); } void IMB_thumb_path_lock(const char *path) { void *key = BLI_strdup(path); - BLI_lock_thread(LOCK_IMAGE); + BLI_thread_lock(LOCK_IMAGE); BLI_assert((thumb_locks.locked_paths != NULL) && (thumb_locks.lock_counter > 0)); if (thumb_locks.locked_paths) { @@ -694,14 +694,14 @@ void IMB_thumb_path_lock(const char *path) } } - BLI_unlock_thread(LOCK_IMAGE); + BLI_thread_unlock(LOCK_IMAGE); } void IMB_thumb_path_unlock(const char *path) { const void *key = path; - BLI_lock_thread(LOCK_IMAGE); + BLI_thread_lock(LOCK_IMAGE); BLI_assert((thumb_locks.locked_paths != NULL) && (thumb_locks.lock_counter > 0)); if (thumb_locks.locked_paths) { @@ -711,5 +711,5 @@ void IMB_thumb_path_unlock(const char *path) BLI_condition_notify_all(&thumb_locks.cond); } - BLI_unlock_thread(LOCK_IMAGE); + BLI_thread_unlock(LOCK_IMAGE); } diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index 407d59f09da..fc3b4afe18d 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -72,7 +72,7 @@ typedef struct Brush { float rake_factor; /* rake actual data (not texture), used for sculpt */ short blend; /* blend mode */ - short ob_mode; /* & with ob->mode to see if the brush is compatible, use for display only. */ + short ob_mode; /* eObjectMode: to see if the brush is compatible, use for display only. */ float weight; /* brush weight */ int size; /* brush diameter */ int flag; /* general purpose flag */ diff --git a/source/blender/makesdna/DNA_meta_types.h b/source/blender/makesdna/DNA_meta_types.h index f9ba45efef8..d1f001fccc4 100644 --- a/source/blender/makesdna/DNA_meta_types.h +++ b/source/blender/makesdna/DNA_meta_types.h @@ -62,7 +62,7 @@ typedef struct MetaElem { /* Draw_Data: stores pointers used for shader attributes */ float draw_scale_xform[3][4]; /* Matrix of Scale and Translation */ - float draw_stiffness_radius; /* stiffness circle radius (only in edit mode) */ + float draw_stiffness_radius; /* radius of the stiffness circle (only in edit mode) */ float pad; } MetaElem; diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 5df7e49c2f3..283e801ea7a 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -603,7 +603,7 @@ typedef struct ClothModifierData { struct Cloth *clothObject; /* The internal data structure for cloth. */ struct ClothSimSettings *sim_parms; /* definition is in DNA_cloth_types.h */ struct ClothCollSettings *coll_parms; /* definition is in DNA_cloth_types.h */ - struct PointCache *point_cache; /* definition is in DNA_object_force.h */ + struct PointCache *point_cache; /* definition is in DNA_object_force_types.h */ struct ListBase ptcaches; /* XXX nasty hack, remove once hair can be separated from cloth modifier data */ struct ClothHairData *hairdata; @@ -655,8 +655,7 @@ typedef struct BooleanModifierData { struct Object *object; char operation; - char solver; - char pad; + char pad[2]; char bm_flag; float double_threshold; } BooleanModifierData; @@ -667,11 +666,6 @@ typedef enum { eBooleanModifierOp_Difference = 2, } BooleanModifierOp; -typedef enum { - eBooleanModifierSolver_Carve = 0, - eBooleanModifierSolver_BMesh = 1, -} BooleanSolver; - /* bm_flag (only used when G_DEBUG) */ enum { eBooleanModifierBMeshFlag_BMesh_Separate = (1 << 0), @@ -800,8 +794,8 @@ typedef enum { typedef struct FluidsimModifierData { ModifierData modifier; - struct FluidsimSettings *fss; /* definition is in DNA_object_fluidsim.h */ - struct PointCache *point_cache; /* definition is in DNA_object_force.h */ + struct FluidsimSettings *fss; /* definition is in DNA_object_fluidsim_types.h */ + struct PointCache *point_cache; /* definition is in DNA_object_force_types.h */ } FluidsimModifierData; typedef struct ShrinkwrapModifierData { diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 0bd36244ffb..63eecebf44a 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -1032,12 +1032,12 @@ typedef struct NodeSunBeams { #define SHD_TANGENT_AXIS_Y 1 #define SHD_TANGENT_AXIS_Z 2 -/* normal map space */ -#define SHD_NORMAL_MAP_TANGENT 0 -#define SHD_NORMAL_MAP_OBJECT 1 -#define SHD_NORMAL_MAP_WORLD 2 -#define SHD_NORMAL_MAP_BLENDER_OBJECT 3 -#define SHD_NORMAL_MAP_BLENDER_WORLD 4 +/* normal map, displacement space */ +#define SHD_SPACE_TANGENT 0 +#define SHD_SPACE_OBJECT 1 +#define SHD_SPACE_WORLD 2 +#define SHD_SPACE_BLENDER_OBJECT 3 +#define SHD_SPACE_BLENDER_WORLD 4 /* math node clamp */ #define SHD_MATH_CLAMP 1 @@ -1077,6 +1077,7 @@ enum { SHD_SUBSURFACE_CUBIC = 1, SHD_SUBSURFACE_GAUSSIAN = 2, SHD_SUBSURFACE_BURLEY = 3, + SHD_SUBSURFACE_RANDOM_WALK = 4, }; /* blur node */ diff --git a/source/blender/makesdna/DNA_object_enums.h b/source/blender/makesdna/DNA_object_enums.h new file mode 100644 index 00000000000..58f9e29297f --- /dev/null +++ b/source/blender/makesdna/DNA_object_enums.h @@ -0,0 +1,49 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file DNA_object_enums.h + * \ingroup DNA + * + * Enums typedef's for use in public headers. + */ + +#ifndef __DNA_OBJECT_ENUMS_H__ +#define __DNA_OBJECT_ENUMS_H__ + +/* Object.mode */ +typedef enum eObjectMode { + OB_MODE_OBJECT = 0, + OB_MODE_EDIT = 1 << 0, + OB_MODE_SCULPT = 1 << 1, + OB_MODE_VERTEX_PAINT = 1 << 2, + OB_MODE_WEIGHT_PAINT = 1 << 3, + OB_MODE_TEXTURE_PAINT = 1 << 4, + OB_MODE_PARTICLE_EDIT = 1 << 5, + OB_MODE_POSE = 1 << 6, + OB_MODE_GPENCIL = 1 << 7, /* NOTE: Just a dummy to make the UI nicer */ +} eObjectMode; + +/* Any mode where the brush system is used. */ +#define OB_MODE_ALL_PAINT (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT) + +/* Any mode that uses Object.sculpt. */ +#define OB_MODE_ALL_SCULPT (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) + +#endif /* __DNA_OBJECT_ENUMS_H__ */ diff --git a/source/blender/makesdna/DNA_object_fluidsim.h b/source/blender/makesdna/DNA_object_fluidsim_types.h index 846d5788d63..b305235083a 100644 --- a/source/blender/makesdna/DNA_object_fluidsim.h +++ b/source/blender/makesdna/DNA_object_fluidsim_types.h @@ -25,12 +25,12 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file DNA_object_fluidsim.h +/** \file DNA_object_fluidsim_types.h * \ingroup DNA */ -#ifndef __DNA_OBJECT_FLUIDSIM_H__ -#define __DNA_OBJECT_FLUIDSIM_H__ +#ifndef __DNA_OBJECT_FLUIDSIM_TYPES_H__ +#define __DNA_OBJECT_FLUIDSIM_TYPES_H__ #include "DNA_ID.h" #include "DNA_defs.h" @@ -189,6 +189,5 @@ typedef struct FluidsimSettings { } #endif -#endif - +#endif /* __DNA_OBJECT_FLUIDSIM_TYPES_H__ */ diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force_types.h index 63e1da4f90e..e7ebd3b72d7 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force_types.h @@ -25,12 +25,12 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file DNA_object_force.h +/** \file DNA_object_force_types.h * \ingroup DNA */ -#ifndef __DNA_OBJECT_FORCE_H__ -#define __DNA_OBJECT_FORCE_H__ +#ifndef __DNA_OBJECT_FORCE_TYPES_H__ +#define __DNA_OBJECT_FORCE_TYPES_H__ #ifdef __cplusplus extern "C" { @@ -459,5 +459,5 @@ typedef struct SoftBody { } #endif -#endif +#endif /* __DNA_OBJECT_FORCE_TYPES_H__ */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 7c3ef5e72be..0b7dccee9ab 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -33,6 +33,8 @@ #ifndef __DNA_OBJECT_TYPES_H__ #define __DNA_OBJECT_TYPES_H__ +#include "DNA_object_enums.h" + #include "DNA_defs.h" #include "DNA_listBase.h" #include "DNA_ID.h" @@ -169,9 +171,6 @@ typedef struct Object { ListBase defbase; /* list of bDeformGroup (vertex groups) names and flag only */ ListBase modifiers; /* list of ModifierData structures */ ListBase fmaps; /* list of facemaps */ - - int mode; /* Local object mode */ - int restore_mode; /* Keep track of what mode to return to after toggling a mode */ /* materials */ struct Material **mat; /* material slots */ @@ -711,25 +710,6 @@ enum { OB_DUPLI_FLAG_RENDER = 1 << 1, }; -/* ob->mode */ -typedef enum eObjectMode { - OB_MODE_OBJECT = 0, - OB_MODE_EDIT = 1 << 0, - OB_MODE_SCULPT = 1 << 1, - OB_MODE_VERTEX_PAINT = 1 << 2, - OB_MODE_WEIGHT_PAINT = 1 << 3, - OB_MODE_TEXTURE_PAINT = 1 << 4, - OB_MODE_PARTICLE_EDIT = 1 << 5, - OB_MODE_POSE = 1 << 6, - OB_MODE_GPENCIL = 1 << 7, /* NOTE: Just a dummy to make the UI nicer */ -} eObjectMode; - -/* any mode where the brush system is used */ -#define OB_MODE_ALL_PAINT (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT) - -/* any mode that uses ob->sculpt */ -#define OB_MODE_ALL_SCULPT (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) - #define MAX_DUPLI_RECUR 8 #ifdef __cplusplus diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index ea7905eb2ad..a7be2e37c4b 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -263,6 +263,11 @@ typedef struct ParticleSettings { short pad5; int recalc; + + float twist; + float pad6; + struct CurveMapping *twistcurve; + void *pad7; } ParticleSettings; typedef struct ParticleSystem { @@ -305,7 +310,8 @@ typedef struct ParticleSystem { char bb_uvname[3][64]; /* billboard uv name, MAX_CUSTOMDATA_LAYER_NAME */ /* if you change these remember to update array lengths to PSYS_TOT_VG! */ - short vgroup[12], vg_neg, rt3; /* vertex groups, 0==disable, 1==starting index */ + short vgroup[13], vg_neg, rt3; /* vertex groups, 0==disable, 1==starting index */ + char pad[6]; /* temporary storage during render */ struct ParticleRenderData *renderdata; @@ -439,6 +445,7 @@ typedef enum eParticleChildFlag { PART_CHILD_USE_CLUMP_NOISE = (1<<0), PART_CHILD_USE_CLUMP_CURVE = (1<<1), PART_CHILD_USE_ROUGH_CURVE = (1<<2), + PART_CHILD_USE_TWIST_CURVE = (1<<3), } eParticleChildFlag; /* part->draw_col */ @@ -566,7 +573,7 @@ typedef enum eParticleChildFlag { #define PART_DUPLIW_CURRENT 1 /* psys->vg */ -#define PSYS_TOT_VG 12 +#define PSYS_TOT_VG 13 #define PSYS_VG_DENSITY 0 #define PSYS_VG_VEL 1 @@ -580,6 +587,7 @@ typedef enum eParticleChildFlag { #define PSYS_VG_TAN 9 #define PSYS_VG_ROT 10 #define PSYS_VG_EFFECTOR 11 +#define PSYS_VG_TWIST 12 /* ParticleTarget->flag */ #define PTARGET_CURRENT 1 @@ -611,7 +619,8 @@ typedef enum eParticleTextureInfluence { PAMAP_KINK_AMP = (1<<12), PAMAP_ROUGH = (1<<9), PAMAP_LENGTH = (1<<4), - PAMAP_CHILD = (PAMAP_CLUMP | PAMAP_KINK_FREQ | PAMAP_KINK_AMP | PAMAP_ROUGH | PAMAP_LENGTH), + PAMAP_TWIST = (1<<13), + PAMAP_CHILD = (PAMAP_CLUMP | PAMAP_KINK_FREQ | PAMAP_KINK_AMP | PAMAP_ROUGH | PAMAP_LENGTH | PAMAP_TWIST), } eParticleTextureInfluence; #endif diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 671ad1bc954..1642da25481 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1623,7 +1623,7 @@ typedef struct Scene { ListBase base DNA_DEPRECATED; struct Base *basact DNA_DEPRECATED; /* active base */ - struct Object *obedit; /* name replaces old G.obedit */ + void *_pad1; float cursor[3]; /* 3d cursor location */ char _pad[4]; @@ -1944,6 +1944,14 @@ extern const char *RE_engine_id_CYCLES; #define BASACT(_view_layer) ((_view_layer)->basact) #define OBACT(_view_layer) (BASACT(_view_layer) ? BASACT(_view_layer)->object: NULL) +#define OBEDIT_FROM_WORKSPACE(workspace, _view_layer) \ + (((workspace)->object_mode & OD_MODE_EDIT) ? OBACT(_view_layer) : NULL) +#define OBEDIT_FROM_EVAL_CTX(eval_ctx) \ + (((eval_ctx)->object_mode & OB_MODE_EDIT) ? OBACT((eval_ctx)->view_layer) : NULL) + +#define OBEDIT_FROM_WINDOW(window) \ + BKE_workspace_edit_object(WM_window_get_active_workspace(window), WM_window_get_active_scene(window)) + #define V3D_CAMERA_LOCAL(v3d) ((!(v3d)->scenelock && (v3d)->camera) ? (v3d)->camera : NULL) #define V3D_CAMERA_SCENE(scene, v3d) ((!(v3d)->scenelock && (v3d)->camera) ? (v3d)->camera : (scene)->camera) diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index fff3ec10292..939ff9eb075 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -71,11 +71,9 @@ typedef struct bScreen { char swap; /* indicator to survive swap-exchange systems */ char skip_handling; /* set to delay screen handling after switching back from maximized area */ char scrubbing; /* set when scrubbing to avoid some costly updates */ - char pad[6]; - - /* XXX mainwin is actually entire window content now, including global bars. Should be moved out of bScreen. */ - short mainwin; /* screensize subwindow, for screenedges and global menus */ - short subwinactive; /* active subwindow */ + char pad[2]; + + struct ARegion *active_region; /* active region that has mouse focus */ struct wmTimer *animtimer; /* if set, screen has timer handler added in window */ void *context; /* context callback */ @@ -258,7 +256,7 @@ typedef struct ARegion { rcti drawrct; /* runtime for partial redraw, same or smaller than winrct */ short winx, winy; /* size */ - short swinid; + short visible; /* region is currently visible on screen */ short regiontype; /* window, header, etc. identifier for drawing */ short alignment; /* how it should split */ short flag; /* hide, ... */ diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h index c95e0a1f54a..9932e16e988 100644 --- a/source/blender/makesdna/DNA_smoke_types.h +++ b/source/blender/makesdna/DNA_smoke_types.h @@ -189,7 +189,7 @@ typedef struct SmokeDomainSettings { char pad[2]; /* Smoke uses only one cache from now on (index [0]), but keeping the array for now for reading old files. */ - struct PointCache *point_cache[2]; /* definition is in DNA_object_force.h */ + struct PointCache *point_cache[2]; /* definition is in DNA_object_force_types.h */ struct ListBase ptcaches[2]; struct EffectorWeights *effector_weights; int border_collisions; /* How domain border collisions are handled */ diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index 995d7645dc0..0eb54a9b5b3 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -86,7 +86,7 @@ typedef struct MTex { float timefac, lengthfac, clumpfac, dampfac; float kinkfac, kinkampfac, roughfac, padensfac, gravityfac; float lifefac, sizefac, ivelfac, fieldfac; - int pad2; + float twistfac; /* lamp */ float shadowfac; diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 38a1c3ae01c..bc7a484cef6 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -413,7 +413,6 @@ typedef struct bTheme { #define UI_THEMESPACE_START(btheme) (CHECK_TYPE_INLINE(btheme, bTheme *), &((btheme)->tbuts)) #define UI_THEMESPACE_END(btheme) (CHECK_TYPE_INLINE(btheme, bTheme *), (&((btheme)->tclip) + 1)) -/* for the moment only the name. may want to store options with this later */ typedef struct bAddon { struct bAddon *next, *prev; char module[64]; diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 4332959bd9a..003e7eb6e46 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -197,8 +197,7 @@ typedef struct wmWindow { short modalcursor; /* the current modal cursor */ short grabcursor; /* cursor grab mode */ short addmousemove; /* internal: tag this for extra mousemove event, makes cursors/buttons active on UI switching */ - short multisamples; /* amount of samples for OpenGL FSA the ghost window was created with, if zero no FSA */ - short pad[3]; + short pad[4]; int winid; /* winid also in screens, is for retrieving this window after read */ @@ -208,8 +207,6 @@ typedef struct wmWindow { struct wmEvent *eventstate; /* storage for event system */ - struct wmSubWindow *curswin; /* internal for wm_subwindow.c only */ - struct wmGesture *tweak; /* internal for wm_operators.c */ /* Input Method Editor data - complex character input (esp. for asian character input) @@ -223,7 +220,6 @@ typedef struct wmWindow { ListBase handlers; /* window+screen handlers, handled last */ ListBase modalhandlers; /* priority handlers, handled first */ - ListBase subwindows; /* opengl stuff for sub windows, see notes in wm_subwindow.c */ ListBase gesture; /* gesture stuff */ /** Global areas aren't part of the screen, but part of the window directly. diff --git a/source/blender/makesdna/DNA_workspace_types.h b/source/blender/makesdna/DNA_workspace_types.h index adc3c1fef2b..dbcc278ea15 100644 --- a/source/blender/makesdna/DNA_workspace_types.h +++ b/source/blender/makesdna/DNA_workspace_types.h @@ -92,6 +92,9 @@ typedef struct WorkSpace { int pad; int flags DNA_PRIVATE_WORKSPACE; /* enum eWorkSpaceFlags */ + short object_mode, object_mode_restore; + char _pad[4]; + /* should be: '#ifdef USE_WORKSPACE_TOOL'. */ bToolDef tool; diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h index 2ab99617ee8..3361e50e257 100644 --- a/source/blender/makesdna/DNA_world_types.h +++ b/source/blender/makesdna/DNA_world_types.h @@ -163,6 +163,12 @@ enum { WO_AOMUL = 3, }; +enum { + WO_MIST_QUADRATIC = 0, + WO_MIST_LINEAR = 1, + WO_MIST_INVERSE_QUADRATIC = 2, +}; + /* ao_samp_method - methods for sampling the AO hemi */ #define WO_AOSAMP_CONSTANT 0 #define WO_AOSAMP_HALTON 1 diff --git a/source/blender/makesdna/intern/CMakeLists.txt b/source/blender/makesdna/intern/CMakeLists.txt index 8c758c33dc5..5b8dcd97108 100644 --- a/source/blender/makesdna/intern/CMakeLists.txt +++ b/source/blender/makesdna/intern/CMakeLists.txt @@ -107,6 +107,7 @@ set(INC_SYS set(SRC ../../blenlib/intern/BLI_ghash.c + ../../blenlib/intern/BLI_ghash_utils.c ../../blenlib/intern/BLI_mempool.c ../../blenlib/intern/endian_switch.c ../../blenlib/intern/hash_mm2a.c diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index 593d93b5615..f0f1c2210f0 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -86,8 +86,8 @@ static const char *includefiles[] = { "DNA_modifier_types.h", "DNA_lattice_types.h", "DNA_object_types.h", - "DNA_object_force.h", - "DNA_object_fluidsim.h", + "DNA_object_force_types.h", + "DNA_object_fluidsim_types.h", "DNA_world_types.h", "DNA_scene_types.h", "DNA_view3d_types.h", @@ -1313,8 +1313,8 @@ int main(int argc, char **argv) #include "DNA_modifier_types.h" #include "DNA_lattice_types.h" #include "DNA_object_types.h" -#include "DNA_object_force.h" -#include "DNA_object_fluidsim.h" +#include "DNA_object_force_types.h" +#include "DNA_object_fluidsim_types.h" #include "DNA_world_types.h" #include "DNA_scene_types.h" #include "DNA_view3d_types.h" diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index e0824281656..2a9b9ebe376 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -411,22 +411,46 @@ typedef struct ParameterDynAlloc { /* Function */ typedef enum FunctionFlag { - FUNC_NO_SELF = (1 << 0), /* for static functions */ - FUNC_USE_SELF_TYPE = (1 << 1), /* for class methods, only used when FUNC_NO_SELF is set */ + /***** Options affecting callback signature. *****/ + /* Those add additionnal parameters at the beginning of the C callback, like that: + * rna_my_func([ID *_selfid], + * [<DNA_STRUCT> *self|StructRNA *type], + * [Main *bmain], + * [bContext *C], + * [ReportList *reports], + * <other RNA-defined parameters>); + */ + /* Pass ID owning 'self' data (i.e. ptr->id.data, might be same as self in case data is an ID...). */ + FUNC_USE_SELF_ID = (1 << 11), + + /* Do not pass the object (DNA struct pointer) from which it is called, used to define static or class functions. */ + FUNC_NO_SELF = (1 << 0), + /* Pass RNA type, used to define class functions, only valid when FUNC_NO_SELF is set. */ + FUNC_USE_SELF_TYPE = (1 << 1), + + /* Pass Main, bContext and/or ReportList. */ FUNC_USE_MAIN = (1 << 2), FUNC_USE_CONTEXT = (1 << 3), FUNC_USE_REPORTS = (1 << 4), - FUNC_USE_SELF_ID = (1 << 11), - FUNC_ALLOW_WRITE = (1 << 12), - /* registering */ + + /***** Registering of python subclasses. *****/ + /* This function is part of the registerable class' interface, and can be implemented/redefined in python. */ FUNC_REGISTER = (1 << 5), + /* Subclasses can choose not to implement this function. */ FUNC_REGISTER_OPTIONAL = FUNC_REGISTER | (1 << 6), + /* If not set, the python function implementing this call is not allowed to write into data-blocks. + * Except for WindowManager and Screen currently, see rna_id_write_error() in bpy_rna.c */ + FUNC_ALLOW_WRITE = (1 << 12), - /* internal flags */ + /***** Internal flags. *****/ + /* UNUSED CURRENTLY? ??? */ FUNC_BUILTIN = (1 << 7), + /* UNUSED CURRENTLY. ??? */ FUNC_EXPORT = (1 << 8), + /* Function has been defined at runtime, not statically in RNA source code. */ FUNC_RUNTIME = (1 << 9), + /* UNUSED CURRENTLY? Function owns its identifier and description strings, and has to free them when deleted. */ FUNC_FREE_POINTERS = (1 << 10), } FunctionFlag; diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index b8dbc69f352..1750c50b9da 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -7053,8 +7053,21 @@ bool RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, prop_dst = rna_ensure_property_realdata(&prop_dst, ptr); prop_src = rna_ensure_property_realdata(&prop_src, fromptr); + /* IDprops: destination may not exist, if source does and is set, try to create it. */ + /* Note: this is sort of quick hack/bandage to fix the issue, we need to rethink how IDProps are handled + * in 'diff' RNA code completely, imho... */ + if (prop_src != NULL && prop_dst == NULL && RNA_property_is_set(fromptr, prop)) { + BLI_assert(prop_src->magic != RNA_MAGIC); + IDProperty *idp_dst = RNA_struct_idprops(ptr, true); + IDProperty *prop_idp_dst = IDP_CopyProperty((IDProperty *)prop_src); + IDP_AddToGroup(idp_dst, prop_idp_dst); + rna_idproperty_touch(prop_idp_dst); + /* Nothing else to do here... */ + return true; + } + if (ELEM(NULL, prop_dst, prop_src)) { - false; + return false; } IDOverrideStaticPropertyOperation opop = { diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 5336a63fb76..aa37c9ffa88 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -31,6 +31,7 @@ #include "DNA_texture_types.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" +#include "DNA_workspace_types.h" #include "BLI_math.h" @@ -43,6 +44,8 @@ #include "WM_types.h" +#include "DEG_depsgraph.h" + static const EnumPropertyItem prop_direction_items[] = { {0, "ADD", 0, "Add", "Add effect of brush"}, {BRUSH_DIR_IN, "SUBTRACT", 0, "Subtract", "Subtract effect of brush"}, @@ -373,21 +376,23 @@ static void rna_Brush_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerR static void rna_Brush_main_tex_update(bContext *C, PointerRNA *ptr) { + const WorkSpace *workspace = CTX_wm_workspace(C); Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); Brush *br = (Brush *)ptr->data; - BKE_paint_invalidate_overlay_tex(scene, view_layer, br->mtex.tex); + BKE_paint_invalidate_overlay_tex(scene, view_layer, br->mtex.tex, workspace->object_mode); rna_Brush_update(bmain, scene, ptr); } static void rna_Brush_secondary_tex_update(bContext *C, PointerRNA *ptr) { Main *bmain = CTX_data_main(C); + const WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); Brush *br = (Brush *)ptr->data; - BKE_paint_invalidate_overlay_tex(scene, view_layer, br->mask_mtex.tex); + BKE_paint_invalidate_overlay_tex(scene, view_layer, br->mask_mtex.tex, workspace->object_mode); rna_Brush_update(bmain, scene, ptr); } @@ -449,8 +454,9 @@ static void rna_TextureSlot_brush_angle_update(bContext *C, PointerRNA *ptr) MTex *mtex = ptr->data; /* skip invalidation of overlay for stencil mode */ if (mtex->mapping != MTEX_MAP_MODE_STENCIL) { + const WorkSpace *workspace = CTX_wm_workspace(C); ViewLayer *view_layer = CTX_data_view_layer(C); - BKE_paint_invalidate_overlay_tex(scene, view_layer, mtex->tex); + BKE_paint_invalidate_overlay_tex(scene, view_layer, mtex->tex, workspace->object_mode); } rna_TextureSlot_update(C, ptr); diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c index 596aff6de8f..b973e0f27ee 100644 --- a/source/blender/makesrna/intern/rna_dynamicpaint.c +++ b/source/blender/makesrna/intern/rna_dynamicpaint.c @@ -34,7 +34,7 @@ #include "DNA_dynamicpaint_types.h" #include "DNA_modifier_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c index 271ead13197..a75aceb6f7e 100644 --- a/source/blender/makesrna/intern/rna_fluidsim.c +++ b/source/blender/makesrna/intern/rna_fluidsim.c @@ -26,7 +26,7 @@ #include <stdlib.h> -#include "DNA_object_fluidsim.h" +#include "DNA_object_fluidsim_types.h" #include "BLI_threads.h" #include "BLI_utildefines.h" diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c index 131378b5c49..7a1c1710a87 100644 --- a/source/blender/makesrna/intern/rna_layer.c +++ b/source/blender/makesrna/intern/rna_layer.c @@ -64,6 +64,7 @@ const EnumPropertyItem rna_enum_collection_type_items[] = { #include "DNA_group_types.h" #include "DNA_object_types.h" +#include "DNA_workspace_types.h" #include "RNA_access.h" @@ -72,6 +73,8 @@ const EnumPropertyItem rna_enum_collection_type_items[] = { #include "BKE_node.h" #include "BKE_scene.h" #include "BKE_mesh.h" +#include "BKE_object.h" +#include "BKE_workspace.h" #include "DEG_depsgraph_build.h" #include "DEG_depsgraph_query.h" @@ -94,7 +97,7 @@ static void rna_SceneCollection_name_set(PointerRNA *ptr, const char *value) { Scene *scene = (Scene *)ptr->id.data; SceneCollection *sc = (SceneCollection *)ptr->data; - BKE_collection_rename(scene, sc, value); + BKE_collection_rename(&scene->id, sc, value); } static PointerRNA rna_SceneCollection_objects_get(CollectionPropertyIterator *iter) @@ -141,6 +144,23 @@ static int rna_SceneCollection_move_into(ID *id, SceneCollection *sc_src, Main * return 1; } +static SceneCollection *rna_SceneCollection_duplicate( + ID *id, SceneCollection *scene_collection, Main *bmain, bContext *C, ReportList *reports) +{ + if (scene_collection == BKE_collection_master(id)) { + BKE_report(reports, RPT_ERROR, "The master collection can't be duplicated"); + return NULL; + } + + SceneCollection *scene_collection_new = BKE_collection_duplicate(id, scene_collection); + + DEG_relations_tag_update(bmain); + /* Don't use id here, since the layer collection may come from a group. */ + WM_event_add_notifier(C, NC_SCENE | ND_LAYER, CTX_data_scene(C)); + + return scene_collection_new; +} + static SceneCollection *rna_SceneCollection_new( ID *id, SceneCollection *sc_parent, Main *bmain, const char *name) { @@ -635,9 +655,9 @@ static int rna_LayerCollection_name_length(PointerRNA *ptr) static void rna_LayerCollection_name_set(PointerRNA *ptr, const char *value) { - Scene *scene = (Scene *)ptr->id.data; + ID *owner_id = (ID *)ptr->id.data; SceneCollection *sc = ((LayerCollection *)ptr->data)->scene_collection; - BKE_collection_rename(scene, sc, value); + BKE_collection_rename(owner_id, sc, value); } static PointerRNA rna_LayerCollection_objects_get(CollectionPropertyIterator *iter) @@ -717,6 +737,23 @@ static Group *rna_LayerCollection_create_group( return group; } +static LayerCollection *rna_LayerCollection_duplicate( + ID *id, LayerCollection *layer_collection, Main *bmain, bContext *C, ReportList *reports) +{ + if (layer_collection->scene_collection == BKE_collection_master(id)) { + BKE_report(reports, RPT_ERROR, "The master collection can't be duplicated"); + return NULL; + } + + LayerCollection *layer_collection_new = BKE_layer_collection_duplicate(id, layer_collection); + + DEG_relations_tag_update(bmain); + /* Don't use id here, since the layer collection may come from a group. */ + WM_event_add_notifier(C, NC_SCENE | ND_LAYER, CTX_data_scene(C)); + + return layer_collection_new; +} + static int rna_LayerCollections_active_collection_index_get(PointerRNA *ptr) { ViewLayer *view_layer = (ViewLayer *)ptr->data; @@ -801,6 +838,18 @@ static void rna_LayerObjects_active_object_set(PointerRNA *ptr, PointerRNA value view_layer->basact = NULL; } +static void rna_LayerObjects_active_object_update(struct bContext *C, PointerRNA *ptr) +{ + wmWindow *win = CTX_wm_window(C); + Scene *scene = WM_window_get_active_scene(win); + + if (scene != ptr->id.data) { + return; + } + ViewLayer *view_layer = (ViewLayer *)ptr->data; + ED_object_base_activate(C, view_layer->basact); +} + static IDProperty *rna_ViewLayer_idprops(PointerRNA *ptr, bool create) { ViewLayer *view_layer = (ViewLayer *)ptr->data; @@ -843,10 +892,14 @@ static int rna_ViewLayer_objects_selected_skip(CollectionPropertyIterator *iter, static PointerRNA rna_ViewLayer_depsgraph_get(PointerRNA *ptr) { - Scene *scene = (Scene *)ptr->id.data; - ViewLayer *view_layer = (ViewLayer *)ptr->data; - Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, false); - return rna_pointer_inherit_refine(ptr, &RNA_Depsgraph, depsgraph); + ID *id = ptr->id.data; + if (GS(id->name) == ID_SCE) { + Scene *scene = (Scene *)id; + ViewLayer *view_layer = (ViewLayer *)ptr->data; + Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, false); + return rna_pointer_inherit_refine(ptr, &RNA_Depsgraph, depsgraph); + } + return PointerRNA_NULL; } static void rna_LayerObjects_selected_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) @@ -881,7 +934,7 @@ static void rna_ObjectBase_select_update(Main *UNUSED(bmain), Scene *UNUSED(scen static char *rna_ViewRenderSettings_path(PointerRNA *UNUSED(ptr)) { - return BLI_sprintfN("viewport_render"); + return BLI_sprintfN("view_render"); } static void rna_ViewRenderSettings_engine_set(PointerRNA *ptr, int value) @@ -1080,6 +1133,12 @@ static void rna_def_scene_collection(BlenderRNA *brna) parm = RNA_def_pointer(func, "sc_dst", "SceneCollection", "Collection", "Collection to insert into"); parm = RNA_def_boolean(func, "result", false, "Result", "Whether the operation succeded"); RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "duplicate", "rna_SceneCollection_duplicate"); + RNA_def_function_ui_description(func, "Create a copy of the collection"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_CONTEXT | FUNC_USE_REPORTS); + parm = RNA_def_pointer(func, "result", "SceneCollection", "", "Newly created collection"); + RNA_def_function_return(func, parm); } static void rna_def_layer_collection_override(BlenderRNA *brna) @@ -1994,6 +2053,12 @@ static void rna_def_layer_collection(BlenderRNA *brna) parm = RNA_def_pointer(func, "result", "Group", "", "Newly created Group"); RNA_def_function_return(func, parm); + func = RNA_def_function(srna, "duplicate", "rna_LayerCollection_duplicate"); + RNA_def_function_ui_description(func, "Create a copy of the collection"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_CONTEXT | FUNC_USE_REPORTS); + parm = RNA_def_pointer(func, "result", "LayerCollection", "", "Newly created collection"); + RNA_def_function_return(func, parm); + /* Flags */ prop = RNA_def_property(srna, "selectable", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", COLLECTION_SELECTABLE); @@ -2079,11 +2144,11 @@ static void rna_def_layer_objects(BlenderRNA *brna, PropertyRNA *cprop) prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "Object"); RNA_def_property_pointer_funcs(prop, "rna_LayerObjects_active_object_get", "rna_LayerObjects_active_object_set", NULL, NULL); - RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK | PROP_CONTEXT_UPDATE); RNA_def_property_ui_text(prop, "Active Object", "Active object for this layer"); /* Could call: ED_object_base_activate(C, rl->basact); * but would be a bad level call and it seems the notifier is enough */ - RNA_def_property_update(prop, NC_SCENE | ND_OB_ACTIVE, NULL); + RNA_def_property_update(prop, NC_SCENE | ND_OB_ACTIVE, "rna_LayerObjects_active_object_update"); prop = RNA_def_property(srna, "selected", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "object_bases", NULL); diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 440af0d0e8e..6f23b0fd281 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -92,13 +92,15 @@ const EnumPropertyItem rna_enum_ramp_blend_items[] = { #include "BKE_texture.h" #include "BKE_node.h" #include "BKE_paint.h" +#include "BKE_scene.h" +#include "BKE_workspace.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" #include "ED_node.h" #include "ED_image.h" -#include "BKE_scene.h" +#include "ED_screen.h" static void rna_Material_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { @@ -201,6 +203,11 @@ static void rna_Material_active_paint_texture_index_update(Main *bmain, Scene *s if (ma->texpaintslot) { Image *image = ma->texpaintslot[ma->paint_active_slot].ima; for (sc = bmain->screen.first; sc; sc = sc->id.next) { + wmWindow *win = ED_screen_window_find(sc, bmain->wm.first); + if (win == NULL) { + continue; + } + Object *obedit = OBEDIT_FROM_WINDOW(win); ScrArea *sa; for (sa = sc->areabase.first; sa; sa = sa->next) { SpaceLink *sl; @@ -209,7 +216,7 @@ static void rna_Material_active_paint_texture_index_update(Main *bmain, Scene *s SpaceImage *sima = (SpaceImage *)sl; if (!sima->pin) - ED_space_image_set(sima, scene, scene->obedit, image); + ED_space_image_set(sima, scene, obedit, image); } } } diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index e721a04bd2a..99417ee7b1b 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -34,7 +34,7 @@ #include "DNA_mesh_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_scene_types.h" #include "MEM_guardedalloc.h" @@ -1960,12 +1960,6 @@ static void rna_def_modifier_boolean(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; - static const EnumPropertyItem prop_solver_items[] = { - {eBooleanModifierSolver_BMesh, "BMESH", 0, "BMesh", "Use the BMesh boolean solver"}, - {eBooleanModifierSolver_Carve, "CARVE", 0, "Carve", "Use the Carve boolean solver"}, - {0, NULL, 0, NULL, NULL} - }; - srna = RNA_def_struct(brna, "BooleanModifier", "Modifier"); RNA_def_struct_ui_text(srna, "Boolean Modifier", "Boolean operations modifier"); RNA_def_struct_sdna(srna, "BooleanModifierData"); @@ -1982,11 +1976,6 @@ static void rna_def_modifier_boolean(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Operation", ""); RNA_def_property_update(prop, 0, "rna_Modifier_update"); - prop = RNA_def_property(srna, "solver", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, prop_solver_items); - RNA_def_property_ui_text(prop, "Solver", ""); - RNA_def_property_update(prop, 0, "rna_Modifier_update"); - prop = RNA_def_property(srna, "double_threshold", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "double_threshold"); RNA_def_property_range(prop, 0, 1.0f); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 2b2c6998eb4..a148efb859d 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3312,11 +3312,18 @@ static const EnumPropertyItem node_script_mode_items[] = { }; static const EnumPropertyItem node_principled_distribution_items[] = { - { SHD_GLOSSY_GGX, "GGX", 0, "GGX", "" }, - { SHD_GLOSSY_MULTI_GGX, "MULTI_GGX", 0, "Multiscatter GGX", "" }, + {SHD_GLOSSY_GGX, "GGX", 0, "GGX", ""}, + {SHD_GLOSSY_MULTI_GGX, "MULTI_GGX", 0, "Multiscatter GGX", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static const EnumPropertyItem node_subsurface_method_items[] = { + {SHD_SUBSURFACE_BURLEY, "BURLEY", 0, "Christensen-Burley", "Approximation to physically based volume scattering"}, + {SHD_SUBSURFACE_RANDOM_WALK, "RANDOM_WALK", 0, "Random Walk", "Volumetric approximation to physically based volume scattering"}, { 0, NULL, 0, NULL, NULL } }; + /* -- Common nodes ---------------------------------------------------------- */ static void def_group_input(StructRNA *srna) @@ -4263,6 +4270,12 @@ static void def_principled(StructRNA *srna) RNA_def_property_enum_items(prop, node_principled_distribution_items); RNA_def_property_ui_text(prop, "Distribution", ""); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNodePrincipled_update"); + + prop = RNA_def_property(srna, "subsurface_method", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom2"); + RNA_def_property_enum_items(prop, node_subsurface_method_items); + RNA_def_property_ui_text(prop, "Subsurface Method", "Method for rendering subsurface scattering"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNodePrincipled_update"); } static void def_refraction(StructRNA *srna) @@ -4350,11 +4363,11 @@ static void def_sh_uvalongstroke(StructRNA *srna) static void def_sh_normal_map(StructRNA *srna) { static const EnumPropertyItem prop_space_items[] = { - {SHD_NORMAL_MAP_TANGENT, "TANGENT", 0, "Tangent Space", "Tangent space normal mapping"}, - {SHD_NORMAL_MAP_OBJECT, "OBJECT", 0, "Object Space", "Object space normal mapping"}, - {SHD_NORMAL_MAP_WORLD, "WORLD", 0, "World Space", "World space normal mapping"}, - {SHD_NORMAL_MAP_BLENDER_OBJECT, "BLENDER_OBJECT", 0, "Blender Object Space", "Object space normal mapping, compatible with Blender render baking"}, - {SHD_NORMAL_MAP_BLENDER_WORLD, "BLENDER_WORLD", 0, "Blender World Space", "World space normal mapping, compatible with Blender render baking"}, + {SHD_SPACE_TANGENT, "TANGENT", 0, "Tangent Space", "Tangent space normal mapping"}, + {SHD_SPACE_OBJECT, "OBJECT", 0, "Object Space", "Object space normal mapping"}, + {SHD_SPACE_WORLD, "WORLD", 0, "World Space", "World space normal mapping"}, + {SHD_SPACE_BLENDER_OBJECT, "BLENDER_OBJECT", 0, "Blender Object Space", "Object space normal mapping, compatible with Blender render baking"}, + {SHD_SPACE_BLENDER_WORLD, "BLENDER_WORLD", 0, "Blender World Space", "World space normal mapping, compatible with Blender render baking"}, {0, NULL, 0, NULL, NULL} }; @@ -4374,6 +4387,45 @@ static void def_sh_normal_map(StructRNA *srna) RNA_def_struct_sdna_from(srna, "bNode", NULL); } +static void def_sh_displacement(StructRNA *srna) +{ + static const EnumPropertyItem prop_space_items[] = { + {SHD_SPACE_OBJECT, "OBJECT", 0, "Object Space", "Displacement is in object space, affected by object scale"}, + {SHD_SPACE_WORLD, "WORLD", 0, "World Space", "Displacement is in world space, not affected by object scale"}, + {0, NULL, 0, NULL, NULL} + }; + + PropertyRNA *prop; + + prop = RNA_def_property(srna, "space", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, prop_space_items); + RNA_def_property_ui_text(prop, "Space", "Space of the input height"); + RNA_def_property_update(prop, 0, "rna_Node_update"); + + RNA_def_struct_sdna_from(srna, "bNode", NULL); +} + +static void def_sh_vector_displacement(StructRNA *srna) +{ + static const EnumPropertyItem prop_space_items[] = { + {SHD_SPACE_TANGENT, "TANGENT", 0, "Tangent Space", "Tagent space vector displacement mapping"}, + {SHD_SPACE_OBJECT, "OBJECT", 0, "Object Space", "Object space vector displacement mapping"}, + {SHD_SPACE_WORLD, "WORLD", 0, "World Space", "World space vector displacement mapping"}, + {0, NULL, 0, NULL, NULL} + }; + + PropertyRNA *prop; + + prop = RNA_def_property(srna, "space", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, prop_space_items); + RNA_def_property_ui_text(prop, "Space", "Space of the input height"); + RNA_def_property_update(prop, 0, "rna_Node_update"); + + RNA_def_struct_sdna_from(srna, "bNode", NULL); +} + static void def_sh_tangent(StructRNA *srna) { static const EnumPropertyItem prop_direction_type_items[] = { @@ -4427,6 +4479,7 @@ static void def_sh_subsurface(StructRNA *srna) {SHD_SUBSURFACE_CUBIC, "CUBIC", 0, "Cubic", "Simple cubic falloff function"}, {SHD_SUBSURFACE_GAUSSIAN, "GAUSSIAN", 0, "Gaussian", "Normal distribution, multiple can be combined to fit more complex profiles"}, {SHD_SUBSURFACE_BURLEY, "BURLEY", 0, "Christensen-Burley", "Approximation to physically based volume scattering"}, + {SHD_SUBSURFACE_RANDOM_WALK, "RANDOM_WALK", 0, "Random Walk", "Volumetric approximation to physically based volume scattering"}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index f2b2e95d21e..e37446028be 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -33,11 +33,12 @@ #include "DNA_group_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_object_types.h" #include "DNA_property_types.h" #include "DNA_scene_types.h" #include "DNA_meta_types.h" +#include "DNA_workspace_types.h" #include "BLI_utildefines.h" #include "BLI_listbase.h" @@ -217,6 +218,12 @@ static void rna_Object_internal_update(Main *UNUSED(bmain), Scene *UNUSED(scene) DEG_id_tag_update(ptr->id.data, OB_RECALC_OB); } +static void rna_Object_internal_update_draw(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + DEG_id_tag_update(ptr->id.data, OB_RECALC_OB); + WM_main_add_notifier(NC_OBJECT | ND_DRAW, ptr->id.data); +} + static void rna_Object_matrix_world_update(Main *bmain, Scene *scene, PointerRNA *ptr) { /* don't use compat so we get predictable rotation */ @@ -294,11 +301,11 @@ void rna_Object_internal_update_data(Main *UNUSED(bmain), Scene *UNUSED(scene), WM_main_add_notifier(NC_OBJECT | ND_DRAW, ptr->id.data); } -static void rna_Object_active_shape_update(Main *bmain, Scene *scene, PointerRNA *ptr) +static void rna_Object_active_shape_update(bContext *C, Main *bmain, Scene *scene, PointerRNA *ptr) { Object *ob = ptr->id.data; - if (scene->obedit == ob) { + if (CTX_data_edit_object(C) == ob) { /* exit/enter editmode to get new shape */ switch (ob->type) { case OB_MESH: @@ -337,7 +344,7 @@ static void rna_Object_data_set(PointerRNA *ptr, PointerRNA value) Object *ob = (Object *)ptr->data; ID *id = value.data; - if (ob->mode & OB_MODE_EDIT) { + if (BKE_object_is_in_editmode(ob)) { return; } @@ -1394,7 +1401,9 @@ static void rna_Object_constraints_clear(Object *object) static ModifierData *rna_Object_modifier_new(Object *object, bContext *C, ReportList *reports, const char *name, int type) { - return ED_object_modifier_add(reports, CTX_data_main(C), CTX_data_scene(C), object, name, type); + Main *bmain = CTX_data_main(C); + const WorkSpace *workspace = CTX_wm_workspace(C); + return ED_object_modifier_add(reports, bmain, CTX_data_scene(C), object, workspace->object_mode, name, type); } static void rna_Object_modifier_remove(Object *object, bContext *C, ReportList *reports, PointerRNA *md_ptr) @@ -2419,12 +2428,6 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Type", "Type of Object"); - prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "mode"); - RNA_def_property_enum_items(prop, rna_enum_object_mode_items); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Mode", "Object interaction mode"); - prop = RNA_def_property(srna, "layers_local_view", PROP_BOOLEAN, PROP_LAYER_MEMBER); RNA_def_property_boolean_sdna(prop, NULL, "lay", 0x01000000); RNA_def_property_array(prop, 8); @@ -2754,7 +2757,7 @@ static void rna_def_object(BlenderRNA *brna) prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "index"); RNA_def_property_ui_text(prop, "Pass Index", "Index number for the \"Object Index\" render pass"); - RNA_def_property_update(prop, NC_OBJECT, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT, "rna_Object_internal_update_draw"); prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "col"); @@ -3021,6 +3024,7 @@ static void rna_def_object(BlenderRNA *brna) prop = RNA_def_property(srna, "active_shape_key_index", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "shapenr"); + RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); /* XXX this is really unpredictable... */ RNA_def_property_int_funcs(prop, "rna_Object_active_shape_key_index_get", "rna_Object_active_shape_key_index_set", "rna_Object_active_shape_key_index_range"); diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 74528a2c0e8..17f19bfc38c 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -526,10 +526,8 @@ void rna_Object_dm_info(struct Object *ob, int type, char *result) static int rna_Object_update_from_editmode(Object *ob) { - if (ob->mode & OB_MODE_EDIT) { - return ED_object_editmode_load(ob); - } - return false; + /* fail gracefully if we aren't in edit-mode. */ + return ED_object_editmode_load(ob); } #else /* RNA_RUNTIME */ diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 9265c7b62cf..8fc6b2b1a58 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -28,7 +28,7 @@ #include "DNA_cloth_types.h" #include "DNA_object_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_particle_types.h" #include "DNA_scene_types.h" #include "DNA_smoke_types.h" @@ -53,6 +53,7 @@ static const EnumPropertyItem effector_shape_items[] = { #include "BLI_math_base.h" +#include "BKE_main.h" /* type specific return values only used from functions */ static const EnumPropertyItem curve_shape_items[] = { @@ -523,7 +524,7 @@ static void rna_FieldSettings_shape_update(Main *bmain, Scene *scene, PointerRNA { if (!particle_id_check(ptr)) { Object *ob = (Object *)ptr->id.data; - ED_object_check_force_modifiers(bmain, scene, ob); + ED_object_check_force_modifiers(bmain, scene, ob, bmain->eval_ctx->object_mode); WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob); WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob); } @@ -710,7 +711,7 @@ static void rna_CollisionSettings_dependency_update(Main *bmain, Scene *scene, P /* add/remove modifier as needed */ if (ob->pd->deflect && !md) - ED_object_modifier_add(NULL, bmain, scene, ob, NULL, eModifierType_Collision); + ED_object_modifier_add(NULL, bmain, scene, ob, bmain->eval_ctx->object_mode, NULL, eModifierType_Collision); else if (!ob->pd->deflect && md) ED_object_modifier_remove(NULL, bmain, ob, md); diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 12e56b8e926..14bf612f467 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -36,7 +36,7 @@ #include "DNA_modifier_types.h" #include "DNA_cloth_types.h" #include "DNA_particle_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_boid_types.h" @@ -953,6 +953,19 @@ static void rna_ParticleSettings_use_roughness_curve_update(Main *bmain, Scene * rna_Particle_redo_child(bmain, scene, ptr); } +static void rna_ParticleSettings_use_twist_curve_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + ParticleSettings *part = ptr->data; + + if (part->child_flag & PART_CHILD_USE_TWIST_CURVE) { + if (!part->twistcurve) { + BKE_particlesettings_twist_curve_init(part); + } + } + + rna_Particle_redo_child(bmain, scene, ptr); +} + static void rna_ParticleSystem_name_set(PointerRNA *ptr, const char *value) { Object *ob = ptr->id.data; @@ -1309,6 +1322,7 @@ static void rna_ParticleVGroup_name_get_8(PointerRNA *ptr, char *value) { psys_v static void rna_ParticleVGroup_name_get_9(PointerRNA *ptr, char *value) { psys_vg_name_get__internal(ptr, value, 9); } static void rna_ParticleVGroup_name_get_10(PointerRNA *ptr, char *value) { psys_vg_name_get__internal(ptr, value, 10); } static void rna_ParticleVGroup_name_get_11(PointerRNA *ptr, char *value) { psys_vg_name_get__internal(ptr, value, 11); } +static void rna_ParticleVGroup_name_get_12(PointerRNA *ptr, char *value) { psys_vg_name_get__internal(ptr, value, 12); } static int rna_ParticleVGroup_name_len_0(PointerRNA *ptr) { return psys_vg_name_len__internal(ptr, 0); } static int rna_ParticleVGroup_name_len_1(PointerRNA *ptr) { return psys_vg_name_len__internal(ptr, 1); } @@ -1322,6 +1336,7 @@ static int rna_ParticleVGroup_name_len_8(PointerRNA *ptr) { return psys_vg_name_ static int rna_ParticleVGroup_name_len_9(PointerRNA *ptr) { return psys_vg_name_len__internal(ptr, 9); } static int rna_ParticleVGroup_name_len_10(PointerRNA *ptr) { return psys_vg_name_len__internal(ptr, 10); } static int rna_ParticleVGroup_name_len_11(PointerRNA *ptr) { return psys_vg_name_len__internal(ptr, 11); } +static int rna_ParticleVGroup_name_len_12(PointerRNA *ptr) { return psys_vg_name_len__internal(ptr, 12); } static void rna_ParticleVGroup_name_set_0(PointerRNA *ptr, const char *value) { psys_vg_name_set__internal(ptr, value, 0); } static void rna_ParticleVGroup_name_set_1(PointerRNA *ptr, const char *value) { psys_vg_name_set__internal(ptr, value, 1); } @@ -1335,6 +1350,7 @@ static void rna_ParticleVGroup_name_set_8(PointerRNA *ptr, const char *value) { static void rna_ParticleVGroup_name_set_9(PointerRNA *ptr, const char *value) { psys_vg_name_set__internal(ptr, value, 9); } static void rna_ParticleVGroup_name_set_10(PointerRNA *ptr, const char *value) { psys_vg_name_set__internal(ptr, value, 10); } static void rna_ParticleVGroup_name_set_11(PointerRNA *ptr, const char *value) { psys_vg_name_set__internal(ptr, value, 11); } +static void rna_ParticleVGroup_name_set_12(PointerRNA *ptr, const char *value) { psys_vg_name_set__internal(ptr, value, 12); } #else @@ -1887,6 +1903,10 @@ static void rna_def_particle_settings_mtex(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Length", "Affect the child hair length"); RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); + prop = RNA_def_property(srna, "use_map_twist", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "mapto", PAMAP_TWIST); + RNA_def_property_ui_text(prop, "Twist", "Affect the child twist"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); /* influence factors */ prop = RNA_def_property(srna, "time_factor", PROP_FLOAT, PROP_NONE); @@ -1968,6 +1988,12 @@ static void rna_def_particle_settings_mtex(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Rough Factor", "Amount texture affects child roughness"); RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); + + prop = RNA_def_property(srna, "twist_factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "twistfac"); + RNA_def_property_ui_range(prop, 0, 1, 10, 3); + RNA_def_property_ui_text(prop, "Twist Factor", "Amount texture affects child twist"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); } static void rna_def_particle_settings(BlenderRNA *brna) @@ -2382,7 +2408,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "draw_size", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0, 1000); RNA_def_property_ui_range(prop, 0, 100, 1, -1); - RNA_def_property_ui_text(prop, "Draw Size", "Size of particles on viewport in BU (0.1 = default)"); + RNA_def_property_ui_text(prop, "Draw Size", "Size of particles on viewport in BU"); RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop = RNA_def_property(srna, "child_type", PROP_ENUM, PROP_NONE); @@ -3174,6 +3200,25 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_struct_type(prop, "FieldSettings"); RNA_def_property_pointer_funcs(prop, "rna_Particle_field2_get", NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Force Field 2", ""); + + /* twist */ + prop = RNA_def_property(srna, "twist", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, -100000.0f, 100000.0f); + RNA_def_property_ui_range(prop, -10.0f, 10.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "Twist", "Number of turns around parent allong the strand"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); + + prop = RNA_def_property(srna, "use_twist_curve", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "child_flag", PART_CHILD_USE_TWIST_CURVE); + RNA_def_property_ui_text(prop, "Use Twist Curve", "Use a curve to define twist"); + RNA_def_property_update(prop, 0, "rna_ParticleSettings_use_twist_curve_update"); + + prop = RNA_def_property(srna, "twist_curve", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "twistcurve"); + RNA_def_property_struct_type(prop, "CurveMapping"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Twist Curve", "Curve defining twist"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); } static void rna_def_particle_target(BlenderRNA *brna) @@ -3507,6 +3552,18 @@ static void rna_def_particle_system(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Vertex Group Field Negate", "Negate the effect of the field vertex group"); RNA_def_property_update(prop, 0, "rna_Particle_reset"); + prop = RNA_def_property(srna, "vertex_group_twist", PROP_STRING, PROP_NONE); + RNA_def_property_string_funcs(prop, "rna_ParticleVGroup_name_get_12", "rna_ParticleVGroup_name_len_12", + "rna_ParticleVGroup_name_set_12"); + RNA_def_property_ui_text(prop, "Vertex Group Twist", "Vertex group to control twist"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); + + prop = RNA_def_property(srna, "invert_vertex_group_twist", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_TWIST)); + RNA_def_property_ui_text(prop, "Vertex Group Twist Negate", + "Negate the effect of the twist vertex group"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); + /* pointcache */ prop = RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL); diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index 38149734bc2..8cf9bc7d39c 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -1444,6 +1444,12 @@ int rna_property_override_diff_default(PointerRNA *ptr_a, PointerRNA *ptr_b, equals = false; continue; } + else if (iter_a.ptr.type == NULL) { + /* NULL RNA pointer... */ + BLI_assert(iter_a.ptr.data == NULL); + BLI_assert(iter_b.ptr.data == NULL); + continue; + } PropertyRNA *propname = RNA_struct_name_property(iter_a.ptr.type); char propname_buff_a[256], propname_buff_b[256]; @@ -1475,10 +1481,10 @@ int rna_property_override_diff_default(PointerRNA *ptr_a, PointerRNA *ptr_b, } if (propname_a != propname_buff_a) { - MEM_freeN(propname_a); + MEM_SAFE_FREE(propname_a); } if (propname_b != propname_buff_b) { - MEM_freeN(propname_b); + MEM_SAFE_FREE(propname_b); } MEM_SAFE_FREE(extended_rna_path); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 5518b296e22..2c3f90d718b 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1703,9 +1703,10 @@ static KeyingSet *rna_Scene_keying_set_new(Scene *sce, ReportList *reports, cons static void rna_UnifiedPaintSettings_update(bContext *C, PointerRNA *UNUSED(ptr)) { + const WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - Brush *br = BKE_paint_brush(BKE_paint_get_active(scene, view_layer)); + Brush *br = BKE_paint_brush(BKE_paint_get_active(scene, view_layer, workspace->object_mode)); WM_main_add_notifier(NC_BRUSH | NA_EDITED, br); } @@ -5720,7 +5721,8 @@ static void rna_def_scene_render_data(BlenderRNA *brna) prop = RNA_def_property(srna, "filter_size", PROP_FLOAT, PROP_PIXEL); RNA_def_property_float_sdna(prop, NULL, "gauss"); - RNA_def_property_range(prop, 0.5f, 1.5f); + RNA_def_property_range(prop, 0.0f, 500.0f); + RNA_def_property_ui_range(prop, 0.01f, 10.0f, 1, 2); RNA_def_property_ui_text(prop, "Filter Size", "Width over which the reconstruction filter combines samples"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); @@ -6961,6 +6963,7 @@ void RNA_def_scene(BlenderRNA *brna) /* Statistics */ func = RNA_def_function(srna, "statistics", "ED_info_stats_string"); + parm = RNA_def_pointer(func, "workspace", "WorkSpace", "", "Active workspace"); parm = RNA_def_pointer(func, "view_layer", "ViewLayer", "", "Active layer"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); parm = RNA_def_string(func, "statistics", NULL, 0, "Statistics", ""); diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index 7d8bf4949d5..f99803a1d99 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -117,9 +117,9 @@ static void rna_Scene_frame_set(Scene *scene, Main *bmain, int frame, float subf static void rna_Scene_uvedit_aspect(Scene *scene, Object *ob, float *aspect) { - if ((ob->type == OB_MESH) && (ob->mode == OB_MODE_EDIT)) { - BMEditMesh *em; - em = BKE_editmesh_from_object(ob); + if (ob->type == OB_MESH) { + /* Will be NULL when not in editmode */ + BMEditMesh *em = BKE_editmesh_from_object(ob); if (EDBM_uv_check(em)) { ED_uvedit_get_aspect(scene, ob, em->bm, aspect, aspect + 1); return; diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c index 21a77019f32..593f5aa669d 100644 --- a/source/blender/makesrna/intern/rna_screen.c +++ b/source/blender/makesrna/intern/rna_screen.c @@ -352,11 +352,6 @@ static void rna_def_region(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Region", "Region in a subdivided screen area"); RNA_def_struct_sdna(srna, "ARegion"); - prop = RNA_def_property(srna, "id", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "swinid"); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Region ID", "Unique ID for this region"); - prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "regiontype"); RNA_def_property_enum_items(prop, rna_enum_region_type_items); diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index cc447f2a028..06c0260d08f 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -39,6 +39,7 @@ #include "DNA_brush_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" +#include "DNA_workspace_types.h" #include "BKE_paint.h" #include "BKE_material.h" @@ -107,6 +108,7 @@ const EnumPropertyItem rna_enum_symmetrize_direction_items[] = { #include "BKE_pointcache.h" #include "BKE_particle.h" #include "BKE_pbvh.h" +#include "BKE_object.h" #include "DEG_depsgraph.h" @@ -391,10 +393,12 @@ static void rna_ImaPaint_stencil_update(bContext *C, PointerRNA *UNUSED(ptr)) static void rna_ImaPaint_canvas_update(bContext *C, PointerRNA *UNUSED(ptr)) { + const WorkSpace *workspace = CTX_wm_workspace(C); Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob = OBACT(view_layer); + Object *obedit = ((workspace->object_mode & OB_MODE_EDIT) && BKE_object_is_in_editmode(ob)) ? ob : NULL; bScreen *sc; Image *ima = scene->toolsettings->imapaint.canvas; @@ -407,7 +411,7 @@ static void rna_ImaPaint_canvas_update(bContext *C, PointerRNA *UNUSED(ptr)) SpaceImage *sima = (SpaceImage *)slink; if (!sima->pin) - ED_space_image_set(sima, scene, scene->obedit, ima); + ED_space_image_set(sima, scene, obedit, ima); } } } diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 61ac81a6d1c..1d0fa7a311c 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -2160,6 +2160,7 @@ static void rna_def_wipe(StructRNA *srna) prop = RNA_def_property(srna, "transition_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "wipetype"); RNA_def_property_enum_items(prop, wipe_type_items); + RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_SEQUENCE); RNA_def_property_ui_text(prop, "Transition Type", ""); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); } diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c index ac13f9d8294..4c5c584b16b 100644 --- a/source/blender/makesrna/intern/rna_smoke.c +++ b/source/blender/makesrna/intern/rna_smoke.c @@ -42,7 +42,7 @@ #include "BKE_pointcache.h" #include "DNA_modifier_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_smoke_types.h" diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index e748299a635..a34f11f11c8 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -575,12 +575,12 @@ static void rna_SpaceView3D_layer_update(Main *bmain, Scene *UNUSED(scene), Poin DEG_on_visible_update(bmain, false); } -static void rna_SpaceView3D_viewport_shade_update(Main *bmain, Scene *scene, PointerRNA *ptr) +static void rna_SpaceView3D_viewport_shade_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { View3D *v3d = (View3D *)(ptr->data); ScrArea *sa = rna_area_from_space(ptr); - ED_view3d_shade_update(bmain, scene, v3d, sa); + ED_view3d_shade_update(bmain, v3d, sa); } static void rna_SpaceView3D_matcap_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) @@ -859,28 +859,31 @@ static int rna_SpaceImageEditor_show_uvedit_get(PointerRNA *ptr) { SpaceImage *sima = (SpaceImage *)(ptr->data); bScreen *sc = (bScreen *)ptr->id.data; - Scene *scene = ED_screen_scene_find(sc, G.main->wm.first); + wmWindow *win = ED_screen_window_find(sc, G.main->wm.first); + Object *obedit = OBEDIT_FROM_WINDOW(win); - return ED_space_image_show_uvedit(sima, scene->obedit); + return ED_space_image_show_uvedit(sima, obedit); } static int rna_SpaceImageEditor_show_maskedit_get(PointerRNA *ptr) { SpaceImage *sima = (SpaceImage *)(ptr->data); bScreen *sc = (bScreen *)ptr->id.data; - Scene *scene = ED_screen_scene_find(sc, G.main->wm.first); + wmWindow *window = NULL; + Scene *scene = ED_screen_scene_find_with_window(sc, G.main->wm.first, &window); ViewLayer *view_layer = BKE_view_layer_context_active_PLACEHOLDER(scene); - - return ED_space_image_check_show_maskedit(view_layer, sima); + const WorkSpace *workspace = WM_window_get_active_workspace(window); + return ED_space_image_check_show_maskedit(sima, workspace, view_layer); } static void rna_SpaceImageEditor_image_set(PointerRNA *ptr, PointerRNA value) { SpaceImage *sima = (SpaceImage *)(ptr->data); bScreen *sc = (bScreen *)ptr->id.data; - Scene *scene = ED_screen_scene_find(sc, G.main->wm.first); - - ED_space_image_set(sima, scene, scene->obedit, (Image *)value.data); + wmWindow *win; + Scene *scene = ED_screen_scene_find_with_window(sc, G.main->wm.first, &win); + Object *obedit = OBEDIT_FROM_WINDOW(win); + ED_space_image_set(sima, scene, obedit, (Image *)value.data); } static void rna_SpaceImageEditor_mask_set(PointerRNA *ptr, PointerRNA value) diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 42e3e2c83fb..e2e44a8ac5c 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -37,6 +37,7 @@ #include "DNA_node_types.h" #include "DNA_particle_types.h" #include "DNA_scene_types.h" /* MAXFRAME only */ +#include "DNA_workspace_types.h" #include "BLI_utildefines.h" @@ -247,10 +248,11 @@ void rna_TextureSlot_update(bContext *C, PointerRNA *ptr) break; case ID_BR: { + const WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene = CTX_data_scene(C); MTex *mtex = ptr->data; ViewLayer *view_layer = CTX_data_view_layer(C); - BKE_paint_invalidate_overlay_tex(scene, view_layer, mtex->tex); + BKE_paint_invalidate_overlay_tex(scene, view_layer, mtex->tex, workspace->object_mode); WM_main_add_notifier(NC_BRUSH, id); break; } diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 7bd1e4bb3b2..8ef70c4d108 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -364,8 +364,11 @@ static void rna_UserDef_weight_color_update(Main *bmain, Scene *scene, PointerRN vDM_ColorBand_store((U.flag & USER_CUSTOM_RANGE) ? (&U.coba_weight) : NULL, btheme->tv3d.vertex_unreferenced); for (ob = bmain->object.first; ob; ob = ob->id.next) { - if (ob->mode & OB_MODE_WEIGHT_PAINT) + /* TODO/OBMODE (not urgent) */ + // if (ob->mode & OB_MODE_WEIGHT_PAINT) + { DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + } } rna_userdef_update(bmain, scene, ptr); @@ -395,26 +398,23 @@ static void rna_userdef_autosave_update(Main *bmain, Scene *scene, PointerRNA *p static bAddon *rna_userdef_addon_new(void) { - bAddon *bext = MEM_callocN(sizeof(bAddon), "bAddon"); - BLI_addtail(&U.addons, bext); - return bext; + ListBase *addons_list = &U.addons; + bAddon *addon = BKE_addon_new(); + BLI_addtail(addons_list, addon); + return addon; } -static void rna_userdef_addon_remove(ReportList *reports, PointerRNA *path_cmp_ptr) +static void rna_userdef_addon_remove(ReportList *reports, PointerRNA *addon_ptr) { - bAddon *bext = path_cmp_ptr->data; - if (BLI_findindex(&U.addons, bext) == -1) { + ListBase *addons_list = &U.addons; + bAddon *addon = addon_ptr->data; + if (BLI_findindex(addons_list, addon) == -1) { BKE_report(reports, RPT_ERROR, "Add-on is no longer valid"); return; } - - if (bext->prop) { - IDP_FreeProperty(bext->prop); - MEM_freeN(bext->prop); - } - - BLI_freelinkN(&U.addons, bext); - RNA_POINTER_INVALIDATE(path_cmp_ptr); + BLI_remlink(addons_list, addon); + BKE_addon_free(addon); + RNA_POINTER_INVALIDATE(addon_ptr); } static bPathCompare *rna_userdef_pathcompare_new(void) diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index bcb5bb524f0..dca4fa3822d 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -473,6 +473,7 @@ const EnumPropertyItem rna_enum_wm_report_items[] = { #include "DNA_workspace_types.h" #include "ED_screen.h" +#include "ED_object.h" #include "UI_interface.h" @@ -778,28 +779,22 @@ static void rna_Window_view_layer_set(PointerRNA *ptr, PointerRNA value) BKE_workspace_view_layer_set(workspace, value.data, scene); } -#ifdef USE_WORKSPACE_MODE - -static int rna_Window_object_mode_get(PointerRNA *ptr) -{ - wmWindow *win = ptr->data; - Scene *scene = WM_window_get_active_scene(win); - WorkSpace *workspace = WM_window_get_active_workspace(win); - - return (int)BKE_workspace_object_mode_get(workspace, scene); -} - -static void rna_Window_object_mode_set(PointerRNA *ptr, int value) +static void rna_Window_view_layer_update(struct bContext *C, PointerRNA *ptr) { wmWindow *win = ptr->data; Scene *scene = WM_window_get_active_scene(win); WorkSpace *workspace = WM_window_get_active_workspace(win); + ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene); + Object *obedit = CTX_data_edit_object(C); - BKE_workspace_object_mode_set(workspace, scene, value); + eObjectMode object_mode = workspace->object_mode; + if (obedit) { + ED_object_editmode_exit(C, EM_FREEDATA); + } + workspace->object_mode = object_mode; + ED_object_base_activate(C, view_layer->basact); } -#endif /* USE_WORKSPACE_MODE */ - static PointerRNA rna_KeyMapItem_properties_get(PointerRNA *ptr) { wmKeyMapItem *kmi = ptr->data; @@ -2083,15 +2078,8 @@ static void rna_def_window(BlenderRNA *brna) RNA_def_property_struct_type(prop, "ViewLayer"); RNA_def_property_pointer_funcs(prop, "rna_Window_view_layer_get", "rna_Window_view_layer_set", NULL, NULL); RNA_def_property_ui_text(prop, "Active View Layer", "The active workspace view layer showing in the window"); - RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL); - RNA_def_property_update(prop, NC_SCREEN | ND_LAYER, NULL); - -#ifdef USE_WORKSPACE_MODE - prop = RNA_def_property(srna, "object_mode", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, rna_enum_object_mode_items); - RNA_def_property_enum_funcs(prop, "rna_Window_object_mode_get", "rna_Window_object_mode_set", NULL); - RNA_def_property_ui_text(prop, "Mode", "Object interaction mode used in this window"); -#endif + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL | PROP_CONTEXT_UPDATE); + RNA_def_property_update(prop, NC_SCREEN | ND_LAYER, "rna_Window_view_layer_update"); prop = RNA_def_property(srna, "x", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "posx"); diff --git a/source/blender/makesrna/intern/rna_workspace.c b/source/blender/makesrna/intern/rna_workspace.c index 0bed91f2807..5e0a4b97981 100644 --- a/source/blender/makesrna/intern/rna_workspace.c +++ b/source/blender/makesrna/intern/rna_workspace.c @@ -121,6 +121,10 @@ static void rna_def_workspace(BlenderRNA *brna) "rna_workspace_transform_orientations_item_get", NULL, NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Transform Orientations", ""); + prop = RNA_def_property(srna, "object_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, rna_enum_object_mode_items); + RNA_def_property_ui_text(prop, "Mode", "Object interaction mode used in this window"); + /* View Render */ prop = RNA_def_property(srna, "view_render", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL); diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index 15fa686a40a..e78355ee426 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -396,9 +396,9 @@ static void rna_def_world_mist(BlenderRNA *brna) PropertyRNA *prop; static const EnumPropertyItem falloff_items[] = { - {0, "QUADRATIC", 0, "Quadratic", "Use quadratic progression"}, - {1, "LINEAR", 0, "Linear", "Use linear progression"}, - {2, "INVERSE_QUADRATIC", 0, "Inverse Quadratic", "Use inverse quadratic progression"}, + {WO_MIST_QUADRATIC, "QUADRATIC", 0, "Quadratic", "Use quadratic progression"}, + {WO_MIST_LINEAR, "LINEAR", 0, "Linear", "Use linear progression"}, + {WO_MIST_INVERSE_QUADRATIC, "INVERSE_QUADRATIC", 0, "Inverse Quadratic", "Use inverse quadratic progression"}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index d6a7b94505f..397a3263e22 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -107,7 +107,6 @@ set(SRC intern/MOD_wireframe.c MOD_modifiertypes.h - intern/MOD_boolean_util.h intern/MOD_fluidsim_util.h intern/MOD_meshcache_util.h intern/MOD_util.h @@ -121,16 +120,6 @@ if(WITH_ALEMBIC) ) endif() -if(WITH_MOD_BOOLEAN) - add_definitions(-DWITH_MOD_BOOLEAN) - list(APPEND SRC - intern/MOD_boolean_util.c - ) - list(APPEND INC - ../../../extern/carve - ) -endif() - if(WITH_MOD_REMESH) add_definitions(-DWITH_MOD_REMESH) list(APPEND INC diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c index 0554fbb0317..7f79c941770 100644 --- a/source/blender/modifiers/intern/MOD_boolean.c +++ b/source/blender/modifiers/intern/MOD_boolean.c @@ -33,10 +33,6 @@ */ // #ifdef DEBUG_TIME -#define USE_BMESH -#ifdef WITH_MOD_BOOLEAN -# define USE_CARVE WITH_MOD_BOOLEAN -#endif #include <stdio.h> @@ -49,11 +45,9 @@ #include "BKE_library_query.h" #include "BKE_modifier.h" -#include "MOD_boolean_util.h" #include "MOD_util.h" -#ifdef USE_BMESH #include "BLI_alloca.h" #include "BLI_math_geom.h" #include "BKE_material.h" @@ -63,18 +57,16 @@ #include "bmesh.h" #include "bmesh_tools.h" #include "tools/bmesh_intersect.h" -#endif #ifdef DEBUG_TIME -#include "PIL_time.h" -#include "PIL_time_utildefines.h" +# include "PIL_time.h" +# include "PIL_time_utildefines.h" #endif static void initData(ModifierData *md) { BooleanModifierData *bmd = (BooleanModifierData *)md; - bmd->solver = eBooleanModifierSolver_BMesh; bmd->double_threshold = 1e-6f; } @@ -118,8 +110,6 @@ static void updateDepsgraph(ModifierData *md, DEG_add_object_relation(node, ob, DEG_OB_COMP_TRANSFORM, "Boolean Modifier"); } -#if defined(USE_CARVE) || defined(USE_BMESH) - static DerivedMesh *get_quick_derivedMesh( Object *ob_self, DerivedMesh *dm_self, Object *ob_other, DerivedMesh *dm_other, @@ -166,13 +156,7 @@ static DerivedMesh *get_quick_derivedMesh( return result; } -#endif /* defined(USE_CARVE) || defined(USE_BMESH) */ - -/* -------------------------------------------------------------------- */ -/* BMESH */ - -#ifdef USE_BMESH /* has no meaning for faces, do this so we can tell which face is which */ #define BM_FACE_TAG BM_ELEM_DRAW @@ -185,8 +169,8 @@ static int bm_face_isect_pair(BMFace *f, void *UNUSED(user_data)) return BM_elem_flag_test(f, BM_FACE_TAG) ? 1 : 0; } -static DerivedMesh *applyModifier_bmesh( - ModifierData *md, Object *ob, +static DerivedMesh *applyModifier( + ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *dm, ModifierApplyFlag flag) { @@ -354,66 +338,6 @@ static DerivedMesh *applyModifier_bmesh( return dm; } -#endif /* USE_BMESH */ - - -/* -------------------------------------------------------------------- */ -/* CARVE */ - -#ifdef USE_CARVE -static DerivedMesh *applyModifier_carve( - ModifierData *md, Object *ob, - DerivedMesh *derivedData, - ModifierApplyFlag flag) -{ - BooleanModifierData *bmd = (BooleanModifierData *) md; - DerivedMesh *dm; - - if (!bmd->object) - return derivedData; - - dm = get_dm_for_modifier(bmd->object, flag); - - if (dm) { - DerivedMesh *result; - - /* when one of objects is empty (has got no faces) we could speed up - * calculation a bit returning one of objects' derived meshes (or empty one) - * Returning mesh is depended on modifiers operation (sergey) */ - result = get_quick_derivedMesh(ob, derivedData, bmd->object, dm, bmd->operation); - - if (result == NULL) { -#ifdef DEBUG_TIME - TIMEIT_START(boolean_carve); -#endif - - result = NewBooleanDerivedMesh(dm, bmd->object, derivedData, ob, - 1 + bmd->operation); -#ifdef DEBUG_TIME - TIMEIT_END(boolean_carve); -#endif - } - - /* if new mesh returned, return it; otherwise there was - * an error, so delete the modifier object */ - if (result) - return result; - else - modifier_setError(md, "Cannot execute boolean operation"); - } - - return derivedData; -} -#endif /* USE_CARVE */ - - -static DerivedMesh *applyModifier_nop( - ModifierData *UNUSED(md), Object *UNUSED(ob), - DerivedMesh *derivedData, - ModifierApplyFlag UNUSED(flag)) -{ - return derivedData; -} static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md)) { @@ -424,28 +348,6 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED( return dataMask; } -static DerivedMesh *applyModifier( - ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), - Object *ob, DerivedMesh *derivedData, - ModifierApplyFlag flag) -{ - BooleanModifierData *bmd = (BooleanModifierData *)md; - - switch (bmd->solver) { -#ifdef USE_CARVE - case eBooleanModifierSolver_Carve: - return applyModifier_carve(md, ob, derivedData, flag); -#endif -#ifdef USE_BMESH - case eBooleanModifierSolver_BMesh: - return applyModifier_bmesh(md, ob, derivedData, flag); -#endif - default: - return applyModifier_nop(md, ob, derivedData, flag); - } -} - - ModifierTypeInfo modifierType_Boolean = { /* name */ "Boolean", /* structName */ "BooleanModifierData", diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c deleted file mode 100644 index 49010664aa8..00000000000 --- a/source/blender/modifiers/intern/MOD_boolean_util.c +++ /dev/null @@ -1,790 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) Blender Foundation - * All rights reserved. - * - * Contributor(s): Sergey Sharybin. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/modifiers/intern/MOD_boolean_util.c - * \ingroup modifiers - */ - -#include "MEM_guardedalloc.h" - -#include "DNA_material_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_object_types.h" - -#include "BLI_utildefines.h" -#include "BLI_alloca.h" -#include "BLI_ghash.h" -#include "BLI_math.h" - -#include "BKE_cdderivedmesh.h" -#include "BKE_material.h" - -#include "MOD_boolean_util.h" - -#include "carve-capi.h" - -/* Adopted from BM_loop_interp_from_face(), - * - * Transform matrix is used in cases when target coordinate needs - * to be converted to source space (namely when interpolating - * boolean result loops from second operand). - * - * TODO(sergey): Consider making it a generic function in DerivedMesh.c. - */ -static void DM_loop_interp_from_poly(DerivedMesh *source_dm, - MVert *source_mverts, - MLoop *source_mloops, - MPoly *source_poly, - DerivedMesh *target_dm, - MVert *target_mverts, - MLoop *target_mloop, - float transform[4][4], - int target_loop_index) -{ - float (*cos_3d)[3] = BLI_array_alloca(cos_3d, source_poly->totloop); - int *source_indices = BLI_array_alloca(source_indices, source_poly->totloop); - float *weights = BLI_array_alloca(weights, source_poly->totloop); - int i; - int target_vert_index = target_mloop[target_loop_index].v; - float coord[3]; - - for (i = 0; i < source_poly->totloop; ++i) { - MLoop *mloop = &source_mloops[source_poly->loopstart + i]; - source_indices[i] = source_poly->loopstart + i; - copy_v3_v3(cos_3d[i], source_mverts[mloop->v].co); - } - - if (transform) { - mul_v3_m4v3(coord, transform, target_mverts[target_vert_index].co); - } - else { - copy_v3_v3(coord, target_mverts[target_vert_index].co); - } - - interp_weights_poly_v3(weights, cos_3d, source_poly->totloop, coord); - - DM_interp_loop_data(source_dm, target_dm, source_indices, weights, - source_poly->totloop, target_loop_index); -} - -typedef struct DMArrays { - MVert *mvert; - MEdge *medge; - MLoop *mloop; - MPoly *mpoly; - bool mvert_allocated; - bool medge_allocated; - bool mloop_allocated; - bool mpoly_allocated; -} DMArrays; - -static void dm_arrays_get(DerivedMesh *dm, DMArrays *arrays) -{ - arrays->mvert = DM_get_vert_array(dm, &arrays->mvert_allocated); - arrays->medge = DM_get_edge_array(dm, &arrays->medge_allocated); - arrays->mloop = DM_get_loop_array(dm, &arrays->mloop_allocated); - arrays->mpoly = DM_get_poly_array(dm, &arrays->mpoly_allocated); -} - -static void dm_arrays_free(DMArrays *arrays) -{ - if (arrays->mvert_allocated) { - MEM_freeN(arrays->mvert); - } - if (arrays->medge_allocated) { - MEM_freeN(arrays->medge); - } - if (arrays->mloop_allocated) { - MEM_freeN(arrays->mloop); - } - if (arrays->mpoly_allocated) { - MEM_freeN(arrays->mpoly); - } -} - -/* **** Importer from derived mesh to Carve **** */ - -typedef struct ImportMeshData { - DerivedMesh *dm; - float obmat[4][4]; - MVert *mvert; - MEdge *medge; - MLoop *mloop; - MPoly *mpoly; -} ImportMeshData; - -/* Get number of vertices. */ -static int importer_GetNumVerts(ImportMeshData *import_data) -{ - DerivedMesh *dm = import_data->dm; - return dm->getNumVerts(dm); -} - -/* Get number of edges. */ -static int importer_GetNumEdges(ImportMeshData *import_data) -{ - DerivedMesh *dm = import_data->dm; - return dm->getNumEdges(dm); -} - -/* Get number of loops. */ -static int importer_GetNumLoops(ImportMeshData *import_data) -{ - DerivedMesh *dm = import_data->dm; - return dm->getNumLoops(dm); -} - -/* Get number of polys. */ -static int importer_GetNumPolys(ImportMeshData *import_data) -{ - DerivedMesh *dm = import_data->dm; - return dm->getNumPolys(dm); -} - -/* Get 3D coordinate of vertex with given index. */ -static void importer_GetVertCoord(ImportMeshData *import_data, int vert_index, float coord[3]) -{ - MVert *mvert = import_data->mvert; - - BLI_assert(vert_index >= 0 && vert_index < import_data->dm->getNumVerts(import_data->dm)); - - mul_v3_m4v3(coord, import_data->obmat, mvert[vert_index].co); -} - -/* Get index of vertices which are adjucent to edge specified by it's index. */ -static void importer_GetEdgeVerts(ImportMeshData *import_data, int edge_index, int *v1, int *v2) -{ - MEdge *medge = &import_data->medge[edge_index]; - - BLI_assert(edge_index >= 0 && edge_index < import_data->dm->getNumEdges(import_data->dm)); - - *v1 = medge->v1; - *v2 = medge->v2; -} - -/* Get number of adjucent vertices to the poly specified by it's index. */ -static int importer_GetPolyNumVerts(ImportMeshData *import_data, int poly_index) -{ - MPoly *mpoly = import_data->mpoly; - - BLI_assert(poly_index >= 0 && poly_index < import_data->dm->getNumPolys(import_data->dm)); - - return mpoly[poly_index].totloop; -} - -/* Get list of adjucent vertices to the poly specified by it's index. */ -static void importer_GetPolyVerts(ImportMeshData *import_data, int poly_index, int *verts) -{ - MPoly *mpoly = &import_data->mpoly[poly_index]; - MLoop *mloop = import_data->mloop + mpoly->loopstart; - int i; - BLI_assert(poly_index >= 0 && poly_index < import_data->dm->getNumPolys(import_data->dm)); - for (i = 0; i < mpoly->totloop; i++, mloop++) { - verts[i] = mloop->v; - } -} - -// Triangulate 2D polygon. -#if 0 -static int importer_triangulate2DPoly(ImportMeshData *UNUSED(import_data), - const float (*vertices)[2], int num_vertices, - unsigned int (*triangles)[3]) -{ - // TODO(sergey): Currently import_data is unused but in the future we could - // put memory arena there which will reduce amount of allocations happening - // over the triangulation period. - // - // However that's not so much straighforward to do it right now because we - // also are tu consider threaded import/export. - - BLI_assert(num_vertices > 3); - - BLI_polyfill_calc(vertices, num_vertices, triangles); - - return num_vertices - 2; -} -#endif - -static CarveMeshImporter MeshImporter = { - importer_GetNumVerts, - importer_GetNumEdges, - importer_GetNumLoops, - importer_GetNumPolys, - importer_GetVertCoord, - importer_GetEdgeVerts, - importer_GetPolyNumVerts, - importer_GetPolyVerts, - - /* TODO(sergey): We don't use BLI_polyfill_calc() because it tends - * to generate degenerated geometry which is fatal for booleans. - * - * For now we stick to Carve's triangulation. - */ - NULL, /* importer_triangulate2DPoly */ -}; - -/* **** Exporter from Carve to derived mesh **** */ - -typedef struct ExportMeshData { - DerivedMesh *dm; - float obimat[4][4]; - MVert *mvert; - MEdge *medge; - MLoop *mloop; - MPoly *mpoly; - int *vert_origindex; - int *edge_origindex; - int *poly_origindex; - int *loop_origindex; - - /* Objects and derived meshes of left and right operands. - * Used for custom data merge and interpolation. - */ - Object *ob_left; - Object *ob_right; - DerivedMesh *dm_left; - DerivedMesh *dm_right; - MVert *mvert_left; - MEdge *medge_left; - MLoop *mloop_left; - MPoly *mpoly_left; - MVert *mvert_right; - MEdge *medge_right; - MLoop *mloop_right; - MPoly *mpoly_right; - - float left_to_right_mat[4][4]; - - /* Hash to map materials from right object to result. */ - GHash *material_hash; -} ExportMeshData; - -BLI_INLINE Object *which_object(ExportMeshData *export_data, int which_mesh) -{ - Object *object = NULL; - switch (which_mesh) { - case CARVE_MESH_LEFT: - object = export_data->ob_left; - break; - case CARVE_MESH_RIGHT: - object = export_data->ob_right; - break; - } - return object; -} - -BLI_INLINE DerivedMesh *which_dm(ExportMeshData *export_data, int which_mesh) -{ - DerivedMesh *dm = NULL; - switch (which_mesh) { - case CARVE_MESH_LEFT: - dm = export_data->dm_left; - break; - case CARVE_MESH_RIGHT: - dm = export_data->dm_right; - break; - } - return dm; -} - -BLI_INLINE MVert *which_mvert(ExportMeshData *export_data, int which_mesh) -{ - MVert *mvert = NULL; - switch (which_mesh) { - case CARVE_MESH_LEFT: - mvert = export_data->mvert_left; - break; - case CARVE_MESH_RIGHT: - mvert = export_data->mvert_right; - break; - } - return mvert; -} - -BLI_INLINE MEdge *which_medge(ExportMeshData *export_data, int which_mesh) -{ - MEdge *medge = NULL; - switch (which_mesh) { - case CARVE_MESH_LEFT: - medge = export_data->medge_left; - break; - case CARVE_MESH_RIGHT: - medge = export_data->medge_right; - break; - } - return medge; -} - -BLI_INLINE MLoop *which_mloop(ExportMeshData *export_data, int which_mesh) -{ - MLoop *mloop = NULL; - switch (which_mesh) { - case CARVE_MESH_LEFT: - mloop = export_data->mloop_left; - break; - case CARVE_MESH_RIGHT: - mloop = export_data->mloop_right; - break; - } - return mloop; -} - -BLI_INLINE MPoly *which_mpoly(ExportMeshData *export_data, int which_mesh) -{ - MPoly *mpoly = NULL; - switch (which_mesh) { - case CARVE_MESH_LEFT: - mpoly = export_data->mpoly_left; - break; - case CARVE_MESH_RIGHT: - mpoly = export_data->mpoly_right; - break; - } - return mpoly; -} - -/* Create new external mesh */ -static void exporter_InitGeomArrays(ExportMeshData *export_data, - int num_verts, int num_edges, - int num_loops, int num_polys) -{ - DerivedMesh *dm = CDDM_new(num_verts, num_edges, 0, - num_loops, num_polys); - DerivedMesh *dm_left = export_data->dm_left, - *dm_right = export_data->dm_right; - - /* Mask for custom data layers to be merged from operands. */ - CustomDataMask merge_mask = CD_MASK_DERIVEDMESH & ~CD_MASK_ORIGINDEX; - - export_data->dm = dm; - export_data->mvert = dm->getVertArray(dm); - export_data->medge = dm->getEdgeArray(dm); - export_data->mloop = dm->getLoopArray(dm); - export_data->mpoly = dm->getPolyArray(dm); - - /* Merge custom data layers from operands. - * - * Will only create custom data layers for all the layers which appears in - * the operand. Data for those layers will not be allocated or initialized. - */ - - CustomData_merge(&dm_left->vertData, &dm->vertData, merge_mask, CD_DEFAULT, num_verts); - CustomData_merge(&dm_right->vertData, &dm->vertData, merge_mask, CD_DEFAULT, num_verts); - - CustomData_merge(&dm_left->loopData, &dm->loopData, merge_mask, CD_DEFAULT, num_loops); - CustomData_merge(&dm_right->loopData, &dm->loopData, merge_mask, CD_DEFAULT, num_loops); - - CustomData_merge(&dm_left->polyData, &dm->polyData, merge_mask, CD_DEFAULT, num_polys); - CustomData_merge(&dm_right->polyData, &dm->polyData, merge_mask, CD_DEFAULT, num_polys); - - CustomData_merge(&dm_left->edgeData, &dm->edgeData, merge_mask, CD_DEFAULT, num_edges); - CustomData_merge(&dm_right->edgeData, &dm->edgeData, merge_mask, CD_DEFAULT, num_edges); - - export_data->vert_origindex = dm->getVertDataArray(dm, CD_ORIGINDEX); - export_data->edge_origindex = dm->getEdgeDataArray(dm, CD_ORIGINDEX); - export_data->poly_origindex = dm->getPolyDataArray(dm, CD_ORIGINDEX); - export_data->loop_origindex = dm->getLoopDataArray(dm, CD_ORIGINDEX); -} - -/* Set coordinate of vertex with given index. */ -static void exporter_SetVert(ExportMeshData *export_data, - int vert_index, float coord[3], - int which_orig_mesh, int orig_vert_index) -{ - DerivedMesh *dm = export_data->dm; - DerivedMesh *dm_orig; - MVert *mvert = export_data->mvert; - - BLI_assert(vert_index >= 0 && vert_index <= dm->getNumVerts(dm)); - - dm_orig = which_dm(export_data, which_orig_mesh); - if (dm_orig) { - BLI_assert(orig_vert_index >= 0 && orig_vert_index < dm_orig->getNumVerts(dm_orig)); - mvert[vert_index] = which_mvert(export_data, which_orig_mesh)[orig_vert_index]; - CustomData_copy_data(&dm_orig->vertData, &dm->vertData, orig_vert_index, vert_index, 1); - } - - /* Set original index of the vertex. */ - if (export_data->vert_origindex) { - if (which_orig_mesh == CARVE_MESH_LEFT) { - export_data->vert_origindex[vert_index] = orig_vert_index; - } - else { - export_data->vert_origindex[vert_index] = ORIGINDEX_NONE; - } - } - - mul_v3_m4v3(mvert[vert_index].co, export_data->obimat, coord); -} - -/* Set vertices which are adjucent to the edge specified by it's index. */ -static void exporter_SetEdge(ExportMeshData *export_data, - int edge_index, int v1, int v2, - int which_orig_mesh, int orig_edge_index) -{ - DerivedMesh *dm = export_data->dm; - MEdge *medge = &export_data->medge[edge_index]; - DerivedMesh *dm_orig; - - BLI_assert(edge_index >= 0 && edge_index < dm->getNumEdges(dm)); - BLI_assert(v1 >= 0 && v1 < dm->getNumVerts(dm)); - BLI_assert(v2 >= 0 && v2 < dm->getNumVerts(dm)); - - dm_orig = which_dm(export_data, which_orig_mesh); - if (dm_orig) { - BLI_assert(orig_edge_index >= 0 && orig_edge_index < dm_orig->getNumEdges(dm_orig)); - - *medge = which_medge(export_data, which_orig_mesh)[orig_edge_index]; - - /* Copy all edge layers, including medge. */ - CustomData_copy_data(&dm_orig->edgeData, &dm->edgeData, orig_edge_index, edge_index, 1); - } - - /* Set original index of the edge. */ - if (export_data->edge_origindex) { - if (which_orig_mesh == CARVE_MESH_LEFT) { - export_data->edge_origindex[edge_index] = orig_edge_index; - } - else { - export_data->edge_origindex[edge_index] = ORIGINDEX_NONE; - } - } - - medge->v1 = v1; - medge->v2 = v2; - - medge->flag |= ME_EDGEDRAW | ME_EDGERENDER; -} - -static void setMPolyMaterial(ExportMeshData *export_data, - MPoly *mpoly, - int which_orig_mesh) -{ - Object *orig_object; - GHash *material_hash; - Material *orig_mat; - - if (which_orig_mesh == CARVE_MESH_LEFT) { - /* No need to change materian index for faces from left operand */ - return; - } - - material_hash = export_data->material_hash; - orig_object = which_object(export_data, which_orig_mesh); - - /* Set material, based on lookup in hash table. */ - orig_mat = give_current_material(orig_object, mpoly->mat_nr + 1); - - if (orig_mat) { - /* For faces from right operand check if there's requested material - * in the left operand. And if it is, use index of that material, - * otherwise fallback to first material (material with index=0). - */ - if (!BLI_ghash_haskey(material_hash, orig_mat)) { - int a, mat_nr; - - mat_nr = 0; - for (a = 0; a < export_data->ob_left->totcol; a++) { - if (give_current_material(export_data->ob_left, a + 1) == orig_mat) { - mat_nr = a; - break; - } - } - - BLI_ghash_insert(material_hash, orig_mat, SET_INT_IN_POINTER(mat_nr)); - - mpoly->mat_nr = mat_nr; - } - else - mpoly->mat_nr = GET_INT_FROM_POINTER(BLI_ghash_lookup(material_hash, orig_mat)); - } - else { - mpoly->mat_nr = 0; - } -} - -/* Set list of adjucent loops to the poly specified by it's index. */ -static void exporter_SetPoly(ExportMeshData *export_data, - int poly_index, int start_loop, int num_loops, - int which_orig_mesh, int orig_poly_index) -{ - DerivedMesh *dm = export_data->dm; - MPoly *mpoly = &export_data->mpoly[poly_index]; - DerivedMesh *dm_orig; - int i; - - /* Poly is always to be either from left or right operand. */ - dm_orig = which_dm(export_data, which_orig_mesh); - - BLI_assert(poly_index >= 0 && poly_index < dm->getNumPolys(dm)); - BLI_assert(start_loop >= 0 && start_loop <= dm->getNumLoops(dm) - num_loops); - BLI_assert(num_loops >= 3); - BLI_assert(dm_orig != NULL); - BLI_assert(orig_poly_index >= 0 && orig_poly_index < dm_orig->getNumPolys(dm_orig)); - - /* Copy all poly layers, including mpoly. */ - *mpoly = which_mpoly(export_data, which_orig_mesh)[orig_poly_index]; - CustomData_copy_data(&dm_orig->polyData, &dm->polyData, orig_poly_index, poly_index, 1); - - /* Set material of the curren poly. - * This would re-map materials from right operand to materials from the - * left one as well. - */ - setMPolyMaterial(export_data, mpoly, which_orig_mesh); - - /* Set original index of the poly. */ - if (export_data->poly_origindex) { - if (which_orig_mesh == CARVE_MESH_LEFT) { - export_data->poly_origindex[poly_index] = orig_poly_index; - } - else { - export_data->poly_origindex[poly_index] = ORIGINDEX_NONE; - } - } - - /* Set poly data itself. */ - mpoly->loopstart = start_loop; - mpoly->totloop = num_loops; - - /* Interpolate data for poly loops. */ - { - MVert *source_mverts = which_mvert(export_data, which_orig_mesh); - MLoop *source_mloops = which_mloop(export_data, which_orig_mesh); - MPoly *source_mpolys = which_mpoly(export_data, which_orig_mesh); - MPoly *source_poly = &source_mpolys[orig_poly_index]; - MVert *target_mverts = export_data->mvert; - MLoop *target_mloops = export_data->mloop; - float (*transform)[4] = NULL; - - if (which_orig_mesh == CARVE_MESH_RIGHT) { - transform = export_data->left_to_right_mat; - } - - for (i = 0; i < mpoly->totloop; i++) { - DM_loop_interp_from_poly(dm_orig, - source_mverts, - source_mloops, - source_poly, - dm, - target_mverts, - target_mloops, - transform, - i + mpoly->loopstart); - } - } -} - -/* Set list vertex and edge which are adjucent to loop with given index. */ -static void exporter_SetLoop(ExportMeshData *export_data, - int loop_index, int vertex, int edge, - int which_orig_mesh, int orig_loop_index) -{ - DerivedMesh *dm = export_data->dm; - MLoop *mloop = &export_data->mloop[loop_index]; - DerivedMesh *dm_orig; - - BLI_assert(loop_index >= 0 && loop_index < dm->getNumLoops(dm)); - BLI_assert(vertex >= 0 && vertex < dm->getNumVerts(dm)); - BLI_assert(edge >= 0 && vertex < dm->getNumEdges(dm)); - - dm_orig = which_dm(export_data, which_orig_mesh); - if (dm_orig) { - BLI_assert(orig_loop_index >= 0 && orig_loop_index < dm_orig->getNumLoops(dm_orig)); - - /* Copy all loop layers, including mloop. */ - *mloop = which_mloop(export_data, which_orig_mesh)[orig_loop_index]; - CustomData_copy_data(&dm_orig->loopData, &dm->loopData, orig_loop_index, loop_index, 1); - } - - /* Set original index of the loop. */ - if (export_data->loop_origindex) { - if (which_orig_mesh == CARVE_MESH_LEFT) { - export_data->loop_origindex[loop_index] = orig_loop_index; - } - else { - export_data->loop_origindex[loop_index] = ORIGINDEX_NONE; - } - } - - mloop->v = vertex; - mloop->e = edge; -} - -/* Edge index from a loop index for a given original mesh. */ -static int exporter_MapLoopToEdge(ExportMeshData *export_data, - int which_mesh, int loop_index) -{ - DerivedMesh *dm = which_dm(export_data, which_mesh); - MLoop *mloop = which_mloop(export_data, which_mesh); - - (void) dm; /* Unused in release builds. */ - - BLI_assert(dm != NULL); - BLI_assert(loop_index >= 0 && loop_index < dm->getNumLoops(dm)); - - return mloop[loop_index].e; -} - -static CarveMeshExporter MeshExporter = { - exporter_InitGeomArrays, - exporter_SetVert, - exporter_SetEdge, - exporter_SetPoly, - exporter_SetLoop, - exporter_MapLoopToEdge -}; - -static int operation_from_optype(int int_op_type) -{ - int operation; - - switch (int_op_type) { - case 1: - operation = CARVE_OP_INTERSECTION; - break; - case 2: - operation = CARVE_OP_UNION; - break; - case 3: - operation = CARVE_OP_A_MINUS_B; - break; - default: - BLI_assert(!"Should not happen"); - operation = -1; - break; - } - - return operation; -} - -static void prepare_import_data(Object *object, - DerivedMesh *dm, - const DMArrays *dm_arrays, - ImportMeshData *import_data) -{ - import_data->dm = dm; - copy_m4_m4(import_data->obmat, object->obmat); - import_data->mvert = dm_arrays->mvert; - import_data->medge = dm_arrays->medge; - import_data->mloop = dm_arrays->mloop; - import_data->mpoly = dm_arrays->mpoly; -} - -static struct CarveMeshDescr *carve_mesh_from_dm(Object *object, - DerivedMesh *dm, - const DMArrays *dm_arrays) -{ - ImportMeshData import_data; - prepare_import_data(object, dm, dm_arrays, &import_data); - return carve_addMesh(&import_data, &MeshImporter); -} - -static void prepare_export_data(Object *object_left, DerivedMesh *dm_left, const DMArrays *dm_left_arrays, - Object *object_right, DerivedMesh *dm_right, const DMArrays *dm_right_arrays, - ExportMeshData *export_data) -{ - float object_right_imat[4][4]; - - invert_m4_m4(export_data->obimat, object_left->obmat); - - export_data->ob_left = object_left; - export_data->ob_right = object_right; - - export_data->dm_left = dm_left; - export_data->dm_right = dm_right; - - export_data->mvert_left = dm_left_arrays->mvert; - export_data->medge_left = dm_left_arrays->medge; - export_data->mloop_left = dm_left_arrays->mloop; - export_data->mpoly_left = dm_left_arrays->mpoly; - export_data->mvert_right = dm_right_arrays->mvert; - export_data->medge_right = dm_right_arrays->medge; - export_data->mloop_right = dm_right_arrays->mloop; - export_data->mpoly_right = dm_right_arrays->mpoly; - - export_data->material_hash = BLI_ghash_ptr_new("CSG_mat gh"); - - /* Matrix to convert coord from left object's loca; space to - * right object's local space. - */ - invert_m4_m4(object_right_imat, object_right->obmat); - mul_m4_m4m4(export_data->left_to_right_mat, object_left->obmat, - object_right_imat); -} - -DerivedMesh *NewBooleanDerivedMesh(DerivedMesh *dm, struct Object *ob, - DerivedMesh *dm_select, struct Object *ob_select, - int int_op_type) -{ - - struct CarveMeshDescr *left, *right, *output = NULL; - DerivedMesh *output_dm = NULL; - int operation; - bool result; - DMArrays dm_left_arrays, dm_right_arrays; - - if (dm == NULL || dm_select == NULL) { - return NULL; - } - - operation = operation_from_optype(int_op_type); - if (operation == -1) { - return NULL; - } - - dm_arrays_get(dm_select, &dm_left_arrays); - dm_arrays_get(dm, &dm_right_arrays); - - left = carve_mesh_from_dm(ob_select, dm_select, &dm_left_arrays); - right = carve_mesh_from_dm(ob, dm, &dm_right_arrays); - - result = carve_performBooleanOperation(left, right, operation, &output); - - carve_deleteMesh(left); - carve_deleteMesh(right); - - if (result) { - ExportMeshData export_data; - - prepare_export_data(ob_select, dm_select, &dm_left_arrays, - ob, dm, &dm_right_arrays, - &export_data); - - carve_exportMesh(output, &MeshExporter, &export_data); - output_dm = export_data.dm; - - /* Free memory used by export mesh. */ - BLI_ghash_free(export_data.material_hash, NULL, NULL); - - output_dm->cd_flag |= dm->cd_flag | dm_select->cd_flag; - output_dm->dirty |= DM_DIRTY_NORMALS; - carve_deleteMesh(output); - } - - dm_arrays_free(&dm_left_arrays); - dm_arrays_free(&dm_right_arrays); - - return output_dm; -} diff --git a/source/blender/modifiers/intern/MOD_boolean_util.h b/source/blender/modifiers/intern/MOD_boolean_util.h deleted file mode 100644 index 00d7c37b266..00000000000 --- a/source/blender/modifiers/intern/MOD_boolean_util.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/modifiers/intern/MOD_boolean_util.h - * \ingroup modifiers - */ - - -#ifndef __MOD_BOOLEAN_UTIL_H__ -#define __MOD_BOOLEAN_UTIL_H__ - -struct Object; -struct DerivedMesh; - -/* Performs a boolean between two mesh objects, it is assumed that both objects - * are in fact mesh object. On success returns a DerivedMesh. On failure - * returns NULL and reports an error. */ - -struct DerivedMesh *NewBooleanDerivedMesh(struct DerivedMesh *dm, struct Object *ob, - struct DerivedMesh *dm_select, struct Object *ob_select, int int_op_type); - -#endif /* MOD_BOOLEAN_UTILS */ diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c index 7a52ede8838..2e0b13b0603 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.c @@ -154,7 +154,7 @@ static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationConte numLoops_dst += mp->totloop; } - BLI_assert(hash_num == BLI_ghash_size(vertHash)); + BLI_assert(hash_num == BLI_ghash_len(vertHash)); /* get the set of edges that will be in the new mesh (i.e. all edges * that have both verts in the new mesh) @@ -187,7 +187,7 @@ static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationConte */ medge = medge_src; hash_num = 0; - BLI_assert(hash_num == BLI_ghash_size(vertHash)); + BLI_assert(hash_num == BLI_ghash_len(vertHash)); for (i = 0; i < numEdges_dst; i++) { void **val_p; me = medge + edgeMap[i]; @@ -201,11 +201,11 @@ static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationConte hash_num++; } } - BLI_assert(hash_num == BLI_ghash_size(vertHash)); + BLI_assert(hash_num == BLI_ghash_len(vertHash)); /* get the set of edges that will be in the new mesh */ for (i = 0; i < numEdges_dst; i++) { - j = BLI_ghash_size(edgeHash); + j = BLI_ghash_len(edgeHash); BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(j), SET_INT_IN_POINTER(edgeMap[i])); @@ -232,8 +232,8 @@ static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationConte /* now we know the number of verts, edges and faces, we can create * the mesh */ - result = CDDM_from_template(dm, BLI_ghash_size(vertHash), - BLI_ghash_size(edgeHash), 0, numLoops_dst, numFaces_dst); + result = CDDM_from_template(dm, BLI_ghash_len(vertHash), + BLI_ghash_len(edgeHash), 0, numLoops_dst, numFaces_dst); /* copy the vertices across */ GHASH_ITER (gh_iter, vertHash) { @@ -250,7 +250,7 @@ static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationConte } /* copy the edges across, remapping indices */ - for (i = 0; i < BLI_ghash_size(edgeHash); i++) { + for (i = 0; i < BLI_ghash_len(edgeHash); i++) { MEdge source; MEdge *dest; int oldIndex = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(i))); diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c index cf3f84364ea..da5d9a29be5 100644 --- a/source/blender/modifiers/intern/MOD_dynamicpaint.c +++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c @@ -29,7 +29,7 @@ #include "DNA_dynamicpaint_types.h" #include "DNA_object_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_scene_types.h" #include "BLI_utildefines.h" diff --git a/source/blender/modifiers/intern/MOD_fluidsim.c b/source/blender/modifiers/intern/MOD_fluidsim.c index f9e7f10653b..75f57de2a37 100644 --- a/source/blender/modifiers/intern/MOD_fluidsim.c +++ b/source/blender/modifiers/intern/MOD_fluidsim.c @@ -34,7 +34,7 @@ #include "DNA_scene_types.h" -#include "DNA_object_fluidsim.h" +#include "DNA_object_fluidsim_types.h" #include "DNA_object_types.h" #include "BLI_utildefines.h" diff --git a/source/blender/modifiers/intern/MOD_fluidsim_util.c b/source/blender/modifiers/intern/MOD_fluidsim_util.c index c9f475ad228..65f45c9af64 100644 --- a/source/blender/modifiers/intern/MOD_fluidsim_util.c +++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c @@ -40,7 +40,7 @@ #include "DNA_scene_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" -#include "DNA_object_fluidsim.h" +#include "DNA_object_fluidsim_types.h" #include "BLI_blenlib.h" #include "BLI_math.h" diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index da233a18d0a..e8fc832b597 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -49,6 +49,8 @@ #include "MEM_guardedalloc.h" +#include "DEG_depsgraph.h" + #include "MOD_util.h" #ifdef __SSE2__ @@ -300,7 +302,7 @@ static void meshdeformModifier_do( * * We'll support this case once granular dependency graph is landed. */ - if (mmd->object == md->scene->obedit) { + if (mmd->object == OBEDIT_FROM_EVAL_CTX(eval_ctx)) { BMEditMesh *em = BKE_editmesh_from_object(mmd->object); tmpdm = editbmesh_get_derived_cage_and_final(eval_ctx, md->scene, mmd->object, em, 0, &cagedm); if (tmpdm) diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index 2b675d36140..6704526ea03 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -48,6 +48,8 @@ #include "MOD_modifiertypes.h" +#include "DEG_depsgraph.h" + static void initData(ModifierData *md) { MultiresModifierData *mmd = (MultiresModifierData *)md; @@ -67,7 +69,7 @@ static void copyData(ModifierData *md, ModifierData *target) modifier_copyData_generic(md, target); } -static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, +static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *eval_ctx, Object *ob, DerivedMesh *dm, ModifierApplyFlag flag) { MultiresModifierData *mmd = (MultiresModifierData *)md; @@ -94,7 +96,7 @@ static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationConte if (ignore_simplify) flags |= MULTIRES_IGNORE_SIMPLIFY; - result = multires_make_derived_from_derived(dm, mmd, ob, flags); + result = multires_make_derived_from_derived(dm, mmd, ob, flags, eval_ctx->object_mode); if (result == dm) return dm; diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c index c87fdd321ab..8b9a7c42eb2 100644 --- a/source/blender/modifiers/intern/MOD_shrinkwrap.c +++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c @@ -103,7 +103,7 @@ static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, walk(userData, ob, &smd->auxTarget, IDWALK_CB_NOP); } -static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), +static void deformVerts(ModifierData *md, const struct EvaluationContext *eval_ctx, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, @@ -118,13 +118,13 @@ static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED dm = get_cddm(ob, NULL, dm, vertexCos, dependsOnNormals(md)); } - shrinkwrapModifier_deform((ShrinkwrapModifierData *)md, ob, dm, vertexCos, numVerts, forRender); + shrinkwrapModifier_deform(eval_ctx, (ShrinkwrapModifierData *)md, ob, dm, vertexCos, numVerts, forRender); if (dm != derivedData) dm->release(dm); } -static void deformVertsEM(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, +static void deformVertsEM(ModifierData *md, const struct EvaluationContext *eval_ctx, Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { @@ -136,7 +136,7 @@ static void deformVertsEM(ModifierData *md, const struct EvaluationContext *UNUS dm = get_cddm(ob, editData, dm, vertexCos, dependsOnNormals(md)); } - shrinkwrapModifier_deform((ShrinkwrapModifierData *)md, ob, dm, vertexCos, numVerts, false); + shrinkwrapModifier_deform(eval_ctx, (ShrinkwrapModifierData *)md, ob, dm, vertexCos, numVerts, false); if (dm != derivedData) dm->release(dm); diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index 97afe6d5e87..d2d8da289b7 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -1470,7 +1470,7 @@ static void hull_merge_triangles(SkinOutput *so, const SkinModifierData *smd) while (!BLI_heap_is_empty(heap)) { BMFace *adj[2]; - e = BLI_heap_popmin(heap); + e = BLI_heap_pop_min(heap); if (BM_edge_face_pair(e, &adj[0], &adj[1])) { /* If both triangles still free, and if they don't already diff --git a/source/blender/modifiers/intern/MOD_smoke.c b/source/blender/modifiers/intern/MOD_smoke.c index e66afe07841..9881d7ee9b9 100644 --- a/source/blender/modifiers/intern/MOD_smoke.c +++ b/source/blender/modifiers/intern/MOD_smoke.c @@ -41,7 +41,7 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_smoke_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "BLI_utildefines.h" diff --git a/source/blender/modifiers/intern/MOD_softbody.c b/source/blender/modifiers/intern/MOD_softbody.c index 020dd3da6a5..d0b1d7361cc 100644 --- a/source/blender/modifiers/intern/MOD_softbody.c +++ b/source/blender/modifiers/intern/MOD_softbody.c @@ -35,7 +35,7 @@ #include <stdio.h> #include "DNA_scene_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "BLI_utildefines.h" diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index a09923d6dfe..8fd510a6662 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -117,7 +117,7 @@ static DerivedMesh *applyModifier(ModifierData *md, const EvaluationContext *eva subsurf_flags |= SUBSURF_USE_RENDER_PARAMS; if (isFinalCalc) subsurf_flags |= SUBSURF_IS_FINAL_CALC; - if (ob->mode & OB_MODE_EDIT) + if (eval_ctx->object_mode & OB_MODE_EDIT) subsurf_flags |= SUBSURF_IN_EDIT_MODE; #ifdef WITH_OPENSUBDIV @@ -132,7 +132,7 @@ static DerivedMesh *applyModifier(ModifierData *md, const EvaluationContext *eva if (U.opensubdiv_compute_type == USER_OPENSUBDIV_COMPUTE_NONE) { modifier_setError(md, "OpenSubdiv is disabled in User Preferences"); } - else if ((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) != 0) { + else if ((eval_ctx->object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) != 0) { modifier_setError(md, "OpenSubdiv is not supported in paint modes"); } else if ((DEG_get_eval_flags_for_id(eval_ctx->depsgraph, &ob->id) & DAG_EVAL_NEED_CPU) == 0) { @@ -143,6 +143,8 @@ static DerivedMesh *applyModifier(ModifierData *md, const EvaluationContext *eva modifier_setError(md, "OpenSubdiv is disabled due to dependencies"); } } +#else + UNUSED_VARS(ob); #endif result = subsurf_make_derived_from_derived(derivedData, smd, NULL, subsurf_flags); diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c index 046a0ab27bf..85347288872 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.c +++ b/source/blender/modifiers/intern/MOD_surfacedeform.c @@ -11,6 +11,8 @@ #include "BKE_library_query.h" #include "BKE_modifier.h" +#include "DEG_depsgraph.h" + #include "MEM_guardedalloc.h" #include "MOD_util.h" @@ -1097,7 +1099,9 @@ static void deformVert( } } -static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], unsigned int numverts, Object *ob) +static void surfacedeformModifier_do( + ModifierData *md, const EvaluationContext *eval_ctx, + float (*vertexCos)[3], unsigned int numverts, Object *ob) { SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; DerivedMesh *tdm; @@ -1110,7 +1114,7 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un } /* Handle target mesh both in and out of edit mode */ - if (smd->target == md->scene->obedit) { + if (smd->target == OBEDIT_FROM_EVAL_CTX(eval_ctx)) { BMEditMesh *em = BKE_editmesh_from_object(smd->target); tdm = em->derivedFinal; } @@ -1180,20 +1184,22 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un } } -static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), - Object *ob, DerivedMesh *UNUSED(derivedData), - float (*vertexCos)[3], int numVerts, - ModifierApplyFlag UNUSED(flag)) +static void deformVerts( + ModifierData *md, const struct EvaluationContext *eval_ctx, + Object *ob, DerivedMesh *UNUSED(derivedData), + float (*vertexCos)[3], int numVerts, + ModifierApplyFlag UNUSED(flag)) { - surfacedeformModifier_do(md, vertexCos, numVerts, ob); + surfacedeformModifier_do(md, eval_ctx, vertexCos, numVerts, ob); } -static void deformVertsEM(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), - Object *ob, struct BMEditMesh *UNUSED(editData), - DerivedMesh *UNUSED(derivedData), - float (*vertexCos)[3], int numVerts) +static void deformVertsEM( + ModifierData *md, const struct EvaluationContext *eval_ctx, + Object *ob, struct BMEditMesh *UNUSED(editData), + DerivedMesh *UNUSED(derivedData), + float (*vertexCos)[3], int numVerts) { - surfacedeformModifier_do(md, vertexCos, numVerts, ob); + surfacedeformModifier_do(md, eval_ctx, vertexCos, numVerts, ob); } static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams)) diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index c83daa185a8..230918776dc 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -32,6 +32,7 @@ set(INC ../blenkernel ../blenlib ../blentranslation + ../depsgraph ../gpu ../imbuf ../makesdna @@ -195,6 +196,7 @@ set(SRC shader/nodes/node_shader_tangent.c shader/nodes/node_shader_bevel.c shader/nodes/node_shader_displacement.c + shader/nodes/node_shader_vector_displacement.c shader/nodes/node_shader_tex_brick.c shader/nodes/node_shader_tex_checker.c shader/nodes/node_shader_tex_coord.c diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h index cbdfd8d3dbf..bb9f9881e33 100644 --- a/source/blender/nodes/NOD_shader.h +++ b/source/blender/nodes/NOD_shader.h @@ -80,6 +80,7 @@ void register_node_type_sh_tex_pointdensity(void); void register_node_type_sh_attribute(void); void register_node_type_sh_bevel(void); void register_node_type_sh_displacement(void); +void register_node_type_sh_vector_displacement(void); void register_node_type_sh_geometry(void); void register_node_type_sh_light_path(void); void register_node_type_sh_light_falloff(void); diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index e2c1fae1bde..394e141647e 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -128,7 +128,8 @@ DefNode( ShaderNode, SH_NODE_UVALONGSTROKE, def_sh_uvalongstroke, "UV DefNode( ShaderNode, SH_NODE_SEPXYZ, 0, "SEPXYZ", SeparateXYZ, "Separate XYZ", "" ) DefNode( ShaderNode, SH_NODE_COMBXYZ, 0, "COMBXYZ", CombineXYZ, "Combine XYZ", "" ) DefNode( ShaderNode, SH_NODE_BEVEL, def_sh_bevel, "BEVEL", Bevel, "Bevel", "" ) -DefNode( ShaderNode, SH_NODE_DISPLACEMENT, 0, "DISPLACEMENT", Displacement, "Displacement", "" ) +DefNode( ShaderNode, SH_NODE_DISPLACEMENT, def_sh_displacement, "DISPLACEMENT", Displacement, "Displacement", "" ) +DefNode( ShaderNode, SH_NODE_VECTOR_DISPLACEMENT,def_sh_vector_displacement,"VECTOR_DISPLACEMENT",VectorDisplacement,"Vector Displacement","" ) DefNode( CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" ) DefNode( CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" ) diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c index 2f65188841e..fd30df4293e 100644 --- a/source/blender/nodes/shader/node_shader_tree.c +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -736,10 +736,10 @@ bool ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr) /* ensure execdata is only initialized once */ if (!exec) { - BLI_lock_thread(LOCK_NODES); + BLI_thread_lock(LOCK_NODES); if (!ntree->execdata) ntree->execdata = ntreeShaderBeginExecTree(ntree); - BLI_unlock_thread(LOCK_NODES); + BLI_thread_unlock(LOCK_NODES); exec = ntree->execdata; } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c index b0ca4128d19..1c291cb5b83 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c @@ -61,6 +61,7 @@ static bNodeSocketTemplate sh_node_bsdf_principled_out[] = { static void node_shader_init_principled(bNodeTree *UNUSED(ntree), bNode *node) { node->custom1 = SHD_GLOSSY_MULTI_GGX; + node->custom2 = SHD_SUBSURFACE_BURLEY; } static int node_shader_gpu_bsdf_principled(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) diff --git a/source/blender/nodes/shader/nodes/node_shader_displacement.c b/source/blender/nodes/shader/nodes/node_shader_displacement.c index d5c191b3966..c26968e8d14 100644 --- a/source/blender/nodes/shader/nodes/node_shader_displacement.c +++ b/source/blender/nodes/shader/nodes/node_shader_displacement.c @@ -31,6 +31,7 @@ static bNodeSocketTemplate sh_node_displacement_in[] = { { SOCK_FLOAT, 0, N_("Height"), 0.00f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, + { SOCK_FLOAT, 0, N_("Midlevel"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, { SOCK_FLOAT, 0, N_("Scale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } @@ -41,13 +42,30 @@ static bNodeSocketTemplate sh_node_displacement_out[] = { { -1, 0, "" } }; +static void node_shader_init_displacement(bNodeTree *UNUSED(ntree), bNode *node) +{ + node->custom1 = SHD_SPACE_OBJECT; /* space */ + + /* Set default value here for backwards compatibility. */ + for (bNodeSocket *sock = node->inputs.first; sock; sock = sock->next) { + if (STREQ(sock->name, "Midlevel")) { + ((bNodeSocketValueFloat *)sock->default_value)->value = 0.5f; + } + } +} + static int gpu_shader_displacement(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { - if (!in[2].link) { - GPU_link(mat, "direction_transform_m4v3", GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &in[2].link); + if (!in[3].link) { + GPU_link(mat, "direction_transform_m4v3", GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &in[3].link); } - return GPU_stack_link(mat, node, "node_displacement", in, out); + if (node->custom1 == SHD_SPACE_OBJECT) { + return GPU_stack_link(mat, node, "node_displacement_object", in, out, GPU_builtin(GPU_OBJECT_MATRIX)); + } + else { + return GPU_stack_link(mat, node, "node_displacement_world", in, out, GPU_builtin(GPU_OBJECT_MATRIX)); + } } /* node type definition */ @@ -59,6 +77,7 @@ void register_node_type_sh_displacement(void) node_type_compatibility(&ntype, NODE_NEW_SHADING); node_type_socket_templates(&ntype, sh_node_displacement_in, sh_node_displacement_out); node_type_storage(&ntype, "", NULL, NULL); + node_type_init(&ntype, node_shader_init_displacement); node_type_gpu(&ntype, gpu_shader_displacement); nodeRegisterType(&ntype); diff --git a/source/blender/nodes/shader/nodes/node_shader_hair_info.c b/source/blender/nodes/shader/nodes/node_shader_hair_info.c index 63adba750cf..6a15c59aa5b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_hair_info.c +++ b/source/blender/nodes/shader/nodes/node_shader_hair_info.c @@ -33,6 +33,7 @@ static bNodeSocketTemplate outputs[] = { { SOCK_FLOAT, 0, N_("Thickness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_VECTOR, 0, N_("Tangent Normal"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, /*{ SOCK_FLOAT, 0, N_("Fade"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},*/ + { SOCK_FLOAT, 0, N_("Random") }, { -1, 0, "" } }; diff --git a/source/blender/nodes/shader/nodes/node_shader_normal_map.c b/source/blender/nodes/shader/nodes/node_shader_normal_map.c index 36d7522e3e6..7584b5eba4d 100644 --- a/source/blender/nodes/shader/nodes/node_shader_normal_map.c +++ b/source/blender/nodes/shader/nodes/node_shader_normal_map.c @@ -68,7 +68,7 @@ static void node_shader_exec_normal_map( float *N = shi->nmapnorm; int uv_index = 0; switch (nm->space) { - case SHD_NORMAL_MAP_TANGENT: + case SHD_SPACE_TANGENT: if (nm->uv_map[0]) { /* find uv map by name */ for (int i = 0; i < shi->totuv; i++) { @@ -96,8 +96,8 @@ static void node_shader_exec_normal_map( } break; - case SHD_NORMAL_MAP_OBJECT: - case SHD_NORMAL_MAP_BLENDER_OBJECT: + case SHD_SPACE_OBJECT: + case SHD_SPACE_BLENDER_OBJECT: if (shi->use_world_space_shading) { mul_mat3_m4_v3((float (*)[4])RE_object_instance_get_matrix(shi->obi, RE_OBJECT_INSTANCE_MATRIX_OB), vecIn); mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), N); @@ -107,8 +107,8 @@ static void node_shader_exec_normal_map( interp_v3_v3v3(out[0]->vec, N, vecIn, strength); break; - case SHD_NORMAL_MAP_WORLD: - case SHD_NORMAL_MAP_BLENDER_WORLD: + case SHD_SPACE_WORLD: + case SHD_SPACE_BLENDER_WORLD: if (shi->use_world_space_shading) mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), N); else @@ -150,10 +150,10 @@ static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *U /* ******* CYCLES or BLENDER INTERNAL with world space shading flag ******* */ const char *color_to_normal_fnc_name = "color_to_normal_new_shading"; - if (nm->space == SHD_NORMAL_MAP_BLENDER_OBJECT || nm->space == SHD_NORMAL_MAP_BLENDER_WORLD || !GPU_material_use_new_shading_nodes(mat)) + if (nm->space == SHD_SPACE_BLENDER_OBJECT || nm->space == SHD_SPACE_BLENDER_WORLD || !GPU_material_use_new_shading_nodes(mat)) color_to_normal_fnc_name = "color_to_blender_normal_new_shading"; switch (nm->space) { - case SHD_NORMAL_MAP_TANGENT: + case SHD_SPACE_TANGENT: GPU_link(mat, "color_to_normal_new_shading", realnorm, &realnorm); GPU_link(mat, "node_normal_map", GPU_attribute(CD_TANGENT, nm->uv_map), negnorm, realnorm, &realnorm); GPU_link(mat, "vec_math_mix", strength, realnorm, GPU_builtin(GPU_VIEW_NORMAL), &out[0].link); @@ -161,14 +161,14 @@ static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *U GPU_link(mat, "direction_transform_m4v3", out[0].link, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &out[0].link); GPU_link(mat, "vect_normalize", out[0].link, &out[0].link); return true; - case SHD_NORMAL_MAP_OBJECT: - case SHD_NORMAL_MAP_BLENDER_OBJECT: + case SHD_SPACE_OBJECT: + case SHD_SPACE_BLENDER_OBJECT: GPU_link(mat, "direction_transform_m4v3", negnorm, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &negnorm); GPU_link(mat, color_to_normal_fnc_name, realnorm, &realnorm); GPU_link(mat, "direction_transform_m4v3", realnorm, GPU_builtin(GPU_OBJECT_MATRIX), &realnorm); break; - case SHD_NORMAL_MAP_WORLD: - case SHD_NORMAL_MAP_BLENDER_WORLD: + case SHD_SPACE_WORLD: + case SHD_SPACE_BLENDER_WORLD: GPU_link(mat, "direction_transform_m4v3", negnorm, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &negnorm); GPU_link(mat, color_to_normal_fnc_name, realnorm, &realnorm); break; @@ -184,15 +184,15 @@ static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *U GPU_link(mat, "vec_math_negate", negnorm, &negnorm); switch (nm->space) { - case SHD_NORMAL_MAP_TANGENT: + case SHD_SPACE_TANGENT: GPU_link(mat, "node_normal_map", GPU_attribute(CD_TANGENT, nm->uv_map), negnorm, realnorm, &realnorm); break; - case SHD_NORMAL_MAP_OBJECT: - case SHD_NORMAL_MAP_BLENDER_OBJECT: + case SHD_SPACE_OBJECT: + case SHD_SPACE_BLENDER_OBJECT: GPU_link(mat, "direction_transform_m4v3", realnorm, GPU_builtin(GPU_LOC_TO_VIEW_MATRIX), &realnorm); break; - case SHD_NORMAL_MAP_WORLD: - case SHD_NORMAL_MAP_BLENDER_WORLD: + case SHD_SPACE_WORLD: + case SHD_SPACE_BLENDER_WORLD: GPU_link(mat, "direction_transform_m4v3", realnorm, GPU_builtin(GPU_VIEW_MATRIX), &realnorm); break; } diff --git a/source/blender/nodes/shader/nodes/node_shader_particle_info.c b/source/blender/nodes/shader/nodes/node_shader_particle_info.c index 8bdc88292e7..69fcbba8f88 100644 --- a/source/blender/nodes/shader/nodes/node_shader_particle_info.c +++ b/source/blender/nodes/shader/nodes/node_shader_particle_info.c @@ -30,6 +30,7 @@ static bNodeSocketTemplate outputs[] = { { SOCK_FLOAT, 0, "Index" }, + { SOCK_FLOAT, 0, "Random" }, { SOCK_FLOAT, 0, "Age" }, { SOCK_FLOAT, 0, "Lifetime" }, { SOCK_VECTOR, 0, "Location" }, @@ -45,7 +46,7 @@ static void node_shader_exec_particle_info(void *data, int UNUSED(thread), bNode { ShadeInput *shi = ((ShaderCallData *)data)->shi; - RE_instance_get_particle_info(shi->obi, out[0]->vec, out[1]->vec, out[2]->vec, out[3]->vec, out[4]->vec, out[5]->vec, out[6]->vec); + RE_instance_get_particle_info(shi->obi, out[0]->vec, out[1]->vec, out[2]->vec, out[3]->vec, out[4]->vec, out[5]->vec, out[6]->vec, out[7]->vec); } static int gpu_shader_particle_info(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c index 4d98b142f37..8a65ee89ffc 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c @@ -102,6 +102,7 @@ void register_node_type_sh_tex_environment(void) node_type_init(&ntype, node_shader_init_tex_environment); node_type_storage(&ntype, "NodeTexEnvironment", node_free_standard_storage, node_copy_standard_storage); node_type_gpu(&ntype, node_shader_gpu_tex_environment); + node_type_label(&ntype, node_image_label); nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c index c86a502b666..22f302a9c59 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c @@ -126,6 +126,7 @@ void register_node_type_sh_tex_image(void) node_type_init(&ntype, node_shader_init_tex_image); node_type_storage(&ntype, "NodeTexImage", node_free_standard_storage, node_copy_standard_storage); node_type_gpu(&ntype, node_shader_gpu_tex_image); + node_type_label(&ntype, node_image_label); nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c new file mode 100644 index 00000000000..79b41509fcc --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c @@ -0,0 +1,83 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "../node_shader_util.h" + +/* **************** OUTPUT ******************** */ + +static bNodeSocketTemplate sh_node_vector_displacement_in[] = { + { SOCK_RGBA, 0, N_("Vector"), 0.00f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f, PROP_NONE, SOCK_HIDE_VALUE}, + { SOCK_FLOAT, 0, N_("Midlevel"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, + { SOCK_FLOAT, 0, N_("Scale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate sh_node_vector_displacement_out[] = { + { SOCK_VECTOR, 0, N_("Displacement"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void node_shader_init_vector_displacement(bNodeTree *UNUSED(ntree), bNode *node) +{ + node->custom1 = SHD_SPACE_TANGENT; /* space */ +} + +static int gpu_shader_vector_displacement(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) +{ + if (node->custom1 == SHD_SPACE_TANGENT) { + return GPU_stack_link(mat, + node, + "node_vector_displacement_tangent", + in, + out, + GPU_attribute(CD_TANGENT, ""), + GPU_builtin(GPU_VIEW_NORMAL), + GPU_builtin(GPU_OBJECT_MATRIX), + GPU_builtin(GPU_VIEW_MATRIX)); + } + else if (node->custom1 == SHD_SPACE_OBJECT) { + return GPU_stack_link(mat, node, "node_vector_displacement_object", in, out, GPU_builtin(GPU_OBJECT_MATRIX)); + } + else { + return GPU_stack_link(mat, node, "node_vector_displacement_world", in, out); + } +} + +/* node type definition */ +void register_node_type_sh_vector_displacement(void) +{ + static bNodeType ntype; + + sh_node_type_base(&ntype, SH_NODE_VECTOR_DISPLACEMENT, "Vector Displacement", NODE_CLASS_OP_VECTOR, 0); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_socket_templates(&ntype, sh_node_vector_displacement_in, sh_node_vector_displacement_out); + node_type_storage(&ntype, "", NULL, NULL); + node_type_init(&ntype, node_shader_init_vector_displacement); + node_type_gpu(&ntype, gpu_shader_vector_displacement); + + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c index dcae9d2345f..fab28bacff8 100644 --- a/source/blender/nodes/texture/node_texture_tree.c +++ b/source/blender/nodes/texture/node_texture_tree.c @@ -35,6 +35,7 @@ #include "DNA_texture_types.h" #include "DNA_node_types.h" #include "DNA_space_types.h" +#include "DNA_workspace_types.h" #include "BLI_listbase.h" #include "BLI_threads.h" @@ -53,13 +54,16 @@ #include "NOD_texture.h" #include "node_texture_util.h" +#include "DEG_depsgraph.h" + #include "RNA_access.h" #include "RE_shader_ext.h" - -static void texture_get_from_context(const bContext *C, bNodeTreeType *UNUSED(treetype), bNodeTree **r_ntree, ID **r_id, ID **r_from) +static void texture_get_from_context( + const bContext *C, bNodeTreeType *UNUSED(treetype), bNodeTree **r_ntree, ID **r_id, ID **r_from) { + const WorkSpace *workspace = CTX_wm_workspace(C); SpaceNode *snode = CTX_wm_space_node(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); @@ -94,7 +98,7 @@ static void texture_get_from_context(const bContext *C, bNodeTreeType *UNUSED(tr else if (snode->texfrom == SNODE_TEX_BRUSH) { struct Brush *brush = NULL; - if (ob && (ob->mode & OB_MODE_SCULPT)) + if (ob && (workspace->object_mode & OB_MODE_SCULPT)) brush = BKE_paint_brush(&scene->toolsettings->sculpt->paint); else brush = BKE_paint_brush(&scene->toolsettings->imapaint.paint); @@ -346,10 +350,10 @@ int ntreeTexExecTree( /* ensure execdata is only initialized once */ if (!exec) { - BLI_lock_thread(LOCK_NODES); + BLI_thread_lock(LOCK_NODES); if (!nodes->execdata) ntreeTexBeginExecTree(nodes); - BLI_unlock_thread(LOCK_NODES); + BLI_thread_unlock(LOCK_NODES); exec = nodes->execdata; } diff --git a/source/blender/nodes/texture/nodes/node_texture_image.c b/source/blender/nodes/texture/nodes/node_texture_image.c index 8e9821c0fcb..69c8f4b7262 100644 --- a/source/blender/nodes/texture/nodes/node_texture_image.c +++ b/source/blender/nodes/texture/nodes/node_texture_image.c @@ -64,10 +64,10 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(i if ( (!xsize) || (!ysize) ) return; if (!ibuf->rect_float) { - BLI_lock_thread(LOCK_IMAGE); + BLI_thread_lock(LOCK_IMAGE); if (!ibuf->rect_float) IMB_float_from_rect(ibuf); - BLI_unlock_thread(LOCK_IMAGE); + BLI_thread_unlock(LOCK_IMAGE); } while (px < 0) px += ibuf->x; diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp index b694b6e994d..5b5639495da 100644 --- a/source/blender/physics/intern/BPH_mass_spring.cpp +++ b/source/blender/physics/intern/BPH_mass_spring.cpp @@ -34,7 +34,7 @@ extern "C" { #include "DNA_cloth_types.h" #include "DNA_scene_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_object_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" diff --git a/source/blender/physics/intern/implicit_blender.c b/source/blender/physics/intern/implicit_blender.c index 16cd335dc0c..d676b1a1521 100644 --- a/source/blender/physics/intern/implicit_blender.c +++ b/source/blender/physics/intern/implicit_blender.c @@ -37,7 +37,7 @@ #include "DNA_scene_types.h" #include "DNA_object_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_meshdata_types.h" #include "DNA_texture_types.h" diff --git a/source/blender/physics/intern/implicit_eigen.cpp b/source/blender/physics/intern/implicit_eigen.cpp index afe1b441632..c36fabcffb0 100644 --- a/source/blender/physics/intern/implicit_eigen.cpp +++ b/source/blender/physics/intern/implicit_eigen.cpp @@ -73,7 +73,7 @@ extern "C" { #include "DNA_scene_types.h" #include "DNA_object_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_meshdata_types.h" #include "DNA_texture_types.h" diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c index 6598d402f72..4dce0dc2a22 100644 --- a/source/blender/python/bmesh/bmesh_py_ops_call.c +++ b/source/blender/python/bmesh/bmesh_py_ops_call.c @@ -566,7 +566,7 @@ static PyObject *bpy_slot_to_py(BMesh *bm, BMOpSlot *slot) switch (slot->slot_subtype.map) { case BMO_OP_SLOT_SUBTYPE_MAP_ELEM: { - item = _PyDict_NewPresized(slot_hash ? BLI_ghash_size(slot_hash) : 0); + item = _PyDict_NewPresized(slot_hash ? BLI_ghash_len(slot_hash) : 0); if (slot_hash) { GHASH_ITER (hash_iter, slot_hash) { BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); @@ -584,7 +584,7 @@ static PyObject *bpy_slot_to_py(BMesh *bm, BMOpSlot *slot) } case BMO_OP_SLOT_SUBTYPE_MAP_FLT: { - item = _PyDict_NewPresized(slot_hash ? BLI_ghash_size(slot_hash) : 0); + item = _PyDict_NewPresized(slot_hash ? BLI_ghash_len(slot_hash) : 0); if (slot_hash) { GHASH_ITER (hash_iter, slot_hash) { BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); @@ -602,7 +602,7 @@ static PyObject *bpy_slot_to_py(BMesh *bm, BMOpSlot *slot) } case BMO_OP_SLOT_SUBTYPE_MAP_INT: { - item = _PyDict_NewPresized(slot_hash ? BLI_ghash_size(slot_hash) : 0); + item = _PyDict_NewPresized(slot_hash ? BLI_ghash_len(slot_hash) : 0); if (slot_hash) { GHASH_ITER (hash_iter, slot_hash) { BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); @@ -620,7 +620,7 @@ static PyObject *bpy_slot_to_py(BMesh *bm, BMOpSlot *slot) } case BMO_OP_SLOT_SUBTYPE_MAP_BOOL: { - item = _PyDict_NewPresized(slot_hash ? BLI_ghash_size(slot_hash) : 0); + item = _PyDict_NewPresized(slot_hash ? BLI_ghash_len(slot_hash) : 0); if (slot_hash) { GHASH_ITER (hash_iter, slot_hash) { BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 629c3a3c7a3..ec787768a57 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -902,7 +902,11 @@ static PyObject *bpy_bmesh_to_mesh(BPy_BMesh *self, PyObject *args) bm = self->bm; - BM_mesh_bm_to_me(bm, me, (&(struct BMeshToMeshParams){0})); + BM_mesh_bm_to_me( + bm, me, + (&(struct BMeshToMeshParams){ + .calc_object_remap = true, + })); /* we could have the user do this but if they forget blender can easy crash * since the references arrays for the objects derived meshes are now invalid */ diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt index 41018468695..a71478cdb15 100644 --- a/source/blender/python/intern/CMakeLists.txt +++ b/source/blender/python/intern/CMakeLists.txt @@ -248,10 +248,6 @@ if(WITH_LIBMV) add_definitions(-DWITH_LIBMV) endif() -if(WITH_MOD_BOOLEAN) - add_definitions(-DWITH_MOD_BOOLEAN) -endif() - if(WITH_MOD_FLUID) add_definitions(-DWITH_MOD_FLUID) endif() diff --git a/source/blender/python/intern/bpy_app_build_options.c b/source/blender/python/intern/bpy_app_build_options.c index 501e09dd6ad..d5c325e4317 100644 --- a/source/blender/python/intern/bpy_app_build_options.c +++ b/source/blender/python/intern/bpy_app_build_options.c @@ -58,7 +58,6 @@ static PyStructSequence_Field app_builtopts_info_fields[] = { {(char *)"sdl_dynload", NULL}, {(char *)"jack", NULL}, {(char *)"libmv", NULL}, - {(char *)"mod_boolean", NULL}, {(char *)"mod_fluid", NULL}, {(char *)"mod_oceansim", NULL}, {(char *)"mod_remesh", NULL}, @@ -237,12 +236,6 @@ static PyObject *make_builtopts_info(void) SetObjIncref(Py_False); #endif -#ifdef WITH_MOD_BOOLEAN - SetObjIncref(Py_True); -#else - SetObjIncref(Py_False); -#endif - #ifdef WITH_MOD_FLUID SetObjIncref(Py_True); #else diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 5b84a7cf73c..0cadbc30a9f 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -384,7 +384,7 @@ static PyObject *pyop_dir(PyObject *UNUSED(self)) int i; WM_operatortype_iter(&iter); - list = PyList_New(BLI_ghash_size(iter.gh)); + list = PyList_New(BLI_ghash_len(iter.gh)); for (i = 0; !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter), i++) { wmOperatorType *ot = BLI_ghashIterator_getValue(&iter); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index e220e6559a6..4ce9ba59a0b 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -223,7 +223,7 @@ static PyObject *id_free_weakref_cb(PyObject *weakinfo_capsule, PyObject *weakre GHash *weakinfo_hash = PyCapsule_GetPointer(weakinfo_capsule, NULL); - if (BLI_ghash_size(weakinfo_hash) > 1) { + if (BLI_ghash_len(weakinfo_hash) > 1) { BLI_ghash_remove(weakinfo_hash, weakref, NULL, NULL); } else { /* get the last id and free it */ @@ -243,7 +243,7 @@ static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash) BLI_ghashIterator_init(&weakinfo_hash_iter, weakinfo_hash); #ifdef DEBUG_RNA_WEAKREF - fprintf(stdout, "id_release_weakref: '%s', %d items\n", id->name, BLI_ghash_size(weakinfo_hash)); + fprintf(stdout, "id_release_weakref: '%s', %d items\n", id->name, BLI_ghash_len(weakinfo_hash)); #endif while (!BLI_ghashIterator_done(&weakinfo_hash_iter)) { @@ -266,7 +266,7 @@ static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash) BLI_ghash_remove(id_weakref_pool, (void *)id, NULL, NULL); BLI_ghash_free(weakinfo_hash, NULL, NULL); - if (BLI_ghash_size(id_weakref_pool) == 0) { + if (BLI_ghash_len(id_weakref_pool) == 0) { BLI_ghash_free(id_weakref_pool, NULL, NULL); id_weakref_pool = NULL; #ifdef DEBUG_RNA_WEAKREF diff --git a/source/blender/python/intern/gpu_offscreen.c b/source/blender/python/intern/gpu_offscreen.c index 91d407d18a8..2da0227cdca 100644 --- a/source/blender/python/intern/gpu_offscreen.c +++ b/source/blender/python/intern/gpu_offscreen.c @@ -39,6 +39,7 @@ #include "GPU_compositing.h" #include "GPU_framebuffer.h" +#include "GPU_texture.h" #include "../mathutils/mathutils.h" @@ -89,7 +90,8 @@ PyDoc_STRVAR(pygpu_offscreen_color_texture_doc, "Color texture.\n\n:type: int"); static PyObject *pygpu_offscreen_color_texture_get(BPy_GPUOffScreen *self, void *UNUSED(type)) { BPY_GPU_OFFSCREEN_CHECK_OBJ(self); - return PyLong_FromLong(GPU_offscreen_color_texture(self->ofs)); + GPUTexture *texture = GPU_offscreen_color_texture(self->ofs); + return PyLong_FromLong(GPU_texture_opengl_bindcode(texture)); } PyDoc_STRVAR(pygpu_offscreen_bind_doc, @@ -354,7 +356,7 @@ static PyObject *pygpu_offscreen_new(PyObject *UNUSED(self), PyObject *args, PyO return NULL; } - ofs = GPU_offscreen_create(width, height, samples, false, err_out); + ofs = GPU_offscreen_create(width, height, samples, true, false, err_out); if (ofs == NULL) { PyErr_Format(PyExc_RuntimeError, diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c index ba0b6eb11a5..88195700a50 100644 --- a/source/blender/python/mathutils/mathutils_bvhtree.c +++ b/source/blender/python/mathutils/mathutils_bvhtree.c @@ -33,7 +33,7 @@ #include "BLI_utildefines.h" #include "BLI_kdopbvh.h" -#include "BLI_polyfill2d.h" +#include "BLI_polyfill_2d.h" #include "BLI_math.h" #include "BLI_ghash.h" #include "BLI_memarena.h" diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c index 72f92d210d7..fa0d271f7d3 100644 --- a/source/blender/python/mathutils/mathutils_geometry.c +++ b/source/blender/python/mathutils/mathutils_geometry.c @@ -34,8 +34,8 @@ #ifndef MATH_STANDALONE /* define when building outside blender */ # include "MEM_guardedalloc.h" # include "BLI_blenlib.h" -# include "BLI_boxpack2d.h" -# include "BLI_convexhull2d.h" +# include "BLI_boxpack_2d.h" +# include "BLI_convexhull_2d.h" # include "BKE_displist.h" # include "BKE_curve.h" #endif diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index 0b392c122db..281f0082d7f 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -215,7 +215,7 @@ int multitex_nodes(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], const short thread, short which_output, struct ShadeInput *shi, struct MTex *mtex, struct ImagePool *pool); float RE_lamp_get_data(struct ShadeInput *shi, struct Object *lamp_obj, float col[4], float lv[3], float *dist, float shadow[4]); -void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]); +void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *random, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]); float RE_fresnel_dielectric(float incoming[3], float normal[3], float eta); diff --git a/source/blender/render/intern/source/bake.c b/source/blender/render/intern/source/bake.c index 71a595d6a8b..48f5f494e58 100644 --- a/source/blender/render/intern/source/bake.c +++ b/source/blender/render/intern/source/bake.c @@ -609,7 +609,7 @@ static int get_next_bake_face(BakeShade *bs) return 0; } - BLI_lock_thread(LOCK_CUSTOM1); + BLI_thread_lock(LOCK_CUSTOM1); for (; obi; obi = obi->next, v = 0) { obr = obi->obr; @@ -725,13 +725,13 @@ static int get_next_bake_face(BakeShade *bs) bs->vlr = vlr; bs->vdone++; /* only for error message if nothing was rendered */ v++; - BLI_unlock_thread(LOCK_CUSTOM1); + BLI_thread_unlock(LOCK_CUSTOM1); return 1; } } } - BLI_unlock_thread(LOCK_CUSTOM1); + BLI_thread_unlock(LOCK_CUSTOM1); return 0; } @@ -846,7 +846,7 @@ static void shade_tface(BakeShade *bs) if (bs->use_mask || bs->use_displacement_buffer) { BakeImBufuserData *userdata = bs->ibuf->userdata; if (userdata == NULL) { - BLI_lock_thread(LOCK_CUSTOM1); + BLI_thread_lock(LOCK_CUSTOM1); userdata = bs->ibuf->userdata; if (userdata == NULL) /* since the thread was locked, its possible another thread alloced the value */ userdata = MEM_callocN(sizeof(BakeImBufuserData), "BakeImBufuserData"); @@ -865,7 +865,7 @@ static void shade_tface(BakeShade *bs) bs->ibuf->userdata = userdata; - BLI_unlock_thread(LOCK_CUSTOM1); + BLI_thread_unlock(LOCK_CUSTOM1); } bs->rect_mask = userdata->mask_buffer; @@ -1041,7 +1041,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up BKE_main_id_tag_listbase(&G.main->mesh, LIB_TAG_DOIT, false); } - BLI_init_threads(&threads, do_bake_thread, re->r.threads); + BLI_threadpool_init(&threads, do_bake_thread, re->r.threads); handles = MEM_callocN(sizeof(BakeShade) * re->r.threads, "BakeShade"); @@ -1078,7 +1078,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up handles[a].displacement_min = FLT_MAX; handles[a].displacement_max = -FLT_MAX; - BLI_insert_thread(&threads, &handles[a]); + BLI_threadpool_insert(&threads, &handles[a]); } /* wait for everything to be done */ @@ -1152,7 +1152,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up MEM_freeN(handles); - BLI_end_threads(&threads); + BLI_threadpool_end(&threads); if (vdone == 0) { result = BAKE_RESULT_NO_OBJECTS; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 19a87784ad4..503748236f6 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -56,7 +56,7 @@ #include "DNA_modifier_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" -#include "DNA_object_fluidsim.h" +#include "DNA_object_fluidsim_types.h" #include "DNA_particle_types.h" #include "DNA_scene_types.h" #include "DNA_texture_types.h" @@ -1293,6 +1293,7 @@ static void get_particle_uvco_mcol(short from, DerivedMesh *dm, float *fuv, int } static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem *psys, int timeoffset) { + const EvaluationContext *eval_ctx = RE_GetEvalCtx(re); Object *ob= obr->ob; // Object *tob=0; Material *ma = NULL; @@ -1339,7 +1340,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if (part->ren_as==PART_DRAW_OB || part->ren_as==PART_DRAW_GR || part->ren_as==PART_DRAW_NOT) return 1; - if ((re->r.scemode & R_VIEWPORT_PREVIEW) && (ob->mode & OB_MODE_PARTICLE_EDIT)) + if ((re->r.scemode & R_VIEWPORT_PREVIEW) && (eval_ctx->object_mode & OB_MODE_PARTICLE_EDIT)) return 0; if (part->ren_as == PART_DRAW_BB && part->bb_ob == NULL && RE_GetCamera(re) == NULL) diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 2a7aab58980..f666bbd2b95 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -71,7 +71,7 @@ static void envmap_split_ima(EnvMap *env, ImBuf *ibuf) int dx, part; /* after lock we test cube[1], if set the other thread has done it fine */ - BLI_lock_thread(LOCK_IMAGE); + BLI_thread_lock(LOCK_IMAGE); if (env->cube[1] == NULL) { BKE_texture_envmap_free_data(env); @@ -119,7 +119,7 @@ static void envmap_split_ima(EnvMap *env, ImBuf *ibuf) } } } - BLI_unlock_thread(LOCK_IMAGE); + BLI_thread_unlock(LOCK_IMAGE); } /* ------------------------------------------------------------------------- */ diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 2714e8b7685..ddf128c0fbc 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -177,7 +177,7 @@ RenderEngine *RE_engine_create_ex(RenderEngineType *type, bool use_for_viewport) if (use_for_viewport) { engine->flag |= RE_ENGINE_USED_FOR_VIEWPORT; - BLI_begin_threaded_malloc(); + BLI_threaded_malloc_begin(); } return engine; @@ -192,7 +192,7 @@ void RE_engine_free(RenderEngine *engine) #endif if (engine->flag & RE_ENGINE_USED_FOR_VIEWPORT) { - BLI_end_threaded_malloc(); + BLI_threaded_malloc_end(); } MEM_freeN(engine); diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index ae02cf56b88..6e5d10fcc84 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -890,18 +890,18 @@ static void image_mipmap_test(Tex *tex, ImBuf *ibuf) if ((ibuf->flags & IB_fields) == 0) { if (ibuf->mipmap[0] && (ibuf->userflags & IB_MIPMAP_INVALID)) { - BLI_lock_thread(LOCK_IMAGE); + BLI_thread_lock(LOCK_IMAGE); if (ibuf->userflags & IB_MIPMAP_INVALID) { IMB_remakemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP); ibuf->userflags &= ~IB_MIPMAP_INVALID; } - BLI_unlock_thread(LOCK_IMAGE); + BLI_thread_unlock(LOCK_IMAGE); } if (ibuf->mipmap[0] == NULL) { - BLI_lock_thread(LOCK_IMAGE); + BLI_thread_lock(LOCK_IMAGE); if (ibuf->mipmap[0] == NULL) IMB_makemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP); - BLI_unlock_thread(LOCK_IMAGE); + BLI_thread_unlock(LOCK_IMAGE); } /* if no mipmap could be made, fall back on non-mipmap render */ if (ibuf->mipmap[0] == NULL) { diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 731a5ec4e22..9182d545089 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -38,7 +38,7 @@ #include "BLI_math.h" #include "BLI_blenlib.h" -#include "BLI_jitter.h" +#include "BLI_jitter_2d.h" #include "BLI_utildefines.h" #include "DNA_camera_types.h" diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c index 4c0355ef604..ddab8b23b59 100644 --- a/source/blender/render/intern/source/multires_bake.c +++ b/source/blender/render/intern/source/multires_bake.c @@ -470,7 +470,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, bool require_t bake_data = initBakeData(bkr, ima); if (tot_thread > 1) - BLI_init_threads(&threads, do_multires_bake_thread, tot_thread); + BLI_threadpool_init(&threads, do_multires_bake_thread, tot_thread); handles = MEM_callocN(tot_thread * sizeof(MultiresBakeThread), "do_multires_bake handles"); @@ -512,12 +512,12 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, bool require_t init_bake_rast(&handle->bake_rast, ibuf, &handle->data, flush_pixel, bkr->do_update); if (tot_thread > 1) - BLI_insert_thread(&threads, handle); + BLI_threadpool_insert(&threads, handle); } /* run threads */ if (tot_thread > 1) - BLI_end_threads(&threads); + BLI_threadpool_end(&threads); else do_multires_bake_thread(&handles[0]); diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index cd93898d846..42200a8278c 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -553,7 +553,7 @@ static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, i occ_build_8_split(tree, begin, end, offset, count); if (depth == 1 && tree->dothreadedbuild) - BLI_init_threads(&threads, exec_occ_build, tree->totbuildthread); + BLI_threadpool_init(&threads, exec_occ_build, tree->totbuildthread); for (b = 0; b < TOTCHILD; b++) { if (count[b] == 0) { @@ -566,7 +566,7 @@ static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, i } else { if (tree->dothreadedbuild) - BLI_lock_thread(LOCK_CUSTOM1); + BLI_thread_lock(LOCK_CUSTOM1); child = BLI_memarena_alloc(tree->arena, sizeof(OccNode)); node->child[b].node = child; @@ -576,7 +576,7 @@ static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, i tree->maxdepth = depth + 1; if (tree->dothreadedbuild) - BLI_unlock_thread(LOCK_CUSTOM1); + BLI_thread_unlock(LOCK_CUSTOM1); if (depth == 1 && tree->dothreadedbuild) { othreads[totthread].tree = tree; @@ -584,7 +584,7 @@ static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, i othreads[totthread].begin = offset[b]; othreads[totthread].end = offset[b] + count[b]; othreads[totthread].depth = depth + 1; - BLI_insert_thread(&threads, &othreads[totthread]); + BLI_threadpool_insert(&threads, &othreads[totthread]); totthread++; } else @@ -593,7 +593,7 @@ static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, i } if (depth == 1 && tree->dothreadedbuild) - BLI_end_threads(&threads); + BLI_threadpool_end(&threads); } /* combine area, position and sh */ @@ -1313,12 +1313,12 @@ void make_occ_tree(Render *re) exec_strandsurface_sample(&othreads[0]); } else { - BLI_init_threads(&threads, exec_strandsurface_sample, totthread); + BLI_threadpool_init(&threads, exec_strandsurface_sample, totthread); for (a = 0; a < totthread; a++) - BLI_insert_thread(&threads, &othreads[a]); + BLI_threadpool_insert(&threads, &othreads[a]); - BLI_end_threads(&threads); + BLI_threadpool_end(&threads); } for (a = 0; a < mesh->totface; a++) { diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 5a5c99724fe..e5426384c6f 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -41,6 +41,7 @@ #include "DNA_image_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" +#include "DNA_particle_types.h" #include "DNA_scene_types.h" #include "DNA_sequence_types.h" #include "DNA_userdef_types.h" @@ -1427,7 +1428,7 @@ static void threaded_tile_processor(Render *re) BLI_thread_queue_nowait(workqueue); /* start all threads */ - BLI_init_threads(&threads, do_render_thread, re->r.threads); + BLI_threadpool_init(&threads, do_render_thread, re->r.threads); for (a = 0; a < re->r.threads; a++) { thread[a].workqueue = workqueue; @@ -1443,7 +1444,7 @@ static void threaded_tile_processor(Render *re) thread[a].duh = NULL; } - BLI_insert_thread(&threads, &thread[a]); + BLI_threadpool_insert(&threads, &thread[a]); } /* wait for results to come back */ @@ -1487,7 +1488,7 @@ static void threaded_tile_processor(Render *re) } } - BLI_end_threads(&threads); + BLI_threadpool_end(&threads); if ((g_break=re->test_break(re->tbh))) break; @@ -2104,6 +2105,28 @@ static void tag_dependend_objects_for_render(Scene *scene, int UNUSED(renderlay) DEG_id_tag_update(&smd->target->id, OB_RECALC_DATA); } } + else if (md->type == eModifierType_ParticleSystem) { + ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; + ParticleSystem *psys = psmd->psys; + ParticleSettings *part = psys->part; + switch (part->ren_as) { + case PART_DRAW_OB: + if (part->dup_ob != NULL) { + DEG_id_tag_update(&part->dup_ob->id, OB_RECALC_DATA); + } + break; + case PART_DRAW_GR: + if (part->dup_group != NULL) { + for (GroupObject *go = part->dup_group->gobject.first; + go != NULL; + go = go->next) + { + DEG_id_tag_update(&go->ob->id, OB_RECALC_DATA); + } + } + break; + } + } } } } diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index 6749fedb16e..f97c8fb0b06 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -1037,7 +1037,7 @@ static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart, cons RenderPass *rpassp; int offs, partx, party; - BLI_lock_thread(LOCK_IMAGE); + BLI_thread_lock(LOCK_IMAGE); for (rlp = rrpart->layers.first; rlp; rlp = rlp->next) { rl = RE_GetRenderLayer(rr, rlp->name); @@ -1086,7 +1086,7 @@ static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart, cons IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0, viewname, false); } - BLI_unlock_thread(LOCK_IMAGE); + BLI_thread_unlock(LOCK_IMAGE); } void render_result_save_empty_result_tiles(Render *re) diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 4241dff96de..e66dd86a75a 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -3675,7 +3675,7 @@ void render_realtime_texture(ShadeInput *shi, Image *ima) if (R.r.scemode & R_NO_TEX) return; if (firsttime) { - BLI_lock_thread(LOCK_IMAGE); + BLI_thread_lock(LOCK_IMAGE); if (firsttime) { const int num_threads = BLI_system_thread_count(); for (a = 0; a < num_threads; a++) { @@ -3686,7 +3686,7 @@ void render_realtime_texture(ShadeInput *shi, Image *ima) firsttime= 0; } - BLI_unlock_thread(LOCK_IMAGE); + BLI_thread_unlock(LOCK_IMAGE); } tex= &imatex[shi->thread]; diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 199322795f3..2fbfcc64c8f 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -1482,9 +1482,10 @@ ObjectInstanceRen *RE_addRenderInstance( return obi; } -void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]) +void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *random, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]) { *index = obi->part_index; + *random = BLI_hash_int_01(obi->part_index); *age = obi->part_age; *lifetime = obi->part_lifetime; copy_v3_v3(co, obi->part_co); diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index 6dd7e2c152d..fb441662829 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -40,7 +40,7 @@ #include "BLI_math.h" #include "BLI_blenlib.h" -#include "BLI_jitter.h" +#include "BLI_jitter_2d.h" #include "BLI_memarena.h" #include "BLI_rand.h" #include "BLI_utildefines.h" @@ -787,10 +787,10 @@ void makeshadowbuf(Render *re, LampRen *lar) shb->totbuf= lar->buffers; /* jitter, weights - not threadsafe! */ - BLI_lock_thread(LOCK_CUSTOM1); + BLI_thread_lock(LOCK_CUSTOM1); shb->jit= give_jitter_tab(get_render_shadow_samples(&re->r, shb->samp)); make_jitter_weight_tab(re, shb, lar->filtertype); - BLI_unlock_thread(LOCK_CUSTOM1); + BLI_thread_unlock(LOCK_CUSTOM1); if (shb->totbuf==4) jitbuf= give_jitter_tab(2); else if (shb->totbuf==9) jitbuf= give_jitter_tab(3); @@ -814,21 +814,21 @@ static void *do_shadow_thread(void *re_v) LampRen *lar; do { - BLI_lock_thread(LOCK_CUSTOM1); + BLI_thread_lock(LOCK_CUSTOM1); for (lar=re->lampren.first; lar; lar=lar->next) { if (lar->shb && !lar->thread_assigned) { lar->thread_assigned= 1; break; } } - BLI_unlock_thread(LOCK_CUSTOM1); + BLI_thread_unlock(LOCK_CUSTOM1); /* if type is irregular, this only sets the perspective matrix and autoclips */ if (lar) { makeshadowbuf(re, lar); - BLI_lock_thread(LOCK_CUSTOM1); + BLI_thread_lock(LOCK_CUSTOM1); lar->thread_ready= 1; - BLI_unlock_thread(LOCK_CUSTOM1); + BLI_thread_unlock(LOCK_CUSTOM1); } } while (lar && !re->test_break(re->tbh)); @@ -878,10 +878,10 @@ void threaded_makeshadowbufs(Render *re) lar->thread_ready= 0; } - BLI_init_threads(&threads, do_shadow_thread, totthread); + BLI_threadpool_init(&threads, do_shadow_thread, totthread); for (a=0; a<totthread; a++) - BLI_insert_thread(&threads, re); + BLI_threadpool_insert(&threads, re); /* keep rendering as long as there are shadow buffers not ready */ do { @@ -890,14 +890,14 @@ void threaded_makeshadowbufs(Render *re) PIL_sleep_ms(50); - BLI_lock_thread(LOCK_CUSTOM1); + BLI_thread_lock(LOCK_CUSTOM1); for (lar=re->lampren.first; lar; lar= lar->next) if (lar->shb && !lar->thread_ready) break; - BLI_unlock_thread(LOCK_CUSTOM1); + BLI_thread_unlock(LOCK_CUSTOM1); } while (lar); - BLI_end_threads(&threads); + BLI_threadpool_end(&threads); /* unset threadsafety */ re->test_break= test_break; diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c index 26ca3ad50e0..c29da9b17c6 100644 --- a/source/blender/render/intern/source/sss.c +++ b/source/blender/render/intern/source/sss.c @@ -973,9 +973,9 @@ void sss_add_points(Render *re, float (*co)[3], float (*color)[3], float *area, p->area= area; p->totpoint= totpoint; - BLI_lock_thread(LOCK_CUSTOM1); + BLI_thread_lock(LOCK_CUSTOM1); BLI_addtail(re->sss_points, p); - BLI_unlock_thread(LOCK_CUSTOM1); + BLI_thread_unlock(LOCK_CUSTOM1); } } diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c index 1022aeeec66..c45bde300e7 100644 --- a/source/blender/render/intern/source/voxeldata.c +++ b/source/blender/render/intern/source/voxeldata.c @@ -61,7 +61,7 @@ #include "BPH_mass_spring.h" #include "DNA_texture_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_object_types.h" #include "DNA_particle_types.h" #include "DNA_modifier_types.h" diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index f39936dc01f..770a270592c 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -42,7 +42,7 @@ #include "BLI_math.h" #include "BLI_blenlib.h" -#include "BLI_jitter.h" +#include "BLI_jitter_2d.h" #include "BLI_threads.h" #include "BLI_utildefines.h" diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt index 059055daea9..0da45202730 100644 --- a/source/blender/windowmanager/CMakeLists.txt +++ b/source/blender/windowmanager/CMakeLists.txt @@ -93,7 +93,6 @@ set(SRC wm_event_system.h wm_event_types.h wm_files.h - wm_subwindow.h wm_window.h manipulators/WM_manipulator_api.h manipulators/WM_manipulator_types.h diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 16c376888df..aaf1a11a416 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -68,6 +68,8 @@ struct ScrArea; struct Main; struct bToolDef; +#include "DNA_object_enums.h" + #ifdef WITH_INPUT_NDOF struct wmNDOFMotionData; #endif @@ -105,6 +107,7 @@ bool WM_window_is_fullscreen(struct wmWindow *win); void WM_windows_scene_data_sync(const ListBase *win_lb, struct Scene *scene) ATTR_NONNULL(); struct Scene *WM_windows_scene_get_from_screen(const struct wmWindowManager *wm, const struct bScreen *screen) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT; struct WorkSpace *WM_windows_workspace_get_from_screen(const wmWindowManager *wm, const struct bScreen *screen) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT; +eObjectMode WM_windows_object_mode_get(const struct wmWindowManager *wm) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT; struct Scene *WM_window_get_active_scene(const struct wmWindow *win) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT; void WM_window_change_active_scene(struct Main *bmain, struct bContext *C, struct wmWindow *win, @@ -140,7 +143,7 @@ void WM_file_autoexec_init(const char *filepath); bool WM_file_read(struct bContext *C, const char *filepath, struct ReportList *reports); void WM_autosave_init(struct wmWindowManager *wm); void WM_recover_last_session(struct bContext *C, struct ReportList *reports); -void WM_file_tag_modified(const struct bContext *C); +void WM_file_tag_modified(void); void WM_lib_reload(struct Library *lib, struct bContext *C, struct ReportList *reports); @@ -456,15 +459,17 @@ struct wmDropBox *WM_dropbox_add(ListBase *lb, const char *idname, int (*poll)(s void (*copy)(struct wmDrag *, struct wmDropBox *)); ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid); - /* Set a subwindow active in pixelspace view, with optional scissor subset */ -void wmSubWindowSet (struct wmWindow *win, int swinid); -void wmSubWindowScissorSet (struct wmWindow *win, int swinid, const struct rcti *srct, bool srct_pad); + /* Set OpenGL viewport and scissor */ +void wmViewport(const struct rcti *rect); +void wmPartialViewport(rcti *drawrct, const rcti *winrct, const rcti *partialrct); +void wmWindowViewport(struct wmWindow *win); /* OpenGL utilities with safety check */ void wmOrtho2 (float x1, float x2, float y1, float y2); /* use for conventions (avoid hard-coded offsets all over) */ void wmOrtho2_region_pixelspace(const struct ARegion *ar); void wmOrtho2_pixelspace(const float x, const float y); +void wmGetProjectionMatrix(float mat[4][4], const struct rcti *winrct); /* threaded Jobs Manager */ enum { diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index cb90029a5e7..50062a04ae9 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -115,6 +115,7 @@ struct ImBuf; #include "RNA_types.h" #include "DNA_listBase.h" +#include "DNA_vec_types.h" #include "BLI_compiler_attrs.h" /* exported types for WM */ @@ -214,7 +215,6 @@ typedef struct wmNotifier { struct wmWindowManager *wm; struct wmWindow *window; - int swinid; /* can't rely on this, notifiers can be added without context, swinid of 0 */ unsigned int category, data, subtype, action; void *reference; @@ -423,7 +423,7 @@ typedef struct wmGesture { struct wmGesture *next, *prev; int event_type; /* event->type */ int type; /* gesture type define */ - int swinid; /* initial subwindow id where it started */ + rcti winrct; /* bounds of region to draw gesture within */ int points; /* optional, amount of points stored */ int points_alloc; /* optional, maximum amount of points stored */ int modal_state; @@ -521,6 +521,10 @@ typedef struct wmNDOFMotionData { } wmNDOFMotionData; #endif /* WITH_INPUT_NDOF */ +typedef enum { /* Timer flags */ + WM_TIMER_NO_FREE_CUSTOM_DATA = 1 << 0, /* Do not attempt to free customdata pointer even if non-NULL. */ +} wmTimerFlags; + typedef struct wmTimer { struct wmTimer *next, *prev; @@ -528,6 +532,7 @@ typedef struct wmTimer { double timestep; /* set by timer user */ int event_type; /* set by timer user, goes to event system */ + wmTimerFlags flags; /* Various flags controlling timer options, see below. */ void *customdata; /* set by timer user, to allow custom values */ double duration; /* total running time in seconds */ @@ -536,7 +541,7 @@ typedef struct wmTimer { double ltime; /* internal, last time timer was activated */ double ntime; /* internal, next time we want to activate the timer */ double stime; /* internal, when the timer started */ - int sleep; /* internal, put timers to sleep when needed */ + bool sleep; /* internal, put timers to sleep when needed */ } wmTimer; typedef struct wmOperatorType { diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 30197537e14..70cff8465fc 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -95,7 +95,7 @@ static void wm_paintcursor_draw(bContext *C, ARegion *ar) bScreen *screen = WM_window_get_active_screen(win); wmPaintCursor *pc; - if (ar->swinid && screen->subwinactive == ar->swinid) { + if (ar->visible && ar == screen->active_region) { for (pc = wm->paintcursors.first; pc; pc = pc->next) { if (pc->poll == NULL || pc->poll(C)) { ARegion *ar_other = CTX_wm_region(C); @@ -223,7 +223,7 @@ static void wm_method_draw_full(bContext *C, wmWindow *win) CTX_wm_area_set(C, sa); for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->swinid) { + if (ar->visible) { CTX_wm_region_set(C, ar); ED_region_do_draw(C, ar); ar->do_draw = false; @@ -242,7 +242,7 @@ static void wm_method_draw_full(bContext *C, wmWindow *win) /* draw overlapping regions */ for (ar = screen->regionbase.first; ar; ar = ar->next) { - if (ar->swinid) { + if (ar->visible) { CTX_wm_menu_set(C, ar); ED_region_do_draw(C, ar); ar->do_draw = false; @@ -300,7 +300,7 @@ static void wm_method_draw_overlap_all(bContext *C, wmWindow *win, int exchange) /* after backbuffer selection draw, we need to redraw */ ED_screen_areas_iter(win, screen, sa) { for (ar = sa->regionbase.first; ar; ar = ar->next) - if (ar->swinid && !wm_area_test_invalid_backbuf(sa)) + if (ar->visible && !wm_area_test_invalid_backbuf(sa)) ED_region_tag_redraw(ar); } @@ -309,18 +309,18 @@ static void wm_method_draw_overlap_all(bContext *C, wmWindow *win, int exchange) /* flush redraws of area regions up to overlapping regions */ ED_screen_areas_iter(win, screen, sa) { for (ar = sa->regionbase.first; ar; ar = ar->next) - if (ar->swinid && ar->do_draw) + if (ar->visible && ar->do_draw) wm_flush_regions_up(screen, &ar->winrct); } /* flush between overlapping regions */ for (ar = screen->regionbase.last; ar; ar = ar->prev) - if (ar->swinid && ar->do_draw) + if (ar->visible && ar->do_draw) wm_flush_regions_up(screen, &ar->winrct); /* flush redraws of overlapping regions down to area regions */ for (ar = screen->regionbase.last; ar; ar = ar->prev) - if (ar->swinid && ar->do_draw) + if (ar->visible && ar->do_draw) wm_flush_regions_down(win, screen, &ar->winrct); } @@ -339,7 +339,7 @@ static void wm_method_draw_overlap_all(bContext *C, wmWindow *win, int exchange) CTX_wm_area_set(C, sa); for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->swinid) { + if (ar->visible) { if (ar->do_draw) { CTX_wm_region_set(C, ar); ED_region_do_draw(C, ar); @@ -396,7 +396,7 @@ static void wm_method_draw_overlap_all(bContext *C, wmWindow *win, int exchange) /* draw marked overlapping regions */ for (ar = screen->regionbase.first; ar; ar = ar->next) { - if (ar->swinid && ar->do_draw) { + if (ar->visible && ar->do_draw) { CTX_wm_menu_set(C, ar); ED_region_do_draw(C, ar); ar->do_draw = false; @@ -437,15 +437,8 @@ static void wm_draw_triple_fail(bContext *C, wmWindow *win) static bool wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple) { /* compute texture sizes */ - triple->x = WM_window_pixels_x(win); - triple->y = WM_window_pixels_y(win); - -#if USE_TEXTURE_RECTANGLE - /* GL_TEXTURE_RECTANGLE is part of GL 3.1 so we can use it soon without runtime checks */ - triple->target = GL_TEXTURE_RECTANGLE; -#else - triple->target = GL_TEXTURE_2D; -#endif + const int sizex = WM_window_pixels_x(win); + const int sizey = WM_window_pixels_y(win); /* generate texture names */ glGenTextures(1, &triple->bind); @@ -454,29 +447,25 @@ static bool wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple) * there is only one texture in use, which may not be the case */ const GLint maxsize = GPU_max_texture_size(); - if (triple->x > maxsize || triple->y > maxsize) { + if (sizex > maxsize || sizey > maxsize) { printf("WM: failed to allocate texture for triple buffer drawing " "(texture too large for graphics card).\n"); return false; } /* setup actual texture */ - glBindTexture(triple->target, triple->bind); + glBindTexture(GL_TEXTURE_2D, triple->bind); /* no mipmaps */ -#if USE_TEXTURE_RECTANGLE - /* already has no mipmaps */ -#else - glTexParameteri(triple->target, GL_TEXTURE_MAX_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); /* GL_TEXTURE_BASE_LEVEL = 0 by default */ -#endif - glTexParameteri(triple->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(triple->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(triple->target, 0, GL_RGB8, triple->x, triple->y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, sizex, sizey, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); - glBindTexture(triple->target, 0); + glBindTexture(GL_TEXTURE_2D, 0); return true; } @@ -487,19 +476,10 @@ void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha) const int sizey = WM_window_pixels_y(win); /* wmOrtho for the screen has this same offset */ - float ratiox = sizex; - float ratioy = sizey; - float halfx = GLA_PIXEL_OFS; - float halfy = GLA_PIXEL_OFS; - -#if USE_TEXTURE_RECTANGLE - /* texture rectangle has unnormalized coordinates */ -#else - ratiox /= triple->x; - ratioy /= triple->y; - halfx /= triple->x; - halfy /= triple->y; -#endif + const float ratiox = 1.0f; + const float ratioy = 1.0f; + const float halfx = GLA_PIXEL_OFS / sizex; + const float halfy = GLA_PIXEL_OFS / sizey; Gwn_VertFormat *format = immVertexFormat(); unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); @@ -507,16 +487,10 @@ void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha) const int activeTex = 7; /* arbitrary */ glActiveTexture(GL_TEXTURE0 + activeTex); - glBindTexture(triple->target, triple->bind); - -#if USE_TEXTURE_RECTANGLE - immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_RECT_MODULATE_ALPHA); -#else - immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_MODULATE_ALPHA); - /* TODO: make pure 2D version - * and a 2D_IMAGE (replace, not modulate) version for when alpha = 1.0 - */ -#endif + glBindTexture(GL_TEXTURE_2D, triple->bind); + + immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_ALPHA); + immUniform1f("alpha", alpha); immUniform1i("image", activeTex); @@ -537,7 +511,7 @@ void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha) immEnd(); immUnbindProgram(); - glBindTexture(triple->target, 0); + glBindTexture(GL_TEXTURE_2D, 0); if (activeTex != 0) glActiveTexture(GL_TEXTURE0); } @@ -547,10 +521,10 @@ static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple) const int sizex = WM_window_pixels_x(win); const int sizey = WM_window_pixels_y(win); - glBindTexture(triple->target, triple->bind); + glBindTexture(GL_TEXTURE_2D, triple->bind); /* what is GL_READ_BUFFER right now? */ - glCopyTexSubImage2D(triple->target, 0, 0, 0, 0, 0, sizex, sizey); - glBindTexture(triple->target, 0); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, sizex, sizey); + glBindTexture(GL_TEXTURE_2D, 0); } static void wm_draw_region_blend(wmWindow *win, ARegion *ar, wmDrawTriple *triple) @@ -559,9 +533,7 @@ static void wm_draw_region_blend(wmWindow *win, ARegion *ar, wmDrawTriple *tripl /* region blend always is 1, except when blend timer is running */ if (fac < 1.0f) { - bScreen *screen = WM_window_get_active_screen(win); - - wmSubWindowScissorSet(win, screen->mainwin, &ar->winrct, true); + wmViewport(&ar->winrct); glEnable(GL_BLEND); wm_triple_draw_textures(win, triple, 1.0f - fac); @@ -583,7 +555,7 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #endif - wmSubWindowSet(win, screen->mainwin); + wmWindowViewport(win); wm_triple_draw_textures(win, drawdata->triple, 1.0f); } @@ -619,7 +591,7 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) CTX_wm_area_set(C, sa); for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->swinid && ar->do_draw) { + if (ar->visible && ar->do_draw) { if (ar->overlap == false) { wm_draw_region(C, ar); copytex = true; @@ -632,7 +604,7 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) } if (copytex) { - wmSubWindowSet(win, screen->mainwin); + wmWindowViewport(win); wm_triple_copy_textures(win, triple); } @@ -640,12 +612,12 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) if (wm->paintcursors.first) { ED_screen_areas_iter(win, screen, sa) { for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->swinid && ar->swinid == screen->subwinactive) { + if (ar->visible && ar == screen->active_region) { CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); /* make region ready for draw, scissor, pixelspace */ - ED_region_set(C, ar); + wmViewport(&ar->winrct); wm_paintcursor_draw(C, ar); CTX_wm_region_set(C, NULL); @@ -654,7 +626,7 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) } } - wmSubWindowSet(win, screen->mainwin); + wmWindowViewport(win); } /* draw overlapping area regions (always like popups) */ @@ -662,7 +634,7 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) CTX_wm_area_set(C, sa); for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->swinid && ar->overlap) { + if (ar->visible && ar->overlap) { wm_draw_region(C, ar); wm_draw_region_blend(win, ar, triple); } @@ -678,7 +650,7 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) /* draw floating regions (menus) */ for (ar = screen->regionbase.first; ar; ar = ar->next) { - if (ar->swinid) { + if (ar->visible) { CTX_wm_menu_set(C, ar); ED_region_do_draw(C, ar); ar->do_draw = false; @@ -717,7 +689,7 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoV glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #endif - wmSubWindowSet(win, screen->mainwin); + wmWindowViewport(win); wm_triple_draw_textures(win, drawdata->triple, 1.0f); } @@ -782,7 +754,7 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoV /* draw marked area regions */ for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->swinid && ar->do_draw) { + if (ar->visible && ar->do_draw) { if (ar->overlap == false) { CTX_wm_region_set(C, ar); @@ -802,7 +774,7 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoV } if (copytex) { - wmSubWindowSet(win, screen->mainwin); + wmWindowViewport(win); wm_triple_copy_textures(win, triple_data); } @@ -810,12 +782,12 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoV if (wm->paintcursors.first) { ED_screen_areas_iter(win, screen, sa) { for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->swinid && ar->swinid == screen->subwinactive) { + if (ar->visible && ar == screen->active_region) { CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); /* make region ready for draw, scissor, pixelspace */ - ED_region_set(C, ar); + wmViewport(&ar->winrct); wm_paintcursor_draw(C, ar); CTX_wm_region_set(C, NULL); @@ -824,7 +796,7 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoV } } - wmSubWindowSet(win, screen->mainwin); + wmWindowViewport(win); } /* draw overlapping area regions (always like popups) */ @@ -832,7 +804,7 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoV CTX_wm_area_set(C, sa); for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->swinid && ar->overlap) { + if (ar->visible && ar->overlap) { CTX_wm_region_set(C, ar); ED_region_do_draw(C, ar); if (sview == STEREO_RIGHT_ID) @@ -855,7 +827,7 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoV /* draw floating regions (menus) */ for (ar = screen->regionbase.first; ar; ar = ar->next) { - if (ar->swinid) { + if (ar->visible) { CTX_wm_menu_set(C, ar); ED_region_do_draw(C, ar); if (sview == STEREO_RIGHT_ID) @@ -874,7 +846,7 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoV } /* copy the ui + overlays */ - wmSubWindowSet(win, screen->mainwin); + wmWindowViewport(win); wm_triple_copy_textures(win, triple_all); } @@ -896,7 +868,7 @@ static bool wm_draw_update_test_window(wmWindow *win) wm_tag_redraw_overlay(win, ar); ar->do_draw_overlay = false; } - if (ar->swinid && ar->do_draw) + if (ar->visible && ar->do_draw) do_draw = true; } @@ -904,7 +876,7 @@ static bool wm_draw_update_test_window(wmWindow *win) for (ar = sa->regionbase.first; ar; ar = ar->next) { wm_region_test_render_do_draw(scene, depsgraph, sa, ar); - if (ar->swinid && ar->do_draw) + if (ar->visible && ar->do_draw) do_draw = true; } } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index e66e7728d31..040ecc63bec 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -182,7 +182,6 @@ static bool wm_test_duplicate_notifier(wmWindowManager *wm, unsigned int type, v /* XXX: in future, which notifiers to send to other windows? */ void WM_event_add_notifier(const bContext *C, unsigned int type, void *reference) { - ARegion *ar; wmWindowManager *wm = CTX_wm_manager(C); wmNotifier *note; @@ -196,10 +195,6 @@ void WM_event_add_notifier(const bContext *C, unsigned int type, void *reference note->window = CTX_wm_window(C); - ar = CTX_wm_region(C); - if (ar) - note->swinid = ar->swinid; - note->category = type & NOTE_CATEGORY; note->data = type & NOTE_DATA; note->subtype = type & NOTE_SUBTYPE; @@ -339,6 +334,9 @@ void wm_event_do_refresh_wm_and_depsgraph(bContext *C) scene->customdata_mask |= scene->customdata_mask_modal; WorkSpace *workspace = WM_window_get_active_workspace(win); + + BKE_workspace_update_object_mode(bmain->eval_ctx, workspace); + BKE_workspace_update_tagged(bmain->eval_ctx, bmain, workspace, scene); } } @@ -383,7 +381,7 @@ void wm_event_do_notifiers(bContext *C) UI_popup_handlers_remove_all(C, &win->modalhandlers); - ED_workspace_change(ref_ws, C, wm, win); + ED_workspace_change(ref_ws, C, win); if (G.debug & G_DEBUG_EVENTS) printf("%s: Workspace set %p\n", __func__, note->reference); } @@ -1219,8 +1217,8 @@ static int wm_operator_invoke( } if ((G.debug & G_DEBUG_HANDLERS) && ((event == NULL) || (event->type != MOUSEMOVE))) { - printf("%s: handle evt %d win %d op %s\n", - __func__, event ? event->type : 0, CTX_wm_screen(C)->subwinactive, ot->idname); + printf("%s: handle evt %d region %p op %s\n", + __func__, event ? event->type : 0, CTX_wm_screen(C)->active_region, ot->idname); } if (op->type->invoke && event) { @@ -1357,6 +1355,8 @@ static int wm_operator_call_internal( switch (context) { case WM_OP_INVOKE_DEFAULT: case WM_OP_INVOKE_REGION_WIN: + case WM_OP_INVOKE_REGION_PREVIEW: + case WM_OP_INVOKE_REGION_CHANNELS: case WM_OP_INVOKE_AREA: case WM_OP_INVOKE_SCREEN: /* window is needed for invoke, cancel operator */ @@ -2783,7 +2783,7 @@ void wm_event_do_handlers(bContext *C) /* Note: setting subwin active should be done here, after modal handlers have been done */ if (event->type == MOUSEMOVE) { /* state variables in screen, cursors. Also used in wm_draw.c, fails for modal handlers though */ - ED_screen_set_subwinactive(C, event); + ED_screen_set_active_region(C, event); /* for regions having custom cursors */ wm_paintcursor_test(C, event); } diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 6a86644da17..98606379a61 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -182,7 +182,6 @@ static void wm_window_match_init(bContext *C, ListBase *wmlist) static void wm_window_substitute_old(wmWindowManager *wm, wmWindow *oldwin, wmWindow *win) { win->ghostwin = oldwin->ghostwin; - win->multisamples = oldwin->multisamples; win->active = oldwin->active; if (win->active) wm->winactive = win; @@ -191,7 +190,6 @@ static void wm_window_substitute_old(wmWindowManager *wm, wmWindow *oldwin, wmWi GHOST_SetWindowUserData(win->ghostwin, win); /* pointer back */ oldwin->ghostwin = NULL; - oldwin->multisamples = 0; win->eventstate = oldwin->eventstate; oldwin->eventstate = NULL; @@ -1365,13 +1363,13 @@ void wm_open_init_use_scripts(wmOperator *op, bool use_prefs) /** \} */ -void WM_file_tag_modified(const bContext *C) +void WM_file_tag_modified(void) { - wmWindowManager *wm = CTX_wm_manager(C); + wmWindowManager *wm = G.main->wm.first; if (wm->file_saved) { wm->file_saved = 0; /* notifier that data changed, for save-over warning or header */ - WM_event_add_notifier(C, NC_WM | ND_DATACHANGED, NULL); + WM_main_add_notifier(NC_WM | ND_DATACHANGED, NULL); } } diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c index cd6a38cb9a8..a33df1bc1f2 100644 --- a/source/blender/windowmanager/intern/wm_files_link.c +++ b/source/blender/windowmanager/intern/wm_files_link.c @@ -320,9 +320,6 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) char path[FILE_MAX_LIBEXTRA], root[FILE_MAXDIR], libname[FILE_MAX_LIBEXTRA], relname[FILE_MAX]; char *group, *name; int totfiles = 0; - short flag; - bool has_item = false; - bool do_append; RNA_string_get(op->ptr, "filename", relname); RNA_string_get(op->ptr, "directory", root); @@ -359,8 +356,8 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - flag = wm_link_append_flag(op); - do_append = (flag & FILE_LINK) == 0; + short flag = wm_link_append_flag(op); + const bool do_append = (flag & FILE_LINK) == 0; /* sanity checks for flag */ if (scene && scene->id.lib) { @@ -406,7 +403,6 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) BLI_ghash_insert(libraries, BLI_strdup(libname), SET_INT_IN_POINTER(lib_idx)); lib_idx++; wm_link_append_data_library_add(lapp_data, libname); - has_item = true; } } } @@ -429,7 +425,6 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) item = wm_link_append_data_item_add(lapp_data, name, BKE_idcode_from_name(group), NULL); BLI_BITMAP_ENABLE(item->libraries, lib_idx); - has_item = true; } } RNA_END; @@ -442,10 +437,10 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) wm_link_append_data_library_add(lapp_data, libname); item = wm_link_append_data_item_add(lapp_data, name, BKE_idcode_from_name(group), NULL); BLI_BITMAP_ENABLE(item->libraries, 0); - has_item = true; } - if (!has_item) { + if (lapp_data->num_items == 0) { + /* Early out in case there is nothing to link. */ wm_link_append_data_free(lapp_data); return OPERATOR_CANCELLED; } @@ -614,7 +609,6 @@ static void lib_relocate_do( LinkNode *itemlink; int item_idx; - bool has_item = false; /* Remove all IDs to be reloaded from Main. */ lba_idx = set_listbasepointers(bmain, lbarray); @@ -636,7 +630,6 @@ static void lib_relocate_do( BLI_remlink(lbarray[lba_idx], id); item = wm_link_append_data_item_add(lapp_data, id->name + 2, idcode, id); BLI_BITMAP_SET_ALL(item->libraries, true, lapp_data->num_libraries); - has_item = true; #ifdef PRINT_DEBUG printf("\tdatablock to seek for: %s\n", id->name); @@ -645,8 +638,8 @@ static void lib_relocate_do( } } - if (!has_item) { - /* nothing to relocate */ + if (lapp_data->num_items == 0) { + /* Early out in case there is nothing to do. */ return; } diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index fa5fd38b7b2..6da9101156a 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -41,7 +41,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_lasso.h" +#include "BLI_lasso_2d.h" #include "BKE_context.h" @@ -49,7 +49,6 @@ #include "WM_types.h" #include "wm.h" -#include "wm_subwindow.h" #include "wm_draw.h" #include "GPU_immediate.h" @@ -64,40 +63,37 @@ wmGesture *WM_gesture_new(bContext *C, const wmEvent *event, int type) wmGesture *gesture = MEM_callocN(sizeof(wmGesture), "new gesture"); wmWindow *window = CTX_wm_window(C); ARegion *ar = CTX_wm_region(C); - int sx, sy; BLI_addtail(&window->gesture, gesture); gesture->type = type; gesture->event_type = event->type; - gesture->swinid = ar->swinid; /* means only in area-region context! */ + gesture->winrct = ar->winrct; gesture->userdata_free = true; /* Free if userdata is set. */ gesture->modal_state = GESTURE_MODAL_NOP; - wm_subwindow_origin_get(window, gesture->swinid, &sx, &sy); - if (ELEM(type, WM_GESTURE_RECT, WM_GESTURE_CROSS_RECT, WM_GESTURE_TWEAK, WM_GESTURE_CIRCLE, WM_GESTURE_STRAIGHTLINE)) { rcti *rect = MEM_callocN(sizeof(rcti), "gesture rect new"); gesture->customdata = rect; - rect->xmin = event->x - sx; - rect->ymin = event->y - sy; + rect->xmin = event->x - gesture->winrct.xmin; + rect->ymin = event->y - gesture->winrct.ymin; if (type == WM_GESTURE_CIRCLE) { /* caller is responsible for initializing 'xmax' to radius. */ } else { - rect->xmax = event->x - sx; - rect->ymax = event->y - sy; + rect->xmax = event->x - gesture->winrct.xmin; + rect->ymax = event->y - gesture->winrct.ymin; } } else if (ELEM(type, WM_GESTURE_LINES, WM_GESTURE_LASSO)) { short *lasso; gesture->points_alloc = 1024; gesture->customdata = lasso = MEM_mallocN(sizeof(short[2]) * gesture->points_alloc, "lasso points"); - lasso[0] = event->x - sx; - lasso[1] = event->y - sy; + lasso[0] = event->x - gesture->winrct.xmin; + lasso[1] = event->y - gesture->winrct.ymin; gesture->points = 1; } @@ -273,14 +269,13 @@ static void draw_filled_lasso_px_cb(int x, int x_end, int y, void *user_data) memset(col, 0x10, x_end - x); } -static void draw_filled_lasso(wmWindow *win, wmGesture *gt) +static void draw_filled_lasso(wmGesture *gt) { const short *lasso = (short *)gt->customdata; const int tot = gt->points; int (*moves)[2] = MEM_mallocN(sizeof(*moves) * (tot + 1), __func__); int i; rcti rect; - rcti rect_win; float red[4] = {1.0f, 0.0f, 0.0f, 0.0f}; for (i = 0; i < tot; i++, lasso += 2) { @@ -290,10 +285,9 @@ static void draw_filled_lasso(wmWindow *win, wmGesture *gt) BLI_lasso_boundbox(&rect, (const int (*)[2])moves, tot); - wm_subwindow_rect_get(win, gt->swinid, &rect_win); - BLI_rcti_translate(&rect, rect_win.xmin, rect_win.ymin); - BLI_rcti_isect(&rect_win, &rect, &rect); - BLI_rcti_translate(&rect, -rect_win.xmin, -rect_win.ymin); + BLI_rcti_translate(&rect, gt->winrct.xmin, gt->winrct.ymin); + BLI_rcti_isect(>->winrct, &rect, &rect); + BLI_rcti_translate(&rect, -gt->winrct.xmin, -gt->winrct.ymin); /* highly unlikely this will fail, but could crash if (tot == 0) */ if (BLI_rcti_is_empty(&rect) == false) { @@ -335,13 +329,13 @@ static void draw_filled_lasso(wmWindow *win, wmGesture *gt) } -static void wm_gesture_draw_lasso(wmWindow *win, wmGesture *gt, bool filled) +static void wm_gesture_draw_lasso(wmGesture *gt, bool filled) { const short *lasso = (short *)gt->customdata; int i; if (filled) { - draw_filled_lasso(win, gt); + draw_filled_lasso(gt); } const int numverts = gt->points; @@ -425,7 +419,7 @@ void wm_gesture_draw(wmWindow *win) glLineWidth(1.0f); for (; gt; gt = gt->next) { /* all in subwindow space */ - wmSubWindowSet(win, gt->swinid); + wmViewport(>->winrct); if (gt->type == WM_GESTURE_RECT) wm_gesture_draw_rect(gt); @@ -442,9 +436,9 @@ void wm_gesture_draw(wmWindow *win) } } else if (gt->type == WM_GESTURE_LINES) - wm_gesture_draw_lasso(win, gt, false); + wm_gesture_draw_lasso(gt, false); else if (gt->type == WM_GESTURE_LASSO) - wm_gesture_draw_lasso(win, gt, true); + wm_gesture_draw_lasso(gt, true); else if (gt->type == WM_GESTURE_STRAIGHTLINE) wm_gesture_draw_line(gt); } diff --git a/source/blender/windowmanager/intern/wm_gesture_ops.c b/source/blender/windowmanager/intern/wm_gesture_ops.c index a554727cacd..01184f47920 100644 --- a/source/blender/windowmanager/intern/wm_gesture_ops.c +++ b/source/blender/windowmanager/intern/wm_gesture_ops.c @@ -47,7 +47,6 @@ #include "wm.h" #include "wm_event_types.h" #include "wm_event_system.h" -#include "wm_subwindow.h" #include "ED_screen.h" @@ -198,18 +197,15 @@ int WM_gesture_border_modal(bContext *C, wmOperator *op, const wmEvent *event) { wmGesture *gesture = op->customdata; rcti *rect = gesture->customdata; - int sx, sy; if (event->type == MOUSEMOVE) { - wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy); - if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->is_active == false) { - rect->xmin = rect->xmax = event->x - sx; - rect->ymin = rect->ymax = event->y - sy; + rect->xmin = rect->xmax = event->x - gesture->winrct.xmin; + rect->ymin = rect->ymax = event->y - gesture->winrct.ymin; } else { - rect->xmax = event->x - sx; - rect->ymax = event->y - sy; + rect->xmax = event->x - gesture->winrct.xmin; + rect->ymax = event->y - gesture->winrct.ymin; } gesture_border_apply_rect(op); @@ -333,13 +329,11 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event) { wmGesture *gesture = op->customdata; rcti *rect = gesture->customdata; - int sx, sy; if (event->type == MOUSEMOVE) { - wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy); - rect->xmin = event->x - sx; - rect->ymin = event->y - sy; + rect->xmin = event->x - gesture->winrct.xmin; + rect->ymin = event->y - gesture->winrct.ymin; wm_gesture_tag_redraw(C); @@ -464,24 +458,22 @@ static void gesture_tweak_modal(bContext *C, const wmEvent *event) wmWindow *window = CTX_wm_window(C); wmGesture *gesture = window->tweak; rcti *rect = gesture->customdata; - int sx, sy, val; + int val; switch (event->type) { case MOUSEMOVE: case INBETWEEN_MOUSEMOVE: - wm_subwindow_origin_get(window, gesture->swinid, &sx, &sy); - - rect->xmax = event->x - sx; - rect->ymax = event->y - sy; + rect->xmax = event->x - gesture->winrct.xmin; + rect->ymax = event->y - gesture->winrct.ymin; if ((val = wm_gesture_evaluate(gesture))) { wmEvent tevent; wm_event_init_from_window(window, &tevent); /* We want to get coord from start of drag, not from point where it becomes a tweak event, see T40549 */ - tevent.x = rect->xmin + sx; - tevent.y = rect->ymin + sy; + tevent.x = rect->xmin + gesture->winrct.xmin; + tevent.y = rect->ymin + gesture->winrct.ymin; if (gesture->event_type == LEFTMOUSE) tevent.type = EVT_TWEAK_L; else if (gesture->event_type == RIGHTMOUSE) @@ -617,7 +609,6 @@ static void gesture_lasso_apply(bContext *C, wmOperator *op) int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event) { wmGesture *gesture = op->customdata; - int sx, sy; switch (event->type) { case MOUSEMOVE: @@ -625,8 +616,6 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event) wm_gesture_tag_redraw(C); - wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy); - if (gesture->points == gesture->points_alloc) { gesture->points_alloc *= 2; gesture->customdata = MEM_reallocN(gesture->customdata, sizeof(short[2]) * gesture->points_alloc); @@ -637,15 +626,15 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event) short *lasso = gesture->customdata; lasso += (2 * gesture->points - 2); - x = (event->x - sx - lasso[0]); - y = (event->y - sy - lasso[1]); + x = (event->x - gesture->winrct.xmin - lasso[0]); + y = (event->y - gesture->winrct.ymin - lasso[1]); /* make a simple distance check to get a smoother lasso * add only when at least 2 pixels between this and previous location */ if ((x * x + y * y) > 4) { lasso += 2; - lasso[0] = event->x - sx; - lasso[1] = event->y - sy; + lasso[0] = event->x - gesture->winrct.xmin; + lasso[1] = event->y - gesture->winrct.ymin; gesture->points++; } } @@ -813,18 +802,15 @@ int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *ev { wmGesture *gesture = op->customdata; rcti *rect = gesture->customdata; - int sx, sy; if (event->type == MOUSEMOVE) { - wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy); - if (gesture->is_active == false) { - rect->xmin = rect->xmax = event->x - sx; - rect->ymin = rect->ymax = event->y - sy; + rect->xmin = rect->xmax = event->x - gesture->winrct.xmin; + rect->ymin = rect->ymax = event->y - gesture->winrct.ymin; } else { - rect->xmax = event->x - sx; - rect->ymax = event->y - sy; + rect->xmax = event->x - gesture->winrct.xmin; + rect->ymax = event->y - gesture->winrct.ymin; gesture_straightline_apply(C, op); } diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 55ed8b2a091..adb03de4612 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -256,7 +256,7 @@ void WM_init(bContext *C, int argc, const char **argv) clear_matcopybuf(); ED_render_clear_mtex_copybuf(); - // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + // glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); wm_history_file_read(); diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c index 528b9e2b3d9..f9fe787ed2d 100644 --- a/source/blender/windowmanager/intern/wm_jobs.c +++ b/source/blender/windowmanager/intern/wm_jobs.c @@ -418,8 +418,8 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job) // printf("job started: %s\n", wm_job->name); - BLI_init_threads(&wm_job->threads, do_job_thread, 1); - BLI_insert_thread(&wm_job->threads, wm_job); + BLI_threadpool_init(&wm_job->threads, do_job_thread, 1); + BLI_threadpool_insert(&wm_job->threads, wm_job); } /* restarted job has timer already */ @@ -450,7 +450,7 @@ static void wm_jobs_kill_job(wmWindowManager *wm, wmJob *wm_job) wm_job->stop = true; WM_job_main_thread_lock_release(wm_job); - BLI_end_threads(&wm_job->threads); + BLI_threadpool_end(&wm_job->threads); WM_job_main_thread_lock_acquire(wm_job); if (wm_job->endjob) @@ -601,7 +601,7 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt) wm_job->running = false; WM_job_main_thread_lock_release(wm_job); - BLI_end_threads(&wm_job->threads); + BLI_threadpool_end(&wm_job->threads); WM_job_main_thread_lock_acquire(wm_job); if (wm_job->endnote) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 8980c4acf26..579892734db 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -59,7 +59,7 @@ #include "PIL_time.h" #include "BLI_blenlib.h" -#include "BLI_dial.h" +#include "BLI_dial_2d.h" #include "BLI_dynstr.h" /*for WM_operator_pystring */ #include "BLI_math.h" #include "BLI_utildefines.h" @@ -3313,7 +3313,7 @@ static void redraw_timer_step( CTX_wm_area_set(C, sa_iter); for (ar_iter = sa_iter->regionbase.first; ar_iter; ar_iter = ar_iter->next) { - if (ar_iter->swinid) { + if (ar_iter->visible) { CTX_wm_region_set(C, ar_iter); ED_region_do_draw(C, ar_iter); ar_iter->do_draw = false; diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index fcb471530e0..d6a1eb81981 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -317,7 +317,7 @@ static void playanim_toscreen(PlayState *ps, PlayAnimPict *picture, struct ImBuf /* checkerboard for case alpha */ if (ibuf->planes == 32) { glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); imm_draw_box_checker_2d(offs_x, offs_y, offs_x + span_x, offs_y + span_y); } diff --git a/source/blender/windowmanager/intern/wm_stereo.c b/source/blender/windowmanager/intern/wm_stereo.c index 84b739a692e..b70769b2d51 100644 --- a/source/blender/windowmanager/intern/wm_stereo.c +++ b/source/blender/windowmanager/intern/wm_stereo.c @@ -110,10 +110,10 @@ static void wm_method_draw_stereo3d_interlace(wmWindow *win) const int sizey = WM_window_pixels_y(win); /* wmOrtho for the screen has this same offset */ - float ratiox = sizex; - float ratioy = sizey; - float halfx = GLA_PIXEL_OFS; - float halfy = GLA_PIXEL_OFS; + float ratiox = 1.0f; + float ratioy = 1.0f; + float halfx = GLA_PIXEL_OFS / sizex; + float halfy = GLA_PIXEL_OFS / sizex; Gwn_VertFormat *format = immVertexFormat(); unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); @@ -124,7 +124,7 @@ static void wm_method_draw_stereo3d_interlace(wmWindow *win) /* leave GL_TEXTURE0 as the latest bind texture */ for (int eye = 1; eye >= 0; eye--) { glActiveTexture(GL_TEXTURE0 + eye); - glBindTexture(drawdata[eye]->triple->target, drawdata[eye]->triple->bind); + glBindTexture(GL_TEXTURE_2D, drawdata[eye]->triple->bind); } immUniform1i("image_a", 0); @@ -149,8 +149,9 @@ static void wm_method_draw_stereo3d_interlace(wmWindow *win) immEnd(); immUnbindProgram(); - for (int eye = 0; eye < 2; eye++) { - glBindTexture(drawdata[eye]->triple->target, 0); + for (int eye = 1; eye >= 0; eye--) { + glActiveTexture(GL_TEXTURE0 + eye); + glBindTexture(GL_TEXTURE_2D, 0); } } @@ -194,7 +195,6 @@ static void wm_method_draw_stereo3d_sidebyside(wmWindow *win) { wmDrawData *drawdata; wmDrawTriple *triple; - float halfx, halfy, ratiox, ratioy; int view; int soffx; bool cross_eyed = (win->stereo3d_format->flag & S3D_SIDEBYSIDE_CROSSEYED) != 0; @@ -203,6 +203,8 @@ static void wm_method_draw_stereo3d_sidebyside(wmWindow *win) unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_ALPHA); + for (view = 0; view < 2; view ++) { drawdata = BLI_findlink(&win->drawdata, (view * 2) + 1); triple = drawdata->triple; @@ -217,27 +219,16 @@ static void wm_method_draw_stereo3d_sidebyside(wmWindow *win) soffx = 0; } - const int sizex = triple->x; - const int sizey = triple->y; + const int sizex = WM_window_pixels_x(win); + const int sizey = WM_window_pixels_y(win); /* wmOrtho for the screen has this same offset */ - ratiox = sizex; - ratioy = sizey; - halfx = GLA_PIXEL_OFS; - halfy = GLA_PIXEL_OFS; - - /* texture rectangle has unnormalized coordinates */ - if (triple->target == GL_TEXTURE_2D) { - ratiox /= triple->x; - ratioy /= triple->y; - halfx /= triple->x; - halfy /= triple->y; - } - - /* TODO: if target is always same for both eyes, bind program & set uniform before loop */ - immBindBuiltinProgram((triple->target == GL_TEXTURE_2D) ? GPU_SHADER_3D_IMAGE_MODULATE_ALPHA : GPU_SHADER_3D_IMAGE_RECT_MODULATE_ALPHA); + const float ratiox = 1.0f; + const float ratioy = 1.0f; + const float halfx = GLA_PIXEL_OFS / sizex; + const float halfy = GLA_PIXEL_OFS / sizey; - glBindTexture(triple->target, triple->bind); + glBindTexture(GL_TEXTURE_2D, triple->bind); immUniform1f("alpha", 1.0f); immUniform1i("image", 0); /* default GL_TEXTURE0 unit */ @@ -257,18 +248,16 @@ static void wm_method_draw_stereo3d_sidebyside(wmWindow *win) immVertex2f(pos, soffx, sizey); immEnd(); - - /* TODO: if target is always same for both eyes, unbind program & texture target after loop */ - glBindTexture(triple->target, 0); - immUnbindProgram(); } + + glBindTexture(GL_TEXTURE_2D, 0); + immUnbindProgram(); } static void wm_method_draw_stereo3d_topbottom(wmWindow *win) { wmDrawData *drawdata; wmDrawTriple *triple; - float halfx, halfy, ratiox, ratioy; int view; int soffy; @@ -276,6 +265,8 @@ static void wm_method_draw_stereo3d_topbottom(wmWindow *win) unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_ALPHA); + for (view = 0; view < 2; view ++) { drawdata = BLI_findlink(&win->drawdata, (view * 2) + 1); triple = drawdata->triple; @@ -287,27 +278,16 @@ static void wm_method_draw_stereo3d_topbottom(wmWindow *win) soffy = 0; } - const int sizex = triple->x; - const int sizey = triple->y; + const int sizex = WM_window_pixels_x(win); + const int sizey = WM_window_pixels_y(win); /* wmOrtho for the screen has this same offset */ - ratiox = sizex; - ratioy = sizey; - halfx = GLA_PIXEL_OFS; - halfy = GLA_PIXEL_OFS; - - /* texture rectangle has unnormalized coordinates */ - if (triple->target == GL_TEXTURE_2D) { - ratiox /= triple->x; - ratioy /= triple->y; - halfx /= triple->x; - halfy /= triple->y; - } - - /* TODO: if target is always same for both eyes, bind program & set uniforms before loop */ - immBindBuiltinProgram((triple->target == GL_TEXTURE_2D) ? GPU_SHADER_3D_IMAGE_MODULATE_ALPHA : GPU_SHADER_3D_IMAGE_RECT_MODULATE_ALPHA); + const float ratiox = 1.0f; + const float ratioy = 1.0f; + const float halfx = GLA_PIXEL_OFS / sizex; + const float halfy = GLA_PIXEL_OFS / sizey; - glBindTexture(triple->target, triple->bind); + glBindTexture(GL_TEXTURE_2D, triple->bind); immUniform1f("alpha", 1.0f); immUniform1i("image", 0); /* default GL_TEXTURE0 unit */ @@ -327,11 +307,10 @@ static void wm_method_draw_stereo3d_topbottom(wmWindow *win) immVertex2f(pos, 0.0f, soffy + (sizey * 0.5f)); immEnd(); - - /* TODO: if target is always same for both eyes, unbind program & texture target after loop */ - immUnbindProgram(); - glBindTexture(triple->target, 0); } + + immUnbindProgram(); + glBindTexture(GL_TEXTURE_2D, 0); } void wm_method_draw_stereo3d(const bContext *UNUSED(C), wmWindow *win) diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index 57085d4f4bd..5ca34880743 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -21,317 +21,87 @@ * Contributor(s): 2007 Blender Foundation (refactor) * * ***** END GPL LICENSE BLOCK ***** - * - * - * Subwindow opengl handling. - * BTW: subwindows open/close in X11 are way too slow, tried it, and choose for my own system... (ton) - * */ /** \file blender/windowmanager/intern/wm_subwindow.c * \ingroup wm * - * Internal subwindows used for OpenGL state, used for regions and screens. + * OpenGL utilities for setting up 2D viewport for window and regions. */ -#include <string.h> - -#include "MEM_guardedalloc.h" +#include "BLI_math.h" +#include "BLI_rect.h" -#include "DNA_windowmanager_types.h" #include "DNA_screen_types.h" - -#include "BLI_blenlib.h" -#include "BLI_math.h" -#include "BLI_utildefines.h" +#include "DNA_windowmanager_types.h" #include "BIF_gl.h" #include "GPU_matrix.h" #include "WM_api.h" -#include "wm_subwindow.h" - -/** - * \note #wmSubWindow stored in #wmWindow but not exposed outside this C file, - * it seems a bit redundant (area regions can store it too, but we keep it - * because we can store all kind of future opengl fanciness here. - * - * We use indices and array because: - * - index has safety, no pointers from this C file hanging around - * - fast lookups of indices with array, list would give overhead - * - old code used it this way... - * - keep option open to have 2 screens using same window - */ - -typedef struct wmSubWindow { - struct wmSubWindow *next, *prev; - - rcti winrct; - int swinid; -} wmSubWindow; - - -/* ******************* open, free, set, get data ******************** */ - -/* not subwindow itself */ -static void wm_subwindow_free(wmSubWindow *UNUSED(swin)) -{ - /* future fancy stuff */ -} - -void wm_subwindows_free(wmWindow *win) -{ - wmSubWindow *swin; - - for (swin = win->subwindows.first; swin; swin = swin->next) - wm_subwindow_free(swin); - - BLI_freelistN(&win->subwindows); -} - - -int wm_subwindow_get_id(wmWindow *win) -{ - if (win->curswin) - return win->curswin->swinid; - return 0; -} - -static wmSubWindow *swin_from_swinid(wmWindow *win, int swinid) -{ - wmSubWindow *swin; - - for (swin = win->subwindows.first; swin; swin = swin->next) - if (swin->swinid == swinid) - break; - return swin; -} - -static void wm_swin_size_get(wmSubWindow *swin, int *x, int *y) -{ - *x = BLI_rcti_size_x(&swin->winrct) + 1; - *y = BLI_rcti_size_y(&swin->winrct) + 1; -} -void wm_subwindow_size_get(wmWindow *win, int swinid, int *x, int *y) +void wmViewport(const rcti *winrct) { - wmSubWindow *swin = swin_from_swinid(win, swinid); - - if (swin) { - wm_swin_size_get(swin, x, y); - } -} + int width = BLI_rcti_size_x(winrct) + 1; + int height = BLI_rcti_size_y(winrct) + 1; + glViewport(winrct->xmin, winrct->ymin, width, height); + glScissor(winrct->xmin, winrct->ymin, width, height); -static void wm_swin_origin_get(wmSubWindow *swin, int *x, int *y) -{ - *x = swin->winrct.xmin; - *y = swin->winrct.ymin; -} -void wm_subwindow_origin_get(wmWindow *win, int swinid, int *x, int *y) -{ - wmSubWindow *swin = swin_from_swinid(win, swinid); - - if (swin) { - wm_swin_origin_get(swin, x, y); - } + wmOrtho2_pixelspace(width, height); + gpuLoadIdentity(); } - -static void wm_swin_matrix_get(wmWindow *win, wmSubWindow *swin, float mat[4][4]) +void wmPartialViewport(rcti *drawrct, const rcti *winrct, const rcti *partialrct) { - const bScreen *screen = WM_window_get_active_screen(win); + /* Setup part of the viewport for partial redraw. */ + bool scissor_pad; - /* used by UI, should find a better way to get the matrix there */ - if (swin->swinid == screen->mainwin) { - int width, height; - - wm_swin_size_get(swin, &width, &height); - orthographic_m4(mat, -GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS, -100, 100); + if (partialrct->xmin == partialrct->xmax) { + /* Full region. */ + *drawrct = *winrct; + scissor_pad = true; } else { - gpuGetProjectionMatrix(mat); - } -} -void wm_subwindow_matrix_get(wmWindow *win, int swinid, float mat[4][4]) -{ - wmSubWindow *swin = swin_from_swinid(win, swinid); - - if (swin) { - wm_swin_matrix_get(win, swin, mat); - } -} - - -static void wm_swin_rect_get(wmSubWindow *swin, rcti *r_rect) -{ - *r_rect = swin->winrct; -} -void wm_subwindow_rect_get(wmWindow *win, int swinid, rcti *r_rect) -{ - wmSubWindow *swin = swin_from_swinid(win, swinid); - - if (swin) { - wm_swin_rect_get(swin, r_rect); - } -} - - -static void wm_swin_rect_set(wmSubWindow *swin, const rcti *rect) -{ - swin->winrct = *rect; -} -void wm_subwindow_rect_set(wmWindow *win, int swinid, const rcti *rect) -{ - wmSubWindow *swin = swin_from_swinid(win, swinid); - - if (swin) { - wm_swin_rect_set(swin, rect); - } -} - - -/* always sets pixel-precise 2D window/view matrices */ -/* coords is in whole pixels. xmin = 15, xmax = 16: means window is 2 pix big */ -int wm_subwindow_open(wmWindow *win, const rcti *winrct, bool activate) -{ - wmSubWindow *swin; - int width, height; - int freewinid = 1; - - for (swin = win->subwindows.first; swin; swin = swin->next) - if (freewinid <= swin->swinid) - freewinid = swin->swinid + 1; - - win->curswin = swin = MEM_callocN(sizeof(wmSubWindow), "swinopen"); - BLI_addtail(&win->subwindows, swin); - - swin->swinid = freewinid; - swin->winrct = *winrct; - - if (activate) { - /* and we appy it all right away */ - wmSubWindowSet(win, swin->swinid); - - /* extra service */ - wm_swin_size_get(swin, &width, &height); - wmOrtho2_pixelspace(width, height); - gpuLoadIdentity(); + /* Partial redraw, clipped to region. */ + BLI_rcti_isect(winrct, partialrct, drawrct); + scissor_pad = false; } - return swin->swinid; -} + int x = drawrct->xmin; + int y = drawrct->ymin; + int width = BLI_rcti_size_x(winrct) + 1; + int height = BLI_rcti_size_y(winrct) + 1; -void wm_subwindow_close(wmWindow *win, int swinid) -{ - wmSubWindow *swin = swin_from_swinid(win, swinid); + int scissor_width = BLI_rcti_size_x(drawrct); + int scissor_height = BLI_rcti_size_y(drawrct); - if (swin) { - if (swin == win->curswin) - win->curswin = NULL; - wm_subwindow_free(swin); - BLI_remlink(&win->subwindows, swin); - MEM_freeN(swin); + /* Partial redraw rect uses different convention than region rect, + * so compensate for that here. One pixel offset is noticeable with + * viewport border render. */ + if (scissor_pad) { + scissor_width += 1; + scissor_height += 1; } - else { - printf("%s: Internal error, bad winid: %d\n", __func__, swinid); - } -} -/* pixels go from 0-99 for a 100 pixel window */ -void wm_subwindow_position(wmWindow *win, int swinid, const rcti *winrct, bool activate) -{ - wmSubWindow *swin = swin_from_swinid(win, swinid); - - if (swin) { - const int window_size_x = WM_window_pixels_x(win); - const int window_size_y = WM_window_pixels_y(win); + glViewport(x, y, width, height); + glScissor(x, y, scissor_width, scissor_height); - int width, height; - - swin->winrct = *winrct; - - /* CRITICAL, this clamping ensures that - * the viewport never goes outside the screen - * edges (assuming the x, y coords aren't - * outside). This caused a hardware lock - * on Matrox cards if it happens. - * - * Really Blender should never _ever_ try - * to do such a thing, but just to be safe - * clamp it anyway (or fix the bScreen - * scaling routine, and be damn sure you - * fixed it). - zr (2001!) - */ - - if (swin->winrct.xmax > window_size_x) - swin->winrct.xmax = window_size_x; - if (swin->winrct.ymax > window_size_y) - swin->winrct.ymax = window_size_y; - - if (activate) { - /* extra service */ - wmSubWindowSet(win, swinid); - wm_swin_size_get(swin, &width, &height); - wmOrtho2_pixelspace(width, height); - } - } - else { - printf("%s: Internal error, bad winid: %d\n", __func__, swinid); - } + wmOrtho2_pixelspace(width, height); + gpuLoadIdentity(); } -/* ---------------- WM versions of OpenGL style API calls ------------------------ */ -/* ----------------- exported in WM_api.h ------------------------------------------------------ */ - -/* internal state, no threaded opengl! XXX */ -static wmWindow *_curwindow = NULL; -static wmSubWindow *_curswin = NULL; - -void wmSubWindowScissorSet(wmWindow *win, int swinid, const rcti *srct, bool srct_pad) +void wmWindowViewport(wmWindow *win) { - int width, height; - _curswin = swin_from_swinid(win, swinid); - - if (_curswin == NULL) { - printf("%s %d: doesn't exist\n", __func__, swinid); - return; - } - - win->curswin = _curswin; - _curwindow = win; - - width = BLI_rcti_size_x(&_curswin->winrct) + 1; - height = BLI_rcti_size_y(&_curswin->winrct) + 1; - glViewport(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height); - - if (srct) { - int scissor_width = BLI_rcti_size_x(srct); - int scissor_height = BLI_rcti_size_y(srct); + int width = WM_window_pixels_x(win); + int height = WM_window_pixels_y(win); - /* typically a single pixel doesn't matter, - * but one pixel offset is noticeable with viewport border render */ - if (srct_pad) { - scissor_width += 1; - scissor_height += 1; - } + glViewport(0, 0, width, height); + glScissor(0, 0, width, height); - glScissor(srct->xmin, srct->ymin, scissor_width, scissor_height); - } - else - glScissor(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height); - wmOrtho2_pixelspace(width, height); gpuLoadIdentity(); - - glFlush(); -} - -/* enable the WM versions of opengl calls */ -void wmSubWindowSet(wmWindow *win, int swinid) -{ - wmSubWindowScissorSet(win, swinid, NULL, true); } void wmOrtho2(float x1, float x2, float y1, float y2) @@ -348,9 +118,7 @@ static void wmOrtho2_offset(const float x, const float y, const float ofs) wmOrtho2(ofs, x + ofs, ofs, y + ofs); } -/** - * default pixel alignment. - */ +/* Default pixel alignment for regions. */ void wmOrtho2_region_pixelspace(const ARegion *ar) { wmOrtho2_offset(ar->winx, ar->winy, -0.01f); @@ -361,5 +129,9 @@ void wmOrtho2_pixelspace(const float x, const float y) wmOrtho2_offset(x, y, -GLA_PIXEL_OFS); } -/* ********** END MY WINDOW ************** */ - +void wmGetProjectionMatrix(float mat[4][4], const rcti *winrct) +{ + int width = BLI_rcti_size_x(winrct) + 1; + int height = BLI_rcti_size_y(winrct) + 1; + orthographic_m4(mat, -GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS, -100, 100); +} diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index a1d9edd2e96..60e67bb2129 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -68,7 +68,6 @@ #include "wm.h" #include "wm_draw.h" #include "wm_window.h" -#include "wm_subwindow.h" #include "wm_event_system.h" #include "ED_scene.h" @@ -175,7 +174,6 @@ static void wm_ghostwindow_destroy(wmWindow *win) if (win->ghostwin) { GHOST_DisposeWindow(g_system, win->ghostwin); win->ghostwin = NULL; - win->multisamples = 0; } } @@ -228,7 +226,6 @@ void wm_window_free(bContext *C, wmWindowManager *wm, wmWindow *win) if (win->eventstate) MEM_freeN(win->eventstate); wm_event_free_all(win); - wm_subwindows_free(win); wm_draw_data_free(win); @@ -474,16 +471,8 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm, const char *title, wm { GHOST_WindowHandle ghostwin; GHOST_GLSettings glSettings = {0}; - static int multisamples = -1; int scr_w, scr_h, posy; - /* force setting multisamples only once, it requires restart - and you cannot - * mix it, either all windows have it, or none (tested in OSX opengl) */ - if (multisamples == -1) - multisamples = U.ogl_multisamples; - - glSettings.numOfAASamples = multisamples; - /* a new window is created when pageflip mode is required for a window */ if (win->stereo3d_format->display_mode == S3D_DISPLAY_PAGEFLIP) glSettings.flags |= GHOST_glStereoVisual; @@ -521,9 +510,6 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm, const char *title, wm if (win->eventstate == NULL) win->eventstate = MEM_callocN(sizeof(wmEvent), "window event state"); - /* store multisamples window was created with, in case user prefs change */ - win->multisamples = multisamples; - /* store actual window size in blender window */ bounds = GHOST_GetClientBounds(win->ghostwin); @@ -1627,6 +1613,7 @@ wmTimer *WM_event_add_timer_notifier(wmWindowManager *wm, wmWindow *win, unsigne wt->timestep = timestep; wt->win = win; wt->customdata = SET_UINT_IN_POINTER(type); + wt->flags |= WM_TIMER_NO_FREE_CUSTOM_DATA; BLI_addtail(&wm->timers, wt); @@ -1648,8 +1635,9 @@ void WM_event_remove_timer(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer * wm->reports.reporttimer = NULL; BLI_remlink(&wm->timers, wt); - if (wt->customdata) + if (wt->customdata != NULL && (wt->flags & WM_TIMER_NO_FREE_CUSTOM_DATA) == 0) { MEM_freeN(wt->customdata); + } MEM_freeN(wt); /* there might be events in queue with this timer as customdata */ @@ -1979,6 +1967,18 @@ WorkSpace *WM_windows_workspace_get_from_screen(const wmWindowManager *wm, const return NULL; } +eObjectMode WM_windows_object_mode_get(const struct wmWindowManager *wm) +{ + eObjectMode object_mode = 0; + for (wmWindow *win = wm->windows.first; win; win = win->next) { + const WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); + if (workspace != NULL) { + object_mode |= workspace->object_mode; + } + } + return object_mode; +} + Scene *WM_window_get_active_scene(const wmWindow *win) { return win->scene; diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c index a9875020fbb..153052d7e1c 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c @@ -390,16 +390,9 @@ static void manipulators_draw_list(const wmManipulatorMap *mmap, const bContext return; } - const bool draw_multisample = (U.ogl_multisamples != USER_MULTISAMPLE_NONE); - /* TODO this will need it own shader probably? don't think it can be handled from that point though. */ /* const bool use_lighting = (U.manipulator_flag & V3D_MANIPULATOR_SHADED) != 0; */ - /* enable multisampling */ - if (draw_multisample) { - glEnable(GL_MULTISAMPLE); - } - bool is_depth_prev = false; /* draw_manipulators contains all visible manipulators - draw them */ @@ -435,10 +428,6 @@ static void manipulators_draw_list(const wmManipulatorMap *mmap, const bContext if (is_depth_prev) { glDisable(GL_DEPTH_TEST); } - - if (draw_multisample) { - glDisable(GL_MULTISAMPLE); - } } void WM_manipulatormap_draw( @@ -619,7 +608,7 @@ wmManipulator *wm_manipulatormap_highlight_find( if (do_step[step]) { if ((mmap->update_flag[step] & MANIPULATORMAP_IS_REFRESH_CALLBACK) && - (mgroup->type->refresh != NULL)) + (mgroup->type->refresh != NULL)) { mgroup->type->refresh(C, mgroup); /* cleared below */ @@ -760,7 +749,7 @@ static bool wm_manipulatormap_select_all_intern( int i; bool changed = false; - wm_manipulatormap_select_array_ensure_len_alloc(mmap, BLI_ghash_size(hash)); + wm_manipulatormap_select_array_ensure_len_alloc(mmap, BLI_ghash_len(hash)); GHASH_ITER_INDEX (gh_iter, hash, i) { wmManipulator *mpr_iter = BLI_ghashIterator_getValue(&gh_iter); @@ -769,7 +758,7 @@ static bool wm_manipulatormap_select_all_intern( /* highlight first manipulator */ wm_manipulatormap_highlight_set(mmap, C, msel->items[0], msel->items[0]->highlight_part); - BLI_assert(BLI_ghash_size(hash) == msel->len); + BLI_assert(BLI_ghash_len(hash) == msel->len); BLI_ghash_free(hash, NULL, NULL); return changed; diff --git a/source/blender/windowmanager/message_bus/intern/wm_message_bus.c b/source/blender/windowmanager/message_bus/intern/wm_message_bus.c index 7183655b0de..dba38dc8c8c 100644 --- a/source/blender/windowmanager/message_bus/intern/wm_message_bus.c +++ b/source/blender/windowmanager/message_bus/intern/wm_message_bus.c @@ -86,6 +86,9 @@ void WM_msgbus_clear_by_owner(struct wmMsgBus *mbus, void *owner) for (wmMsgSubscribeValueLink *msg_lnk = msg_key->values.first; msg_lnk; msg_lnk = msg_lnk_next) { msg_lnk_next = msg_lnk->next; if (msg_lnk->params.owner == owner) { + if (msg_lnk->params.tag) { + mbus->messages_tag_count -= 1; + } if (msg_lnk->params.free_data) { msg_lnk->params.free_data(msg_key, &msg_lnk->params); } diff --git a/source/blender/windowmanager/message_bus/intern/wm_message_bus_static.c b/source/blender/windowmanager/message_bus/intern/wm_message_bus_static.c index 59bebad7f7b..d768e77c8fe 100644 --- a/source/blender/windowmanager/message_bus/intern/wm_message_bus_static.c +++ b/source/blender/windowmanager/message_bus/intern/wm_message_bus_static.c @@ -18,7 +18,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/windowmanager/intern/wm_message_bus_static.c +/** \file blender/windowmanager/intern/message_bus/wm_message_bus_static.c * \ingroup wm */ diff --git a/source/blender/windowmanager/message_bus/wm_message_bus.h b/source/blender/windowmanager/message_bus/wm_message_bus.h index 53f283cacd2..8a800d18101 100644 --- a/source/blender/windowmanager/message_bus/wm_message_bus.h +++ b/source/blender/windowmanager/message_bus/wm_message_bus.h @@ -18,7 +18,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/windowmanager/wm_message_bus.h +/** \file blender/windowmanager/message_bus/wm_message_bus.h * \ingroup wm */ diff --git a/source/blender/windowmanager/wm_draw.h b/source/blender/windowmanager/wm_draw.h index 56dff304719..fa3d443e6ae 100644 --- a/source/blender/windowmanager/wm_draw.h +++ b/source/blender/windowmanager/wm_draw.h @@ -34,12 +34,8 @@ #include "GPU_glew.h" -#define USE_TEXTURE_RECTANGLE 1 - typedef struct wmDrawTriple { GLuint bind; - int x, y; - GLenum target; } wmDrawTriple; typedef struct wmDrawData { diff --git a/source/blender/windowmanager/wm_subwindow.h b/source/blender/windowmanager/wm_subwindow.h deleted file mode 100644 index cc9abf87514..00000000000 --- a/source/blender/windowmanager/wm_subwindow.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2007 Blender Foundation. - * All rights reserved. - * - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/windowmanager/wm_subwindow.h - * \ingroup wm - */ - - -#ifndef __WM_SUBWINDOW_H__ -#define __WM_SUBWINDOW_H__ - - -/* *************** internal api ************** */ -void wm_subwindows_free(wmWindow *win); - -int wm_subwindow_open(wmWindow *win, const rcti *winrct, bool activate); -void wm_subwindow_close(wmWindow *win, int swinid); -int wm_subwindow_get_id(wmWindow *win); /* returns id */ - -void wm_subwindow_position(wmWindow *win, int swinid, const rcti *winrct, bool activate); - -void wm_subwindow_size_get(wmWindow *win, int swinid, int *x, int *y); -void wm_subwindow_origin_get(wmWindow *win, int swinid, int *x, int *y); -void wm_subwindow_matrix_get(wmWindow *win, int swinid, float mat[4][4]); -void wm_subwindow_rect_get(wmWindow *win, int swinid, struct rcti *r_rect); -void wm_subwindow_rect_set(wmWindow *win, int swinid, const rcti *rect); - -#endif /* __WM_SUBWINDOW_H__ */ - diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt index 328453df118..dc7acb5ccd7 100644 --- a/source/blenderplayer/CMakeLists.txt +++ b/source/blenderplayer/CMakeLists.txt @@ -197,10 +197,6 @@ endif() list(APPEND BLENDER_SORTED_LIBS extern_ceres) endif() - if(WITH_MOD_BOOLEAN) - list(APPEND BLENDER_SORTED_LIBS extern_carve) - endif() - if(WITH_GHOST_XDND) list(APPEND BLENDER_SORTED_LIBS extern_xdnd) endif() diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 332a64f138f..a0489d7609a 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -448,7 +448,7 @@ void UI_view2d_sync(struct bScreen *screen, struct ScrArea *sa, struct View2D *v struct EditBone *ED_armature_bone_get_mirrored(const struct ListBase *edbo, EditBone *ebo) RET_NULL struct EditBone *ED_armature_edit_bone_add(struct bArmature *arm, const char *name) RET_NULL -struct ListBase *get_active_constraints (struct Object *ob) RET_NULL +struct ListBase *get_active_constraints (const struct EvaluationContext *eval_ctx, struct Object *ob) RET_NULL struct ListBase *get_constraint_lb(struct Object *ob, struct bConstraint *con, struct bPoseChannel **r_pchan) RET_NULL bool ED_space_image_show_uvedit(struct SpaceImage *sima, struct Object *obedit) RET_ZERO @@ -521,7 +521,7 @@ bool ANIM_remove_driver(struct ReportList *reports, struct ID *id, const char rn void ED_space_image_release_buffer(struct SpaceImage *sima, struct ImBuf *ibuf, void *lock) RET_NONE struct ImBuf *ED_space_image_acquire_buffer(struct SpaceImage *sima, void **r_lock) RET_NULL void ED_space_image_get_zoom(struct SpaceImage *sima, struct ARegion *ar, float *zoomx, float *zoomy) RET_NONE -const char *ED_info_stats_string(struct Scene *scene, struct ViewLayer *view_layer) RET_NULL +const char *ED_info_stats_string(struct Scene *scene, struct WorkSpace *workspace, struct ViewLayer *view_layer) RET_NULL void ED_area_tag_redraw(struct ScrArea *sa) RET_NONE void ED_area_tag_refresh(struct ScrArea *sa) RET_NONE void ED_area_newspace(struct bContext *C, struct ScrArea *sa, int type, const bool skip_ar_exit) RET_NONE @@ -548,21 +548,25 @@ void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, bool do_c void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist) RET_NONE void ED_view3d_update_viewmat(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4], const struct rcti *rect) RET_NONE float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit) RET_ZERO -void ED_view3d_shade_update(struct Main *bmain, struct Scene *scene, struct View3D *v3d, struct ScrArea *sa) RET_NONE +void ED_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrArea *sa) RET_NONE void ED_node_shader_default(const struct bContext *C, struct ID *id) RET_NONE void ED_screen_animation_timer_update(struct bScreen *screen, int redraws, int refresh) RET_NONE struct bScreen *ED_screen_animation_playing(const struct wmWindowManager *wm) RET_NULL struct Scene *ED_screen_scene_find(const struct bScreen *screen, const struct wmWindowManager *wm) RET_NULL +struct Scene *ED_screen_scene_find_with_window(const struct bScreen *screen, const struct wmWindowManager *wm, struct wmWindow **r_window) RET_NULL +struct wmWindow *ED_screen_window_find(const struct bScreen *screen, const struct wmWindowManager *wm) RET_NULL; void ED_screen_global_topbar_area_create(const struct bContext *C, struct wmWindow *win, const struct bScreen *screen) RET_NONE bool ED_scene_view_layer_delete(struct Main *bmain, Scene *scene, ViewLayer *layer, ReportList *reports) RET_ZERO void ED_object_base_select(struct Base *base, eObjectSelect_Mode mode) RET_NONE +void ED_object_base_activate(struct bContext *C, struct Base *base) RET_NONE bool ED_object_modifier_remove(struct ReportList *reports, struct Main *bmain, struct Object *ob, struct ModifierData *md) RET_ZERO -struct ModifierData *ED_object_modifier_add(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob, const char *name, int type) RET_ZERO +struct ModifierData *ED_object_modifier_add(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob, eObjectMode object_mode, const char *name, int type) RET_ZERO void ED_object_modifier_clear(struct Main *bmain, struct Object *ob) RET_NONE void ED_object_editmode_enter(struct bContext *C, int flag) RET_NONE void ED_object_editmode_exit(struct bContext *C, int flag) RET_NONE +void ED_object_editmode_exit_ex(struct bContext *C, struct WorkSpace *workspace, struct Scene *scene, struct Object *obedit, int flag) RET_NONE bool ED_object_editmode_load(struct Object *obedit) RET_ZERO -void ED_object_check_force_modifiers(struct Main *bmain, struct Scene *scene, struct Object *object) RET_NONE +void ED_object_check_force_modifiers(struct Main *bmain, struct Scene *scene, struct Object *object, eObjectMode object_mode) RET_NONE bool uiLayoutGetActive(struct uiLayout *layout) RET_ZERO int uiLayoutGetOperatorContext(struct uiLayout *layout) RET_ZERO int uiLayoutGetAlignment(struct uiLayout *layout) RET_ZERO @@ -602,7 +606,7 @@ int ED_mesh_mirror_spatial_table(struct Object *ob, struct BMEditMesh *em, struc float ED_rollBoneToVector(EditBone *bone, const float new_up_axis[3], const bool axis_only) RET_ZERO void ED_space_image_get_size(struct SpaceImage *sima, int *width, int *height) RET_NONE -bool ED_space_image_check_show_maskedit(struct ViewLayer *view_layer, struct SpaceImage *sima) RET_ZERO +bool ED_space_image_check_show_maskedit(struct SpaceImage *sima, const struct WorkSpace *workspace, struct ViewLayer *view_layer) RET_ZERO bool ED_texture_context_check_world(const struct bContext *C) RET_ZERO bool ED_texture_context_check_material(const struct bContext *C) RET_ZERO @@ -774,7 +778,7 @@ void RE_point_density_cache(struct Scene *scene, struct ViewLayer *view_layer, s void RE_point_density_minmax(struct Scene *scene, struct ViewLayer *view_layer, struct PointDensity *pd, const bool use_render_params, float r_min[3], float r_max[3]) RET_NONE void RE_point_density_sample(struct Scene *scene, struct ViewLayer *view_layer, struct PointDensity *pd, const int resolution, const bool use_render_params, float *values) RET_NONE void RE_point_density_free(struct PointDensity *pd) RET_NONE -void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]) RET_NONE +void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *random, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]) RET_NONE void RE_FreeAllPersistentData(void) RET_NONE float RE_fresnel_dielectric(float incoming[3], float normal[3], float eta) RET_ZERO void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer, const char *name, int channels, const char *chanid, int type) RET_NONE diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index c5acd7e640e..b6229539cd9 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -1030,70 +1030,4 @@ if(WIN32 AND NOT WITH_PYTHON_MODULE) COMPONENT Blender DESTINATION "." ) - if(CMAKE_CL_64) - set(_WIN_PLATFORM x64) - else() - set(_WIN_PLATFORM x86) - endif() - if(MSVC12_REDIST_DIR) - install( - FILES - ${MSVC12_REDIST_DIR}/${_WIN_PLATFORM}/Microsoft.VC120.CRT/msvcp120.dll - ${MSVC12_REDIST_DIR}/${_WIN_PLATFORM}/Microsoft.VC120.CRT/msvcr120.dll - DESTINATION "." - ) - if(WITH_OPENMP) - install( - FILES ${MSVC12_REDIST_DIR}/${_WIN_PLATFORM}/Microsoft.VC120.OpenMP/vcomp120.dll - DESTINATION "." - ) - endif() - endif() - - if(MSVC14_REDIST_DIR) - set(KITSDIRx86 "$ENV{${ProgramFilesX86_NAME}}/Windows Kits/10/") - set(KITSDIR "$ENV{ProgramFiles}/Windows Kits/10/") - if(IS_DIRECTORY ${KITSDIR}) - set(KITSPATH "${KITSDIR}/Redist/ucrt/DLLs/${_WIN_PLATFORM}") - else() - if(IS_DIRECTORY ${KITSDIRx86}) - set(KITSPATH "${KITSDIRx86}/Redist/ucrt/DLLs/${_WIN_PLATFORM}") - else() - message(FATAL_ERROR "Windows 10 SDK directory not found") - endif() - endif() - FILE(TO_CMAKE_PATH ${KITSPATH} KITSPATH) - install( - FILES - ${KITSPATH}/api-ms-win-core-file-l1-2-0.dll - ${KITSPATH}/api-ms-win-core-file-l2-1-0.dll - ${KITSPATH}/api-ms-win-core-localization-l1-2-0.dll - ${KITSPATH}/api-ms-win-core-processthreads-l1-1-0.dll - ${KITSPATH}/api-ms-win-core-processthreads-l1-1-1.dll - ${KITSPATH}/api-ms-win-core-synch-l1-1-0.dll - ${KITSPATH}/api-ms-win-core-synch-l1-2-0.dll - ${KITSPATH}/api-ms-win-core-timezone-l1-1-0.dll - ${KITSPATH}/api-ms-win-crt-conio-l1-1-0.dll - ${KITSPATH}/api-ms-win-crt-convert-l1-1-0.dll - ${KITSPATH}/api-ms-win-crt-environment-l1-1-0.dll - ${KITSPATH}/api-ms-win-crt-filesystem-l1-1-0.dll - ${KITSPATH}/api-ms-win-crt-heap-l1-1-0.dll - ${KITSPATH}/api-ms-win-crt-locale-l1-1-0.dll - ${KITSPATH}/api-ms-win-crt-math-l1-1-0.dll - ${KITSPATH}/api-ms-win-crt-process-l1-1-0.dll - ${KITSPATH}/api-ms-win-crt-runtime-l1-1-0.dll - ${KITSPATH}/api-ms-win-crt-stdio-l1-1-0.dll - ${KITSPATH}/api-ms-win-crt-string-l1-1-0.dll - ${KITSPATH}/api-ms-win-crt-time-l1-1-0.dll - ${KITSPATH}/ucrtbase.dll - ${MSVC14_REDIST_DIR}/${_WIN_PLATFORM}/Microsoft.VC140.CRT/vcruntime140.dll - DESTINATION "." - ) - if(WITH_OPENMP) - install( - FILES ${MSVC14_REDIST_DIR}/${_WIN_PLATFORM}/Microsoft.VC140.OpenMP/vcomp140.dll - DESTINATION "." - ) - endif() - endif() endif() diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c index 6b47d7c3474..fba3189d5ed 100644 --- a/source/creator/creator_args.c +++ b/source/creator/creator_args.c @@ -1348,7 +1348,7 @@ static const char arg_handle_render_frame_doc[] = "\n" "\t* +<frame> start frame relative, -<frame> end frame relative.\n" "\t* A comma separated list of frames can also be used (no spaces).\n" -"\t* A range of frames can be expressed using '..' seperator between the first and last frames (inclusive).\n" +"\t* A range of frames can be expressed using '..' separator between the first and last frames (inclusive).\n" ; static int arg_handle_render_frame(int argc, const char **argv, void *data) { @@ -1373,7 +1373,7 @@ static int arg_handle_render_frame(int argc, const char **argv, void *data) } re = RE_NewSceneRender(scene); - BLI_begin_threaded_malloc(); + BLI_threaded_malloc_begin(); BKE_reports_init(&reports, RPT_STORE); RE_SetReports(re, &reports); render_set_depgraph(C, re); @@ -1390,7 +1390,7 @@ static int arg_handle_render_frame(int argc, const char **argv, void *data) } RE_SetReports(re, NULL); BKE_reports_clear(&reports); - BLI_end_threaded_malloc(); + BLI_threaded_malloc_end(); MEM_freeN(frame_range_arr); return 1; } @@ -1416,14 +1416,14 @@ static int arg_handle_render_animation(int UNUSED(argc), const char **UNUSED(arg Main *bmain = CTX_data_main(C); Render *re = RE_NewSceneRender(scene); ReportList reports; - BLI_begin_threaded_malloc(); + BLI_threaded_malloc_begin(); BKE_reports_init(&reports, RPT_STORE); RE_SetReports(re, &reports); render_set_depgraph(C, re); RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step); RE_SetReports(re, NULL); BKE_reports_clear(&reports); - BLI_end_threaded_malloc(); + BLI_threaded_malloc_end(); } else { printf("\nError: no blend loaded. cannot use '-a'.\n"); diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index acd425e788a..dda1864f07c 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -132,7 +132,7 @@ #include "DNA_key_types.h" #include "DNA_armature_types.h" #include "DNA_action_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_constraint_types.h" #include "MEM_guardedalloc.h" @@ -1688,6 +1688,7 @@ struct parentChildLink { SG_Node* m_gamechildnode; }; +#if 0 static bPoseChannel *get_active_posechannel2(Object *ob) { bArmature *arm= (bArmature*)ob->data; @@ -1701,6 +1702,7 @@ static bPoseChannel *get_active_posechannel2(Object *ob) return NULL; } +#endif static ListBase *get_active_constraints2(Object *ob) { @@ -1708,6 +1710,7 @@ static ListBase *get_active_constraints2(Object *ob) return NULL; // XXX - shouldnt we care about the pose data and not the mode??? +#if 0 if (ob->mode & OB_MODE_POSE) { bPoseChannel *pchan; @@ -1715,8 +1718,11 @@ static ListBase *get_active_constraints2(Object *ob) if (pchan) return &pchan->constraints; } - else + else +#endif + { return &ob->constraints; + } return NULL; } diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index 72c96668fe7..78d2d88cc65 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -49,7 +49,7 @@ subject to the following restrictions: #include "DNA_scene_types.h" #include "DNA_world_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" extern "C" { #include "BLI_utildefines.h" diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp index 083e9e28502..10196804656 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -467,8 +467,8 @@ bool VideoFFmpeg::startCache() CachePacket *packet = new CachePacket(); BLI_addtail(&m_packetCacheFree, packet); } - BLI_init_threads(&m_thread, cacheThread, 1); - BLI_insert_thread(&m_thread, this); + BLI_threadpool_init(&m_thread, cacheThread, 1); + BLI_threadpool_insert(&m_thread, this); m_cacheStarted = true; } return m_cacheStarted; @@ -479,7 +479,7 @@ void VideoFFmpeg::stopCache() if (m_cacheStarted) { m_stopThread = true; - BLI_end_threads(&m_thread); + BLI_threadpool_end(&m_thread); // now delete the cache CacheFrame *frame; CachePacket *packet; diff --git a/source/tools b/source/tools -Subproject ccf20e08702ee6424edbda01544bb9f8bc386de +Subproject b11375e89061303401376f7aeae42ac2fd64692 |