diff options
Diffstat (limited to 'source/blender')
928 files changed, 26621 insertions, 17854 deletions
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index 2f7d5a60a6f..95b074fa2df 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -509,7 +509,7 @@ void BLF_color4fv(int fontid, const float rgba[4]) void BLF_color4f(int fontid, float r, float g, float b, float a) { - float rgba[4] = {r, g, b, a}; + const float rgba[4] = {r, g, b, a}; BLF_color4fv(fontid, rgba); } @@ -523,7 +523,7 @@ void BLF_color3fv_alpha(int fontid, const float rgb[3], float alpha) void BLF_color3f(int fontid, float r, float g, float b) { - float rgba[4] = {r, g, b, 1.0f}; + const float rgba[4] = {r, g, b, 1.0f}; BLF_color4fv(fontid, rgba); } diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index 50a8223a84c..ff31878a929 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -194,6 +194,8 @@ static GPUTexture *blf_batch_cache_texture_load(void) int offset_x = bitmap_len_landed % tex_width; int offset_y = bitmap_len_landed / tex_width; + GPU_texture_bind(gc->texture, 0); + /* TODO(germano): Update more than one row in a single call. */ while (remain) { int remain_row = tex_width - offset_x; diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 797c4f9f355..ae0a669bfb3 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -31,15 +31,15 @@ extern "C" { */ /* Blender major and minor version. */ -#define BLENDER_VERSION 290 +#define BLENDER_VERSION 291 /* Blender patch version for bugfix releases. */ #define BLENDER_VERSION_PATCH 0 /** Blender release cycle stage: alpha/beta/rc/release. */ -#define BLENDER_VERSION_CYCLE beta +#define BLENDER_VERSION_CYCLE alpha /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 7 +#define BLENDER_FILE_SUBVERSION 0 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h index 5a68514a387..1ada83c0163 100644 --- a/source/blender/blenkernel/BKE_colortools.h +++ b/source/blender/blenkernel/BKE_colortools.h @@ -69,7 +69,7 @@ void BKE_curvemapping_changed(struct CurveMapping *cumap, const bool rem_doubles void BKE_curvemapping_changed_all(struct CurveMapping *cumap); /* call before _all_ evaluation functions */ -void BKE_curvemapping_initialize(struct CurveMapping *cumap); +void BKE_curvemapping_init(struct CurveMapping *cumap); /* keep these (const CurveMap) - to help with thread safety */ /* single curve, no table check */ diff --git a/source/blender/blenkernel/BKE_curveprofile.h b/source/blender/blenkernel/BKE_curveprofile.h index 84dbcd25b32..9c72a866fa9 100644 --- a/source/blender/blenkernel/BKE_curveprofile.h +++ b/source/blender/blenkernel/BKE_curveprofile.h @@ -71,7 +71,7 @@ void BKE_curveprofile_create_samples(struct CurveProfile *profile, bool sample_straight_edges, struct CurveProfilePoint *r_samples); -void BKE_curveprofile_initialize(struct CurveProfile *profile, short segments_len); +void BKE_curveprofile_init(struct CurveProfile *profile, short segments_len); /* Called for a complete update of the widget after modifications */ enum { diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index a18084f8bbd..f052ba400fc 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -54,6 +54,7 @@ void BKE_image_free_packedfiles(struct Image *image); void BKE_image_free_views(struct Image *image); void BKE_image_free_buffers(struct Image *image); void BKE_image_free_buffers_ex(struct Image *image, bool do_lock); +void BKE_image_free_gputextures(struct Image *ima); /* call from library */ void BKE_image_free(struct Image *image); @@ -273,6 +274,10 @@ void BKE_image_free_anim_ibufs(struct Image *ima, int except_frame); /* does all images with type MOVIE or SEQUENCE */ void BKE_image_all_free_anim_ibufs(struct Main *bmain, int except_frame); +void BKE_image_free_all_gputextures(struct Main *bmain); +void BKE_image_free_anim_gputextures(struct Main *bmain); +void BKE_image_free_old_gputextures(struct Main *bmain); + bool BKE_image_memorypack(struct Image *ima); void BKE_image_packfiles(struct ReportList *reports, struct Image *ima, const char *basepath); void BKE_image_packfiles_from_mem(struct ReportList *reports, @@ -361,6 +366,30 @@ bool BKE_image_has_loaded_ibuf(struct Image *image); struct ImBuf *BKE_image_get_ibuf_with_name(struct Image *image, const char *name); struct ImBuf *BKE_image_get_first_ibuf(struct Image *image); +/* Not to be use directly. */ +struct GPUTexture *BKE_image_create_gpu_texture_from_ibuf(struct Image *image, struct ImBuf *ibuf); + +/* Get the GPUTexture for a given `Image`. + * + * `iuser` and `ibuf` are mutual exclusive parameters. The caller can pass the `ibuf` when already + * available. It is also required when requesting the GPUTexture for a render result. */ +struct GPUTexture *BKE_image_get_gpu_texture(struct Image *image, + struct ImageUser *iuser, + struct ImBuf *ibuf); +struct GPUTexture *BKE_image_get_gpu_tiles(struct Image *image, + struct ImageUser *iuser, + struct ImBuf *ibuf); +struct GPUTexture *BKE_image_get_gpu_tilemap(struct Image *image, + struct ImageUser *iuser, + struct ImBuf *ibuf); + +void BKE_image_update_gputexture( + struct Image *ima, struct ImageUser *iuser, int x, int y, int w, int h); +void BKE_image_paint_set_mipmap(struct Main *bmain, bool mipmap); + +/* Delayed free of OpenGL buffers by main thread */ +void BKE_image_free_unused_gpu_textures(void); + struct RenderSlot *BKE_image_add_renderslot(struct Image *ima, const char *name); bool BKE_image_remove_renderslot(struct Image *ima, struct ImageUser *iuser, int slot); struct RenderSlot *BKE_image_get_renderslot(struct Image *ima, int slot); diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h index 5af73a1579d..5843992b25c 100644 --- a/source/blender/blenkernel/BKE_lib_override.h +++ b/source/blender/blenkernel/BKE_lib_override.h @@ -140,7 +140,7 @@ void BKE_lib_override_library_main_update(struct Main *bmain); /* For now, we just use a temp main list. */ typedef struct Main OverrideLibraryStorage; -OverrideLibraryStorage *BKE_lib_override_library_operations_store_initialize(void); +OverrideLibraryStorage *BKE_lib_override_library_operations_store_init(void); struct ID *BKE_lib_override_library_operations_store_start( struct Main *bmain, OverrideLibraryStorage *override_storage, struct ID *local); void BKE_lib_override_library_operations_store_end(OverrideLibraryStorage *override_storage, diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h index d1f6efc035b..958fbef1f97 100644 --- a/source/blender/blenkernel/BKE_movieclip.h +++ b/source/blender/blenkernel/BKE_movieclip.h @@ -112,6 +112,11 @@ bool BKE_movieclip_put_frame_if_possible(struct MovieClip *clip, struct MovieClipUser *user, struct ImBuf *ibuf); +struct GPUTexture *BKE_movieclip_get_gpu_texture(struct MovieClip *clip, + struct MovieClipUser *cuser); + +void BKE_movieclip_free_gputexture(struct MovieClip *clip); + /* Dependency graph evaluation. */ void BKE_movieclip_eval_update(struct Depsgraph *depsgraph, diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index b9e2531755b..ef46bc0f202 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -1330,6 +1330,8 @@ int ntreeTexExecTree(struct bNodeTree *ntree, #define SIM_NODE_EMIT_PARTICLES 1009 #define SIM_NODE_TIME 1010 #define SIM_NODE_PARTICLE_ATTRIBUTE 1011 +#define SIM_NODE_AGE_REACHED_EVENT 1012 +#define SIM_NODE_KILL_PARTICLE 1013 /** \} */ @@ -1343,6 +1345,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree, #define FN_NODE_GROUP_INSTANCE_ID 1203 #define FN_NODE_COMBINE_STRINGS 1204 #define FN_NODE_OBJECT_TRANSFORMS 1205 +#define FN_NODE_RANDOM_FLOAT 1206 /** \} */ diff --git a/source/blender/blenkernel/BKE_ocean.h b/source/blender/blenkernel/BKE_ocean.h index 6d488cc3142..1f8cdf27eb1 100644 --- a/source/blender/blenkernel/BKE_ocean.h +++ b/source/blender/blenkernel/BKE_ocean.h @@ -69,8 +69,10 @@ typedef struct OceanCache { struct Ocean *BKE_ocean_add(void); void BKE_ocean_free_data(struct Ocean *oc); void BKE_ocean_free(struct Ocean *oc); -bool BKE_ocean_ensure(struct OceanModifierData *omd); -void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData const *omd); +bool BKE_ocean_ensure(struct OceanModifierData *omd, const int resolution); +void BKE_ocean_init_from_modifier(struct Ocean *ocean, + struct OceanModifierData const *omd, + const int resolution); void BKE_ocean_init(struct Ocean *o, int M, diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index e2381bf68ac..4e520948bcb 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -41,6 +41,7 @@ struct EdgeSet; struct GHash; struct GridPaintMask; struct ImagePool; +struct ListBase; struct MLoop; struct MLoopTri; struct MVert; @@ -259,10 +260,20 @@ typedef struct SculptPoseIKChain { /* Cloth Brush */ typedef struct SculptClothLengthConstraint { - int v1; - int v2; + /* Elements that are affected by the constraint. */ + /* Element a should always be a mesh vertex with the index stored in elem_index_a as it is always + * deformed. Element b could be another vertex of the same mesh or any other position (arbitrary + * point, position for a previous state). In that case, elem_index_a and elem_index_b should be + * the same to avoid affecting two different vertices when solving the constraints. + * *elem_position points to the position which is owned by the element. */ + int elem_index_a; + float *elem_position_a; + + int elem_index_b; + float *elem_position_b; float length; + float strength; } SculptClothLengthConstraint; typedef struct SculptClothSimulation { @@ -272,6 +283,11 @@ typedef struct SculptClothSimulation { int capacity_length_constraints; float *length_constraint_tweak; + /* Position anchors for deformation brushes. These positions are modified by the brush and the + * final positions of the simulated vertices are updated with constraints that use these points + * as targets. */ + float (*deformation_pos)[3]; + float mass; float damping; @@ -279,7 +295,9 @@ typedef struct SculptClothSimulation { float (*pos)[3]; float (*init_pos)[3]; float (*prev_pos)[3]; + float (*last_iteration_pos)[3]; + struct ListBase *collider_list; } SculptClothSimulation; typedef struct SculptPersistentBase { @@ -317,6 +335,9 @@ typedef struct SculptSession { int level; } multires; + /* Depsgraph for the Cloth Brush solver to get the colliders. */ + struct Depsgraph *depsgraph; + /* These are always assigned to base mesh data when using PBVH_FACES and PBVH_GRIDS. */ struct MVert *mvert; struct MPoly *mpoly; diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 1e7a4ae75fb..7d317538f44 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -579,7 +579,7 @@ void psys_particle_on_dm(struct Mesh *mesh_final, /* particle_system.c */ void distribute_particles(struct ParticleSimulationData *sim, int from); -void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa); +void init_particle(struct ParticleSimulationData *sim, struct ParticleData *pa); void psys_calc_dmcache(struct Object *ob, struct Mesh *mesh_final, struct Mesh *mesh_original, diff --git a/source/blender/blenkernel/BKE_persistent_data_handle.hh b/source/blender/blenkernel/BKE_persistent_data_handle.hh index c8e02062f0b..bcc84f9c9d0 100644 --- a/source/blender/blenkernel/BKE_persistent_data_handle.hh +++ b/source/blender/blenkernel/BKE_persistent_data_handle.hh @@ -84,45 +84,45 @@ class PersistentObjectHandle : public PersistentIDHandle { class PersistentDataHandleMap { private: - Map<int32_t, const ID *> id_by_handle_; - Map<const ID *, int32_t> handle_by_id_; + Map<int32_t, ID *> id_by_handle_; + Map<ID *, int32_t> handle_by_id_; public: - void add(int32_t handle, const ID &id) + void add(int32_t handle, ID &id) { BLI_assert(handle >= 0); handle_by_id_.add(&id, handle); id_by_handle_.add(handle, &id); } - PersistentIDHandle lookup(const ID *id) const + PersistentIDHandle lookup(ID *id) const { const int handle = handle_by_id_.lookup_default(id, -1); return PersistentIDHandle(handle); } - PersistentObjectHandle lookup(const Object *object) const + PersistentObjectHandle lookup(Object *object) const { - const int handle = handle_by_id_.lookup_default((const ID *)object, -1); + const int handle = handle_by_id_.lookup_default((ID *)object, -1); return PersistentObjectHandle(handle); } - const ID *lookup(const PersistentIDHandle &handle) const + ID *lookup(const PersistentIDHandle &handle) const { - const ID *id = id_by_handle_.lookup_default(handle.handle_, nullptr); + ID *id = id_by_handle_.lookup_default(handle.handle_, nullptr); return id; } - const Object *lookup(const PersistentObjectHandle &handle) const + Object *lookup(const PersistentObjectHandle &handle) const { - const ID *id = this->lookup((const PersistentIDHandle &)handle); + ID *id = this->lookup((const PersistentIDHandle &)handle); if (id == nullptr) { return nullptr; } if (GS(id->name) != ID_OB) { return nullptr; } - return (const Object *)id; + return (Object *)id; } }; diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index 735d6dc6e89..edab543fc37 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -72,7 +72,7 @@ typedef struct SpaceType { /* Initial allocation, after this WM will call init() too. Some editors need * area and scene data (e.g. frame range) to set their initial scrolling. */ - struct SpaceLink *(*new)(const struct ScrArea *area, const struct Scene *scene); + struct SpaceLink *(*create)(const struct ScrArea *area, const struct Scene *scene); /* not free spacelink itself */ void (*free)(struct SpaceLink *sl); diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 03f14be8772..b6d901c8ef2 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -627,6 +627,10 @@ void BKE_sequencer_color_balance_apply(struct StripColorBalance *cb, void BKE_sequencer_all_free_anim_ibufs(struct Scene *scene, int cfra); bool BKE_sequencer_check_scene_recursion(struct Scene *scene, struct ReportList *reports); bool BKE_sequencer_render_loop_check(struct Sequence *seq_main, struct Sequence *seq); +void BKE_sequencer_flag_for_removal(struct Scene *scene, + struct ListBase *seqbase, + struct Sequence *seq); +void BKE_sequencer_remove_flagged_sequences(struct Scene *scene, struct ListBase *seqbase); /* A debug and development function which checks whether sequences have unique UUIDs. * Errors will be reported to the console. */ diff --git a/source/blender/blenkernel/BKE_simulation.h b/source/blender/blenkernel/BKE_simulation.h index 98d1cf1e9b5..2c436f2bff8 100644 --- a/source/blender/blenkernel/BKE_simulation.h +++ b/source/blender/blenkernel/BKE_simulation.h @@ -31,6 +31,7 @@ void *BKE_simulation_add(struct Main *bmain, const char *name); void BKE_simulation_data_update(struct Depsgraph *depsgraph, struct Scene *scene, struct Simulation *simulation); +void BKE_simulation_update_dependencies(struct Simulation *simulation, struct Main *bmain); SimulationState *BKE_simulation_state_add(Simulation *simulation, const char *type, diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index d702da55ea8..ada341ff570 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -100,6 +100,7 @@ set(SRC intern/context.c intern/crazyspace.c intern/curve.c + intern/curve_bevel.c intern/curve_decimate.c intern/curve_deform.c intern/curveprofile.c @@ -134,6 +135,7 @@ set(SRC intern/idtype.c intern/image.c intern/image_gen.c + intern/image_gpu.c intern/image_save.c intern/ipo.c intern/kelvinlet.c diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c index e035d5cbb68..8d8301362b3 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -32,8 +32,6 @@ #include "CCGSubSurf.h" #include "CCGSubSurf_intern.h" -#include "GPU_glew.h" - /***/ int BKE_ccg_gridsize(int level) diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 8031e3dadf8..af4829691c2 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -80,11 +80,9 @@ //#define USE_MODIFIER_VALIDATE #ifdef USE_MODIFIER_VALIDATE -# define ASSERT_IS_VALID_DM(dm) (BLI_assert((dm == NULL) || (DM_is_valid(dm) == true))) # define ASSERT_IS_VALID_MESH(mesh) \ (BLI_assert((mesh == NULL) || (BKE_mesh_is_valid(mesh) == true))) #else -# define ASSERT_IS_VALID_DM(dm) # define ASSERT_IS_VALID_MESH(mesh) #endif diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index ea5a4bd99d1..5b5e32f1d81 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -1150,7 +1150,7 @@ static int nlaevalchan_validate_index(NlaEvalChannel *nec, int index) return 0; } -/* Initialise default values for NlaEvalChannel from the property data. */ +/* Initialize default values for NlaEvalChannel from the property data. */ static void nlaevalchan_get_default_values(NlaEvalChannel *nec, float *r_values) { PointerRNA *ptr = &nec->key.ptr; diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 985be4ac99f..631ce4edd20 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -2582,7 +2582,7 @@ void BKE_pose_where_is(struct Depsgraph *depsgraph, Scene *scene, Object *ob) } /* 2a. construct the IK tree (standard IK) */ - BIK_initialize_tree(depsgraph, scene, ob, ctime); + BIK_init_tree(depsgraph, scene, ob, ctime); /* 2b. construct the Spline IK trees * - this is not integrated as an IK plugin, since it should be able diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c index d66991aed70..97c717572bc 100644 --- a/source/blender/blenkernel/intern/armature_update.c +++ b/source/blender/blenkernel/intern/armature_update.c @@ -658,7 +658,7 @@ void BKE_pose_eval_init_ik(struct Depsgraph *depsgraph, Scene *scene, Object *ob return; } /* construct the IK tree (standard IK) */ - BIK_initialize_tree(depsgraph, scene, object, ctime); + BIK_init_tree(depsgraph, scene, object, ctime); /* 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. */ diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index a0da1b1677d..a7324ffe738 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -873,7 +873,7 @@ static Object *boid_find_ground(BoidBrainData *bbd, return bpa->ground; } - float zvec[3] = {0.0f, 0.0f, 2000.0f}; + const float zvec[3] = {0.0f, 0.0f, 2000.0f}; ParticleCollision col; ColliderCache *coll; BVHTreeRayHit hit; diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 7223187831e..ce0249c71ce 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -557,7 +557,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type) /* Curve. */ custom_curve = brush->gpencil_settings->curve_sensitivity; BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f); - BKE_curvemapping_initialize(custom_curve); + BKE_curvemapping_init(custom_curve); brush_gpencil_curvemap_reset(custom_curve->cm, 3, GPCURVE_PRESET_INK); brush->gpencil_settings->icon_id = GP_BRUSH_ICON_INK; @@ -594,7 +594,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type) /* Curve. */ custom_curve = brush->gpencil_settings->curve_sensitivity; BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f); - BKE_curvemapping_initialize(custom_curve); + BKE_curvemapping_init(custom_curve); brush_gpencil_curvemap_reset(custom_curve->cm, 3, GPCURVE_PRESET_INKNOISE); brush->gpencil_settings->icon_id = GP_BRUSH_ICON_INKNOISE; @@ -631,7 +631,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type) /* Curve. */ custom_curve = brush->gpencil_settings->curve_sensitivity; BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f); - BKE_curvemapping_initialize(custom_curve); + BKE_curvemapping_init(custom_curve); brush_gpencil_curvemap_reset(custom_curve->cm, 4, GPCURVE_PRESET_MARKER); brush->gpencil_settings->icon_id = GP_BRUSH_ICON_MARKER; @@ -667,12 +667,12 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type) /* Curve. */ custom_curve = brush->gpencil_settings->curve_sensitivity; BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f); - BKE_curvemapping_initialize(custom_curve); + BKE_curvemapping_init(custom_curve); brush_gpencil_curvemap_reset(custom_curve->cm, 3, GPCURVE_PRESET_CHISEL_SENSIVITY); custom_curve = brush->gpencil_settings->curve_strength; BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f); - BKE_curvemapping_initialize(custom_curve); + BKE_curvemapping_init(custom_curve); brush_gpencil_curvemap_reset(custom_curve->cm, 4, GPCURVE_PRESET_CHISEL_STRENGTH); brush->gpencil_settings->icon_id = GP_BRUSH_ICON_CHISEL; @@ -1740,7 +1740,7 @@ float BKE_brush_sample_tex_3d(const Scene *scene, } else if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) { float rotation = -mtex->rot; - float point_2d[2] = {point[0], point[1]}; + const float point_2d[2] = {point[0], point[1]}; float x, y; float co[3]; @@ -1770,7 +1770,7 @@ float BKE_brush_sample_tex_3d(const Scene *scene, } else { float rotation = -mtex->rot; - float point_2d[2] = {point[0], point[1]}; + const float point_2d[2] = {point[0], point[1]}; float x = 0.0f, y = 0.0f; /* Quite warnings */ float invradius = 1.0f; /* Quite warnings */ float co[3]; @@ -1853,7 +1853,7 @@ float BKE_brush_sample_masktex( } if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) { float rotation = -mtex->rot; - float point_2d[2] = {point[0], point[1]}; + const float point_2d[2] = {point[0], point[1]}; float x, y; float co[3]; @@ -1883,7 +1883,7 @@ float BKE_brush_sample_masktex( } else { float rotation = -mtex->rot; - float point_2d[2] = {point[0], point[1]}; + const float point_2d[2] = {point[0], point[1]}; float x = 0.0f, y = 0.0f; /* Quite warnings */ float invradius = 1.0f; /* Quite warnings */ float co[3]; @@ -2274,7 +2274,7 @@ struct ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br, bool secondary, bool int half = side / 2; int i, j; - BKE_curvemapping_initialize(br->curve); + BKE_curvemapping_init(br->curve); texcache = BKE_brush_gen_texture_cache(br, half, secondary); im->rect_float = MEM_callocN(sizeof(float) * side * side, "radial control rect"); im->x = im->y = side; diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c index da9dab36044..9ad6ae84c5c 100644 --- a/source/blender/blenkernel/intern/cachefile.c +++ b/source/blender/blenkernel/intern/cachefile.c @@ -61,6 +61,8 @@ static void cache_file_init_data(ID *id) BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(cache_file, id)); cache_file->scale = 1.0f; + cache_file->velocity_unit = CACHEFILE_VELOCITY_UNIT_SECOND; + BLI_strncpy(cache_file->velocity_name, ".velocities", sizeof(cache_file->velocity_name)); } static void cache_file_copy_data(Main *UNUSED(bmain), diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index 7c0e4064cdb..d8b4150b2b1 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -186,9 +186,8 @@ int BKE_camera_sensor_fit(int sensor_fit, float sizex, float sizey) if (sizex >= sizey) { return CAMERA_SENSOR_FIT_HOR; } - else { - return CAMERA_SENSOR_FIT_VERT; - } + + return CAMERA_SENSOR_FIT_VERT; } return sensor_fit; @@ -636,64 +635,63 @@ static bool camera_frame_fit_calc_from_data(CameraParams *params, return true; } - else { - float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3]; - float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3]; - float plane_isect_pt_1[3], plane_isect_pt_2[3]; + float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3]; + float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3]; - /* apply the dist-from-plane's to the transformed plane points */ - for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) { - float co[3]; - mul_v3_v3fl(co, data->normal_tx[i], sqrtf_signed(data->dist_vals_sq[i])); - plane_from_point_normal_v3(plane_tx[i], co, data->normal_tx[i]); - } + float plane_isect_pt_1[3], plane_isect_pt_2[3]; - if ((!isect_plane_plane_v3(plane_tx[0], plane_tx[2], plane_isect_1, plane_isect_1_no)) || - (!isect_plane_plane_v3(plane_tx[1], plane_tx[3], plane_isect_2, plane_isect_2_no))) { - return false; - } + /* apply the dist-from-plane's to the transformed plane points */ + for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) { + float co[3]; + mul_v3_v3fl(co, data->normal_tx[i], sqrtf_signed(data->dist_vals_sq[i])); + plane_from_point_normal_v3(plane_tx[i], co, data->normal_tx[i]); + } - add_v3_v3v3(plane_isect_1_other, plane_isect_1, plane_isect_1_no); - add_v3_v3v3(plane_isect_2_other, plane_isect_2, plane_isect_2_no); + if ((!isect_plane_plane_v3(plane_tx[0], plane_tx[2], plane_isect_1, plane_isect_1_no)) || + (!isect_plane_plane_v3(plane_tx[1], plane_tx[3], plane_isect_2, plane_isect_2_no))) { + return false; + } - if (isect_line_line_v3(plane_isect_1, - plane_isect_1_other, - plane_isect_2, - plane_isect_2_other, - plane_isect_pt_1, - plane_isect_pt_2) != 0) { - float cam_plane_no[3]; - float plane_isect_delta[3]; - float plane_isect_delta_len; + add_v3_v3v3(plane_isect_1_other, plane_isect_1, plane_isect_1_no); + add_v3_v3v3(plane_isect_2_other, plane_isect_2, plane_isect_2_no); - float shift_fac = BKE_camera_sensor_size( - params->sensor_fit, params->sensor_x, params->sensor_y) / - params->lens; + if (isect_line_line_v3(plane_isect_1, + plane_isect_1_other, + plane_isect_2, + plane_isect_2_other, + plane_isect_pt_1, + plane_isect_pt_2) != 0) { + float cam_plane_no[3]; + float plane_isect_delta[3]; + float plane_isect_delta_len; - /* we want (0, 0, -1) transformed by camera_rotmat, this is a quicker shortcut. */ - negate_v3_v3(cam_plane_no, data->camera_rotmat[2]); + float shift_fac = BKE_camera_sensor_size( + params->sensor_fit, params->sensor_x, params->sensor_y) / + params->lens; - sub_v3_v3v3(plane_isect_delta, plane_isect_pt_2, plane_isect_pt_1); - plane_isect_delta_len = len_v3(plane_isect_delta); + /* we want (0, 0, -1) transformed by camera_rotmat, this is a quicker shortcut. */ + negate_v3_v3(cam_plane_no, data->camera_rotmat[2]); - if (dot_v3v3(plane_isect_delta, cam_plane_no) > 0.0f) { - copy_v3_v3(r_co, plane_isect_pt_1); + sub_v3_v3v3(plane_isect_delta, plane_isect_pt_2, plane_isect_pt_1); + plane_isect_delta_len = len_v3(plane_isect_delta); - /* offset shift */ - normalize_v3(plane_isect_1_no); - madd_v3_v3fl(r_co, plane_isect_1_no, params->shifty * plane_isect_delta_len * shift_fac); - } - else { - copy_v3_v3(r_co, plane_isect_pt_2); + if (dot_v3v3(plane_isect_delta, cam_plane_no) > 0.0f) { + copy_v3_v3(r_co, plane_isect_pt_1); - /* offset shift */ - normalize_v3(plane_isect_2_no); - madd_v3_v3fl(r_co, plane_isect_2_no, params->shiftx * plane_isect_delta_len * shift_fac); - } + /* offset shift */ + normalize_v3(plane_isect_1_no); + madd_v3_v3fl(r_co, plane_isect_1_no, params->shifty * plane_isect_delta_len * shift_fac); + } + else { + copy_v3_v3(r_co, plane_isect_pt_2); - return true; + /* offset shift */ + normalize_v3(plane_isect_2_no); + madd_v3_v3fl(r_co, plane_isect_2_no, params->shiftx * plane_isect_delta_len * shift_fac); } + + return true; } return false; @@ -775,11 +773,10 @@ static void camera_stereo3d_model_matrix(const Object *camera, camera_model_matrix(camera, r_modelmat); return; } - else { - float size[3]; - mat4_to_size(size, camera->obmat); - size_to_mat4(sizemat, size); - } + + float size[3]; + mat4_to_size(size, camera->obmat); + size_to_mat4(sizemat, size); if (pivot == CAM_S3D_PIVOT_CENTER) { fac = 0.5f; @@ -931,9 +928,8 @@ bool BKE_camera_multiview_spherical_stereo(const RenderData *rd, const Object *c if (camera->type != OB_CAMERA) { return false; } - else { - cam = camera->data; - } + + cam = camera->data; if ((rd->views_format == SCE_VIEWS_FORMAT_STEREO_3D) && ELEM(cam->type, CAM_PANO, CAM_PERSP) && ((cam->stereo.flag & CAM_S3D_SPHERICAL) != 0)) { @@ -984,13 +980,12 @@ Object *BKE_camera_multiview_render(const Scene *scene, Object *camera, const ch if (!is_multiview) { return camera; } - else if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) { + if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) { return camera; } - else { /* SCE_VIEWS_FORMAT_MULTIVIEW */ - const char *suffix = BKE_scene_multiview_view_suffix_get(&scene->r, viewname); - return camera_multiview_advanced(scene, camera, suffix); - } + /* SCE_VIEWS_FORMAT_MULTIVIEW */ + const char *suffix = BKE_scene_multiview_view_suffix_get(&scene->r, viewname); + return camera_multiview_advanced(scene, camera, suffix); } static float camera_stereo3d_shift_x(const Object *camera, const char *viewname) @@ -1044,12 +1039,11 @@ float BKE_camera_multiview_shift_x(const RenderData *rd, if (!is_multiview) { return data->shiftx; } - else if (rd->views_format == SCE_VIEWS_FORMAT_MULTIVIEW) { + if (rd->views_format == SCE_VIEWS_FORMAT_MULTIVIEW) { return data->shiftx; } - else { /* SCE_VIEWS_SETUP_BASIC */ - return camera_stereo3d_shift_x(camera, viewname); - } + /* SCE_VIEWS_SETUP_BASIC */ + return camera_stereo3d_shift_x(camera, viewname); } void BKE_camera_multiview_params(const RenderData *rd, diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 467bd68c631..027761335b0 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -825,7 +825,7 @@ static int cloth_from_object( MVert *mvert = NULL; ClothVertex *verts = NULL; float(*shapekey_rest)[3] = NULL; - float tnull[3] = {0, 0, 0}; + const float tnull[3] = {0, 0, 0}; // If we have a clothObject, free it. if (clmd->clothObject != NULL) { @@ -1355,7 +1355,7 @@ BLI_INLINE void cross_identity_v3(float r[3][3], const float v[3]) r[2][1] = -v[0]; } -BLI_INLINE void madd_m3_m3fl(float r[3][3], float m[3][3], float f) +BLI_INLINE void madd_m3_m3fl(float r[3][3], const float m[3][3], float f) { r[0][0] += m[0][0] * f; r[0][1] += m[0][1] * f; diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index 6118325c231..6d2432f53e4 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -540,9 +540,8 @@ const char *BKE_collection_ui_name_get(struct Collection *collection) if (collection->flag & COLLECTION_IS_MASTER) { return IFACE_("Scene Collection"); } - else { - return collection->id.name + 2; - } + + return collection->id.name + 2; } /** \} */ @@ -617,9 +616,8 @@ Base *BKE_collection_or_layer_objects(const ViewLayer *view_layer, Collection *c if (collection) { return BKE_collection_object_cache_get(collection).first; } - else { - return FIRSTBASE(view_layer); - } + + return FIRSTBASE(view_layer); } /** \} */ @@ -671,14 +669,13 @@ static bool collection_object_cyclic_check_internal(Object *object, Collection * if (dup_collection == collection) { return true; } - else { - FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (dup_collection, collection_object) { - if (collection_object_cyclic_check_internal(collection_object, dup_collection)) { - return true; - } + + FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (dup_collection, collection_object) { + if (collection_object_cyclic_check_internal(collection_object, dup_collection)) { + return true; } - FOREACH_COLLECTION_OBJECT_RECURSIVE_END; } + FOREACH_COLLECTION_OBJECT_RECURSIVE_END; /* un-flag the object, it's allowed to have the same collection multiple times in parallel */ dup_collection->id.tag |= LIB_TAG_DOIT; @@ -725,9 +722,8 @@ static Collection *collection_next_find(Main *bmain, Scene *scene, Collection *c if (scene && collection == scene->master_collection) { return bmain->collections.first; } - else { - return collection->id.next; - } + + return collection->id.next; } Collection *BKE_collection_object_find(Main *bmain, @@ -1510,9 +1506,8 @@ bool BKE_collection_objects_select(ViewLayer *view_layer, Collection *collection if (layer_collection != NULL) { return BKE_layer_collection_objects_select(view_layer, layer_collection, deselect); } - else { - return collection_objects_select(view_layer, collection, deselect); - } + + return collection_objects_select(view_layer, collection, deselect); } /** \} */ diff --git a/source/blender/blenkernel/intern/colorband.c b/source/blender/blenkernel/intern/colorband.c index 499b0305c9d..323a2f0cf53 100644 --- a/source/blender/blenkernel/intern/colorband.c +++ b/source/blender/blenkernel/intern/colorband.c @@ -587,7 +587,7 @@ static int vergcband(const void *a1, const void *a2) if (x1->pos > x2->pos) { return 1; } - else if (x1->pos < x2->pos) { + if (x1->pos < x2->pos) { return -1; } return 0; @@ -620,18 +620,17 @@ CBData *BKE_colorband_element_add(struct ColorBand *coba, float position) if (coba->tot == MAXCOLORBAND) { return NULL; } - else { - CBData *xnew; - xnew = &coba->data[coba->tot]; - xnew->pos = position; + CBData *xnew; - if (coba->tot != 0) { - BKE_colorband_evaluate(coba, position, &xnew->r); - } - else { - zero_v4(&xnew->r); - } + xnew = &coba->data[coba->tot]; + xnew->pos = position; + + if (coba->tot != 0) { + BKE_colorband_evaluate(coba, position, &xnew->r); + } + else { + zero_v4(&xnew->r); } coba->tot++; diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 4f4eb8f9f9d..11928dada2b 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -603,28 +603,24 @@ static float curvemap_calc_extend(const CurveMapping *cumap, /* extrapolate horizontally */ return first[1]; } - else { - if (cuma->ext_in[0] == 0.0f) { - return first[1] + cuma->ext_in[1] * 10000.0f; - } - else { - return first[1] + cuma->ext_in[1] * (x - first[0]) / cuma->ext_in[0]; - } + + if (cuma->ext_in[0] == 0.0f) { + return first[1] + cuma->ext_in[1] * 10000.0f; } + + return first[1] + cuma->ext_in[1] * (x - first[0]) / cuma->ext_in[0]; } - else if (x >= last[0]) { + if (x >= last[0]) { if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) { /* extrapolate horizontally */ return last[1]; } - else { - if (cuma->ext_out[0] == 0.0f) { - return last[1] - cuma->ext_out[1] * 10000.0f; - } - else { - return last[1] + cuma->ext_out[1] * (x - last[0]) / cuma->ext_out[0]; - } + + if (cuma->ext_out[0] == 0.0f) { + return last[1] - cuma->ext_out[1] * 10000.0f; } + + return last[1] + cuma->ext_out[1] * (x - last[0]) / cuma->ext_out[0]; } return 0.0f; } @@ -870,7 +866,7 @@ static int sort_curvepoints(const void *a1, const void *a2) if (x1->x > x2->x) { return 1; } - else if (x1->x < x2->x) { + if (x1->x < x2->x) { return -1; } return 0; @@ -984,17 +980,16 @@ float BKE_curvemap_evaluateF(const CurveMapping *cumap, const CurveMap *cuma, fl if (fi < 0.0f || fi > CM_TABLE) { return curvemap_calc_extend(cumap, cuma, value, &cuma->table[0].x, &cuma->table[CM_TABLE].x); } - else { - if (i < 0) { - return cuma->table[0].y; - } - if (i >= CM_TABLE) { - return cuma->table[CM_TABLE].y; - } - fi = fi - (float)i; - return (1.0f - fi) * cuma->table[i].y + (fi)*cuma->table[i + 1].y; + if (i < 0) { + return cuma->table[0].y; } + if (i >= CM_TABLE) { + return cuma->table[CM_TABLE].y; + } + + fi = fi - (float)i; + return (1.0f - fi) * cuma->table[i].y + (fi)*cuma->table[i + 1].y; } /* works with curve 'cur' */ @@ -1202,7 +1197,7 @@ int BKE_curvemapping_RGBA_does_something(const CurveMapping *cumap) return 0; } -void BKE_curvemapping_initialize(CurveMapping *cumap) +void BKE_curvemapping_init(CurveMapping *cumap) { int a; diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 2ef32895db9..87d1b2561a9 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -2404,7 +2404,7 @@ static void armdef_get_tarmat(struct Depsgraph *UNUSED(depsgraph), } } -static void armdef_accumulate_matrix(float obmat[4][4], +static void armdef_accumulate_matrix(const float obmat[4][4], const float iobmat[4][4], const float basemat[4][4], const float bonemat[4][4], @@ -5284,9 +5284,8 @@ const bConstraintTypeInfo *BKE_constraint_typeinfo_from_type(int type) /* there shouldn't be any segfaults here... */ return constraintsTypeInfo[type]; } - else { - CLOG_WARN(&LOG, "No valid constraint type-info data available. Type = %i", type); - } + + CLOG_WARN(&LOG, "No valid constraint type-info data available. Type = %i", type); return NULL; } @@ -5300,9 +5299,8 @@ const bConstraintTypeInfo *BKE_constraint_typeinfo_get(bConstraint *con) if (con) { return BKE_constraint_typeinfo_from_type(con->type); } - else { - return NULL; - } + + return NULL; } /* ************************* General Constraints API ************************** */ @@ -5384,9 +5382,8 @@ bool BKE_constraint_remove(ListBase *list, bConstraint *con) BLI_freelinkN(list, con); return true; } - else { - return false; - } + + return false; } bool BKE_constraint_remove_ex(ListBase *list, Object *ob, bConstraint *con, bool clear_dep) @@ -5399,9 +5396,8 @@ bool BKE_constraint_remove_ex(ListBase *list, Object *ob, bConstraint *con, bool } return true; } - else { - return false; - } + + return false; } /* ......... */ diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 30f021b0e81..e9ba3a5f873 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -255,13 +255,12 @@ static void *ctx_wm_python_context_get(const bContext *C, if (RNA_struct_is_a(result.ptr.type, member_type)) { return result.ptr.data; } - else { - CLOG_WARN(&LOG, - "PyContext '%s' is a '%s', expected a '%s'", - member, - RNA_struct_identifier(result.ptr.type), - RNA_struct_identifier(member_type)); - } + + CLOG_WARN(&LOG, + "PyContext '%s' is a '%s', expected a '%s'", + member, + RNA_struct_identifier(result.ptr.type), + RNA_struct_identifier(member_type)); } } #else @@ -360,9 +359,8 @@ static void *ctx_data_pointer_get(const bContext *C, const char *member) BLI_assert(result.type == CTX_DATA_TYPE_POINTER); return result.ptr.data; } - else { - return NULL; - } + + return NULL; } static int ctx_data_pointer_verify(const bContext *C, const char *member, void **pointer) @@ -374,15 +372,14 @@ static int ctx_data_pointer_verify(const bContext *C, const char *member, void * *pointer = NULL; return 1; } - else if (ctx_data_get((bContext *)C, member, &result) == 1) { + if (ctx_data_get((bContext *)C, member, &result) == 1) { BLI_assert(result.type == CTX_DATA_TYPE_POINTER); *pointer = result.ptr.data; return 1; } - else { - *pointer = NULL; - return 0; - } + + *pointer = NULL; + return 0; } static int ctx_data_collection_get(const bContext *C, const char *member, ListBase *list) @@ -441,9 +438,8 @@ PointerRNA CTX_data_pointer_get(const bContext *C, const char *member) BLI_assert(result.type == CTX_DATA_TYPE_POINTER); return result.ptr; } - else { - return PointerRNA_NULL; - } + + return PointerRNA_NULL; } PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type) @@ -454,13 +450,12 @@ PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, Stru if (RNA_struct_is_a(ptr.type, type)) { return ptr; } - else { - CLOG_WARN(&LOG, - "member '%s' is '%s', not '%s'", - member, - RNA_struct_identifier(ptr.type), - RNA_struct_identifier(type)); - } + + CLOG_WARN(&LOG, + "member '%s' is '%s', not '%s'", + member, + RNA_struct_identifier(ptr.type), + RNA_struct_identifier(type)); } return PointerRNA_NULL; @@ -473,9 +468,8 @@ PointerRNA CTX_data_pointer_get_type_silent(const bContext *C, const char *membe if (ptr.data && RNA_struct_is_a(ptr.type, type)) { return ptr; } - else { - return PointerRNA_NULL; - } + + return PointerRNA_NULL; } ListBase CTX_data_collection_get(const bContext *C, const char *member) @@ -486,10 +480,9 @@ ListBase CTX_data_collection_get(const bContext *C, const char *member) BLI_assert(result.type == CTX_DATA_TYPE_COLLECTION); return result.list; } - else { - ListBase list = {NULL, NULL}; - return list; - } + + ListBase list = {NULL, NULL}; + return list; } /* 1:found, -1:found but not set, 0:not found */ @@ -667,9 +660,8 @@ int ctx_data_list_count(const bContext *C, int (*func)(const bContext *, ListBas BLI_freelistN(&list); return tot; } - else { - return 0; - } + + return 0; } void CTX_data_dir_set(bContextDataResult *result, const char **dir) @@ -985,9 +977,8 @@ Main *CTX_data_main(const bContext *C) if (ctx_data_pointer_verify(C, "blend_data", (void *)&bmain)) { return bmain; } - else { - return C->data.main; - } + + return C->data.main; } void CTX_data_main_set(bContext *C, Main *bmain) @@ -1003,9 +994,8 @@ Scene *CTX_data_scene(const bContext *C) if (ctx_data_pointer_verify(C, "scene", (void *)&scene)) { return scene; } - else { - return C->data.scene; - } + + return C->data.scene; } ViewLayer *CTX_data_view_layer(const bContext *C) @@ -1102,34 +1092,34 @@ enum eContextObjectMode CTX_data_mode_enum_ex(const Object *obedit, if (object_mode & OB_MODE_POSE) { return CTX_MODE_POSE; } - else if (object_mode & OB_MODE_SCULPT) { + if (object_mode & OB_MODE_SCULPT) { return CTX_MODE_SCULPT; } - else if (object_mode & OB_MODE_WEIGHT_PAINT) { + if (object_mode & OB_MODE_WEIGHT_PAINT) { return CTX_MODE_PAINT_WEIGHT; } - else if (object_mode & OB_MODE_VERTEX_PAINT) { + if (object_mode & OB_MODE_VERTEX_PAINT) { return CTX_MODE_PAINT_VERTEX; } - else if (object_mode & OB_MODE_TEXTURE_PAINT) { + if (object_mode & OB_MODE_TEXTURE_PAINT) { return CTX_MODE_PAINT_TEXTURE; } - else if (object_mode & OB_MODE_PARTICLE_EDIT) { + if (object_mode & OB_MODE_PARTICLE_EDIT) { return CTX_MODE_PARTICLE; } - else if (object_mode & OB_MODE_PAINT_GPENCIL) { + if (object_mode & OB_MODE_PAINT_GPENCIL) { return CTX_MODE_PAINT_GPENCIL; } - else if (object_mode & OB_MODE_EDIT_GPENCIL) { + if (object_mode & OB_MODE_EDIT_GPENCIL) { return CTX_MODE_EDIT_GPENCIL; } - else if (object_mode & OB_MODE_SCULPT_GPENCIL) { + if (object_mode & OB_MODE_SCULPT_GPENCIL) { return CTX_MODE_SCULPT_GPENCIL; } - else if (object_mode & OB_MODE_WEIGHT_GPENCIL) { + if (object_mode & OB_MODE_WEIGHT_GPENCIL) { return CTX_MODE_WEIGHT_GPENCIL; } - else if (object_mode & OB_MODE_VERTEX_GPENCIL) { + if (object_mode & OB_MODE_VERTEX_GPENCIL) { return CTX_MODE_VERTEX_GPENCIL; } } @@ -1173,9 +1163,8 @@ ToolSettings *CTX_data_tool_settings(const bContext *C) if (scene) { return scene->toolsettings; } - else { - return NULL; - } + + return NULL; } int CTX_data_selected_nodes(const bContext *C, ListBase *list) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 0627d2005d5..8e03f61d601 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -223,7 +223,7 @@ void BKE_curve_init(Curve *cu, const short curve_type) cu->vfont->id.us += 4; cu->str = MEM_malloc_arrayN(12, sizeof(unsigned char), "str"); BLI_strncpy(cu->str, "Text", 12); - cu->len = cu->len_wchar = cu->pos = 4; + cu->len = cu->len_char32 = cu->pos = 4; cu->strinfo = MEM_calloc_arrayN(12, sizeof(CharInfo), "strinfo new"); cu->totbox = cu->actbox = 1; cu->tb = MEM_calloc_arrayN(MAXTEXTBOX, sizeof(TextBox), "textbox"); @@ -1726,205 +1726,6 @@ static void forward_diff_bezier_cotangent(const float p0[3], } } -/* ***************** BEVEL ****************** */ - -void BKE_curve_bevel_make(Object *ob, ListBase *disp) -{ - DispList *dl, *dlnew; - Curve *bevcu, *cu; - float *fp, facx, facy, angle, dangle; - int nr, a; - - cu = ob->data; - BLI_listbase_clear(disp); - - /* if a font object is being edited, then do nothing */ - // XXX if ( ob == obedit && ob->type == OB_FONT ) return; - - if (cu->bevobj) { - if (cu->bevobj->type != OB_CURVE) { - return; - } - - bevcu = cu->bevobj->data; - if (bevcu->ext1 == 0.0f && bevcu->ext2 == 0.0f) { - ListBase bevdisp = {NULL, NULL}; - facx = cu->bevobj->scale[0]; - facy = cu->bevobj->scale[1]; - - if (cu->bevobj->runtime.curve_cache) { - dl = cu->bevobj->runtime.curve_cache->disp.first; - } - else { - BLI_assert(cu->bevobj->runtime.curve_cache != NULL); - dl = NULL; - } - - while (dl) { - if (ELEM(dl->type, DL_POLY, DL_SEGM)) { - dlnew = MEM_mallocN(sizeof(DispList), "makebevelcurve1"); - *dlnew = *dl; - dlnew->verts = MEM_malloc_arrayN( - dl->parts * dl->nr, 3 * sizeof(float), "makebevelcurve1"); - memcpy(dlnew->verts, dl->verts, 3 * sizeof(float) * dl->parts * dl->nr); - - if (dlnew->type == DL_SEGM) { - dlnew->flag |= (DL_FRONT_CURVE | DL_BACK_CURVE); - } - - BLI_addtail(disp, dlnew); - fp = dlnew->verts; - nr = dlnew->parts * dlnew->nr; - while (nr--) { - fp[2] = fp[1] * facy; - fp[1] = -fp[0] * facx; - fp[0] = 0.0; - fp += 3; - } - } - dl = dl->next; - } - - BKE_displist_free(&bevdisp); - } - } - else if (cu->ext1 == 0.0f && cu->ext2 == 0.0f) { - /* pass */ - } - else if (cu->ext2 == 0.0f) { - dl = MEM_callocN(sizeof(DispList), "makebevelcurve2"); - dl->verts = MEM_malloc_arrayN(2, sizeof(float[3]), "makebevelcurve2"); - BLI_addtail(disp, dl); - dl->type = DL_SEGM; - dl->parts = 1; - dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE; - dl->nr = 2; - - fp = dl->verts; - fp[0] = fp[1] = 0.0; - fp[2] = -cu->ext1; - fp[3] = fp[4] = 0.0; - fp[5] = cu->ext1; - } - else if ((cu->flag & (CU_FRONT | CU_BACK)) == 0 && cu->ext1 == 0.0f) { - /* We make a full round bevel in that case. */ - - nr = 4 + 2 * cu->bevresol; - - dl = MEM_callocN(sizeof(DispList), "makebevelcurve p1"); - dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), "makebevelcurve p1"); - BLI_addtail(disp, dl); - dl->type = DL_POLY; - dl->parts = 1; - dl->flag = DL_BACK_CURVE; - dl->nr = nr; - - /* a circle */ - fp = dl->verts; - dangle = (2.0f * (float)M_PI / (nr)); - angle = -(nr - 1) * dangle; - - for (a = 0; a < nr; a++) { - fp[0] = 0.0; - fp[1] = (cosf(angle) * (cu->ext2)); - fp[2] = (sinf(angle) * (cu->ext2)) - cu->ext1; - angle += dangle; - fp += 3; - } - } - else { - /* The general case for nonzero extrusion or an incomplete loop. */ - dl = MEM_callocN(sizeof(DispList), "makebevelcurve"); - if ((cu->flag & (CU_FRONT | CU_BACK)) == 0) { - /* The full loop. */ - nr = 4 * cu->bevresol + 6; - dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE; - } - else if ((cu->flag & CU_FRONT) && (cu->flag & CU_BACK)) { - /* Half the loop. */ - nr = 2 * (cu->bevresol + 1) + ((cu->ext1 == 0.0f) ? 1 : 2); - dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE; - } - else { - /* One quarter of the loop (just front or back). */ - nr = (cu->ext1 == 0.0f) ? cu->bevresol + 2 : cu->bevresol + 3; - dl->flag = (cu->flag & CU_FRONT) ? DL_FRONT_CURVE : DL_BACK_CURVE; - } - - dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), "makebevelcurve"); - BLI_addtail(disp, dl); - /* Use a different type depending on whether the loop is complete or not. */ - dl->type = ((cu->flag & (CU_FRONT | CU_BACK)) == 0) ? DL_POLY : DL_SEGM; - dl->parts = 1; - dl->nr = nr; - - fp = dl->verts; - dangle = (float)M_PI_2 / (cu->bevresol + 1); - angle = 0.0; - - /* Build the back section. */ - if (cu->flag & CU_BACK || !(cu->flag & CU_FRONT)) { - angle = (float)M_PI_2 * 3.0f; - for (a = 0; a < cu->bevresol + 2; a++) { - fp[0] = 0.0; - fp[1] = (float)(cosf(angle) * (cu->ext2)); - fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1; - angle += dangle; - fp += 3; - } - if ((cu->ext1 != 0.0f) && !(cu->flag & CU_FRONT) && (cu->flag & CU_BACK)) { - /* Add the extrusion if we're only building the back. */ - fp[0] = 0.0; - fp[1] = cu->ext2; - fp[2] = cu->ext1; - } - } - - /* Build the front section. */ - if (cu->flag & CU_FRONT || !(cu->flag & CU_BACK)) { - if ((cu->ext1 != 0.0f) && !(cu->flag & CU_BACK) && (cu->flag & CU_FRONT)) { - /* Add the extrusion if we're only building the back. */ - fp[0] = 0.0; - fp[1] = cu->ext2; - fp[2] = -cu->ext1; - fp += 3; - } - /* Don't duplicate the last back vertex. */ - angle = (cu->ext1 == 0.0f && (cu->flag & CU_BACK)) ? dangle : 0; - int front_len = (cu->ext1 == 0.0f && ((cu->flag & CU_BACK) || !(cu->flag & CU_FRONT))) ? - cu->bevresol + 1 : - cu->bevresol + 2; - for (a = 0; a < front_len; a++) { - fp[0] = 0.0; - fp[1] = (float)(cosf(angle) * (cu->ext2)); - fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1; - angle += dangle; - fp += 3; - } - } - - /* Build the other half only if we're building the full loop. */ - if (!(cu->flag & (CU_FRONT | CU_BACK))) { - for (a = 0; a < cu->bevresol + 1; a++) { - fp[0] = 0.0; - fp[1] = (float)(cosf(angle) * (cu->ext2)); - fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1; - angle += dangle; - fp += 3; - } - - angle = (float)M_PI; - for (a = 0; a < cu->bevresol + 1; a++) { - fp[0] = 0.0; - fp[1] = (float)(cosf(angle) * (cu->ext2)); - fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1; - angle += dangle; - fp += 3; - } - } - } -} - static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], @@ -2500,7 +2301,7 @@ static void make_bevel_list_3D_tangent(BevList *bl) while (nr--) { /* make perpendicular, modify tan in place, is ok */ float cross_tmp[3]; - float zero[3] = {0, 0, 0}; + const float zero[3] = {0, 0, 0}; cross_v3_v3v3(cross_tmp, bevp1->tan, bevp1->dir); normalize_v3(cross_tmp); @@ -3797,7 +3598,10 @@ static void bezier_clamp( } /* write changes to a bezier handle */ -static void bezier_output_handle_inner(BezTriple *bezt, bool right, float newval[3], bool endpoint) +static void bezier_output_handle_inner(BezTriple *bezt, + bool right, + const float newval[3], + bool endpoint) { float tmp[3]; @@ -5441,7 +5245,7 @@ void BKE_curve_material_index_remove(Curve *cu, int index) if (curvetype == OB_FONT) { struct CharInfo *info = cu->strinfo; int i; - for (i = cu->len_wchar - 1; i >= 0; i--, info++) { + for (i = cu->len_char32 - 1; i >= 0; i--, info++) { if (info->mat_nr && info->mat_nr >= index) { info->mat_nr--; } @@ -5465,7 +5269,7 @@ bool BKE_curve_material_index_used(Curve *cu, int index) if (curvetype == OB_FONT) { struct CharInfo *info = cu->strinfo; int i; - for (i = cu->len_wchar - 1; i >= 0; i--, info++) { + for (i = cu->len_char32 - 1; i >= 0; i--, info++) { if (info->mat_nr == index) { return true; } @@ -5491,7 +5295,7 @@ void BKE_curve_material_index_clear(Curve *cu) if (curvetype == OB_FONT) { struct CharInfo *info = cu->strinfo; int i; - for (i = cu->len_wchar - 1; i >= 0; i--, info++) { + for (i = cu->len_char32 - 1; i >= 0; i--, info++) { info->mat_nr = 0; } } @@ -5513,7 +5317,7 @@ bool BKE_curve_material_index_validate(Curve *cu) CharInfo *info = cu->strinfo; const int max_idx = max_ii(0, cu->totcol); /* OB_FONT use 1 as first mat index, not 0!!! */ int i; - for (i = cu->len_wchar - 1; i >= 0; i--, info++) { + for (i = cu->len_char32 - 1; i >= 0; i--, info++) { if (info->mat_nr > max_idx) { info->mat_nr = 0; is_valid = false; @@ -5561,7 +5365,7 @@ void BKE_curve_material_remap(Curve *cu, const unsigned int *remap, unsigned int } else { strinfo = cu->strinfo; - charinfo_len = cu->len_wchar; + charinfo_len = cu->len_char32; } for (i = 0; i <= charinfo_len; i++) { diff --git a/source/blender/blenkernel/intern/curve_bevel.c b/source/blender/blenkernel/intern/curve_bevel.c new file mode 100644 index 00000000000..7f23f0215cc --- /dev/null +++ b/source/blender/blenkernel/intern/curve_bevel.c @@ -0,0 +1,272 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** \file + * \ingroup bke + * + * Handle curve object data bevel options, + * both extruding + */ + +#include <string.h> + +#include "BLI_listbase.h" +#include "BLI_math_base.h" + +#include "MEM_guardedalloc.h" + +#include "DNA_curve_types.h" +#include "DNA_object_types.h" + +#include "BKE_curve.h" +#include "BKE_displist.h" + +typedef enum CurveBevelFillType { + BACK = 0, + FRONT, + HALF, + FULL, +} CurveBevelFillType; + +static CurveBevelFillType curve_bevel_get_fill_type(const Curve *curve) +{ + if (!(curve->flag & (CU_FRONT | CU_BACK))) { + return FULL; + } + if ((curve->flag & CU_FRONT) && (curve->flag & CU_BACK)) { + return HALF; + } + + return (curve->flag & CU_FRONT) ? FRONT : BACK; +} + +static void curve_bevel_make_extrude_and_fill(Curve *cu, + ListBase *disp, + const bool use_extrude, + const CurveBevelFillType fill_type) +{ + DispList *dl = MEM_callocN(sizeof(DispList), __func__); + + int nr; + if (fill_type == FULL) { + /* The full loop. */ + nr = 4 * cu->bevresol + 6; + dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE; + } + else if (fill_type == HALF) { + /* Half the loop. */ + nr = 2 * (cu->bevresol + 1) + (use_extrude ? 2 : 1); + dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE; + } + else { + /* One quarter of the loop (just front or back). */ + nr = use_extrude ? cu->bevresol + 3 : cu->bevresol + 2; + dl->flag = (fill_type == FRONT) ? DL_FRONT_CURVE : DL_BACK_CURVE; + } + + dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), __func__); + BLI_addtail(disp, dl); + /* Use a different type depending on whether the loop is complete or not. */ + dl->type = (fill_type == FULL) ? DL_POLY : DL_SEGM; + dl->parts = 1; + dl->nr = nr; + + float *fp = dl->verts; + const float dangle = (float)M_PI_2 / (cu->bevresol + 1); + float angle = 0.0f; + + /* Build the back section. */ + if (ELEM(fill_type, BACK, HALF, FULL)) { + angle = (float)M_PI_2 * 3.0f; + for (int i = 0; i < cu->bevresol + 2; i++) { + fp[0] = 0.0f; + fp[1] = (float)(cosf(angle) * (cu->ext2)); + fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1; + angle += dangle; + fp += 3; + } + if (use_extrude && fill_type == BACK) { + /* Add the extrusion if we're only building the back. */ + fp[0] = 0.0f; + fp[1] = cu->ext2; + fp[2] = cu->ext1; + } + } + + /* Build the front section. */ + if (ELEM(fill_type, FRONT, HALF, FULL)) { + if (use_extrude && fill_type == FRONT) { + /* Add the extrusion if we're only building the front. */ + fp[0] = 0.0f; + fp[1] = cu->ext2; + fp[2] = -cu->ext1; + fp += 3; + } + /* Don't duplicate the last back vertex. */ + angle = (!use_extrude && ELEM(fill_type, HALF, FULL)) ? dangle : 0; + int front_len = (!use_extrude && ELEM(fill_type, HALF, FULL)) ? cu->bevresol + 1 : + cu->bevresol + 2; + for (int i = 0; i < front_len; i++) { + fp[0] = 0.0f; + fp[1] = (float)(cosf(angle) * (cu->ext2)); + fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1; + angle += dangle; + fp += 3; + } + } + + /* Build the other half only if we're building the full loop. */ + if (fill_type == FULL) { + for (int i = 0; i < cu->bevresol + 1; i++) { + fp[0] = 0.0f; + fp[1] = (float)(cosf(angle) * (cu->ext2)); + fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1; + angle += dangle; + fp += 3; + } + + angle = (float)M_PI; + for (int i = 0; i < cu->bevresol + 1; i++) { + fp[0] = 0.0f; + fp[1] = (float)(cosf(angle) * (cu->ext2)); + fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1; + angle += dangle; + fp += 3; + } + } +} + +static void curve_bevel_make_full_circle(Curve *cu, ListBase *disp) +{ + const int nr = 4 + 2 * cu->bevresol; + + DispList *dl = MEM_callocN(sizeof(DispList), __func__); + dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), __func__); + BLI_addtail(disp, dl); + dl->type = DL_POLY; + dl->parts = 1; + dl->flag = DL_BACK_CURVE; + dl->nr = nr; + + float *fp = dl->verts; + const float dangle = (2.0f * (float)M_PI / (nr)); + float angle = -(nr - 1) * dangle; + + for (int i = 0; i < nr; i++) { + fp[0] = 0.0; + fp[1] = (cosf(angle) * (cu->ext2)); + fp[2] = (sinf(angle) * (cu->ext2)) - cu->ext1; + angle += dangle; + fp += 3; + } +} + +static void curve_bevel_make_only_extrude(Curve *cu, ListBase *disp) +{ + DispList *dl = MEM_callocN(sizeof(DispList), __func__); + dl->verts = MEM_malloc_arrayN(2, sizeof(float[3]), __func__); + BLI_addtail(disp, dl); + dl->type = DL_SEGM; + dl->parts = 1; + dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE; + dl->nr = 2; + + float *fp = dl->verts; + fp[0] = fp[1] = 0.0; + fp[2] = -cu->ext1; + fp[3] = fp[4] = 0.0; + fp[5] = cu->ext1; +} + +static void curve_bevel_make_from_object(Curve *cu, ListBase *disp) +{ + if (cu->bevobj->type != OB_CURVE) { + return; + } + + Curve *bevcu = cu->bevobj->data; + if (bevcu->ext1 == 0.0f && bevcu->ext2 == 0.0f) { + ListBase bevdisp = {NULL, NULL}; + float facx = cu->bevobj->scale[0]; + float facy = cu->bevobj->scale[1]; + + DispList *dl; + if (cu->bevobj->runtime.curve_cache) { + dl = cu->bevobj->runtime.curve_cache->disp.first; + } + else { + BLI_assert(cu->bevobj->runtime.curve_cache != NULL); + dl = NULL; + } + + while (dl) { + if (ELEM(dl->type, DL_POLY, DL_SEGM)) { + DispList *dlnew = MEM_mallocN(sizeof(DispList), __func__); + *dlnew = *dl; + dlnew->verts = MEM_malloc_arrayN(dl->parts * dl->nr, 3 * sizeof(float), __func__); + memcpy(dlnew->verts, dl->verts, 3 * sizeof(float) * dl->parts * dl->nr); + + if (dlnew->type == DL_SEGM) { + dlnew->flag |= (DL_FRONT_CURVE | DL_BACK_CURVE); + } + + BLI_addtail(disp, dlnew); + float *fp = dlnew->verts; + int nr = dlnew->parts * dlnew->nr; + while (nr--) { + fp[2] = fp[1] * facy; + fp[1] = -fp[0] * facx; + fp[0] = 0.0; + fp += 3; + } + } + dl = dl->next; + } + + BKE_displist_free(&bevdisp); + } +} + +void BKE_curve_bevel_make(Object *ob, ListBase *disp) +{ + Curve *curve = ob->data; + + const bool use_extrude = curve->ext1 != 0.0f; + const bool use_bevel = curve->ext2 != 0.0f; + + BLI_listbase_clear(disp); + + if (curve->bevobj) { + curve_bevel_make_from_object(curve, disp); + } + else if (!(use_extrude || use_bevel)) { + /* Pass. */ + } + else if (use_extrude && !use_bevel) { + curve_bevel_make_only_extrude(curve, disp); + } + else { + CurveBevelFillType fill_type = curve_bevel_get_fill_type(curve); + + if (!use_extrude && fill_type == FULL) { + curve_bevel_make_full_circle(curve, disp); + } + else { + /* The general case for nonzero extrusion or an incomplete loop. */ + curve_bevel_make_extrude_and_fill(curve, disp, use_extrude, fill_type); + } + } +} diff --git a/source/blender/blenkernel/intern/curveprofile.c b/source/blender/blenkernel/intern/curveprofile.c index 6919d4fa10f..068f8845e64 100644 --- a/source/blender/blenkernel/intern/curveprofile.c +++ b/source/blender/blenkernel/intern/curveprofile.c @@ -254,7 +254,7 @@ void BKE_curveprofile_remove_by_flag(CurveProfile *profile, const short flag) CurveProfilePoint *BKE_curveprofile_insert(CurveProfile *profile, float x, float y) { CurveProfilePoint *new_pt = NULL; - float new_loc[2] = {x, y}; + const float new_loc[2] = {x, y}; /* Don't add more control points than the maximum size of the higher resolution table. */ if (profile->path_len == PROF_TABLE_MAX - 1) { @@ -266,8 +266,8 @@ CurveProfilePoint *BKE_curveprofile_insert(CurveProfile *profile, float x, float float min_distance = FLT_MAX; int i_insert = 0; for (int i = 0; i < profile->path_len - 1; i++) { - float loc1[2] = {profile->path[i].x, profile->path[i].y}; - float loc2[2] = {profile->path[i + 1].x, profile->path[i + 1].y}; + const float loc1[2] = {profile->path[i].x, profile->path[i].y}; + const float loc2[2] = {profile->path[i + 1].x, profile->path[i + 1].y}; distance = dist_squared_to_line_segment_v2(new_loc, loc1, loc2); if (distance < min_distance) { @@ -689,9 +689,8 @@ static int sort_points_curvature(const void *in_a, const void *in_b) if (a->bezt_curvature > b->bezt_curvature) { return 0; } - else { - return 1; - } + + return 1; } /** @@ -886,7 +885,7 @@ void BKE_curveprofile_create_samples(CurveProfile *profile, */ static void curveprofile_make_table(CurveProfile *profile) { - int n_samples = PROF_N_TABLE(profile->path_len); + int n_samples = PROF_TABLE_LEN(profile->path_len); CurveProfilePoint *new_table = MEM_callocN(sizeof(CurveProfilePoint) * (n_samples + 1), "high-res table"); @@ -1040,7 +1039,7 @@ void BKE_curveprofile_update(CurveProfile *profile, const int update_flags) * Also sets the number of segments used for the display preview of the locations * of the sampled points. */ -void BKE_curveprofile_initialize(CurveProfile *profile, short segments_len) +void BKE_curveprofile_init(CurveProfile *profile, short segments_len) { if (segments_len != profile->segments_len) { profile->flag |= PROF_DIRTY_PRESET; @@ -1055,11 +1054,11 @@ void BKE_curveprofile_initialize(CurveProfile *profile, short segments_len) * Gives the distance to the next point in the widgets sampled table, in other words the length * of the \a 'i' edge of the table. * - * \note Requires curveprofile_initialize or #BKE_curveprofile_update call before to fill table. + * \note Requires #BKE_curveprofile_init or #BKE_curveprofile_update call before to fill table. */ static float curveprofile_distance_to_next_table_point(const CurveProfile *profile, int i) { - BLI_assert(i < PROF_N_TABLE(profile->path_len)); + BLI_assert(i < PROF_TABLE_LEN(profile->path_len)); return len_v2v2(&profile->table[i].x, &profile->table[i + 1].x); } @@ -1067,12 +1066,12 @@ static float curveprofile_distance_to_next_table_point(const CurveProfile *profi /** * Calculates the total length of the profile from the curves sampled in the table. * - * \note Requires curveprofile_initialize or #BKE_curveprofile_update call before to fill table. + * \note Requires #BKE_curveprofile_init or #BKE_curveprofile_update call before to fill table. */ float BKE_curveprofile_total_length(const CurveProfile *profile) { float total_length = 0; - for (int i = 0; i < PROF_N_TABLE(profile->path_len) - 1; i++) { + for (int i = 0; i < PROF_TABLE_LEN(profile->path_len) - 1; i++) { total_length += len_v2v2(&profile->table[i].x, &profile->table[i + 1].x); } return total_length; @@ -1082,7 +1081,7 @@ float BKE_curveprofile_total_length(const CurveProfile *profile) * Samples evenly spaced positions along the curve profile's table (generated from path). Fills * an entire table at once for a speedup if all of the results are going to be used anyway. * - * \note Requires curveprofile_initialize or #BKE_curveprofile_update call before to fill table. + * \note Requires #BKE_curveprofile_init or #BKE_curveprofile_update call before to fill table. * \note Working, but would conflict with "Sample Straight Edges" option, so this is unused for * now. */ @@ -1145,7 +1144,7 @@ void BKE_curveprofile_create_samples_even_spacing(CurveProfile *profile, * Travels down (length_portion * path) length and returns the position at that point. * * \param length_portion: The portion (0 to 1) of the path's full length to sample at. - * \note Requires curveprofile_initialize or #BKE_curveprofile_update call before to fill table. + * \note Requires #BKE_curveprofile_init or #BKE_curveprofile_update call before to fill table. */ void BKE_curveprofile_evaluate_length_portion(const CurveProfile *profile, float length_portion, @@ -1160,7 +1159,7 @@ void BKE_curveprofile_evaluate_length_portion(const CurveProfile *profile, float length_travelled = 0.0f; while (length_travelled < requested_length) { /* Check if we reached the last point before the final one. */ - if (i == PROF_N_TABLE(profile->path_len) - 2) { + if (i == PROF_TABLE_LEN(profile->path_len) - 2) { break; } float new_length = curveprofile_distance_to_next_table_point(profile, i); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 707db46a856..0c1717ea184 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -771,7 +771,7 @@ static void layerCopyValue_mloopcol(const void *source, if (mixmode == CDT_MIX_REPLACE_ABOVE_THRESHOLD && f < mixfactor) { return; /* Do Nothing! */ } - else if (mixmode == CDT_MIX_REPLACE_BELOW_THRESHOLD && f > mixfactor) { + if (mixmode == CDT_MIX_REPLACE_BELOW_THRESHOLD && f > mixfactor) { return; /* Do Nothing! */ } } @@ -1358,7 +1358,7 @@ static void layerCopyValue_propcol(const void *source, if (mixmode == CDT_MIX_REPLACE_ABOVE_THRESHOLD && f < mixfactor) { return; /* Do Nothing! */ } - else if (mixmode == CDT_MIX_REPLACE_BELOW_THRESHOLD && f > mixfactor) { + if (mixmode == CDT_MIX_REPLACE_BELOW_THRESHOLD && f > mixfactor) { return; /* Do Nothing! */ } } @@ -2201,13 +2201,13 @@ bool CustomData_merge(const struct CustomData *source, if (flag & CD_FLAG_NOCOPY) { continue; } - else if (!(mask & CD_TYPE_AS_MASK(type))) { + if (!(mask & CD_TYPE_AS_MASK(type))) { continue; } - else if ((maxnumber != -1) && (number >= maxnumber)) { + if ((maxnumber != -1) && (number >= maxnumber)) { continue; } - else if (CustomData_get_named_layer_index(dest, type, layer->name) != -1) { + if (CustomData_get_named_layer_index(dest, type, layer->name) != -1) { continue; } @@ -2643,11 +2643,13 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data, } if (alloctype == CD_DUPLICATE && layerdata) { - if (typeInfo->copy) { - typeInfo->copy(layerdata, newlayerdata, totelem); - } - else { - memcpy(newlayerdata, layerdata, (size_t)totelem * typeInfo->size); + if (totelem > 0) { + if (typeInfo->copy) { + typeInfo->copy(layerdata, newlayerdata, totelem); + } + else { + memcpy(newlayerdata, layerdata, (size_t)totelem * typeInfo->size); + } } } else if (alloctype == CD_DEFAULT) { @@ -4050,9 +4052,8 @@ bool CustomData_data_equals(int type, const void *data1, const void *data2) if (typeInfo->equal) { return typeInfo->equal(data1, data2); } - else { - return !memcmp(data1, data2, typeInfo->size); - } + + return !memcmp(data1, data2, typeInfo->size); } void CustomData_data_initminmax(int type, void *min, void *max) @@ -4409,7 +4410,7 @@ int CustomData_layertype_layers_max(const int type) if (typeInfo->defaultname == NULL) { return 1; } - else if (typeInfo->layers_max == NULL) { + if (typeInfo->layers_max == NULL) { return -1; } diff --git a/source/blender/blenkernel/intern/customdata_file.c b/source/blender/blenkernel/intern/customdata_file.c index 1463e50f6e3..4fa232a368b 100644 --- a/source/blender/blenkernel/intern/customdata_file.c +++ b/source/blender/blenkernel/intern/customdata_file.c @@ -101,9 +101,8 @@ static int cdf_endian(void) if (ENDIAN_ORDER == L_ENDIAN) { return CDF_ENDIAN_LITTLE; } - else { - return CDF_ENDIAN_BIG; - } + + return CDF_ENDIAN_BIG; } CDataFile *cdf_create(int type) @@ -318,9 +317,8 @@ bool cdf_read_layer(CDataFile *cdf, CDataFileLayer *blay) if (&cdf->layer[a] == blay) { break; } - else { - offset += cdf->layer[a].datasize; - } + + offset += cdf->layer[a].datasize; } return (fseek(cdf->readf, offset, SEEK_SET) == 0); diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c index 7bf87d0e639..179f2f44180 100644 --- a/source/blender/blenkernel/intern/data_transfer.c +++ b/source/blender/blenkernel/intern/data_transfer.c @@ -961,7 +961,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, } return true; } - else if (cddata_type == CD_FAKE_BWEIGHT) { + if (cddata_type == CD_FAKE_BWEIGHT) { const size_t elem_size = sizeof(*((MVert *)NULL)); const size_t data_size = sizeof(((MVert *)NULL)->bweight); const size_t data_offset = offsetof(MVert, bweight); @@ -993,7 +993,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, } return true; } - else if (cddata_type == CD_FAKE_MDEFORMVERT) { + if (cddata_type == CD_FAKE_MDEFORMVERT) { bool ret; cd_src = &me_src->vdata; @@ -1018,7 +1018,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, me_dst->dvert = CustomData_get_layer(&me_dst->vdata, CD_MDEFORMVERT); return ret; } - else if (cddata_type == CD_FAKE_SHAPEKEY) { + if (cddata_type == CD_FAKE_SHAPEKEY) { /* TODO: leaving shapekeys aside for now, quite specific case, * since we can't access them from MVert :/ */ return false; @@ -1049,7 +1049,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, } return true; } - else if (cddata_type == CD_FAKE_CREASE) { + if (cddata_type == CD_FAKE_CREASE) { const size_t elem_size = sizeof(*((MEdge *)NULL)); const size_t data_size = sizeof(((MEdge *)NULL)->crease); const size_t data_offset = offsetof(MEdge, crease); @@ -1081,7 +1081,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, } return true; } - else if (cddata_type == CD_FAKE_BWEIGHT) { + if (cddata_type == CD_FAKE_BWEIGHT) { const size_t elem_size = sizeof(*((MEdge *)NULL)); const size_t data_size = sizeof(((MEdge *)NULL)->bweight); const size_t data_offset = offsetof(MEdge, bweight); @@ -1113,7 +1113,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, } return true; } - else if (r_map && ELEM(cddata_type, CD_FAKE_SHARP, CD_FAKE_SEAM)) { + if (r_map && ELEM(cddata_type, CD_FAKE_SHARP, CD_FAKE_SEAM)) { const size_t elem_size = sizeof(*((MEdge *)NULL)); const size_t data_size = sizeof(((MEdge *)NULL)->flag); const size_t data_offset = offsetof(MEdge, flag); @@ -1136,9 +1136,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, interp_data); return true; } - else { - return false; - } + + return false; } else if (elem_type == ME_LOOP) { if (cddata_type == CD_FAKE_UV) { @@ -1176,9 +1175,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, } return true; } - else { - return false; - } + + return false; } else if (elem_type == ME_POLY) { if (cddata_type == CD_FAKE_UV) { @@ -1209,7 +1207,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, } return true; } - else if (r_map && cddata_type == CD_FAKE_SHARP) { + if (r_map && cddata_type == CD_FAKE_SHARP) { const size_t elem_size = sizeof(*((MPoly *)NULL)); const size_t data_size = sizeof(((MPoly *)NULL)->flag); const size_t data_offset = offsetof(MPoly, flag); @@ -1232,9 +1230,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, interp_data); return true; } - else { - return false; - } + + return false; } return false; diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 98fc5f9a23a..1a32deac776 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -510,36 +510,35 @@ int *BKE_object_defgroup_flip_map(const Object *ob, int *flip_map_len, const boo if (defbase_tot == 0) { return NULL; } - else { - bDeformGroup *dg; - char name_flip[sizeof(dg->name)]; - int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__); - for (i = 0; i < defbase_tot; i++) { - map[i] = -1; - } + bDeformGroup *dg; + char name_flip[sizeof(dg->name)]; + int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__); - for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) { - if (map[i] == -1) { /* may be calculated previously */ + for (i = 0; i < defbase_tot; i++) { + map[i] = -1; + } - /* in case no valid value is found, use this */ - if (use_default) { - map[i] = i; - } + for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) { + if (map[i] == -1) { /* may be calculated previously */ - BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip)); + /* in case no valid value is found, use this */ + if (use_default) { + map[i] = i; + } - if (!STREQ(name_flip, dg->name)) { - flip_num = BKE_object_defgroup_name_index(ob, name_flip); - if (flip_num >= 0) { - map[i] = flip_num; - map[flip_num] = i; /* save an extra lookup */ - } + BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip)); + + if (!STREQ(name_flip, dg->name)) { + flip_num = BKE_object_defgroup_name_index(ob, name_flip); + if (flip_num >= 0) { + map[i] = flip_num; + map[flip_num] = i; /* save an extra lookup */ } } } - return map; } + return map; } /** @@ -555,29 +554,28 @@ int *BKE_object_defgroup_flip_map_single(const Object *ob, if (defbase_tot == 0) { return NULL; } - else { - bDeformGroup *dg; - char name_flip[sizeof(dg->name)]; - int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__); - for (i = 0; i < defbase_tot; i++) { - map[i] = use_default ? i : -1; - } + bDeformGroup *dg; + char name_flip[sizeof(dg->name)]; + int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__); - dg = BLI_findlink(&ob->defbase, defgroup); + for (i = 0; i < defbase_tot; i++) { + map[i] = use_default ? i : -1; + } - BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip)); - if (!STREQ(name_flip, dg->name)) { - flip_num = BKE_object_defgroup_name_index(ob, name_flip); + dg = BLI_findlink(&ob->defbase, defgroup); - if (flip_num != -1) { - map[defgroup] = flip_num; - map[flip_num] = defgroup; - } - } + BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip)); + if (!STREQ(name_flip, dg->name)) { + flip_num = BKE_object_defgroup_name_index(ob, name_flip); - return map; + if (flip_num != -1) { + map[defgroup] = flip_num; + map[flip_num] = defgroup; + } } + + return map; } int BKE_object_defgroup_flip_index(const Object *ob, int index, const bool use_default) @@ -658,7 +656,7 @@ float BKE_defvert_array_find_weight_safe(const struct MDeformVert *dvert, if (defgroup == -1) { return 1.0f; } - else if (dvert == NULL) { + if (dvert == NULL) { return 0.0f; } @@ -909,10 +907,9 @@ float BKE_defvert_calc_lock_relative_weight(float weight, if (weight != 0.0f) { return 1.0f; } - else { - /* resolve 0/0 to 0 */ - return 0.0f; - } + + /* resolve 0/0 to 0 */ + return 0.0f; } /* non-degenerate division */ diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 7b7b7ceb84b..a39f2ccb6d8 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -320,7 +320,7 @@ static int dynamicPaint_surfaceNumOfPoints(DynamicPaintSurface *surface) if (surface->format == MOD_DPAINT_SURFACE_F_PTEX) { return 0; /* not supported atm */ } - else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { + if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { const Mesh *canvas_mesh = dynamicPaint_canvas_mesh_get(surface->canvas); return (canvas_mesh) ? canvas_mesh->totvert : 0; } @@ -353,7 +353,7 @@ bool dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, Object Mesh *me = ob->data; return (CustomData_get_named_layer_index(&me->ldata, CD_MLOOPCOL, name) != -1); } - else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) { + if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) { return (BKE_object_defgroup_name_index(ob, name) != -1); } } @@ -602,7 +602,7 @@ static bool boundIntersectPoint(Bounds3D *b, const float point[3], const float r } /* expand bounds by a new point */ -static void boundInsert(Bounds3D *b, float point[3]) +static void boundInsert(Bounds3D *b, const float point[3]) { if (!b->valid) { copy_v3_v3(b->min, point); @@ -2675,7 +2675,7 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa int w = bdata->w, h = bdata->h, px = bdata->px, py = bdata->py; - int final_pixel[2] = {(int)floorf(tgt_pixel[0] * w), (int)floorf(tgt_pixel[1] * h)}; + const int final_pixel[2] = {(int)floorf(tgt_pixel[0] * w), (int)floorf(tgt_pixel[1] * h)}; /* If current pixel uv is outside of texture */ if (final_pixel[0] < 0 || final_pixel[0] >= w || final_pixel[1] < 0 || final_pixel[1] >= h) { @@ -3742,7 +3742,7 @@ static bool meshBrush_boundsIntersect(Bounds3D *b1, if (brush->collision == MOD_DPAINT_COL_VOLUME) { return boundsIntersect(b1, b2); } - else if (brush->collision == MOD_DPAINT_COL_DIST || brush->collision == MOD_DPAINT_COL_VOLDIST) { + if (brush->collision == MOD_DPAINT_COL_DIST || brush->collision == MOD_DPAINT_COL_VOLDIST) { return boundsIntersectDist(b1, b2, brush_radius); } return true; diff --git a/source/blender/blenkernel/intern/editmesh_cache.c b/source/blender/blenkernel/intern/editmesh_cache.c index 5017a48d14e..d0509c94fc6 100644 --- a/source/blender/blenkernel/intern/editmesh_cache.c +++ b/source/blender/blenkernel/intern/editmesh_cache.c @@ -148,11 +148,10 @@ bool BKE_editmesh_cache_calc_minmax(struct BMEditMesh *em, } return true; } - else { - zero_v3(min); - zero_v3(max); - return false; - } + + zero_v3(min); + zero_v3(max); + return false; } /** \} */ diff --git a/source/blender/blenkernel/intern/editmesh_tangent.c b/source/blender/blenkernel/intern/editmesh_tangent.c index 6fcaf84d4ca..897fc7e692b 100644 --- a/source/blender/blenkernel/intern/editmesh_tangent.c +++ b/source/blender/blenkernel/intern/editmesh_tangent.c @@ -274,8 +274,8 @@ static void emDM_calc_loop_tangents_thread(TaskPool *__restrict UNUSED(pool), vo /** * \see #BKE_mesh_calc_loop_tangent, same logic but used arrays instead of #BMesh data. * - * \note This function is not so normal, its using `bm->ldata` as input, - * but output's to `dm->loopData`. + * \note This function is not so normal, its using #BMesh.ldata as input, + * but output's to #Mesh.ldata. * This is done because #CD_TANGENT is cache data used only for drawing. */ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em, diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index a43553ee89f..97f9cebf58b 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -313,10 +313,10 @@ ListBase *BKE_effectors_create(Depsgraph *depsgraph, if (ob == ob_src) { continue; } - else if (weights->weight[ob->pd->forcefield] == 0.0f) { + if (weights->weight[ob->pd->forcefield] == 0.0f) { continue; } - else if (ob->pd->shape == PFIELD_SHAPE_POINTS && BKE_object_get_evaluated_mesh(ob) == NULL) { + if (ob->pd->shape == PFIELD_SHAPE_POINTS && BKE_object_get_evaluated_mesh(ob) == NULL) { continue; } diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index acbbf50701a..abed90e7192 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -320,7 +320,7 @@ int BKE_fcurves_filter(ListBase *dst, ListBase *src, const char *dataPrefix, con if (ELEM(NULL, dst, src, dataPrefix, dataName)) { return 0; } - else if ((dataPrefix[0] == 0) || (dataName[0] == 0)) { + if ((dataPrefix[0] == 0) || (dataName[0] == 0)) { return 0; } @@ -915,7 +915,7 @@ void bezt_add_to_cfra_elem(ListBase *lb, BezTriple *bezt) return; } /* should key be inserted before this column? */ - else if (ce->cfra > bezt->vec[1][0]) { + if (ce->cfra > bezt->vec[1][0]) { break; } } diff --git a/source/blender/blenkernel/intern/fcurve_driver.c b/source/blender/blenkernel/intern/fcurve_driver.c index 10d804f437e..b11a3cb9457 100644 --- a/source/blender/blenkernel/intern/fcurve_driver.c +++ b/source/blender/blenkernel/intern/fcurve_driver.c @@ -21,12 +21,6 @@ * \ingroup bke */ -// #include <float.h> -// #include <math.h> -// #include <stddef.h> -// #include <stdio.h> -// #include <string.h> - #include "MEM_guardedalloc.h" #include "DNA_anim_types.h" @@ -66,17 +60,19 @@ static ThreadMutex python_driver_lock = BLI_MUTEX_INITIALIZER; static CLG_LogRef LOG = {"bke.fcurve"}; -/* Driver Variables --------------------------- */ +/* -------------------------------------------------------------------- */ +/** \name Driver Variables + * \{ */ /* TypeInfo for Driver Variables (dvti) */ typedef struct DriverVarTypeInfo { - /* evaluation callback */ + /* Evaluation callback. */ float (*get_value)(ChannelDriver *driver, DriverVar *dvar); - /* allocation of target slots */ - int num_targets; /* number of target slots required */ - const char *target_names[MAX_DRIVER_TARGETS]; /* UI names that should be given to the slots */ - short target_flags[MAX_DRIVER_TARGETS]; /* flags defining the requirements for each slot */ + /* Allocation of target slots. */ + int num_targets; /* Number of target slots required. */ + const char *target_names[MAX_DRIVER_TARGETS]; /* UI names that should be given to the slots. */ + short target_flags[MAX_DRIVER_TARGETS]; /* Flags defining the requirements for each slot. */ } DriverVarTypeInfo; /* Macro to begin definitions */ @@ -85,7 +81,11 @@ typedef struct DriverVarTypeInfo { /* Macro to end definitions */ #define END_DVAR_TYPEDEF } -/* ......... */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Driver Target Utilities + * \{ */ static ID *dtar_id_ensure_proxy_from(ID *id) { @@ -107,14 +107,14 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar) int index = -1; float value = 0.0f; - /* sanity check */ + /* Sanity check. */ if (ELEM(NULL, driver, dtar)) { return 0.0f; } id = dtar_id_ensure_proxy_from(dtar->id); - /* error check for missing pointer... */ + /* Error check for missing pointer. */ if (id == NULL) { if (G.debug & G_DEBUG) { CLOG_ERROR(&LOG, "driver has an invalid target to use (path = %s)", dtar->rna_path); @@ -125,12 +125,12 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar) return 0.0f; } - /* get RNA-pointer for the ID-block given in target */ + /* Get RNA-pointer for the ID-block given in target. */ RNA_id_pointer_create(id, &id_ptr); - /* get property to read from, and get value as appropriate */ + /* Get property to read from, and get value as appropriate. */ if (!RNA_path_resolve_property_full(&id_ptr, dtar->rna_path, &ptr, &prop, &index)) { - /* path couldn't be resolved */ + /* Path couldn't be resolved. */ if (G.debug & G_DEBUG) { CLOG_ERROR(&LOG, "Driver Evaluation Error: cannot resolve target for %s -> %s", @@ -144,9 +144,9 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar) } if (RNA_property_array_check(prop)) { - /* array */ + /* Array. */ if (index < 0 || index >= RNA_property_array_length(&ptr, prop)) { - /* out of bounds */ + /* Out of bounds. */ if (G.debug & G_DEBUG) { CLOG_ERROR(&LOG, "Driver Evaluation Error: array index is out of bounds for %s -> %s (%d)", @@ -175,7 +175,7 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar) } } else { - /* not an array */ + /* Not an array. */ switch (RNA_property_type(prop)) { case PROP_BOOLEAN: value = (float)RNA_property_boolean_get(&ptr, prop); @@ -194,7 +194,7 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar) } } - /* if we're still here, we should be ok... */ + /* If we're still here, we should be ok. */ dtar->flag &= ~DTAR_FLAG_INVALID; return value; } @@ -214,14 +214,14 @@ bool driver_get_variable_property(ChannelDriver *driver, ID *id; int index = -1; - /* sanity check */ + /* Sanity check. */ if (ELEM(NULL, driver, dtar)) { return false; } id = dtar_id_ensure_proxy_from(dtar->id); - /* error check for missing pointer... */ + /* Error check for missing pointer. */ if (id == NULL) { if (G.debug & G_DEBUG) { CLOG_ERROR(&LOG, "driver has an invalid target to use (path = %s)", dtar->rna_path); @@ -232,19 +232,19 @@ bool driver_get_variable_property(ChannelDriver *driver, return false; } - /* get RNA-pointer for the ID-block given in target */ + /* Get RNA-pointer for the ID-block given in target. */ RNA_id_pointer_create(id, &id_ptr); - /* get property to read from, and get value as appropriate */ + /* Get property to read from, and get value as appropriate. */ if (dtar->rna_path == NULL || dtar->rna_path[0] == '\0') { ptr = PointerRNA_NULL; - prop = NULL; /* ok */ + prop = NULL; /* OK. */ } else if (RNA_path_resolve_property_full(&id_ptr, dtar->rna_path, &ptr, &prop, &index)) { - /* ok */ + /* OK. */ } else { - /* path couldn't be resolved */ + /* Path couldn't be resolved. */ if (G.debug & G_DEBUG) { CLOG_ERROR(&LOG, "Driver Evaluation Error: cannot resolve target for %s -> %s", @@ -265,7 +265,7 @@ bool driver_get_variable_property(ChannelDriver *driver, *r_prop = prop; *r_index = index; - /* if we're still here, we should be ok... */ + /* If we're still here, we should be ok. */ dtar->flag &= ~DTAR_FLAG_INVALID; return true; } @@ -277,14 +277,14 @@ static short driver_check_valid_targets(ChannelDriver *driver, DriverVar *dvar) DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) { Object *ob = (Object *)dtar_id_ensure_proxy_from(dtar->id); - /* check if this target has valid data */ + /* Check if this target has valid data. */ if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) { - /* invalid target, so will not have enough targets */ + /* Invalid target, so will not have enough targets. */ driver->flag |= DRIVER_FLAG_INVALID; dtar->flag |= DTAR_FLAG_INVALID; } else { - /* target seems to be OK now... */ + /* Target seems to be OK now. */ dtar->flag &= ~DTAR_FLAG_INVALID; valid_targets++; } @@ -294,21 +294,25 @@ static short driver_check_valid_targets(ChannelDriver *driver, DriverVar *dvar) return valid_targets; } -/* ......... */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Driver Variable Utilities + * \{ */ -/* evaluate 'single prop' driver variable */ +/* Evaluate 'single prop' driver variable. */ static float dvar_eval_singleProp(ChannelDriver *driver, DriverVar *dvar) { - /* just evaluate the first target slot */ + /* Just evaluate the first target slot. */ return dtar_get_prop_val(driver, &dvar->targets[0]); } -/* evaluate 'rotation difference' driver variable */ +/* Evaluate 'rotation difference' driver variable. */ static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar) { short valid_targets = driver_check_valid_targets(driver, dvar); - /* make sure we have enough valid targets to use - all or nothing for now... */ + /* Make sure we have enough valid targets to use - all or nothing for now. */ if (driver_check_valid_targets(driver, dvar) != 2) { if (G.debug & G_DEBUG) { CLOG_WARN(&LOG, @@ -324,31 +328,31 @@ static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar) /* NOTE: for now, these are all just worldspace */ for (int i = 0; i < 2; i++) { - /* get pointer to loc values to store in */ + /* Get pointer to loc values to store in. */ DriverTarget *dtar = &dvar->targets[i]; Object *ob = (Object *)dtar_id_ensure_proxy_from(dtar->id); bPoseChannel *pchan; - /* after the checks above, the targets should be valid here... */ + /* After the checks above, the targets should be valid here. */ BLI_assert((ob != NULL) && (GS(ob->id.name) == ID_OB)); - /* try to get posechannel */ + /* Try to get pose-channel. */ pchan = BKE_pose_channel_find_name(ob->pose, dtar->pchan_name); - /* check if object or bone */ + /* Check if object or bone. */ if (pchan) { - /* bone */ + /* Bone. */ mat[i] = pchan->pose_mat; } else { - /* object */ + /* Object. */ mat[i] = ob->obmat; } } float q1[4], q2[4], quat[4], angle; - /* use the final posed locations */ + /* Use the final posed locations. */ mat4_to_quat(q1, mat[0]); mat4_to_quat(q2, mat[1]); @@ -360,15 +364,18 @@ static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar) return (angle > (float)M_PI) ? (float)((2.0f * (float)M_PI) - angle) : (float)(angle); } -/* evaluate 'location difference' driver variable */ -/* TODO: this needs to take into account space conversions... */ +/** + * Evaluate 'location difference' driver variable. + * + * TODO: this needs to take into account space conversions. + */ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar) { float loc1[3] = {0.0f, 0.0f, 0.0f}; float loc2[3] = {0.0f, 0.0f, 0.0f}; short valid_targets = driver_check_valid_targets(driver, dvar); - /* make sure we have enough valid targets to use - all or nothing for now... */ + /* Make sure we have enough valid targets to use - all or nothing for now. */ if (valid_targets < dvar->num_targets) { if (G.debug & G_DEBUG) { CLOG_WARN(&LOG, @@ -381,72 +388,72 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar) } /* SECOND PASS: get two location values */ - /* NOTE: for now, these are all just worldspace */ + /* NOTE: for now, these are all just world-space */ DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) { - /* get pointer to loc values to store in */ + /* Get pointer to loc values to store in. */ Object *ob = (Object *)dtar_id_ensure_proxy_from(dtar->id); bPoseChannel *pchan; float tmp_loc[3]; - /* after the checks above, the targets should be valid here... */ + /* After the checks above, the targets should be valid here. */ BLI_assert((ob != NULL) && (GS(ob->id.name) == ID_OB)); - /* try to get posechannel */ + /* Try to get pose-channel. */ pchan = BKE_pose_channel_find_name(ob->pose, dtar->pchan_name); - /* check if object or bone */ + /* Check if object or bone. */ if (pchan) { - /* bone */ + /* Bone. */ if (dtar->flag & DTAR_FLAG_LOCALSPACE) { if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) { float mat[4][4]; - /* extract transform just like how the constraints do it! */ + /* Extract transform just like how the constraints do it! */ copy_m4_m4(mat, pchan->pose_mat); BKE_constraint_mat_convertspace( ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false); - /* ... and from that, we get our transform */ + /* ... and from that, we get our transform. */ copy_v3_v3(tmp_loc, mat[3]); } else { - /* transform space (use transform values directly) */ + /* Transform space (use transform values directly). */ copy_v3_v3(tmp_loc, pchan->loc); } } else { - /* convert to worldspace */ + /* Convert to worldspace. */ copy_v3_v3(tmp_loc, pchan->pose_head); mul_m4_v3(ob->obmat, tmp_loc); } } else { - /* object */ + /* Object. */ if (dtar->flag & DTAR_FLAG_LOCALSPACE) { if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) { - /* XXX: this should practically be the same as transform space... */ + /* XXX: this should practically be the same as transform space. */ float mat[4][4]; - /* extract transform just like how the constraints do it! */ + /* Extract transform just like how the constraints do it! */ copy_m4_m4(mat, ob->obmat); BKE_constraint_mat_convertspace( ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false); - /* ... and from that, we get our transform */ + /* ... and from that, we get our transform. */ copy_v3_v3(tmp_loc, mat[3]); } else { - /* transform space (use transform values directly) */ + /* Transform space (use transform values directly). */ copy_v3_v3(tmp_loc, ob->loc); } } else { - /* worldspace */ + /* World-space. */ copy_v3_v3(tmp_loc, ob->obmat[3]); } } - /* copy the location to the right place */ + /* Copy the location to the right place. */ if (tarIndex) { copy_v3_v3(loc2, tmp_loc); } @@ -456,13 +463,14 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar) } DRIVER_TARGETS_LOOPER_END; - /* if we're still here, there should now be two targets to use, - * so just take the length of the vector between these points - */ + /* If we're still here, there should now be two targets to use, + * so just take the length of the vector between these points. */ return len_v3v3(loc1, loc2); } -/* evaluate 'transform channel' driver variable */ +/** + * Evaluate 'transform channel' driver variable. + */ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar) { DriverTarget *dtar = &dvar->targets[0]; @@ -473,17 +481,16 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar) bool use_eulers = false; short rot_order = ROT_MODE_EUL; - /* check if this target has valid data */ + /* Check if this target has valid data. */ if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) { - /* invalid target, so will not have enough targets */ + /* Invalid target, so will not have enough targets. */ driver->flag |= DRIVER_FLAG_INVALID; dtar->flag |= DTAR_FLAG_INVALID; return 0.0f; } - else { - /* target should be valid now */ - dtar->flag &= ~DTAR_FLAG_INVALID; - } + + /* Target should be valid now. */ + dtar->flag &= ~DTAR_FLAG_INVALID; /* Try to get pose-channel. */ pchan = BKE_pose_channel_find_name(ob->pose, dtar->pchan_name); @@ -495,7 +502,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar) * but #DTAR_FLAG_LOCAL_CONSTS is for all the common "corrective-shapes-for-limbs" situations. */ if (pchan) { - /* bone */ + /* Bone. */ if (pchan->rotmode > 0) { copy_v3_v3(oldEul, pchan->eul); rot_order = pchan->rotmode; @@ -504,16 +511,15 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar) if (dtar->flag & DTAR_FLAG_LOCALSPACE) { if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) { - /* just like how the constraints do it! */ + /* Just like how the constraints do it! */ copy_m4_m4(mat, pchan->pose_mat); BKE_constraint_mat_convertspace( ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false); } else { - /* specially calculate local matrix, since chan_mat is not valid + /* Specially calculate local matrix, since chan_mat is not valid * since it stores delta transform of pose_mat so that deforms work - * so it cannot be used here for "transform" space - */ + * so it cannot be used here for "transform" space. */ BKE_pchan_to_mat4(pchan, mat); } } @@ -523,7 +529,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar) } } else { - /* object */ + /* Object. */ if (ob->rotmode > 0) { copy_v3_v3(oldEul, ob->rot); rot_order = ob->rotmode; @@ -532,42 +538,39 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar) if (dtar->flag & DTAR_FLAG_LOCALSPACE) { if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) { - /* just like how the constraints do it! */ + /* Just like how the constraints do it! */ copy_m4_m4(mat, ob->obmat); BKE_constraint_mat_convertspace( ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false); } else { - /* transforms to matrix */ + /* Transforms to matrix. */ BKE_object_to_mat4(ob, mat); } } else { - /* worldspace matrix - just the good-old one */ + /* World-space matrix - just the good-old one. */ copy_m4_m4(mat, ob->obmat); } } - /* check which transform */ + /* Check which transform. */ if (dtar->transChan >= MAX_DTAR_TRANSCHAN_TYPES) { - /* not valid channel */ + /* Not valid channel. */ return 0.0f; } - else if (dtar->transChan == DTAR_TRANSCHAN_SCALE_AVG) { + if (dtar->transChan == DTAR_TRANSCHAN_SCALE_AVG) { /* Cubic root of the change in volume, equal to the geometric mean * of scale over all three axes unless the matrix includes shear. */ return cbrtf(mat4_to_volume_scale(mat)); } - else if (ELEM(dtar->transChan, - DTAR_TRANSCHAN_SCALEX, - DTAR_TRANSCHAN_SCALEY, - DTAR_TRANSCHAN_SCALEZ)) { + if (ELEM(dtar->transChan, DTAR_TRANSCHAN_SCALEX, DTAR_TRANSCHAN_SCALEY, DTAR_TRANSCHAN_SCALEZ)) { /* Extract scale, and choose the right axis, * inline 'mat4_to_size'. */ return len_v3(mat[dtar->transChan - DTAR_TRANSCHAN_SCALEX]); } - else if (dtar->transChan >= DTAR_TRANSCHAN_ROTX) { - /* extract rotation as eulers (if needed) + if (dtar->transChan >= DTAR_TRANSCHAN_ROTX) { + /* Extract rotation as eulers (if needed) * - definitely if rotation order isn't eulers already * - if eulers, then we have 2 options: * a) decompose transform matrix as required, then try to make eulers from @@ -595,10 +598,9 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar) return quat[channel]; } - else { - /* extract location and choose right axis */ - return mat[3][dtar->transChan]; - } + + /* Extract location and choose right axis. */ + return mat[3][dtar->transChan]; } /* Convert a quaternion to pseudo-angles representing the weighted amount of rotation. */ @@ -666,83 +668,90 @@ void BKE_driver_target_matrix_to_rot_channels( } } -/* ......... */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Driver Variable Type Info + * \{ */ /* Table of Driver Variable Type Info Data */ static DriverVarTypeInfo dvar_types[MAX_DVAR_TYPES] = { - BEGIN_DVAR_TYPEDEF(DVAR_TYPE_SINGLE_PROP) dvar_eval_singleProp, /* eval callback */ - 1, /* number of targets used */ + BEGIN_DVAR_TYPEDEF(DVAR_TYPE_SINGLE_PROP) dvar_eval_singleProp, /* Eval callback. */ + 1, /* Number of targets used. */ {"Property"}, /* UI names for targets */ - {0} /* flags */ + {0} /* Flags. */ END_DVAR_TYPEDEF, - BEGIN_DVAR_TYPEDEF(DVAR_TYPE_ROT_DIFF) dvar_eval_rotDiff, /* eval callback */ - 2, /* number of targets used */ + BEGIN_DVAR_TYPEDEF(DVAR_TYPE_ROT_DIFF) dvar_eval_rotDiff, /* Eval callback. */ + 2, /* Number of targets used. */ {"Object/Bone 1", "Object/Bone 2"}, /* UI names for targets */ {DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY, - DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* flags */ + DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* Flags. */ END_DVAR_TYPEDEF, - BEGIN_DVAR_TYPEDEF(DVAR_TYPE_LOC_DIFF) dvar_eval_locDiff, /* eval callback */ - 2, /* number of targets used */ + BEGIN_DVAR_TYPEDEF(DVAR_TYPE_LOC_DIFF) dvar_eval_locDiff, /* Eval callback. */ + 2, /* Number of targets used. */ {"Object/Bone 1", "Object/Bone 2"}, /* UI names for targets */ {DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY, - DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* flags */ + DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* Flags. */ END_DVAR_TYPEDEF, - BEGIN_DVAR_TYPEDEF(DVAR_TYPE_TRANSFORM_CHAN) dvar_eval_transChan, /* eval callback */ - 1, /* number of targets used */ + BEGIN_DVAR_TYPEDEF(DVAR_TYPE_TRANSFORM_CHAN) dvar_eval_transChan, /* Eval callback. */ + 1, /* Number of targets used. */ {"Object/Bone"}, /* UI names for targets */ - {DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* flags */ + {DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* Flags. */ END_DVAR_TYPEDEF, }; /* Get driver variable typeinfo */ static const DriverVarTypeInfo *get_dvar_typeinfo(int type) { - /* check if valid type */ + /* Check if valid type. */ if ((type >= 0) && (type < MAX_DVAR_TYPES)) { return &dvar_types[type]; } - else { - return NULL; - } + + return NULL; } -/* Driver API --------------------------------- */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Driver API + * \{ */ /* Perform actual freeing driver variable and remove it from the given list */ void driver_free_variable(ListBase *variables, DriverVar *dvar) { - /* sanity checks */ + /* Sanity checks. */ if (dvar == NULL) { return; } - /* free target vars + /* Free target vars: * - need to go over all of them, not just up to the ones that are used * currently, since there may be some lingering RNA paths from * previous users needing freeing */ DRIVER_TARGETS_LOOPER_BEGIN (dvar) { - /* free RNA path if applicable */ + /* Free RNA path if applicable. */ if (dtar->rna_path) { MEM_freeN(dtar->rna_path); } } DRIVER_TARGETS_LOOPER_END; - /* remove the variable from the driver */ + /* Remove the variable from the driver. */ BLI_freelinkN(variables, dvar); } /* Free the driver variable and do extra updates */ void driver_free_variable_ex(ChannelDriver *driver, DriverVar *dvar) { - /* remove and free the driver variable */ + /* Remove and free the driver variable. */ driver_free_variable(&driver->variables, dvar); - /* since driver variables are cached, the expression needs re-compiling too */ + /* Since driver variables are cached, the expression needs re-compiling too. */ BKE_driver_invalidate_expression(driver, false, true); } @@ -753,9 +762,9 @@ void driver_variables_copy(ListBase *dst_vars, const ListBase *src_vars) BLI_duplicatelist(dst_vars, src_vars); LISTBASE_FOREACH (DriverVar *, dvar, dst_vars) { - /* need to go over all targets so that we don't leave any dangling paths */ + /* Need to go over all targets so that we don't leave any dangling paths. */ DRIVER_TARGETS_LOOPER_BEGIN (dvar) { - /* make a copy of target's rna path if available */ + /* Make a copy of target's rna path if available. */ if (dtar->rna_path) { dtar->rna_path = MEM_dupallocN(dtar->rna_path); } @@ -769,25 +778,24 @@ void driver_change_variable_type(DriverVar *dvar, int type) { const DriverVarTypeInfo *dvti = get_dvar_typeinfo(type); - /* sanity check */ + /* Sanity check. */ if (ELEM(NULL, dvar, dvti)) { return; } - /* set the new settings */ + /* Set the new settings. */ dvar->type = type; dvar->num_targets = dvti->num_targets; - /* make changes to the targets based on the defines for these types - * NOTE: only need to make sure the ones we're using here are valid... - */ + /* Make changes to the targets based on the defines for these types. + * NOTE: only need to make sure the ones we're using here are valid. */ DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) { short flags = dvti->target_flags[tarIndex]; - /* store the flags */ + /* Store the flags. */ dtar->flag = flags; - /* object ID types only, or idtype not yet initialized */ + /* Object ID types only, or idtype not yet initialized. */ if ((flags & DTAR_FLAG_ID_OB_ONLY) || (dtar->idtype == 0)) { dtar->idtype = ID_OB; } @@ -804,12 +812,12 @@ void driver_variable_name_validate(DriverVar *dvar) '?', ':', ';', '<', '>', '{', '}', '[', ']', '|', ' ', '.', '\t', '\n', '\r', }; - /* sanity checks */ + /* Sanity checks. */ if (dvar == NULL) { return; } - /* clear all invalid-name flags */ + /* Clear all invalid-name flags. */ dvar->flag &= ~DVAR_ALL_INVALID_FLAGS; /* 0) Zero-length identifiers are not allowed */ @@ -870,16 +878,16 @@ DriverVar *driver_add_new_variable(ChannelDriver *driver) { DriverVar *dvar; - /* sanity checks */ + /* Sanity checks. */ if (driver == NULL) { return NULL; } - /* make a new variable */ + /* Make a new variable. */ dvar = MEM_callocN(sizeof(DriverVar), "DriverVar"); BLI_addtail(&driver->variables, dvar); - /* give the variable a 'unique' name */ + /* Give the variable a 'unique' name. */ strcpy(dvar->name, CTX_DATA_(BLT_I18NCONTEXT_ID_ACTION, "var")); BLI_uniquename(&driver->variables, dvar, @@ -888,13 +896,13 @@ DriverVar *driver_add_new_variable(ChannelDriver *driver) offsetof(DriverVar, name), sizeof(dvar->name)); - /* set the default type to 'single prop' */ + /* Set the default type to 'single prop'. */ driver_change_variable_type(dvar, DVAR_TYPE_SINGLE_PROP); - /* since driver variables are cached, the expression needs re-compiling too */ + /* Since driver variables are cached, the expression needs re-compiling too. */ BKE_driver_invalidate_expression(driver, false, true); - /* return the target */ + /* Return the target. */ return dvar; } @@ -904,20 +912,20 @@ void fcurve_free_driver(FCurve *fcu) ChannelDriver *driver; DriverVar *dvar, *dvarn; - /* sanity checks */ + /* Sanity checks. */ if (ELEM(NULL, fcu, fcu->driver)) { return; } driver = fcu->driver; - /* free driver targets */ + /* Free driver targets. */ for (dvar = driver->variables.first; dvar; dvar = dvarn) { dvarn = dvar->next; driver_free_variable_ex(driver, dvar); } #ifdef WITH_PYTHON - /* free compiled driver expression */ + /* Free compiled driver expression. */ if (driver->expr_comp) { BPY_DECREF(driver->expr_comp); } @@ -936,27 +944,31 @@ ChannelDriver *fcurve_copy_driver(const ChannelDriver *driver) { ChannelDriver *ndriver; - /* sanity checks */ + /* Sanity checks. */ if (driver == NULL) { return NULL; } - /* copy all data */ + /* Copy all data. */ ndriver = MEM_dupallocN(driver); ndriver->expr_comp = NULL; ndriver->expr_simple = NULL; - /* copy variables */ + /* Copy variables. */ - /* to get rid of refs to non-copied data (that's still used on original) */ + /* To get rid of refs to non-copied data (that's still used on original). */ BLI_listbase_clear(&ndriver->variables); driver_variables_copy(&ndriver->variables, &driver->variables); - /* return the new driver */ + /* Return the new driver. */ return ndriver; } -/* Driver Expression Evaluation --------------- */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Driver Expression Evaluation + * \{ */ /* Index constants for the expression parameter array. */ enum { @@ -1026,7 +1038,7 @@ static bool driver_evaluate_simple_expr(ChannelDriver *driver, return true; default: - /* arriving here means a bug, not user error */ + /* Arriving here means a bug, not user error. */ CLOG_ERROR(&LOG, "simple driver expression evaluation failed: '%s'", driver->expression); return false; } @@ -1108,10 +1120,9 @@ bool BKE_driver_expression_depends_on_time(ChannelDriver *driver) /* Simple expressions can be checked exactly. */ return driver_check_simple_expr_depends_on_time(driver->expr_simple); } - else { - /* Otherwise, heuristically scan the expression string for certain patterns. */ - return python_driver_exression_depends_on_time(driver->expression); - } + + /* Otherwise, heuristically scan the expression string for certain patterns. */ + return python_driver_exression_depends_on_time(driver->expression); } /* Reset cached compiled expression data */ @@ -1135,22 +1146,25 @@ void BKE_driver_invalidate_expression(ChannelDriver *driver, #endif } -/* Driver Evaluation -------------------------- */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Driver Evaluation + * \{ */ /* Evaluate a Driver Variable to get a value that contributes to the final */ float driver_get_variable_value(ChannelDriver *driver, DriverVar *dvar) { const DriverVarTypeInfo *dvti; - /* sanity check */ + /* Sanity check. */ if (ELEM(NULL, driver, dvar)) { return 0.0f; } - /* call the relevant callbacks to get the variable value + /* Call the relevant callbacks to get the variable value * using the variable type info, storing the obtained value - * in dvar->curval so that drivers can be debugged - */ + * in `dvar->curval` so that drivers can be debugged. */ dvti = get_dvar_typeinfo(dvar->type); if (dvti && dvti->get_value) { @@ -1167,25 +1181,25 @@ static void evaluate_driver_sum(ChannelDriver *driver) { DriverVar *dvar; - /* check how many variables there are first (i.e. just one?) */ + /* Check how many variables there are first (i.e. just one?). */ if (BLI_listbase_is_single(&driver->variables)) { - /* just one target, so just use that */ + /* Just one target, so just use that. */ dvar = driver->variables.first; driver->curval = driver_get_variable_value(driver, dvar); return; } - /* more than one target, so average the values of the targets */ + /* More than one target, so average the values of the targets. */ float value = 0.0f; int tot = 0; - /* loop through targets, adding (hopefully we don't get any overflow!) */ + /* Loop through targets, adding (hopefully we don't get any overflow!). */ for (dvar = driver->variables.first; dvar; dvar = dvar->next) { value += driver_get_variable_value(driver, dvar); tot++; } - /* perform operations on the total if appropriate */ + /* Perform operations on the total if appropriate. */ if (driver->type == DRIVER_TYPE_AVERAGE) { driver->curval = tot ? (value / (float)tot) : 0.0f; } @@ -1199,34 +1213,34 @@ static void evaluate_driver_min_max(ChannelDriver *driver) DriverVar *dvar; float value = 0.0f; - /* loop through the variables, getting the values and comparing them to existing ones */ + /* Loop through the variables, getting the values and comparing them to existing ones. */ for (dvar = driver->variables.first; dvar; dvar = dvar->next) { - /* get value */ + /* Get value. */ float tmp_val = driver_get_variable_value(driver, dvar); - /* store this value if appropriate */ + /* Store this value if appropriate. */ if (dvar->prev) { - /* check if greater/smaller than the baseline */ + /* Check if greater/smaller than the baseline. */ if (driver->type == DRIVER_TYPE_MAX) { - /* max? */ + /* Max? */ if (tmp_val > value) { value = tmp_val; } } else { - /* min? */ + /* Min? */ if (tmp_val < value) { value = tmp_val; } } } else { - /* first item - make this the baseline for comparisons */ + /* First item - make this the baseline for comparisons. */ value = tmp_val; } } - /* store value in driver */ + /* Store value in driver. */ driver->curval = value; } @@ -1235,62 +1249,63 @@ static void evaluate_driver_python(PathResolvedRNA *anim_rna, ChannelDriver *driver_orig, const AnimationEvalContext *anim_eval_context) { - /* check for empty or invalid expression */ + /* Check for empty or invalid expression. */ if ((driver_orig->expression[0] == '\0') || (driver_orig->flag & DRIVER_FLAG_INVALID)) { driver->curval = 0.0f; } else if (!driver_try_evaluate_simple_expr( driver, driver_orig, &driver->curval, anim_eval_context->eval_time)) { #ifdef WITH_PYTHON - /* this evaluates the expression using Python, and returns its result: - * - on errors it reports, then returns 0.0f - */ + /* This evaluates the expression using Python, and returns its result: + * - on errors it reports, then returns 0.0f. */ BLI_mutex_lock(&python_driver_lock); driver->curval = BPY_driver_exec(anim_rna, driver, driver_orig, anim_eval_context); BLI_mutex_unlock(&python_driver_lock); -#else /* WITH_PYTHON*/ +#else /* WITH_PYTHON */ UNUSED_VARS(anim_rna, anim_eval_context); -#endif /* WITH_PYTHON*/ +#endif /* WITH_PYTHON */ } } -/* Evaluate an Channel-Driver to get a 'time' value to use instead of "evaltime" - * - "evaltime" is the frame at which F-Curve is being evaluated - * - has to return a float value - * - driver_orig is where we cache Python expressions, in case of COW +/** + * Evaluate an Channel-Driver to get a 'time' value to use + * instead of `anim_eval_context->eval_time`. + * + * - `anim_eval_context->eval_time` is the frame at which F-Curve is being evaluated. + * - Has to return a float value. + * - \a driver_orig is where we cache Python expressions, in case of COW */ float evaluate_driver(PathResolvedRNA *anim_rna, ChannelDriver *driver, ChannelDriver *driver_orig, const AnimationEvalContext *anim_eval_context) { - /* check if driver can be evaluated */ + /* Check if driver can be evaluated. */ if (driver_orig->flag & DRIVER_FLAG_INVALID) { return 0.0f; } switch (driver->type) { - case DRIVER_TYPE_AVERAGE: /* average values of driver targets */ - case DRIVER_TYPE_SUM: /* sum values of driver targets */ + case DRIVER_TYPE_AVERAGE: /* Average values of driver targets. */ + case DRIVER_TYPE_SUM: /* Sum values of driver targets. */ evaluate_driver_sum(driver); break; - case DRIVER_TYPE_MIN: /* smallest value */ - case DRIVER_TYPE_MAX: /* largest value */ + case DRIVER_TYPE_MIN: /* Smallest value. */ + case DRIVER_TYPE_MAX: /* Largest value. */ evaluate_driver_min_max(driver); break; - case DRIVER_TYPE_PYTHON: /* expression */ + case DRIVER_TYPE_PYTHON: /* Expression. */ evaluate_driver_python(anim_rna, driver, driver_orig, anim_eval_context); break; default: - /* special 'hack' - just use stored value + /* Special 'hack' - just use stored value * This is currently used as the mechanism which allows animated settings to be able - * to be changed via the UI. - */ + * to be changed via the UI. */ break; } - /* return value for driver */ + /* Return value for driver. */ return driver->curval; } diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c index 079b436a3ea..b37d940195e 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.c @@ -533,14 +533,14 @@ static bool BKE_fluid_modifier_init( /* Allocate fluid. */ return BKE_fluid_reallocate_fluid(fds, fds->res, 0); } - else if (fmd->type & MOD_FLUID_TYPE_FLOW) { + if (fmd->type & MOD_FLUID_TYPE_FLOW) { if (!fmd->flow) { BKE_fluid_modifier_create_type_data(fmd); } fmd->time = scene_framenr; return true; } - else if (fmd->type & MOD_FLUID_TYPE_EFFEC) { + if (fmd->type & MOD_FLUID_TYPE_EFFEC) { if (!fmd->effector) { BKE_fluid_modifier_create_type_data(fmd); } @@ -575,7 +575,7 @@ static int get_light(ViewLayer *view_layer, float *light) copy_v3_v3(light, base_tmp->object->obmat[3]); return 1; } - else if (!found_light) { + if (!found_light) { copy_v3_v3(light, base_tmp->object->obmat[3]); found_light = 1; } @@ -655,7 +655,7 @@ typedef struct FluidObjectBB { int total_cells, valid; } FluidObjectBB; -static void bb_boundInsert(FluidObjectBB *bb, float point[3]) +static void bb_boundInsert(FluidObjectBB *bb, const float point[3]) { int i = 0; if (!bb->valid) { @@ -955,7 +955,7 @@ static void obstacles_from_mesh_task_cb(void *__restrict userdata, for (int y = data->min[1]; y < data->max[1]; y++) { const int index = manta_get_index( x - bb->min[0], bb->res[0], y - bb->min[1], bb->res[1], z - bb->min[2]); - float ray_start[3] = {(float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f}; + const float ray_start[3] = {(float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f}; /* Calculate object velocities. Result in bb->velocity. */ sample_effector(data->fes, @@ -1119,6 +1119,7 @@ static void ensure_obstaclefields(FluidDomainSettings *fds) if (fds->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE) { manta_ensure_guiding(fds->fluid, fds->fmd); } + manta_update_pointers(fds->fluid, fds->fmd, false); } static void update_obstacleflags(FluidDomainSettings *fds, @@ -2596,7 +2597,7 @@ static void ensure_flowsfields(FluidDomainSettings *fds) manta_smoke_ensure_fire(fds->fluid, fds->fmd); } if (fds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS) { - /* initialize all smoke with "active_color" */ + /* Initialize all smoke with "active_color". */ manta_smoke_ensure_colors(fds->fluid, fds->fmd); } if (fds->type == FLUID_DOMAIN_TYPE_LIQUID && @@ -2605,6 +2606,7 @@ static void ensure_flowsfields(FluidDomainSettings *fds) fds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER)) { manta_liquid_ensure_sndparts(fds->fluid, fds->fmd); } + manta_update_pointers(fds->fluid, fds->fmd, false); } static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int numflowobj) @@ -2617,7 +2619,7 @@ static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int n FLUID_DOMAIN_ACTIVE_HEAT | FLUID_DOMAIN_ACTIVE_FIRE); active_fields &= ~prev_flags; - /* Monitor active fields based on flow settings */ + /* Monitor active fields based on flow settings. */ for (flow_index = 0; flow_index < numflowobj; flow_index++) { Object *flow_ob = flowobjs[flow_index]; FluidModifierData *fmd2 = (FluidModifierData *)BKE_modifiers_findby_type(flow_ob, @@ -2628,6 +2630,7 @@ static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int n continue; } + /* Activate specific grids if at least one flow object requires this grid. */ if ((fmd2->type & MOD_FLUID_TYPE_FLOW) && fmd2->flow) { FluidFlowSettings *ffs = fmd2->flow; if (!ffs) { @@ -2648,17 +2651,17 @@ static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int n continue; } - /* activate heat field if flow produces any heat */ - if (ffs->temperature) { + /* Activate heat field if a flow object produces any heat. */ + if (ffs->temperature != 0.0) { active_fields |= FLUID_DOMAIN_ACTIVE_HEAT; } - /* activate fuel field if flow adds any fuel */ - if (ffs->fuel_amount && - (ffs->type == FLUID_FLOW_TYPE_FIRE || ffs->type == FLUID_FLOW_TYPE_SMOKEFIRE)) { + /* Activate fuel field if a flow object is of fire type. */ + if (ffs->fuel_amount != 0.0 || ffs->type == FLUID_FLOW_TYPE_FIRE || + ffs->type == FLUID_FLOW_TYPE_SMOKEFIRE) { active_fields |= FLUID_DOMAIN_ACTIVE_FIRE; } - /* activate color field if flows add smoke with varying colors */ - if (ffs->density && + /* Activate color field if flows add smoke with varying colors. */ + if (ffs->density != 0.0 && (ffs->type == FLUID_FLOW_TYPE_SMOKE || ffs->type == FLUID_FLOW_TYPE_SMOKEFIRE)) { if (!(active_fields & FLUID_DOMAIN_ACTIVE_COLOR_SET)) { copy_v3_v3(fds->active_color, ffs->color); @@ -2671,11 +2674,11 @@ static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int n } } } - /* Monitor active fields based on domain settings */ + /* Monitor active fields based on domain settings. */ if (fds->type == FLUID_DOMAIN_TYPE_GAS && active_fields & FLUID_DOMAIN_ACTIVE_FIRE) { - /* heat is always needed for fire */ + /* Heat is always needed for fire. */ active_fields |= FLUID_DOMAIN_ACTIVE_HEAT; - /* also activate colors if domain smoke color differs from active color */ + /* Also activate colors if domain smoke color differs from active color. */ if (!(active_fields & FLUID_DOMAIN_ACTIVE_COLOR_SET)) { copy_v3_v3(fds->active_color, fds->flame_smoke_color); active_fields |= FLUID_DOMAIN_ACTIVE_COLOR_SET; @@ -2924,8 +2927,21 @@ static void update_flowsfluids(struct Depsgraph *depsgraph, float *velx_initial = manta_get_in_velocity_x(fds->fluid); float *vely_initial = manta_get_in_velocity_y(fds->fluid); float *velz_initial = manta_get_in_velocity_z(fds->fluid); - uint z; + float *forcex = manta_get_force_x(fds->fluid); + float *forcey = manta_get_force_y(fds->fluid); + float *forcez = manta_get_force_z(fds->fluid); + + BLI_assert(forcex && forcey && forcez); + + /* Either all or no components have to exist. */ + BLI_assert((color_r && color_g && color_b) || (!color_r && !color_g && !color_b)); + BLI_assert((color_r_in && color_g_in && color_b_in) || + (!color_r_in && !color_g_in && !color_b_in)); + BLI_assert((velx_initial && vely_initial && velz_initial) || + (!velx_initial && !vely_initial && !velz_initial)); + + uint z; /* Grid reset before writing again. */ for (z = 0; z < fds->res[0] * fds->res[1] * fds->res[2]; z++) { /* Only reset static phi on first frame, dynamic phi gets reset every time. */ @@ -2949,7 +2965,7 @@ static void update_flowsfluids(struct Depsgraph *depsgraph, if (heat_in) { heat_in[z] = heat[z]; } - if (color_r_in) { + if (color_r_in && color_g_in && color_b_in) { color_r_in[z] = color_r[z]; color_g_in[z] = color_b[z]; color_b_in[z] = color_g[z]; @@ -2961,11 +2977,15 @@ static void update_flowsfluids(struct Depsgraph *depsgraph, if (emission_in) { emission_in[z] = 0.0f; } - if (velx_initial) { + if (velx_initial && vely_initial && velz_initial) { velx_initial[z] = 0.0f; vely_initial[z] = 0.0f; velz_initial[z] = 0.0f; } + /* Reset forces here as update_effectors() is skipped when no external forces are present. */ + forcex[z] = 0.0f; + forcey[z] = 0.0f; + forcez[z] = 0.0f; } /* Apply emission data for every flow object. */ @@ -3149,13 +3169,13 @@ static void update_effectors_task_cb(void *__restrict userdata, continue; } - /* get velocities from manta grid space and convert to blender units */ + /* Get velocities from manta grid space and convert to blender units. */ vel[0] = data->velocity_x[index]; vel[1] = data->velocity_y[index]; vel[2] = data->velocity_z[index]; mul_v3_fl(vel, fds->dx); - /* convert vel to global space */ + /* Convert vel to global space. */ mag = len_v3(vel); mul_mat3_m4_v3(fds->obmat, vel); normalize_v3(vel); @@ -3166,18 +3186,18 @@ static void update_effectors_task_cb(void *__restrict userdata, voxel_center[2] = fds->p0[2] + fds->cell_size[2] * ((float)(z + fds->res_min[2]) + 0.5f); mul_m4_v3(fds->obmat, voxel_center); - /* do effectors */ + /* Do effectors. */ pd_point_from_loc(data->scene, voxel_center, vel, index, &epoint); BKE_effectors_apply( data->effectors, NULL, fds->effector_weights, &epoint, retvel, NULL, NULL); - /* convert retvel to local space */ + /* Convert retvel to local space. */ mag = len_v3(retvel); mul_mat3_m4_v3(fds->imat, retvel); normalize_v3(retvel); mul_v3_fl(retvel, mag); - /* constrain forces to interval -1 to 1 */ + /* Constrain forces to interval -1 to 1. */ data->force_x[index] = min_ff(max_ff(-1.0f, retvel[0] * 0.2f), 1.0f); data->force_y[index] = min_ff(max_ff(-1.0f, retvel[1] * 0.2f), 1.0f); data->force_z[index] = min_ff(max_ff(-1.0f, retvel[2] * 0.2f), 1.0f); @@ -3617,14 +3637,16 @@ static int manta_step( fds->time_per_frame = time_per_frame; fds->time_total = time_total; } + /* Total time must not exceed framecount times framelength. Correct tiny errors here. */ CLAMP(fds->time_total, fds->time_total, time_total_old + fds->frame_length); + /* Compute shadow grid for gas simulations. Make sure to skip if bake job was canceled early. */ if (fds->type == FLUID_DOMAIN_TYPE_GAS && result) { manta_smoke_calc_transparency(fds, DEG_get_evaluated_view_layer(depsgraph)); } - BLI_mutex_unlock(&object_update_lock); + BLI_mutex_unlock(&object_update_lock); return result; } @@ -3716,29 +3738,35 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd, int mode = fds->cache_type; /* Do not process modifier if current frame is out of cache range. */ + bool escape = false; switch (mode) { case FLUID_DOMAIN_CACHE_ALL: case FLUID_DOMAIN_CACHE_MODULAR: if (fds->cache_frame_offset > 0) { if (scene_framenr < fds->cache_frame_start || scene_framenr > fds->cache_frame_end + fds->cache_frame_offset) { - return; + escape = true; } } else { if (scene_framenr < fds->cache_frame_start + fds->cache_frame_offset || scene_framenr > fds->cache_frame_end) { - return; + escape = true; } } break; case FLUID_DOMAIN_CACHE_REPLAY: default: if (scene_framenr < fds->cache_frame_start || scene_framenr > fds->cache_frame_end) { - return; + escape = true; } break; } + /* If modifier will not be processed, update/flush pointers from (old) fluid object once more. */ + if (escape && fds->fluid) { + manta_update_pointers(fds->fluid, fmd, true); + return; + } /* Reset fluid if no fluid present. Also resets active fields. */ if (!fds->fluid) { @@ -3830,7 +3858,15 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd, has_mesh = manta_has_mesh(fds->fluid, fmd, scene_framenr); has_particles = manta_has_particles(fds->fluid, fmd, scene_framenr); has_guide = manta_has_guiding(fds->fluid, fmd, scene_framenr, guide_parent); - has_config = false; + has_config = manta_read_config(fds->fluid, fmd, scene_framenr); + + /* When reading data from cache (has_config == true) ensure that active fields are allocated. + * update_flowsflags() and update_obstacleflags() will not find flow sources hidden from renders. + * See also: T72192. */ + if (has_config) { + ensure_flowsfields(fds); + ensure_obstaclefields(fds); + } bool baking_data, baking_noise, baking_mesh, baking_particles, baking_guide; baking_data = fds->cache_flag & FLUID_DOMAIN_BAKING_DATA; @@ -3947,7 +3983,9 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd, /* Read mesh cache. */ if (with_liquid && with_mesh) { - has_config = manta_read_config(fds->fluid, fmd, mesh_frame); + if (mesh_frame != scene_framenr) { + has_config = manta_read_config(fds->fluid, fmd, mesh_frame); + } /* Update mesh data from file is faster than via Python (manta_read_mesh()). */ has_mesh = manta_read_mesh(fds->fluid, fmd, mesh_frame); @@ -3955,7 +3993,9 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd, /* Read particles cache. */ if (with_liquid && with_particles) { - has_config = manta_read_config(fds->fluid, fmd, particles_frame); + if (particles_frame != scene_framenr) { + has_config = manta_read_config(fds->fluid, fmd, particles_frame); + } read_partial = !baking_data && !baking_particles && next_particles; read_all = !read_partial && with_resumable_cache; @@ -3970,7 +4010,9 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd, /* Read noise and data cache */ if (with_smoke && with_noise) { - has_config = manta_read_config(fds->fluid, fmd, noise_frame); + if (noise_frame != scene_framenr) { + has_config = manta_read_config(fds->fluid, fmd, noise_frame); + } /* Only reallocate when just reading cache or when resuming during bake. */ if (has_data && has_config && manta_needs_realloc(fds->fluid, fmd)) { @@ -3988,7 +4030,9 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd, } /* Read data cache only */ else { - has_config = manta_read_config(fds->fluid, fmd, data_frame); + if (data_frame != scene_framenr) { + has_config = manta_read_config(fds->fluid, fmd, data_frame); + } if (with_smoke) { /* Read config and realloc fluid object if needed. */ @@ -4073,6 +4117,9 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd, } } + /* Ensure that fluid pointers are always up to date at the end of modifier processing. */ + manta_update_pointers(fds->fluid, fmd, false); + fds->flags &= ~FLUID_DOMAIN_FILE_LOAD; fmd->time = scene_framenr; } diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index c85283e3653..c973b681fe7 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -285,9 +285,8 @@ static double sinc(double x) if (fabs(x) < 0.0001) { return 1.0; } - else { - return sin(M_PI * x) / (M_PI * x); - } + + return sin(M_PI * x) / (M_PI * x); } static void fcm_fn_generator_evaluate( @@ -525,29 +524,28 @@ int BKE_fcm_envelope_find_index(FCM_EnvelopeData array[], CLOG_WARN(&LOG, "encountered invalid array"); return 0; } - else { - /* check whether to add before/after/on */ - float framenum; - /* 'First' Point (when only one point, this case is used) */ - framenum = array[0].time; - if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) { - *r_exists = true; - return 0; - } - else if (frame < framenum) { - return 0; - } + /* check whether to add before/after/on */ + float framenum; - /* 'Last' Point */ - framenum = array[(arraylen - 1)].time; - if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) { - *r_exists = true; - return (arraylen - 1); - } - else if (frame > framenum) { - return arraylen; - } + /* 'First' Point (when only one point, this case is used) */ + framenum = array[0].time; + if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) { + *r_exists = true; + return 0; + } + if (frame < framenum) { + return 0; + } + + /* 'Last' Point */ + framenum = array[(arraylen - 1)].time; + if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) { + *r_exists = true; + return (arraylen - 1); + } + if (frame > framenum) { + return arraylen; } /* most of the time, this loop is just to find where to put it @@ -1076,9 +1074,8 @@ const FModifierTypeInfo *get_fmodifier_typeinfo(const int type) /* there shouldn't be any segfaults here... */ return fmodifiersTypeInfo[type]; } - else { - CLOG_ERROR(&LOG, "No valid F-Curve Modifier type-info data available. Type = %i", type); - } + + CLOG_ERROR(&LOG, "No valid F-Curve Modifier type-info data available. Type = %i", type); return NULL; } @@ -1092,9 +1089,8 @@ const FModifierTypeInfo *fmodifier_get_typeinfo(const FModifier *fcm) if (fcm) { return get_fmodifier_typeinfo(fcm->type); } - else { - return NULL; - } + + return NULL; } /* API --------------------------- */ @@ -1239,12 +1235,11 @@ bool remove_fmodifier(ListBase *modifiers, FModifier *fcm) return true; } - else { - /* XXX this case can probably be removed some day, as it shouldn't happen... */ - CLOG_STR_ERROR(&LOG, "no modifier stack given"); - MEM_freeN(fcm); - return false; - } + + /* XXX this case can probably be removed some day, as it shouldn't happen... */ + CLOG_STR_ERROR(&LOG, "no modifier stack given"); + MEM_freeN(fcm); + return false; } /* Remove all of a given F-Curve's modifiers */ @@ -1397,13 +1392,13 @@ static float eval_fmodifier_influence(FModifier *fcm, float evaltime) /* out of range */ return 0.0f; } - else if ((evaltime > fcm->sfra) && (evaltime < fcm->sfra + fcm->blendin)) { + if ((evaltime > fcm->sfra) && (evaltime < fcm->sfra + fcm->blendin)) { /* blend in range */ float a = fcm->sfra; float b = fcm->sfra + fcm->blendin; return influence * (evaltime - a) / (b - a); } - else if ((evaltime < fcm->efra) && (evaltime > fcm->efra - fcm->blendout)) { + if ((evaltime < fcm->efra) && (evaltime > fcm->efra - fcm->blendout)) { /* blend out range */ float a = fcm->efra; float b = fcm->efra - fcm->blendout; diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index dfa5ff6975f..4bedba8f76b 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -193,13 +193,12 @@ static PackedFile *get_builtin_packedfile(void) return NULL; } - else { - void *mem = MEM_mallocN(builtin_font_size, "vfd_builtin"); - memcpy(mem, builtin_font_data, builtin_font_size); + void *mem = MEM_mallocN(builtin_font_size, "vfd_builtin"); - return BKE_packedfile_new_from_memory(mem, builtin_font_size); - } + memcpy(mem, builtin_font_data, builtin_font_size); + + return BKE_packedfile_new_from_memory(mem, builtin_font_size); } static VFontData *vfont_get_data(VFont *vfont) @@ -621,12 +620,11 @@ int BKE_vfont_select_get(Object *ob, int *r_start, int *r_end) if (start == end + 1) { return 0; } - else { - BLI_assert(start < end + 1); - *r_start = start; - *r_end = end; - return direction; - } + + BLI_assert(start < end + 1); + *r_start = start; + *r_end = end; + return direction; } void BKE_vfont_select_clamp(Object *ob) @@ -647,12 +645,11 @@ static float char_width(Curve *cu, VChar *che, CharInfo *info) if (che == NULL) { return 0.0f; } - else if (info->flag & CU_CHINFO_SMALLCAPS_CHECK) { + if (info->flag & CU_CHINFO_SMALLCAPS_CHECK) { return che->width * cu->smallcaps_scale; } - else { - return che->width; - } + + return che->width; } static void textbox_scale(TextBox *tb_dst, const TextBox *tb_src, float scale) @@ -797,7 +794,7 @@ static bool vfont_to_curve(Object *ob, } else { char32_t *mem_tmp; - slen = cu->len_wchar; + slen = cu->len_char32; /* Create unicode string */ mem_tmp = MEM_malloc_arrayN((slen + 1), sizeof(*mem_tmp), "convertedmem"); @@ -1603,32 +1600,32 @@ static bool vfont_to_curve(Object *ob, } return true; } + + ok = true; +finally: + if (r_text) { + *r_text = mem; + *r_text_len = slen; + *r_text_free = (ef == NULL); + } else { - ok = true; - finally: - if (r_text) { - *r_text = mem; - *r_text_len = slen; - *r_text_free = (ef == NULL); + if (ef == NULL) { + MEM_freeN((void *)mem); + } + } + + if (chartransdata) { + if (ok && r_chartransdata) { + *r_chartransdata = chartransdata; } else { - if (ef == NULL) { - MEM_freeN((void *)mem); - } + MEM_freeN(chartransdata); } + } - if (chartransdata) { - if (ok && r_chartransdata) { - *r_chartransdata = chartransdata; - } - else { - MEM_freeN(chartransdata); - } - } + /* Store the effective scale, to use for the textbox lines. */ + cu->fsize_realtime = font_size; - /* Store the effective scale, to use for the textbox lines. */ - cu->fsize_realtime = font_size; - } return ok; #undef MARGIN_X_MIN diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index eeb55c44d6e..c64f1b86eab 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -381,7 +381,7 @@ bGPDframe *BKE_gpencil_frame_addcopy(bGPDlayer *gpl, int cframe) /* no layer */ return NULL; } - else if (gpl->actframe == NULL) { + if (gpl->actframe == NULL) { /* no active frame, so just create a new one from scratch */ return BKE_gpencil_frame_addnew(gpl, cframe); } @@ -398,7 +398,7 @@ bGPDframe *BKE_gpencil_frame_addcopy(bGPDlayer *gpl, int cframe) found = true; break; } - else if (gpf->framenum == cframe) { + if (gpf->framenum == cframe) { /* This only happens when we're editing with framelock on... * - Delete the new frame and don't do anything else here... */ @@ -1009,7 +1009,7 @@ bGPDframe *BKE_gpencil_layer_frame_get(bGPDlayer *gpl, int cframe, eGP_GetFrame_ found = true; break; } - else if ((gpf->next) && (gpf->next->framenum > cframe)) { + if ((gpf->next) && (gpf->next->framenum > cframe)) { found = true; break; } @@ -1484,10 +1484,9 @@ Material *BKE_gpencil_object_material_ensure_from_brush(Main *bmain, Object *ob, return ma; } - else { - /* using active material instead */ - return BKE_object_material_get(ob, ob->actcol); - } + + /* using active material instead */ + return BKE_object_material_get(ob, ob->actcol); } /** @@ -1546,9 +1545,8 @@ Material *BKE_gpencil_object_material_from_brush_get(Object *ob, Brush *brush) Material *ma = BKE_gpencil_brush_material_get(brush); return ma; } - else { - return BKE_object_material_get(ob, ob->actcol); - } + + return BKE_object_material_get(ob, ob->actcol); } /** @@ -1562,9 +1560,8 @@ int BKE_gpencil_object_material_get_index_from_brush(Object *ob, Brush *brush) if ((brush) && (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED)) { return BKE_gpencil_object_material_index_get(ob, brush->gpencil_settings->material); } - else { - return ob->actcol - 1; - } + + return ob->actcol - 1; } /** @@ -1581,9 +1578,8 @@ Material *BKE_gpencil_object_material_ensure_from_active_input_toolsettings(Main return BKE_gpencil_object_material_ensure_from_active_input_brush( bmain, ob, ts->gp_paint->paint.brush); } - else { - return BKE_gpencil_object_material_ensure_from_active_input_brush(bmain, ob, NULL); - } + + return BKE_gpencil_object_material_ensure_from_active_input_brush(bmain, ob, NULL); } /** @@ -1602,7 +1598,7 @@ Material *BKE_gpencil_object_material_ensure_from_active_input_brush(Main *bmain if (ma) { return ma; } - else if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) { + if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) { /* it is easier to just unpin a NULL material, instead of setting a new one */ brush->gpencil_settings->flag &= ~GP_BRUSH_MATERIAL_PINNED; } @@ -2425,31 +2421,29 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph, unit_m4(diff_mat); return; } - else { - if ((gpl->partype == PAROBJECT) || (gpl->partype == PARSKEL)) { - mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse); + + if ((gpl->partype == PAROBJECT) || (gpl->partype == PARSKEL)) { + mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse); + add_v3_v3(diff_mat[3], ob_eval->obmat[3]); + return; + } + if (gpl->partype == PARBONE) { + bPoseChannel *pchan = BKE_pose_channel_find_name(obparent_eval->pose, gpl->parsubstr); + if (pchan) { + float tmp_mat[4][4]; + mul_m4_m4m4(tmp_mat, obparent_eval->obmat, pchan->pose_mat); + mul_m4_m4m4(diff_mat, tmp_mat, gpl->inverse); add_v3_v3(diff_mat[3], ob_eval->obmat[3]); - return; - } - else if (gpl->partype == PARBONE) { - bPoseChannel *pchan = BKE_pose_channel_find_name(obparent_eval->pose, gpl->parsubstr); - if (pchan) { - float tmp_mat[4][4]; - mul_m4_m4m4(tmp_mat, obparent_eval->obmat, pchan->pose_mat); - mul_m4_m4m4(diff_mat, tmp_mat, gpl->inverse); - add_v3_v3(diff_mat[3], ob_eval->obmat[3]); - } - else { - /* if bone not found use object (armature) */ - mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse); - add_v3_v3(diff_mat[3], ob_eval->obmat[3]); - } - return; } else { - unit_m4(diff_mat); /* not defined type */ + /* if bone not found use object (armature) */ + mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse); + add_v3_v3(diff_mat[3], ob_eval->obmat[3]); } + return; } + + unit_m4(diff_mat); /* not defined type */ } /** diff --git a/source/blender/blenkernel/intern/gpencil_curve.c b/source/blender/blenkernel/intern/gpencil_curve.c index a7adbed6c4b..3e568bd5e1e 100644 --- a/source/blender/blenkernel/intern/gpencil_curve.c +++ b/source/blender/blenkernel/intern/gpencil_curve.c @@ -50,7 +50,7 @@ #include "DEG_depsgraph_query.h" /* Helper: Check materials with same color. */ -static int gpencil_check_same_material_color(Object *ob_gp, float color[4], Material **r_mat) +static int gpencil_check_same_material_color(Object *ob_gp, const float color[4], Material **r_mat) { Material *ma = NULL; float color_cu[4]; diff --git a/source/blender/blenkernel/intern/gpencil_geom.c b/source/blender/blenkernel/intern/gpencil_geom.c index 579ebc9b9b3..672d65f1585 100644 --- a/source/blender/blenkernel/intern/gpencil_geom.c +++ b/source/blender/blenkernel/intern/gpencil_geom.c @@ -245,24 +245,23 @@ static int stroke_march_next_point(const bGPDstroke *gps, return 0; } - else { - float ratio = remaining_march / remaining_till_next; - interp_v3_v3v3(result, step_start, point, ratio); - *pressure = interpf( - gps->points[next_point_index].pressure, gps->points[next_point_index - 1].pressure, ratio); - *strength = interpf( - gps->points[next_point_index].strength, gps->points[next_point_index - 1].strength, ratio); - interp_v4_v4v4(vert_color, - gps->points[next_point_index - 1].vert_color, - gps->points[next_point_index].vert_color, - ratio); - - *index_from = next_point_index - 1; - *index_to = next_point_index; - *ratio_result = ratio; - return next_point_index; - } + float ratio = remaining_march / remaining_till_next; + interp_v3_v3v3(result, step_start, point, ratio); + *pressure = interpf( + gps->points[next_point_index].pressure, gps->points[next_point_index - 1].pressure, ratio); + *strength = interpf( + gps->points[next_point_index].strength, gps->points[next_point_index - 1].strength, ratio); + interp_v4_v4v4(vert_color, + gps->points[next_point_index - 1].vert_color, + gps->points[next_point_index].vert_color, + ratio); + + *index_from = next_point_index - 1; + *index_to = next_point_index; + *ratio_result = ratio; + + return next_point_index; } static int stroke_march_next_point_no_interp(const bGPDstroke *gps, @@ -306,11 +305,10 @@ static int stroke_march_next_point_no_interp(const bGPDstroke *gps, copy_v3_v3(result, &pt->x); return 0; } - else { - float ratio = remaining_march / remaining_till_next; - interp_v3_v3v3(result, step_start, point, ratio); - return next_point_index; - } + + float ratio = remaining_march / remaining_till_next; + interp_v3_v3v3(result, step_start, point, ratio); + return next_point_index; } static int stroke_march_count(const bGPDstroke *gps, const float dist) @@ -1352,10 +1350,9 @@ bool BKE_gpencil_stroke_trim(bGPDstroke *gps) if ((lambda <= 0.0f) || (lambda >= 1.0f)) { continue; } - else { - intersect = true; - break; - } + + intersect = true; + break; } } } @@ -2599,10 +2596,9 @@ void BKE_gpencil_stroke_set_random_color(bGPDstroke *gps) float color[4] = {1.0f, 1.0f, 1.0f, 1.0f}; bGPDspoint *pt = &gps->points[0]; - color[0] *= BLI_hash_int_01(BLI_hash_int_2d(gps->totpoints, pt->x)); - color[1] *= BLI_hash_int_01(BLI_hash_int_2d(gps->totpoints, pt->y)); - color[2] *= BLI_hash_int_01(BLI_hash_int_2d(gps->totpoints, pt->z)); - + color[0] *= BLI_hash_int_01(BLI_hash_int_2d(gps->totpoints / 5, pt->x + pt->z)); + color[1] *= BLI_hash_int_01(BLI_hash_int_2d(gps->totpoints + pt->x, pt->y * pt->z + pt->x)); + color[2] *= BLI_hash_int_01(BLI_hash_int_2d(gps->totpoints - pt->x, pt->z * pt->x + pt->y)); for (int i = 0; i < gps->totpoints; i++) { pt = &gps->points[i]; copy_v4_v4(pt->vert_color, color); diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c index e92bf5a4502..c2e330e8f04 100644 --- a/source/blender/blenkernel/intern/gpencil_modifier.c +++ b/source/blender/blenkernel/intern/gpencil_modifier.c @@ -348,9 +348,8 @@ const GpencilModifierTypeInfo *BKE_gpencil_modifier_get_info(GpencilModifierType modifier_gpencil_types[type]->name[0] != '\0') { return modifier_gpencil_types[type]; } - else { - return NULL; - } + + return NULL; } /** diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c index 90761d24b73..2905bfc978a 100644 --- a/source/blender/blenkernel/intern/hair.c +++ b/source/blender/blenkernel/intern/hair.c @@ -202,8 +202,8 @@ BoundBox *BKE_hair_boundbox_get(Object *ob) for (int a = 0; a < hair->totpoint; a++) { float *co = hair_co[a]; float radius = (hair_radius) ? hair_radius[a] : 0.0f; - float co_min[3] = {co[0] - radius, co[1] - radius, co[2] - radius}; - float co_max[3] = {co[0] + radius, co[1] + radius, co[2] + radius}; + const float co_min[3] = {co[0] - radius, co[1] - radius, co[2] - radius}; + const float co_max[3] = {co[0] + radius, co[1] + radius, co[2] + radius}; DO_MIN(co_min, min); DO_MAX(co_max, max); } diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c index 6da48195aab..bec0da750e1 100644 --- a/source/blender/blenkernel/intern/icons.c +++ b/source/blender/blenkernel/intern/icons.c @@ -765,9 +765,8 @@ bool BKE_icon_delete(const int icon_id) icon_free(icon); return true; } - else { - return false; - } + + return false; } bool BKE_icon_delete_unmanaged(const int icon_id) @@ -783,15 +782,13 @@ bool BKE_icon_delete_unmanaged(const int icon_id) BLI_ghash_insert(gIcons, POINTER_FROM_INT(icon_id), icon); return false; } - else { - icon_free_data(icon_id, icon); - icon_free(icon); - return true; - } - } - else { - return false; + + icon_free_data(icon_id, icon); + icon_free(icon); + return true; } + + return false; } /* -------------------------------------------------------------------- */ diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index c3c67b9ed51..e394242001c 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -181,7 +181,7 @@ void IDP_ResizeIDPArray(IDProperty *prop, int newlen) prop->len = newlen; return; } - else if (newlen >= prop->len) { + if (newlen >= prop->len) { prop->len = newlen; return; } @@ -836,17 +836,16 @@ IDProperty *IDP_GetProperties(ID *id, const bool create_if_needed) if (id->properties) { return id->properties; } - else { - if (create_if_needed) { - id->properties = MEM_callocN(sizeof(IDProperty), "IDProperty"); - id->properties->type = IDP_GROUP; - /* don't overwrite the data's name and type - * some functions might need this if they - * don't have a real ID, should be named elsewhere - Campbell */ - /* strcpy(id->name, "top_level_group");*/ - } - return id->properties; + + if (create_if_needed) { + id->properties = MEM_callocN(sizeof(IDProperty), "IDProperty"); + id->properties->type = IDP_GROUP; + /* don't overwrite the data's name and type + * some functions might need this if they + * don't have a real ID, should be named elsewhere - Campbell */ + /* strcpy(id->name, "top_level_group");*/ } + return id->properties; } /** @@ -856,10 +855,10 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is if (prop1 == NULL && prop2 == NULL) { return true; } - else if (prop1 == NULL || prop2 == NULL) { + if (prop1 == NULL || prop2 == NULL) { return is_strict ? false : true; } - else if (prop1->type != prop2->type) { + if (prop1->type != prop2->type) { return false; } diff --git a/source/blender/blenkernel/intern/idtype.c b/source/blender/blenkernel/intern/idtype.c index 1166ad9ad2f..4ab7d362e0e 100644 --- a/source/blender/blenkernel/intern/idtype.c +++ b/source/blender/blenkernel/intern/idtype.c @@ -135,9 +135,8 @@ const IDTypeInfo *BKE_idtype_get_info_from_idcode(const short id_code) id_types[id_index]->name[0] != '\0') { return id_types[id_index]; } - else { - return NULL; - } + + return NULL; } const IDTypeInfo *BKE_idtype_get_info_from_id(const ID *id) diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 9365ee040c2..4bd966cffc6 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -57,6 +57,7 @@ #include "DNA_packedFile_types.h" #include "DNA_scene_types.h" #include "DNA_sequence_types.h" +#include "DNA_simulation_types.h" #include "DNA_world_types.h" #include "BLI_blenlib.h" @@ -89,7 +90,6 @@ #include "RE_pipeline.h" -#include "GPU_draw.h" #include "GPU_texture.h" #include "BLI_sys_types.h" // for intptr_t support @@ -392,7 +392,7 @@ void BKE_image_free_buffers_ex(Image *ima, bool do_lock) ima->rr = NULL; } - GPU_free_image(ima); + BKE_image_free_gputextures(ima); LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { tile->ok = IMA_OK; @@ -667,9 +667,8 @@ char BKE_image_alpha_mode_from_extension_ex(const char *filepath) if (BLI_path_extension_check_n(filepath, ".exr", ".cin", ".dpx", ".hdr", NULL)) { return IMA_ALPHA_PREMUL; } - else { - return IMA_ALPHA_STRAIGHT; - } + + return IMA_ALPHA_STRAIGHT; } void BKE_image_alpha_mode_from_extension(Image *image) @@ -1201,57 +1200,56 @@ int BKE_image_imtype_to_ftype(const char imtype, ImbFormatOptions *r_options) if (imtype == R_IMF_IMTYPE_TARGA) { return IMB_FTYPE_TGA; } - else if (imtype == R_IMF_IMTYPE_RAWTGA) { + if (imtype == R_IMF_IMTYPE_RAWTGA) { r_options->flag = RAWTGA; return IMB_FTYPE_TGA; } - else if (imtype == R_IMF_IMTYPE_IRIS) { + if (imtype == R_IMF_IMTYPE_IRIS) { return IMB_FTYPE_IMAGIC; } #ifdef WITH_HDR - else if (imtype == R_IMF_IMTYPE_RADHDR) { + if (imtype == R_IMF_IMTYPE_RADHDR) { return IMB_FTYPE_RADHDR; } #endif - else if (imtype == R_IMF_IMTYPE_PNG) { + if (imtype == R_IMF_IMTYPE_PNG) { r_options->quality = 15; return IMB_FTYPE_PNG; } #ifdef WITH_DDS - else if (imtype == R_IMF_IMTYPE_DDS) { + if (imtype == R_IMF_IMTYPE_DDS) { return IMB_FTYPE_DDS; } #endif - else if (imtype == R_IMF_IMTYPE_BMP) { + if (imtype == R_IMF_IMTYPE_BMP) { return IMB_FTYPE_BMP; } #ifdef WITH_TIFF - else if (imtype == R_IMF_IMTYPE_TIFF) { + if (imtype == R_IMF_IMTYPE_TIFF) { return IMB_FTYPE_TIF; } #endif - else if (imtype == R_IMF_IMTYPE_OPENEXR || imtype == R_IMF_IMTYPE_MULTILAYER) { + if (imtype == R_IMF_IMTYPE_OPENEXR || imtype == R_IMF_IMTYPE_MULTILAYER) { return IMB_FTYPE_OPENEXR; } #ifdef WITH_CINEON - else if (imtype == R_IMF_IMTYPE_CINEON) { + if (imtype == R_IMF_IMTYPE_CINEON) { return IMB_FTYPE_CINEON; } - else if (imtype == R_IMF_IMTYPE_DPX) { + if (imtype == R_IMF_IMTYPE_DPX) { return IMB_FTYPE_DPX; } #endif #ifdef WITH_OPENJPEG - else if (imtype == R_IMF_IMTYPE_JP2) { + if (imtype == R_IMF_IMTYPE_JP2) { r_options->flag |= JP2_JP2; r_options->quality = 90; return IMB_FTYPE_JP2; } #endif - else { - r_options->quality = 90; - return IMB_FTYPE_JPG; - } + + r_options->quality = 90; + return IMB_FTYPE_JPG; } char BKE_image_ftype_to_imtype(const int ftype, const ImbFormatOptions *options) @@ -1259,57 +1257,55 @@ char BKE_image_ftype_to_imtype(const int ftype, const ImbFormatOptions *options) if (ftype == 0) { return R_IMF_IMTYPE_TARGA; } - else if (ftype == IMB_FTYPE_IMAGIC) { + if (ftype == IMB_FTYPE_IMAGIC) { return R_IMF_IMTYPE_IRIS; } #ifdef WITH_HDR - else if (ftype == IMB_FTYPE_RADHDR) { + if (ftype == IMB_FTYPE_RADHDR) { return R_IMF_IMTYPE_RADHDR; } #endif - else if (ftype == IMB_FTYPE_PNG) { + if (ftype == IMB_FTYPE_PNG) { return R_IMF_IMTYPE_PNG; } #ifdef WITH_DDS - else if (ftype == IMB_FTYPE_DDS) { + if (ftype == IMB_FTYPE_DDS) { return R_IMF_IMTYPE_DDS; } #endif - else if (ftype == IMB_FTYPE_BMP) { + if (ftype == IMB_FTYPE_BMP) { return R_IMF_IMTYPE_BMP; } #ifdef WITH_TIFF - else if (ftype == IMB_FTYPE_TIF) { + if (ftype == IMB_FTYPE_TIF) { return R_IMF_IMTYPE_TIFF; } #endif - else if (ftype == IMB_FTYPE_OPENEXR) { + if (ftype == IMB_FTYPE_OPENEXR) { return R_IMF_IMTYPE_OPENEXR; } #ifdef WITH_CINEON - else if (ftype == IMB_FTYPE_CINEON) { + if (ftype == IMB_FTYPE_CINEON) { return R_IMF_IMTYPE_CINEON; } - else if (ftype == IMB_FTYPE_DPX) { + if (ftype == IMB_FTYPE_DPX) { return R_IMF_IMTYPE_DPX; } #endif - else if (ftype == IMB_FTYPE_TGA) { + if (ftype == IMB_FTYPE_TGA) { if (options && (options->flag & RAWTGA)) { return R_IMF_IMTYPE_RAWTGA; } - else { - return R_IMF_IMTYPE_TARGA; - } + + return R_IMF_IMTYPE_TARGA; } #ifdef WITH_OPENJPEG - else if (ftype == IMB_FTYPE_JP2) { + if (ftype == IMB_FTYPE_JP2) { return R_IMF_IMTYPE_JP2; } #endif - else { - return R_IMF_IMTYPE_JPEG90; - } + + return R_IMF_IMTYPE_JPEG90; } bool BKE_imtype_is_movie(const char imtype) @@ -1443,78 +1439,77 @@ char BKE_imtype_from_arg(const char *imtype_arg) if (STREQ(imtype_arg, "TGA")) { return R_IMF_IMTYPE_TARGA; } - else if (STREQ(imtype_arg, "IRIS")) { + if (STREQ(imtype_arg, "IRIS")) { return R_IMF_IMTYPE_IRIS; } #ifdef WITH_DDS - else if (STREQ(imtype_arg, "DDS")) { + if (STREQ(imtype_arg, "DDS")) { return R_IMF_IMTYPE_DDS; } #endif - else if (STREQ(imtype_arg, "JPEG")) { + if (STREQ(imtype_arg, "JPEG")) { return R_IMF_IMTYPE_JPEG90; } - else if (STREQ(imtype_arg, "IRIZ")) { + if (STREQ(imtype_arg, "IRIZ")) { return R_IMF_IMTYPE_IRIZ; } - else if (STREQ(imtype_arg, "RAWTGA")) { + if (STREQ(imtype_arg, "RAWTGA")) { return R_IMF_IMTYPE_RAWTGA; } - else if (STREQ(imtype_arg, "AVIRAW")) { + if (STREQ(imtype_arg, "AVIRAW")) { return R_IMF_IMTYPE_AVIRAW; } - else if (STREQ(imtype_arg, "AVIJPEG")) { + if (STREQ(imtype_arg, "AVIJPEG")) { return R_IMF_IMTYPE_AVIJPEG; } - else if (STREQ(imtype_arg, "PNG")) { + if (STREQ(imtype_arg, "PNG")) { return R_IMF_IMTYPE_PNG; } - else if (STREQ(imtype_arg, "BMP")) { + if (STREQ(imtype_arg, "BMP")) { return R_IMF_IMTYPE_BMP; } #ifdef WITH_HDR - else if (STREQ(imtype_arg, "HDR")) { + if (STREQ(imtype_arg, "HDR")) { return R_IMF_IMTYPE_RADHDR; } #endif #ifdef WITH_TIFF - else if (STREQ(imtype_arg, "TIFF")) { + if (STREQ(imtype_arg, "TIFF")) { return R_IMF_IMTYPE_TIFF; } #endif #ifdef WITH_OPENEXR - else if (STREQ(imtype_arg, "OPEN_EXR")) { + if (STREQ(imtype_arg, "OPEN_EXR")) { return R_IMF_IMTYPE_OPENEXR; } - else if (STREQ(imtype_arg, "OPEN_EXR_MULTILAYER")) { + if (STREQ(imtype_arg, "OPEN_EXR_MULTILAYER")) { return R_IMF_IMTYPE_MULTILAYER; } - else if (STREQ(imtype_arg, "EXR")) { + if (STREQ(imtype_arg, "EXR")) { return R_IMF_IMTYPE_OPENEXR; } - else if (STREQ(imtype_arg, "MULTILAYER")) { + if (STREQ(imtype_arg, "MULTILAYER")) { return R_IMF_IMTYPE_MULTILAYER; } #endif - else if (STREQ(imtype_arg, "FFMPEG")) { + if (STREQ(imtype_arg, "FFMPEG")) { return R_IMF_IMTYPE_FFMPEG; } #ifdef WITH_CINEON - else if (STREQ(imtype_arg, "CINEON")) { + if (STREQ(imtype_arg, "CINEON")) { return R_IMF_IMTYPE_CINEON; } - else if (STREQ(imtype_arg, "DPX")) { + if (STREQ(imtype_arg, "DPX")) { return R_IMF_IMTYPE_DPX; } #endif #ifdef WITH_OPENJPEG - else if (STREQ(imtype_arg, "JP2")) { + if (STREQ(imtype_arg, "JP2")) { return R_IMF_IMTYPE_JP2; } #endif - else { - return R_IMF_IMTYPE_INVALID; - } + + return R_IMF_IMTYPE_INVALID; } static bool do_add_image_extension(char *string, @@ -1638,13 +1633,11 @@ static bool do_add_image_extension(char *string, if (BLI_path_extension_check_array(string, imb_ext_image)) { return BLI_path_extension_replace(string, FILE_MAX, extension); } - else { - return BLI_path_extension_ensure(string, FILE_MAX, extension); - } - } - else { - return false; + + return BLI_path_extension_ensure(string, FILE_MAX, extension); } + + return false; } int BKE_image_path_ensure_ext_from_imformat(char *string, const ImageFormatData *im_format) @@ -3240,6 +3233,12 @@ static void image_walk_id_all_users( if (scene->nodetree && scene->use_nodes && !skip_nested_nodes) { image_walk_ntree_all_users(scene->nodetree, &scene->id, customdata, callback); } + break; + } + case ID_SIM: { + Simulation *simulation = (Simulation *)id; + image_walk_ntree_all_users(simulation->nodetree, &simulation->id, customdata, callback); + break; } default: break; @@ -3344,8 +3343,7 @@ static void image_free_tile(Image *ima, ImageTile *tile) for (int i = 0; i < TEXTARGET_COUNT; i++) { /* Only two textures depends on all tiles, so if this is a secondary tile we can keep the other * two. */ - if (tile != ima->tiles.first && - !(ELEM(i, TEXTARGET_TEXTURE_2D_ARRAY, TEXTARGET_TEXTURE_TILE_MAPPING))) { + if (tile != ima->tiles.first && !(ELEM(i, TEXTARGET_2D_ARRAY, TEXTARGET_TILE_MAPPING))) { continue; } @@ -3543,9 +3541,8 @@ static RenderPass *image_render_pass_get(RenderLayer *rl, /* no multiview or left eye */ break; } - else { - rp_name = rpass->name; - } + + rp_name = rpass->name; } /* multiview */ else if (rp_name[0] && STREQ(rpass->name, rp_name) && (rpass->view_id == view)) { @@ -3622,13 +3619,13 @@ ImageTile *BKE_image_add_tile(struct Image *ima, int tile_number, const char *la for (int eye = 0; eye < 2; eye++) { /* Reallocate GPU tile array. */ - if (ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][eye] != NULL) { - GPU_texture_free(ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][eye]); - ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][eye] = NULL; + if (ima->gputexture[TEXTARGET_2D_ARRAY][eye] != NULL) { + GPU_texture_free(ima->gputexture[TEXTARGET_2D_ARRAY][eye]); + ima->gputexture[TEXTARGET_2D_ARRAY][eye] = NULL; } - if (ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING][eye] != NULL) { - GPU_texture_free(ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING][eye]); - ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING][eye] = NULL; + if (ima->gputexture[TEXTARGET_TILE_MAPPING][eye] != NULL) { + GPU_texture_free(ima->gputexture[TEXTARGET_TILE_MAPPING][eye]); + ima->gputexture[TEXTARGET_TILE_MAPPING][eye] = NULL; } } @@ -3708,9 +3705,8 @@ RenderPass *BKE_image_multilayer_index(RenderResult *rr, ImageUser *iuser) iuser->multi_index = index + rp_index; break; } - else { - index += BLI_listbase_count(&rl->passes); - } + + index += BLI_listbase_count(&rl->passes); } } @@ -3937,7 +3933,7 @@ static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr) #endif /* WITH_OPENEXR */ /* common stuff to do with images after loading */ -static void image_initialize_after_load(Image *ima, ImageUser *iuser, ImBuf *UNUSED(ibuf)) +static void image_init_after_load(Image *ima, ImageUser *iuser, ImBuf *UNUSED(ibuf)) { /* Preview is NULL when it has never been used as an icon before. * Never handle previews/icons outside of main thread. */ @@ -3981,13 +3977,12 @@ static int image_num_files(Image *ima) if (!is_multiview) { return 1; } - else if (ima->views_format == R_IMF_VIEWS_STEREO_3D) { + if (ima->views_format == R_IMF_VIEWS_STEREO_3D) { return 1; } /* R_IMF_VIEWS_INDIVIDUAL */ - else { - return BLI_listbase_count(&ima->views); - } + + return BLI_listbase_count(&ima->views); } static ImBuf *load_sequence_single( @@ -4040,11 +4035,11 @@ static ImBuf *load_sequence_single( } } else { - image_initialize_after_load(ima, iuser, ibuf); + image_init_after_load(ima, iuser, ibuf); *r_assign = true; } #else - image_initialize_after_load(ima, iuser, ibuf); + image_init_after_load(ima, iuser, ibuf); *r_assign = true; #endif } @@ -4149,7 +4144,7 @@ static ImBuf *image_load_sequence_multilayer(Image *ima, ImageUser *iuser, int e BKE_imbuf_stamp_info(ima->rr, ibuf); - image_initialize_after_load(ima, iuser, ibuf); + image_init_after_load(ima, iuser, ibuf); image_assign_ibuf(ima, ibuf, iuser ? iuser->multi_index : 0, entry); } // else printf("pass not found\n"); @@ -4213,7 +4208,7 @@ static ImBuf *load_movie_single(Image *ima, ImageUser *iuser, int frame, const i ibuf = IMB_makeSingleUser(IMB_anim_absolute(ia->anim, fra, IMB_TC_RECORD_RUN, IMB_PROXY_NONE)); if (ibuf) { - image_initialize_after_load(ima, iuser, ibuf); + image_init_after_load(ima, iuser, ibuf); } else { tile->ok = 0; @@ -4358,7 +4353,7 @@ static ImBuf *load_image_single(Image *ima, else #endif { - image_initialize_after_load(ima, iuser, ibuf); + image_init_after_load(ima, iuser, ibuf); *r_assign = true; /* make packed file for autopack */ @@ -4472,7 +4467,7 @@ static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser) if (rpass) { ibuf = IMB_allocImBuf(ima->rr->rectx, ima->rr->recty, 32, 0); - image_initialize_after_load(ima, iuser, ibuf); + image_init_after_load(ima, iuser, ibuf); ibuf->rect_float = rpass->rect; ibuf->flags |= IB_rectfloat; @@ -4702,7 +4697,7 @@ static int image_get_multiview_index(Image *ima, ImageUser *iuser) if (is_multilayer) { return iuser ? iuser->multi_index : index; } - else if (is_backdrop) { + if (is_backdrop) { if (BKE_image_is_stereo(ima)) { /* backdrop hackaround (since there is no iuser */ return ima->eye; @@ -4839,7 +4834,7 @@ BLI_INLINE bool image_quick_test(Image *ima, const ImageUser *iuser) if (tile == NULL) { return false; } - else if (tile->ok == 0) { + if (tile->ok == 0) { return false; } @@ -5156,58 +5151,57 @@ int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, bool *r_is_in_ran if (len == 0) { return 0; } - else { - int framenr; - cfra = cfra - iuser->sfra + 1; - - /* cyclic */ - if (iuser->cycl) { - cfra = ((cfra) % len); - if (cfra < 0) { - cfra += len; - } - if (cfra == 0) { - cfra = len; - } - if (r_is_in_range) { - *r_is_in_range = true; - } - } + int framenr; + cfra = cfra - iuser->sfra + 1; + /* cyclic */ + if (iuser->cycl) { + cfra = ((cfra) % len); if (cfra < 0) { - cfra = 0; + cfra += len; } - else if (cfra > len) { + if (cfra == 0) { cfra = len; } - else { - if (r_is_in_range) { - *r_is_in_range = true; - } - } - /* transform to images space */ - framenr = cfra; - if (framenr > iuser->frames) { - framenr = iuser->frames; + if (r_is_in_range) { + *r_is_in_range = true; } + } - if (iuser->cycl) { - framenr = ((framenr) % len); - while (framenr < 0) { - framenr += len; - } - if (framenr == 0) { - framenr = len; - } + if (cfra < 0) { + cfra = 0; + } + else if (cfra > len) { + cfra = len; + } + else { + if (r_is_in_range) { + *r_is_in_range = true; } + } - /* important to apply after else we cant loop on frames 100 - 110 for eg. */ - framenr += iuser->offset; + /* transform to images space */ + framenr = cfra; + if (framenr > iuser->frames) { + framenr = iuser->frames; + } - return framenr; + if (iuser->cycl) { + framenr = ((framenr) % len); + while (framenr < 0) { + framenr += len; + } + if (framenr == 0) { + framenr = len; + } } + + /* important to apply after else we cant loop on frames 100 - 110 for eg. */ + framenr += iuser->offset; + + return framenr; } void BKE_image_user_frame_calc(Image *ima, ImageUser *iuser, int cfra) @@ -5373,9 +5367,8 @@ bool BKE_image_has_alpha(struct Image *image) if (planes == 32) { return true; } - else { - return false; - } + + return false; } void BKE_image_get_size(Image *image, ImageUser *iuser, int *r_width, int *r_height) @@ -5841,17 +5834,16 @@ bool BKE_image_clear_renderslot(Image *ima, ImageUser *iuser, int index) RE_ClearResult(re); return true; } - else { - RenderSlot *slot = BLI_findlink(&ima->renderslots, index); - if (!slot) { - return false; - } - if (slot->render) { - RE_FreeRenderResult(slot->render); - slot->render = NULL; - } - return true; + + RenderSlot *slot = BLI_findlink(&ima->renderslots, index); + if (!slot) { + return false; } + if (slot->render) { + RE_FreeRenderResult(slot->render); + slot->render = NULL; + } + return true; } RenderSlot *BKE_image_get_renderslot(Image *ima, int index) diff --git a/source/blender/blenkernel/intern/image_gpu.c b/source/blender/blenkernel/intern/image_gpu.c new file mode 100644 index 00000000000..22fb6dfd02a --- /dev/null +++ b/source/blender/blenkernel/intern/image_gpu.c @@ -0,0 +1,774 @@ +/* + * 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. + */ + +/** \file + * \ingroup bke + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_boxpack_2d.h" +#include "BLI_linklist.h" +#include "BLI_listbase.h" +#include "BLI_threads.h" + +#include "DNA_image_types.h" +#include "DNA_userdef_types.h" + +#include "IMB_colormanagement.h" +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + +#include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_main.h" + +#include "GPU_extensions.h" +#include "GPU_state.h" +#include "GPU_texture.h" + +#include "PIL_time.h" + +/* Prototypes. */ +static void gpu_free_unused_buffers(void); +static void image_free_gpu(Image *ima, const bool immediate); + +/* -------------------------------------------------------------------- */ +/** \name UDIM gpu texture + * \{ */ + +static bool is_over_resolution_limit(int w, int h) +{ + return (w > GPU_texture_size_with_limit(w) || h > GPU_texture_size_with_limit(h)); +} + +static int smaller_power_of_2_limit(int num) +{ + return power_of_2_min_i(GPU_texture_size_with_limit(num)); +} + +static GPUTexture *gpu_texture_create_tile_mapping(Image *ima, const int multiview_eye) +{ + GPUTexture *tilearray = ima->gputexture[TEXTARGET_2D_ARRAY][multiview_eye]; + + if (tilearray == NULL) { + return 0; + } + + float array_w = GPU_texture_width(tilearray); + float array_h = GPU_texture_height(tilearray); + + ImageTile *last_tile = (ImageTile *)ima->tiles.last; + /* Tiles are sorted by number. */ + int max_tile = last_tile->tile_number - 1001; + + /* create image */ + int width = max_tile + 1; + float *data = (float *)MEM_callocN(width * 8 * sizeof(float), __func__); + for (int i = 0; i < width; i++) { + data[4 * i] = -1.0f; + } + LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { + int i = tile->tile_number - 1001; + data[4 * i] = tile->runtime.tilearray_layer; + + float *tile_info = &data[4 * width + 4 * i]; + tile_info[0] = tile->runtime.tilearray_offset[0] / array_w; + tile_info[1] = tile->runtime.tilearray_offset[1] / array_h; + tile_info[2] = tile->runtime.tilearray_size[0] / array_w; + tile_info[3] = tile->runtime.tilearray_size[1] / array_h; + } + + GPUTexture *tex = GPU_texture_create_1d_array(width, 2, GPU_RGBA32F, data, NULL); + GPU_texture_mipmap_mode(tex, false, false); + + MEM_freeN(data); + + return tex; +} + +typedef struct PackTile { + FixedSizeBoxPack boxpack; + ImageTile *tile; + float pack_score; +} PackTile; + +static int compare_packtile(const void *a, const void *b) +{ + const PackTile *tile_a = (const PackTile *)a; + const PackTile *tile_b = (const PackTile *)b; + + return tile_a->pack_score < tile_b->pack_score; +} + +static GPUTexture *gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf) +{ + int arraywidth = 0, arrayheight = 0; + ListBase boxes = {NULL}; + + LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { + ImageUser iuser; + BKE_imageuser_default(&iuser); + iuser.tile = tile->tile_number; + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); + + if (ibuf) { + PackTile *packtile = (PackTile *)MEM_callocN(sizeof(PackTile), __func__); + packtile->tile = tile; + packtile->boxpack.w = ibuf->x; + packtile->boxpack.h = ibuf->y; + + if (is_over_resolution_limit(packtile->boxpack.w, packtile->boxpack.h)) { + packtile->boxpack.w = smaller_power_of_2_limit(packtile->boxpack.w); + packtile->boxpack.h = smaller_power_of_2_limit(packtile->boxpack.h); + } + arraywidth = max_ii(arraywidth, packtile->boxpack.w); + arrayheight = max_ii(arrayheight, packtile->boxpack.h); + + /* We sort the tiles by decreasing size, with an additional penalty term + * for high aspect ratios. This improves packing efficiency. */ + float w = packtile->boxpack.w, h = packtile->boxpack.h; + packtile->pack_score = max_ff(w, h) / min_ff(w, h) * w * h; + + BKE_image_release_ibuf(ima, ibuf, NULL); + BLI_addtail(&boxes, packtile); + } + } + + BLI_assert(arraywidth > 0 && arrayheight > 0); + + BLI_listbase_sort(&boxes, compare_packtile); + int arraylayers = 0; + /* Keep adding layers until all tiles are packed. */ + while (boxes.first != NULL) { + ListBase packed = {NULL}; + BLI_box_pack_2d_fixedarea(&boxes, arraywidth, arrayheight, &packed); + BLI_assert(packed.first != NULL); + + LISTBASE_FOREACH (PackTile *, packtile, &packed) { + ImageTile *tile = packtile->tile; + int *tileoffset = tile->runtime.tilearray_offset; + int *tilesize = tile->runtime.tilearray_size; + + tileoffset[0] = packtile->boxpack.x; + tileoffset[1] = packtile->boxpack.y; + tilesize[0] = packtile->boxpack.w; + tilesize[1] = packtile->boxpack.h; + tile->runtime.tilearray_layer = arraylayers; + } + + BLI_freelistN(&packed); + arraylayers++; + } + + const bool use_high_bitdepth = (ima->flag & IMA_HIGH_BITDEPTH); + /* Create Texture without content. */ + GPUTexture *tex = IMB_touch_gpu_texture( + main_ibuf, arraywidth, arrayheight, arraylayers, use_high_bitdepth); + + GPU_texture_bind(tex, 0); + + /* Upload each tile one by one. */ + LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { + int tilelayer = tile->runtime.tilearray_layer; + int *tileoffset = tile->runtime.tilearray_offset; + int *tilesize = tile->runtime.tilearray_size; + + if (tilesize[0] == 0 || tilesize[1] == 0) { + continue; + } + + ImageUser iuser; + BKE_imageuser_default(&iuser); + iuser.tile = tile->tile_number; + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); + + if (ibuf) { + const bool store_premultiplied = ibuf->rect_float ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) : + (ima->alpha_mode == IMA_ALPHA_PREMUL); + IMB_update_gpu_texture_sub(tex, + ibuf, + UNPACK2(tileoffset), + tilelayer, + UNPACK2(tilesize), + use_high_bitdepth, + store_premultiplied); + } + + BKE_image_release_ibuf(ima, ibuf, NULL); + } + + if (GPU_mipmap_enabled()) { + GPU_texture_generate_mipmap(tex); + GPU_texture_mipmap_mode(tex, true, true); + if (ima) { + ima->gpuflag |= IMA_GPU_MIPMAP_COMPLETE; + } + } + else { + GPU_texture_mipmap_mode(tex, false, true); + } + + GPU_texture_unbind(tex); + + return tex; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Regular gpu texture + * \{ */ + +static GPUTexture **get_image_gpu_texture_ptr(Image *ima, + eGPUTextureTarget textarget, + const int multiview_eye) +{ + const bool in_range = (textarget >= 0) && (textarget < TEXTARGET_COUNT); + BLI_assert(in_range); + + if (in_range) { + return &(ima->gputexture[textarget][multiview_eye]); + } + return NULL; +} + +static GPUTexture *image_gpu_texture_error_create(eGPUTextureTarget textarget) +{ + switch (textarget) { + case TEXTARGET_2D_ARRAY: + return GPU_texture_create_error(2, true); + case TEXTARGET_TILE_MAPPING: + return GPU_texture_create_error(1, true); + case TEXTARGET_2D: + default: + return GPU_texture_create_error(2, false); + } +} + +static GPUTexture *image_get_gpu_texture(Image *ima, + ImageUser *iuser, + ImBuf *ibuf, + eGPUTextureTarget textarget) +{ + if (ima == NULL) { + return NULL; + } + + /* Free any unused GPU textures, since we know we are in a thread with OpenGL + * context and might as well ensure we have as much space free as possible. */ + gpu_free_unused_buffers(); + + /* currently, gpu refresh tagging is used by ima sequences */ + if (ima->gpuflag & IMA_GPU_REFRESH) { + image_free_gpu(ima, true); + ima->gpuflag &= ~IMA_GPU_REFRESH; + } + + /* Tag as in active use for garbage collector. */ + BKE_image_tag_time(ima); + + /* Test if we already have a texture. */ + GPUTexture **tex = get_image_gpu_texture_ptr(ima, textarget, iuser ? iuser->multiview_eye : 0); + if (*tex) { + return *tex; + } + + /* Check if we have a valid image. If not, we return a dummy + * texture with zero bind-code so we don't keep trying. */ + ImageTile *tile = BKE_image_get_tile(ima, 0); + if (tile == NULL || tile->ok == 0) { + *tex = image_gpu_texture_error_create(textarget); + return *tex; + } + + /* check if we have a valid image buffer */ + ImBuf *ibuf_intern = ibuf; + if (ibuf_intern == NULL) { + ibuf_intern = BKE_image_acquire_ibuf(ima, iuser, NULL); + if (ibuf_intern == NULL) { + *tex = image_gpu_texture_error_create(textarget); + return *tex; + } + } + + if (textarget == TEXTARGET_2D_ARRAY) { + *tex = gpu_texture_create_tile_array(ima, ibuf_intern); + } + else if (textarget == TEXTARGET_TILE_MAPPING) { + *tex = gpu_texture_create_tile_mapping(ima, iuser ? iuser->multiview_eye : 0); + } + else { + const bool use_high_bitdepth = (ima->flag & IMA_HIGH_BITDEPTH); + const bool store_premultiplied = ibuf_intern->rect_float ? + (ima ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) : false) : + (ima ? (ima->alpha_mode == IMA_ALPHA_PREMUL) : true); + + *tex = IMB_create_gpu_texture(ibuf_intern, use_high_bitdepth, store_premultiplied); + + if (GPU_mipmap_enabled()) { + GPU_texture_bind(*tex, 0); + GPU_texture_generate_mipmap(*tex); + GPU_texture_unbind(*tex); + if (ima) { + ima->gpuflag |= IMA_GPU_MIPMAP_COMPLETE; + } + GPU_texture_mipmap_mode(*tex, true, true); + } + else { + GPU_texture_mipmap_mode(*tex, false, true); + } + } + + /* if `ibuf` was given, we don't own the `ibuf_intern` */ + if (ibuf == NULL) { + BKE_image_release_ibuf(ima, ibuf_intern, NULL); + } + + GPU_texture_orig_size_set(*tex, ibuf_intern->x, ibuf_intern->y); + + return *tex; +} + +GPUTexture *BKE_image_get_gpu_texture(Image *image, ImageUser *iuser, ImBuf *ibuf) +{ + return image_get_gpu_texture(image, iuser, ibuf, TEXTARGET_2D); +} + +GPUTexture *BKE_image_get_gpu_tiles(Image *image, ImageUser *iuser, ImBuf *ibuf) +{ + return image_get_gpu_texture(image, iuser, ibuf, TEXTARGET_2D_ARRAY); +} + +GPUTexture *BKE_image_get_gpu_tilemap(Image *image, ImageUser *iuser, ImBuf *ibuf) +{ + return image_get_gpu_texture(image, iuser, ibuf, TEXTARGET_TILE_MAPPING); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Delayed GPU texture free + * + * Image datablocks can be deleted by any thread, but there may not be any active OpenGL context. + * In that case we push them into a queue and free the buffers later. + * \{ */ + +static LinkNode *gpu_texture_free_queue = NULL; +static ThreadMutex gpu_texture_queue_mutex = BLI_MUTEX_INITIALIZER; + +static void gpu_free_unused_buffers(void) +{ + if (gpu_texture_free_queue == NULL) { + return; + } + + BLI_mutex_lock(&gpu_texture_queue_mutex); + + while (gpu_texture_free_queue != NULL) { + GPUTexture *tex = BLI_linklist_pop(&gpu_texture_free_queue); + GPU_texture_free(tex); + } + + BLI_mutex_unlock(&gpu_texture_queue_mutex); +} + +void BKE_image_free_unused_gpu_textures() +{ + if (BLI_thread_is_main()) { + gpu_free_unused_buffers(); + } +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Deletion + * \{ */ + +static void image_free_gpu(Image *ima, const bool immediate) +{ + for (int eye = 0; eye < 2; eye++) { + for (int i = 0; i < TEXTARGET_COUNT; i++) { + if (ima->gputexture[i][eye] != NULL) { + if (immediate) { + GPU_texture_free(ima->gputexture[i][eye]); + } + else { + BLI_mutex_lock(&gpu_texture_queue_mutex); + BLI_linklist_prepend(&gpu_texture_free_queue, ima->gputexture[i][eye]); + BLI_mutex_unlock(&gpu_texture_queue_mutex); + } + + ima->gputexture[i][eye] = NULL; + } + } + } + + ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE; +} + +void BKE_image_free_gputextures(Image *ima) +{ + image_free_gpu(ima, BLI_thread_is_main()); +} + +void BKE_image_free_all_gputextures(Main *bmain) +{ + if (bmain) { + LISTBASE_FOREACH (Image *, ima, &bmain->images) { + BKE_image_free_gputextures(ima); + } + } +} + +/* same as above but only free animated images */ +void BKE_image_free_anim_gputextures(Main *bmain) +{ + if (bmain) { + LISTBASE_FOREACH (Image *, ima, &bmain->images) { + if (BKE_image_is_animated(ima)) { + BKE_image_free_gputextures(ima); + } + } + } +} + +void BKE_image_free_old_gputextures(Main *bmain) +{ + static int lasttime = 0; + int ctime = (int)PIL_check_seconds_timer(); + + /* + * Run garbage collector once for every collecting period of time + * if textimeout is 0, that's the option to NOT run the collector + */ + if (U.textimeout == 0 || ctime % U.texcollectrate || ctime == lasttime) { + return; + } + + /* of course not! */ + if (G.is_rendering) { + return; + } + + lasttime = ctime; + + LISTBASE_FOREACH (Image *, ima, &bmain->images) { + if ((ima->flag & IMA_NOCOLLECT) == 0 && ctime - ima->lastused > U.textimeout) { + /* If it's in GL memory, deallocate and set time tag to current time + * This gives textures a "second chance" to be used before dying. */ + if (BKE_image_has_opengl_texture(ima)) { + BKE_image_free_gputextures(ima); + ima->lastused = ctime; + } + /* Otherwise, just kill the buffers */ + else { + BKE_image_free_buffers(ima); + } + } + } +} +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Paint Update + * \{ */ + +static ImBuf *update_do_scale(uchar *rect, + float *rect_float, + int *x, + int *y, + int *w, + int *h, + int limit_w, + int limit_h, + int full_w, + int full_h) +{ + /* Partial update with scaling. */ + float xratio = limit_w / (float)full_w; + float yratio = limit_h / (float)full_h; + + int part_w = *w, part_h = *h; + + /* Find sub coordinates in scaled image. Take ceiling because we will be + * losing 1 pixel due to rounding errors in x,y. */ + *x *= xratio; + *y *= yratio; + *w = (int)ceil(xratio * (*w)); + *h = (int)ceil(yratio * (*h)); + + /* ...but take back if we are over the limit! */ + if (*x + *w > limit_w) { + (*w)--; + } + if (*y + *h > limit_h) { + (*h)--; + } + + /* Scale pixels. */ + ImBuf *ibuf = IMB_allocFromBuffer((uint *)rect, rect_float, part_w, part_h, 4); + IMB_scaleImBuf(ibuf, *w, *h); + + return ibuf; +} + +static void gpu_texture_update_scaled(GPUTexture *tex, + uchar *rect, + float *rect_float, + int full_w, + int full_h, + int x, + int y, + int layer, + const int *tile_offset, + const int *tile_size, + int w, + int h) +{ + ImBuf *ibuf; + if (layer > -1) { + ibuf = update_do_scale( + rect, rect_float, &x, &y, &w, &h, tile_size[0], tile_size[1], full_w, full_h); + + /* Shift to account for tile packing. */ + x += tile_offset[0]; + y += tile_offset[1]; + } + else { + /* Partial update with scaling. */ + int limit_w = smaller_power_of_2_limit(full_w); + int limit_h = smaller_power_of_2_limit(full_h); + + ibuf = update_do_scale(rect, rect_float, &x, &y, &w, &h, limit_w, limit_h, full_w, full_h); + } + + void *data = (ibuf->rect_float) ? (void *)(ibuf->rect_float) : (void *)(ibuf->rect); + eGPUDataFormat data_format = (ibuf->rect_float) ? GPU_DATA_FLOAT : GPU_DATA_UNSIGNED_BYTE; + + GPU_texture_update_sub(tex, data_format, data, x, y, layer, w, h, 1); + + IMB_freeImBuf(ibuf); +} + +static void gpu_texture_update_unscaled(GPUTexture *tex, + uchar *rect, + float *rect_float, + int x, + int y, + int layer, + const int tile_offset[2], + int w, + int h, + int tex_stride, + int tex_offset) +{ + if (layer > -1) { + /* Shift to account for tile packing. */ + x += tile_offset[0]; + y += tile_offset[1]; + } + + void *data = (rect_float) ? (void *)(rect_float + tex_offset) : (void *)(rect + tex_offset); + eGPUDataFormat data_format = (rect_float) ? GPU_DATA_FLOAT : GPU_DATA_UNSIGNED_BYTE; + + /* Partial update without scaling. Stride and offset are used to copy only a + * subset of a possible larger buffer than what we are updating. */ + GPU_unpack_row_length_set(tex_stride); + + GPU_texture_update_sub(tex, data_format, data, x, y, layer, w, h, 1); + /* Restore default. */ + GPU_unpack_row_length_set(0); +} + +static void gpu_texture_update_from_ibuf( + GPUTexture *tex, Image *ima, ImBuf *ibuf, ImageTile *tile, int x, int y, int w, int h) +{ + bool scaled; + if (tile != NULL) { + int *tilesize = tile->runtime.tilearray_size; + scaled = (ibuf->x != tilesize[0]) || (ibuf->y != tilesize[1]); + } + else { + scaled = is_over_resolution_limit(ibuf->x, ibuf->y); + } + + if (scaled) { + /* Extra padding to account for bleed from neighboring pixels. */ + const int padding = 4; + const int xmax = min_ii(x + w + padding, ibuf->x); + const int ymax = min_ii(y + h + padding, ibuf->y); + x = max_ii(x - padding, 0); + y = max_ii(y - padding, 0); + w = xmax - x; + h = ymax - y; + } + + /* Get texture data pointers. */ + float *rect_float = ibuf->rect_float; + uchar *rect = (uchar *)ibuf->rect; + int tex_stride = ibuf->x; + int tex_offset = ibuf->channels * (y * ibuf->x + x); + + if (rect_float == NULL) { + /* Byte pixels. */ + if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) { + const bool compress_as_srgb = !IMB_colormanagement_space_is_scene_linear( + ibuf->rect_colorspace); + + rect = (uchar *)MEM_mallocN(sizeof(uchar) * 4 * w * h, __func__); + if (rect == NULL) { + return; + } + + tex_stride = w; + tex_offset = 0; + + /* Convert to scene linear with sRGB compression, and premultiplied for + * correct texture interpolation. */ + const bool store_premultiplied = (ima->alpha_mode == IMA_ALPHA_PREMUL); + IMB_colormanagement_imbuf_to_byte_texture( + rect, x, y, w, h, ibuf, compress_as_srgb, store_premultiplied); + } + } + else { + /* Float pixels. */ + const bool store_premultiplied = (ima->alpha_mode != IMA_ALPHA_STRAIGHT); + + if (ibuf->channels != 4 || scaled || !store_premultiplied) { + rect_float = (float *)MEM_mallocN(sizeof(float) * 4 * w * h, __func__); + if (rect_float == NULL) { + return; + } + + tex_stride = w; + tex_offset = 0; + + IMB_colormanagement_imbuf_to_float_texture( + rect_float, x, y, w, h, ibuf, store_premultiplied); + } + } + + GPU_texture_bind(tex, 0); + + if (scaled) { + /* Slower update where we first have to scale the input pixels. */ + if (tile != NULL) { + int *tileoffset = tile->runtime.tilearray_offset; + int *tilesize = tile->runtime.tilearray_size; + int tilelayer = tile->runtime.tilearray_layer; + gpu_texture_update_scaled( + tex, rect, rect_float, ibuf->x, ibuf->y, x, y, tilelayer, tileoffset, tilesize, w, h); + } + else { + gpu_texture_update_scaled( + tex, rect, rect_float, ibuf->x, ibuf->y, x, y, -1, NULL, NULL, w, h); + } + } + else { + /* Fast update at same resolution. */ + if (tile != NULL) { + int *tileoffset = tile->runtime.tilearray_offset; + int tilelayer = tile->runtime.tilearray_layer; + gpu_texture_update_unscaled( + tex, rect, rect_float, x, y, tilelayer, tileoffset, w, h, tex_stride, tex_offset); + } + else { + gpu_texture_update_unscaled( + tex, rect, rect_float, x, y, -1, NULL, w, h, tex_stride, tex_offset); + } + } + + /* Free buffers if needed. */ + if (rect && rect != (uchar *)ibuf->rect) { + MEM_freeN(rect); + } + if (rect_float && rect_float != ibuf->rect_float) { + MEM_freeN(rect_float); + } + + if (GPU_mipmap_enabled()) { + GPU_texture_generate_mipmap(tex); + } + else { + ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE; + } + + GPU_texture_unbind(tex); +} + +/* Partial update of texture for texture painting. This is often much + * quicker than fully updating the texture for high resolution images. */ +void BKE_image_update_gputexture(Image *ima, ImageUser *iuser, int x, int y, int w, int h) +{ + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL); + ImageTile *tile = BKE_image_get_tile_from_iuser(ima, iuser); + + if ((ibuf == NULL) || (w == 0) || (h == 0)) { + /* Full reload of texture. */ + BKE_image_free_gputextures(ima); + } + + GPUTexture *tex = ima->gputexture[TEXTARGET_2D][0]; + /* Check if we need to update the main gputexture. */ + if (tex != NULL && tile == ima->tiles.first) { + gpu_texture_update_from_ibuf(tex, ima, ibuf, NULL, x, y, w, h); + } + + /* Check if we need to update the array gputexture. */ + tex = ima->gputexture[TEXTARGET_2D_ARRAY][0]; + if (tex != NULL) { + gpu_texture_update_from_ibuf(tex, ima, ibuf, tile, x, y, w, h); + } + + BKE_image_release_ibuf(ima, ibuf, NULL); +} + +/* these two functions are called on entering and exiting texture paint mode, + * temporary disabling/enabling mipmapping on all images for quick texture + * updates with glTexSubImage2D. images that didn't change don't have to be + * re-uploaded to OpenGL */ +void BKE_image_paint_set_mipmap(Main *bmain, bool mipmap) +{ + LISTBASE_FOREACH (Image *, ima, &bmain->images) { + if (BKE_image_has_opengl_texture(ima)) { + if (ima->gpuflag & IMA_GPU_MIPMAP_COMPLETE) { + for (int eye = 0; eye < 2; eye++) { + for (int a = 0; a < TEXTARGET_COUNT; a++) { + if (ELEM(a, TEXTARGET_2D, TEXTARGET_2D_ARRAY)) { + GPUTexture *tex = ima->gputexture[a][eye]; + if (tex != NULL) { + GPU_texture_mipmap_mode(tex, mipmap, true); + } + } + } + } + } + else { + BKE_image_free_gputextures(ima); + } + } + else { + ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE; + } + } +} + +/** \} */ diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 7bf9cb2d0a1..a7fdf93f656 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -517,9 +517,8 @@ static const char *mtex_adrcodes_to_paths(int adrcode, int *UNUSED(array_index)) BLI_snprintf(buf, 128, "%s.%s", base, prop); return buf; } - else { - return NULL; - } + + return NULL; } /* Texture types */ @@ -1074,10 +1073,9 @@ static char *get_rna_access(ID *id, return NULL; } - else { - if (array_index) { - *array_index = dummy_index; - } + + if (array_index) { + *array_index = dummy_index; } /* 'buf' _must_ be initialized in this block */ @@ -1976,7 +1974,7 @@ void do_versions_ipos_to_animato(Main *bmain) CLOG_WARN(&LOG, "Animation data too new to convert (Version %d)", bmain->versionfile); return; } - else if (G.debug & G_DEBUG) { + if (G.debug & G_DEBUG) { printf("INFO: Converting to Animato...\n"); } diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 4d523ffa2e0..4d073593da7 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -356,9 +356,8 @@ bool object_deform_mball(Object *ob, ListBase *dispbase) return true; } - else { - return false; - } + + return false; } static BPoint *latt_bp(Lattice *lt, int u, int v, int w) @@ -575,9 +574,8 @@ struct BPoint *BKE_lattice_active_point_get(Lattice *lt) if ((lt->actbp != LT_ACTBP_NONE) && (lt->actbp < lt->pntsu * lt->pntsv * lt->pntsw)) { return <->def[lt->actbp]; } - else { - return NULL; - } + + return NULL; } void BKE_lattice_center_median(Lattice *lt, float cent[3]) diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c index 64649d84320..cf6139d9449 100644 --- a/source/blender/blenkernel/intern/layer.c +++ b/source/blender/blenkernel/intern/layer.c @@ -221,7 +221,7 @@ ViewLayer *BKE_view_layer_add(Scene *scene, view_layer_new = view_layer_add(name); BLI_addtail(&scene->view_layers, view_layer_new); - /* Initialise layercollections */ + /* Initialize layer-collections. */ BKE_layer_collection_sync(scene, view_layer_new); layer_collection_exclude_all(view_layer_new->layer_collections.first); @@ -555,21 +555,19 @@ static bool layer_collection_hidden(ViewLayer *view_layer, LayerCollection *lc) if (lc->flag & LAYER_COLLECTION_HIDE || lc->collection->flag & COLLECTION_RESTRICT_VIEWPORT) { return true; } - else { - /* Restriction flags stay set, so we need to check parents */ - CollectionParent *parent = lc->collection->parents.first; - if (parent) { - lc = BKE_layer_collection_first_from_scene_collection(view_layer, parent->collection); + /* Restriction flags stay set, so we need to check parents */ + CollectionParent *parent = lc->collection->parents.first; - return lc && layer_collection_hidden(view_layer, lc); - } - else { - return false; - } + if (parent) { + lc = BKE_layer_collection_first_from_scene_collection(view_layer, parent->collection); + + return lc && layer_collection_hidden(view_layer, lc); } return false; + + return false; } /** @@ -1610,10 +1608,9 @@ void BKE_view_layer_selected_editable_objects_iterator_begin(BLI_Iterator *iter, // First object is valid (selectable and not libdata) -> all good. return; } - else { - // Object is selectable but not editable -> search for another one. - BKE_view_layer_selected_editable_objects_iterator_next(iter); - } + + // Object is selectable but not editable -> search for another one. + BKE_view_layer_selected_editable_objects_iterator_next(iter); } } diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c index a64e550579d..3b7aae98327 100644 --- a/source/blender/blenkernel/intern/lib_id.c +++ b/source/blender/blenkernel/intern/lib_id.c @@ -2203,13 +2203,12 @@ char *BKE_id_to_unique_string_key(const struct ID *id) if (id->lib == NULL) { return BLI_strdup(id->name); } - else { - /* Prefix with an ascii character in the range of 32..96 (visible) - * this ensures we can't have a library ID pair that collide. - * Where 'LIfooOBbarOBbaz' could be ('LIfoo, OBbarOBbaz') or ('LIfooOBbar', 'OBbaz'). */ - const char ascii_len = strlen(id->lib->id.name + 2) + 32; - return BLI_sprintfN("%c%s%s", ascii_len, id->lib->id.name, id->name); - } + + /* Prefix with an ascii character in the range of 32..96 (visible) + * this ensures we can't have a library ID pair that collide. + * Where 'LIfooOBbarOBbaz' could be ('LIfoo, OBbarOBbaz') or ('LIfooOBbar', 'OBbaz'). */ + const char ascii_len = strlen(id->lib->id.name + 2) + 32; + return BLI_sprintfN("%c%s%s", ascii_len, id->lib->id.name, id->name); } void BKE_id_tag_set_atomic(ID *id, int tag) @@ -2258,7 +2257,7 @@ static int id_order_compare(const void *a, const void *b) if (*order_a < *order_b) { return -1; } - else if (*order_a > *order_b) { + if (*order_a > *order_b) { return 1; } } diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index 2989c910c45..12d7f0e9e8e 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -117,9 +117,8 @@ void BKE_lib_override_library_copy(ID *dst_id, const ID *src_id, const bool do_f BKE_lib_override_library_free(&dst_id->override_library, true); return; } - else { - BKE_lib_override_library_clear(dst_id->override_library, true); - } + + BKE_lib_override_library_clear(dst_id->override_library, true); } else if (src_id->override_library == NULL) { /* Virtual overrides of embedded data does not require any extra work. */ @@ -1515,7 +1514,7 @@ void BKE_lib_override_library_main_update(Main *bmain) */ /** Initialize an override storage. */ -OverrideLibraryStorage *BKE_lib_override_library_operations_store_initialize(void) +OverrideLibraryStorage *BKE_lib_override_library_operations_store_init(void) { return BKE_main_new(); } diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c index 00a42b12e07..e687e94073d 100644 --- a/source/blender/blenkernel/intern/lib_query.c +++ b/source/blender/blenkernel/intern/lib_query.c @@ -96,9 +96,8 @@ bool BKE_lib_query_foreachid_process(LibraryForeachIDData *data, ID **id_pp, int } return true; } - else { - return false; - } + + return false; } int BKE_lib_query_foreachid_process_flags_get(LibraryForeachIDData *data) @@ -412,6 +411,8 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used) return ELEM(id_type_used, ID_MA); case ID_VO: return ELEM(id_type_used, ID_MA); + case ID_SIM: + return ELEM(id_type_used, ID_OB, ID_IM); case ID_IM: case ID_VF: case ID_TXT: @@ -422,7 +423,6 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used) case ID_PAL: case ID_PC: case ID_CF: - case ID_SIM: /* Those types never use/reference other IDs... */ return false; case ID_IP: diff --git a/source/blender/blenkernel/intern/light.c b/source/blender/blenkernel/intern/light.c index aa1005c663f..f42df6765c4 100644 --- a/source/blender/blenkernel/intern/light.c +++ b/source/blender/blenkernel/intern/light.c @@ -58,7 +58,7 @@ static void light_init_data(ID *id) MEMCPY_STRUCT_AFTER(la, DNA_struct_default_get(Light), id); la->curfalloff = BKE_curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f); - BKE_curvemapping_initialize(la->curfalloff); + BKE_curvemapping_init(la->curfalloff); } /** diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 7e859799a4e..444ed0c65b5 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -124,13 +124,11 @@ static MaskSplinePoint *mask_spline_point_next(MaskSpline *spline, if (spline->flag & MASK_SPLINE_CYCLIC) { return &points_array[0]; } - else { - return NULL; - } - } - else { - return point + 1; + + return NULL; } + + return point + 1; } static MaskSplinePoint *mask_spline_point_prev(MaskSpline *spline, @@ -141,13 +139,11 @@ static MaskSplinePoint *mask_spline_point_prev(MaskSpline *spline, if (spline->flag & MASK_SPLINE_CYCLIC) { return &points_array[spline->tot_point - 1]; } - else { - return NULL; - } - } - else { - return point - 1; + + return NULL; } + + return point - 1; } BezTriple *BKE_mask_spline_point_next_bezt(MaskSpline *spline, @@ -158,13 +154,11 @@ BezTriple *BKE_mask_spline_point_next_bezt(MaskSpline *spline, if (spline->flag & MASK_SPLINE_CYCLIC) { return &(points_array[0].bezt); } - else { - return NULL; - } - } - else { - return &((point + 1))->bezt; + + return NULL; } + + return &((point + 1))->bezt; } MaskSplinePoint *BKE_mask_spline_point_array(MaskSpline *spline) @@ -703,15 +697,14 @@ float BKE_mask_point_weight_scalar(MaskSpline *spline, MaskSplinePoint *point, c if (!bezt_next) { return bezt->weight; } - else if (u <= 0.0f) { + if (u <= 0.0f) { return bezt->weight; } - else if (u >= 1.0f) { + if (u >= 1.0f) { return bezt_next->weight; } - else { - return mask_point_interp_weight(bezt, bezt_next, u); - } + + return mask_point_interp_weight(bezt, bezt_next, u); } float BKE_mask_point_weight(MaskSpline *spline, MaskSplinePoint *point, const float u) @@ -724,53 +717,51 @@ float BKE_mask_point_weight(MaskSpline *spline, MaskSplinePoint *point, const fl if (!bezt_next) { return bezt->weight; } - else if (u <= 0.0f) { + if (u <= 0.0f) { return bezt->weight; } - else if (u >= 1.0f) { + if (u >= 1.0f) { return bezt_next->weight; } - else { - float cur_u = 0.0f, cur_w = 0.0f, next_u = 0.0f, next_w = 0.0f, fac; /* Quite warnings */ - int i; - for (i = 0; i <= point->tot_uw; i++) { + float cur_u = 0.0f, cur_w = 0.0f, next_u = 0.0f, next_w = 0.0f, fac; /* Quite warnings */ + int i; - if (i == 0) { - cur_u = 0.0f; - cur_w = 1.0f; /* mask_point_interp_weight will scale it */ - } - else { - cur_u = point->uw[i - 1].u; - cur_w = point->uw[i - 1].w; - } + for (i = 0; i <= point->tot_uw; i++) { - if (i == point->tot_uw) { - next_u = 1.0f; - next_w = 1.0f; /* mask_point_interp_weight will scale it */ - } - else { - next_u = point->uw[i].u; - next_w = point->uw[i].w; - } - - if (u >= cur_u && u <= next_u) { - break; - } + if (i == 0) { + cur_u = 0.0f; + cur_w = 1.0f; /* mask_point_interp_weight will scale it */ + } + else { + cur_u = point->uw[i - 1].u; + cur_w = point->uw[i - 1].w; } - fac = (u - cur_u) / (next_u - cur_u); - - cur_w *= mask_point_interp_weight(bezt, bezt_next, cur_u); - next_w *= mask_point_interp_weight(bezt, bezt_next, next_u); - - if (spline->weight_interp == MASK_SPLINE_INTERP_EASE) { - return cur_w + (next_w - cur_w) * (3.0f * fac * fac - 2.0f * fac * fac * fac); + if (i == point->tot_uw) { + next_u = 1.0f; + next_w = 1.0f; /* mask_point_interp_weight will scale it */ } else { - return (1.0f - fac) * cur_w + fac * next_w; + next_u = point->uw[i].u; + next_w = point->uw[i].w; } + + if (u >= cur_u && u <= next_u) { + break; + } + } + + fac = (u - cur_u) / (next_u - cur_u); + + cur_w *= mask_point_interp_weight(bezt, bezt_next, cur_u); + next_w *= mask_point_interp_weight(bezt, bezt_next, next_u); + + if (spline->weight_interp == MASK_SPLINE_INTERP_EASE) { + return cur_w + (next_w - cur_w) * (3.0f * fac * fac - 2.0f * fac * fac * fac); } + + return (1.0f - fac) * cur_w + fac * next_w; } MaskSplinePointUW *BKE_mask_point_sort_uw(MaskSplinePoint *point, MaskSplinePointUW *uw) @@ -1521,7 +1512,8 @@ static void mask_layer_shape_from_mask_point(BezTriple *bezt, fp[7] = bezt->radius; } -static void mask_layer_shape_to_mask_point(BezTriple *bezt, float fp[MASK_OBJECT_SHAPE_ELEM_SIZE]) +static void mask_layer_shape_to_mask_point(BezTriple *bezt, + const float fp[MASK_OBJECT_SHAPE_ELEM_SIZE]) { copy_v2_v2(bezt->vec[0], &fp[0]); copy_v2_v2(bezt->vec[1], &fp[2]); @@ -1642,7 +1634,7 @@ MaskLayerShape *BKE_mask_layer_shape_find_frame(MaskLayer *masklay, const int fr if (frame == masklay_shape->frame) { return masklay_shape; } - else if (frame < masklay_shape->frame) { + if (frame < masklay_shape->frame) { break; } } @@ -1667,17 +1659,16 @@ int BKE_mask_layer_shape_find_frame_range(MaskLayer *masklay, *r_masklay_shape_b = NULL; return 1; } - else if (frame < masklay_shape->frame) { + if (frame < masklay_shape->frame) { if (masklay_shape->prev) { *r_masklay_shape_a = masklay_shape->prev; *r_masklay_shape_b = masklay_shape; return 2; } - else { - *r_masklay_shape_a = masklay_shape; - *r_masklay_shape_b = NULL; - return 1; - } + + *r_masklay_shape_a = masklay_shape; + *r_masklay_shape_b = NULL; + return 1; } } @@ -1686,12 +1677,11 @@ int BKE_mask_layer_shape_find_frame_range(MaskLayer *masklay, *r_masklay_shape_b = NULL; return 1; } - else { - *r_masklay_shape_a = NULL; - *r_masklay_shape_b = NULL; - return 0; - } + *r_masklay_shape_a = NULL; + *r_masklay_shape_b = NULL; + + return 0; } MaskLayerShape *BKE_mask_layer_shape_verify_frame(MaskLayer *masklay, const int frame) @@ -1738,12 +1728,11 @@ static int mask_layer_shape_sort_cb(const void *masklay_shape_a_ptr, if (masklay_shape_a->frame < masklay_shape_b->frame) { return -1; } - else if (masklay_shape_a->frame > masklay_shape_b->frame) { + if (masklay_shape_a->frame > masklay_shape_b->frame) { return 1; } - else { - return 0; - } + + return 0; } void BKE_mask_layer_shape_sort(MaskLayer *masklay) diff --git a/source/blender/blenkernel/intern/mask_evaluate.c b/source/blender/blenkernel/intern/mask_evaluate.c index 9b281103a0f..d0f80bf92b9 100644 --- a/source/blender/blenkernel/intern/mask_evaluate.c +++ b/source/blender/blenkernel/intern/mask_evaluate.c @@ -126,9 +126,8 @@ int BKE_mask_spline_differentiate_calc_total(const MaskSpline *spline, const uns if (spline->flag & MASK_SPLINE_CYCLIC) { return spline->tot_point * resol; } - else { - return ((spline->tot_point - 1) * resol) + 1; - } + + return ((spline->tot_point - 1) * resol) + 1; } float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline, diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 01d44d070b3..b28cd9c6c8e 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -354,43 +354,38 @@ static bool layer_bucket_isect_test(const MaskRasterLayer *layer, if (isect_point_tri_v2(cent, v1, v2, v3)) { return true; } - else { - if ((dist_squared_to_line_segment_v2(cent, v1, v2) < bucket_max_rad_squared) || - (dist_squared_to_line_segment_v2(cent, v2, v3) < bucket_max_rad_squared) || - (dist_squared_to_line_segment_v2(cent, v3, v1) < bucket_max_rad_squared)) { - return true; - } - else { - // printf("skip tri\n"); - return false; - } - } - } - else { - const float *v1 = cos[face[0]]; - const float *v2 = cos[face[1]]; - const float *v3 = cos[face[2]]; - const float *v4 = cos[face[3]]; - if (isect_point_tri_v2(cent, v1, v2, v3)) { + if ((dist_squared_to_line_segment_v2(cent, v1, v2) < bucket_max_rad_squared) || + (dist_squared_to_line_segment_v2(cent, v2, v3) < bucket_max_rad_squared) || + (dist_squared_to_line_segment_v2(cent, v3, v1) < bucket_max_rad_squared)) { return true; } - else if (isect_point_tri_v2(cent, v1, v3, v4)) { - return true; - } - else { - if ((dist_squared_to_line_segment_v2(cent, v1, v2) < bucket_max_rad_squared) || - (dist_squared_to_line_segment_v2(cent, v2, v3) < bucket_max_rad_squared) || - (dist_squared_to_line_segment_v2(cent, v3, v4) < bucket_max_rad_squared) || - (dist_squared_to_line_segment_v2(cent, v4, v1) < bucket_max_rad_squared)) { - return true; - } - else { - // printf("skip quad\n"); - return false; - } - } + + // printf("skip tri\n"); + return false; + } + + const float *v1 = cos[face[0]]; + const float *v2 = cos[face[1]]; + const float *v3 = cos[face[2]]; + const float *v4 = cos[face[3]]; + + if (isect_point_tri_v2(cent, v1, v2, v3)) { + return true; + } + if (isect_point_tri_v2(cent, v1, v3, v4)) { + return true; } + + if ((dist_squared_to_line_segment_v2(cent, v1, v2) < bucket_max_rad_squared) || + (dist_squared_to_line_segment_v2(cent, v2, v3) < bucket_max_rad_squared) || + (dist_squared_to_line_segment_v2(cent, v3, v4) < bucket_max_rad_squared) || + (dist_squared_to_line_segment_v2(cent, v4, v1) < bucket_max_rad_squared)) { + return true; + } + + // printf("skip quad\n"); + return false; } static void layer_bucket_init_dummy(MaskRasterLayer *layer) @@ -1348,9 +1343,8 @@ static float layer_bucket_depth_from_xy(MaskRasterLayer *layer, const float xy[2 } return best_dist; } - else { - return 1.0f; - } + + return 1.0f; } float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2]) diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index b0b542f6000..0520ba3faae 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -268,27 +268,27 @@ Material ***BKE_object_material_array_p(Object *ob) Mesh *me = ob->data; return &(me->mat); } - else if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) { + if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) { Curve *cu = ob->data; return &(cu->mat); } - else if (ob->type == OB_MBALL) { + if (ob->type == OB_MBALL) { MetaBall *mb = ob->data; return &(mb->mat); } - else if (ob->type == OB_GPENCIL) { + if (ob->type == OB_GPENCIL) { bGPdata *gpd = ob->data; return &(gpd->mat); } - else if (ob->type == OB_HAIR) { + if (ob->type == OB_HAIR) { Hair *hair = ob->data; return &(hair->mat); } - else if (ob->type == OB_POINTCLOUD) { + if (ob->type == OB_POINTCLOUD) { PointCloud *pointcloud = ob->data; return &(pointcloud->mat); } - else if (ob->type == OB_VOLUME) { + if (ob->type == OB_VOLUME) { Volume *volume = ob->data; return &(volume->mat); } @@ -301,27 +301,27 @@ short *BKE_object_material_len_p(Object *ob) Mesh *me = ob->data; return &(me->totcol); } - else if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) { + if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) { Curve *cu = ob->data; return &(cu->totcol); } - else if (ob->type == OB_MBALL) { + if (ob->type == OB_MBALL) { MetaBall *mb = ob->data; return &(mb->totcol); } - else if (ob->type == OB_GPENCIL) { + if (ob->type == OB_GPENCIL) { bGPdata *gpd = ob->data; return &(gpd->totcol); } - else if (ob->type == OB_HAIR) { + if (ob->type == OB_HAIR) { Hair *hair = ob->data; return &(hair->totcol); } - else if (ob->type == OB_POINTCLOUD) { + if (ob->type == OB_POINTCLOUD) { PointCloud *pointcloud = ob->data; return &(pointcloud->totcol); } - else if (ob->type == OB_VOLUME) { + if (ob->type == OB_VOLUME) { Volume *volume = ob->data; return &(volume->totcol); } @@ -582,7 +582,7 @@ Material **BKE_object_material_get_p(Object *ob, short act) if (act > ob->totcol) { return NULL; } - else if (act <= 0) { + if (act <= 0) { if (act < 0) { CLOG_ERROR(&LOG, "Negative material index!"); } @@ -627,9 +627,8 @@ Material *BKE_gpencil_material(Object *ob, short act) if (ma != NULL) { return ma; } - else { - return BKE_material_default_gpencil(); - } + + return BKE_material_default_gpencil(); } MaterialGPencilStyle *BKE_gpencil_material_settings(Object *ob, short act) @@ -642,9 +641,8 @@ MaterialGPencilStyle *BKE_gpencil_material_settings(Object *ob, short act) return ma->gp_style; } - else { - return BKE_material_default_gpencil()->gp_style; - } + + return BKE_material_default_gpencil()->gp_style; } void BKE_object_material_resize(Main *bmain, Object *ob, const short totcol, bool do_id_user) @@ -959,14 +957,13 @@ void BKE_object_material_array_assign(Main *bmain, const bool to_object_only) { int actcol_orig = ob->actcol; - short i; while ((ob->totcol > totcol) && BKE_object_material_slot_remove(bmain, ob)) { /* pass */ } /* now we have the right number of slots */ - for (i = 0; i < totcol; i++) { + for (int i = 0; i < totcol; i++) { if (to_object_only && ob->matbits[i] == 0) { /* If we only assign to object, and that slot uses obdata material, do nothing. */ continue; @@ -1136,9 +1133,8 @@ static bNode *nodetree_uv_node_recursive(bNode *node) if (inode->typeinfo->nclass == NODE_CLASS_INPUT && inode->typeinfo->type == SH_NODE_UVMAP) { return inode; } - else { - return nodetree_uv_node_recursive(inode); - } + + return nodetree_uv_node_recursive(inode); } } diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 94e5f435a43..3a514608c77 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -341,9 +341,8 @@ bool BKE_mball_is_basis_for(Object *ob1, Object *ob2) if (STREQ(basis1name, basis2name)) { return BKE_mball_is_basis(ob1); } - else { - return false; - } + + return false; } bool BKE_mball_is_any_selected(const MetaBall *mb) diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 048af022adb..fccc4380fec 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -591,9 +591,8 @@ bool BKE_mesh_has_custom_loop_normals(Mesh *me) if (me->edit_mesh) { return CustomData_has_layer(&me->edit_mesh->bm->ldata, CD_CUSTOMLOOPNORMAL); } - else { - return CustomData_has_layer(&me->ldata, CD_CUSTOMLOOPNORMAL); - } + + return CustomData_has_layer(&me->ldata, CD_CUSTOMLOOPNORMAL); } /** Free (or release) any data used by this mesh (does not free the mesh itself). */ @@ -1096,9 +1095,8 @@ Mesh *BKE_mesh_from_object(Object *ob) if (ob->type == OB_MESH) { return ob->data; } - else { - return NULL; - } + + return NULL; } void BKE_mesh_assign_object(Main *bmain, Object *ob, Mesh *me) @@ -1270,12 +1268,11 @@ int BKE_mesh_edge_other_vert(const MEdge *e, int v) if (e->v1 == v) { return e->v2; } - else if (e->v2 == v) { + if (e->v2 == v) { return e->v1; } - else { - return -1; - } + + return -1; } /** @@ -1406,30 +1403,29 @@ void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh) if (UNLIKELY(mesh->cd_flag)) { return; } - else { - MVert *mv; - MEdge *med; - int i; - for (mv = mesh->mvert, i = 0; i < mesh->totvert; mv++, i++) { - if (mv->bweight != 0) { - mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT; - break; - } + MVert *mv; + MEdge *med; + int i; + + for (mv = mesh->mvert, i = 0; i < mesh->totvert; mv++, i++) { + if (mv->bweight != 0) { + mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT; + break; } + } - for (med = mesh->medge, i = 0; i < mesh->totedge; med++, i++) { - if (med->bweight != 0) { - mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT; - if (mesh->cd_flag & ME_CDFLAG_EDGE_CREASE) { - break; - } + for (med = mesh->medge, i = 0; i < mesh->totedge; med++, i++) { + if (med->bweight != 0) { + mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT; + if (mesh->cd_flag & ME_CDFLAG_EDGE_CREASE) { + break; } - if (med->crease != 0) { - mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE; - if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) { - break; - } + } + if (med->crease != 0) { + mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE; + if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) { + break; } } } diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index 49957b584ad..fe4b8a60796 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -1408,7 +1408,7 @@ static bool loop_split_generator_check_cyclic_smooth_fan(const MLoop *mloops, return false; } /* Smooth loop/edge... */ - else if (BLI_BITMAP_TEST(skip_loops, mlfan_vert_index)) { + if (BLI_BITMAP_TEST(skip_loops, mlfan_vert_index)) { if (mlfan_vert_index == ml_curr_index) { /* We walked around a whole cyclic smooth fan without finding any already-processed loop, * means we can use initial ml_curr/ml_prev edge as start for this smooth fan. */ @@ -1417,10 +1417,9 @@ static bool loop_split_generator_check_cyclic_smooth_fan(const MLoop *mloops, /* ... already checked in some previous looping, we can abort. */ return false; } - else { - /* ... we can skip it in future, and keep checking the smooth fan. */ - BLI_BITMAP_ENABLE(skip_loops, mlfan_vert_index); - } + + /* ... we can skip it in future, and keep checking the smooth fan. */ + BLI_BITMAP_ENABLE(skip_loops, mlfan_vert_index); } } @@ -2315,22 +2314,21 @@ float BKE_mesh_calc_poly_area(const MPoly *mpoly, const MLoop *loopstart, const return area_tri_v3( mvarray[loopstart[0].v].co, mvarray[loopstart[1].v].co, mvarray[loopstart[2].v].co); } - else { - int i; - const MLoop *l_iter = loopstart; - float area; - float(*vertexcos)[3] = BLI_array_alloca(vertexcos, (size_t)mpoly->totloop); - - /* pack vertex cos into an array for area_poly_v3 */ - for (i = 0; i < mpoly->totloop; i++, l_iter++) { - copy_v3_v3(vertexcos[i], mvarray[l_iter->v].co); - } - /* finally calculate the area */ - area = area_poly_v3((const float(*)[3])vertexcos, (unsigned int)mpoly->totloop); + int i; + const MLoop *l_iter = loopstart; + float area; + float(*vertexcos)[3] = BLI_array_alloca(vertexcos, (size_t)mpoly->totloop); - return area; + /* pack vertex cos into an array for area_poly_v3 */ + for (i = 0; i < mpoly->totloop; i++, l_iter++) { + copy_v3_v3(vertexcos[i], mvarray[l_iter->v].co); } + + /* finally calculate the area */ + area = area_poly_v3((const float(*)[3])vertexcos, (unsigned int)mpoly->totloop); + + return area; } float BKE_mesh_calc_area(const Mesh *me) diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c index 686f58a0ceb..3572939f78c 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.c +++ b/source/blender/blenkernel/intern/mesh_mapping.c @@ -1047,10 +1047,9 @@ static bool mesh_check_island_boundary_uv(const MPoly *UNUSED(mp), } return false; } - else { - /* Edge is UV boundary if tagged as seam. */ - return (me->flag & ME_SEAM) != 0; - } + + /* Edge is UV boundary if tagged as seam. */ + return (me->flag & ME_SEAM) != 0; } static bool mesh_calc_islands_loop_poly_uv(MVert *UNUSED(verts), diff --git a/source/blender/blenkernel/intern/mesh_merge.c b/source/blender/blenkernel/intern/mesh_merge.c index 1b9b8ea6572..ef28e9958fc 100644 --- a/source/blender/blenkernel/intern/mesh_merge.c +++ b/source/blender/blenkernel/intern/mesh_merge.c @@ -115,11 +115,10 @@ static int cddm_poly_compare(MLoop *mloop_array, same_loops = true; break; /* Polys are identical */ } - else { - compare_completed = true; - same_loops = false; - break; /* Polys are different */ - } + + compare_completed = true; + same_loops = false; + break; /* Polys are different */ } mloop_source++; @@ -201,9 +200,8 @@ static bool poly_gset_compare_fn(const void *k1, const void *k2) /* Equality - note that this does not mean equality of polys */ return false; } - else { - return true; - } + + return true; } /** @@ -412,7 +410,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, /* In this mode, all vertices merged is enough to dump face */ continue; } - else if (merge_mode == MESH_MERGE_VERTS_DUMP_IF_EQUAL) { + if (merge_mode == MESH_MERGE_VERTS_DUMP_IF_EQUAL) { /* Additional condition for face dump: target vertices must make up an identical face */ /* The test has 2 steps: (1) first step is fast ghash lookup, but not failproof */ /* (2) second step is thorough but more costly poly compare */ @@ -578,7 +576,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, BLI_assert(created_edges == 0); continue; } - else if (UNLIKELY(c < 3)) { + if (UNLIKELY(c < 3)) { STACK_DISCARD(oldl, c); STACK_DISCARD(mloop, c); if (created_edges > 0) { diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c index a4991675d2d..a8937f74dee 100644 --- a/source/blender/blenkernel/intern/mesh_remap.c +++ b/source/blender/blenkernel/intern/mesh_remap.c @@ -73,9 +73,8 @@ static bool mesh_remap_bvhtree_query_nearest(BVHTreeFromMesh *treedata, *r_hit_dist = sqrtf(nearest->dist_sq); return true; } - else { - return false; - } + + return false; } static bool mesh_remap_bvhtree_query_raycast(BVHTreeFromMesh *treedata, @@ -107,9 +106,8 @@ static bool mesh_remap_bvhtree_query_raycast(BVHTreeFromMesh *treedata, *r_hit_dist = rayhit->dist; return true; } - else { - return false; - } + + return false; } /** \} */ diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index 4d8c0568eb6..338420641cf 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -111,7 +111,7 @@ static int int64_cmp(const void *v1, const void *v2) if (x1 > x2) { return 1; } - else if (x1 < x2) { + if (x1 < x2) { return -1; } @@ -125,28 +125,28 @@ static int search_face_cmp(const void *v1, const void *v2) if (sfa->es[0].edval > sfb->es[0].edval) { return 1; } - else if (sfa->es[0].edval < sfb->es[0].edval) { + if (sfa->es[0].edval < sfb->es[0].edval) { return -1; } - else if (sfa->es[1].edval > sfb->es[1].edval) { + if (sfa->es[1].edval > sfb->es[1].edval) { return 1; } - else if (sfa->es[1].edval < sfb->es[1].edval) { + if (sfa->es[1].edval < sfb->es[1].edval) { return -1; } - else if (sfa->es[2].edval > sfb->es[2].edval) { + if (sfa->es[2].edval > sfb->es[2].edval) { return 1; } - else if (sfa->es[2].edval < sfb->es[2].edval) { + if (sfa->es[2].edval < sfb->es[2].edval) { return -1; } - else if (sfa->es[3].edval > sfb->es[3].edval) { + if (sfa->es[3].edval > sfb->es[3].edval) { return 1; } - else if (sfa->es[3].edval < sfb->es[3].edval) { + if (sfa->es[3].edval < sfb->es[3].edval) { return -1; } @@ -214,6 +214,7 @@ static int search_polyloop_cmp(const void *v1, const void *v2) * * \return false if no changes needed to be made. */ +/* NOLINTNEXTLINE: readability-function-size */ bool BKE_mesh_validate_arrays(Mesh *mesh, MVert *mverts, unsigned int totvert, @@ -1082,9 +1083,8 @@ bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_ DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY); return true; } - else { - return false; - } + + return false; } /** @@ -1161,9 +1161,8 @@ bool BKE_mesh_validate_material_indices(Mesh *me) DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY); return true; } - else { - return false; - } + + return false; } /** \} */ @@ -1341,13 +1340,13 @@ static int vergedgesort(const void *v1, const void *v2) if (x1->v1 > x2->v1) { return 1; } - else if (x1->v1 < x2->v1) { + if (x1->v1 < x2->v1) { return -1; } - else if (x1->v2 > x2->v2) { + if (x1->v2 > x2->v2) { return 1; } - else if (x1->v2 < x2->v2) { + if (x1->v2 < x2->v2) { return -1; } diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 327e8bfca7a..5789e0f0557 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -112,9 +112,8 @@ const ModifierTypeInfo *BKE_modifier_get_info(ModifierType type) if (type < NUM_MODIFIER_TYPES && modifier_types[type] && modifier_types[type]->name[0] != '\0') { return modifier_types[type]; } - else { - return NULL; - } + + return NULL; } /** @@ -919,11 +918,10 @@ const char *BKE_modifier_path_relbase(Main *bmain, Object *ob) if (G.relbase_valid || ID_IS_LINKED(ob)) { return ID_BLEND_PATH(bmain, &ob->id); } - else { - /* last resort, better then using "" which resolves to the current - * working directory */ - return BKE_tempdir_session(); - } + + /* last resort, better then using "" which resolves to the current + * working directory */ + return BKE_tempdir_session(); } const char *BKE_modifier_path_relbase_from_global(Object *ob) @@ -931,11 +929,10 @@ const char *BKE_modifier_path_relbase_from_global(Object *ob) if (G.relbase_valid || ID_IS_LINKED(ob)) { return ID_BLEND_PATH_FROM_GLOBAL(&ob->id); } - else { - /* last resort, better then using "" which resolves to the current - * working directory */ - return BKE_tempdir_session(); - } + + /* last resort, better then using "" which resolves to the current + * working directory */ + return BKE_tempdir_session(); } /* initializes the path with either */ diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 4a65c6ff5e7..dcac7b01899 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -717,9 +717,8 @@ static bool put_imbuf_cache( IMB_moviecache_put(clip->cache->moviecache, &key, ibuf); return true; } - else { - return IMB_moviecache_put_if_possible(clip->cache->moviecache, &key, ibuf); - } + + return IMB_moviecache_put_if_possible(clip->cache->moviecache, &key, ibuf); } static bool moviecache_check_free_proxy(ImBuf *UNUSED(ibuf), void *userkey, void *UNUSED(userdata)) @@ -1866,3 +1865,88 @@ void BKE_movieclip_eval_selection_update(struct Depsgraph *depsgraph, MovieClip DEG_debug_print_eval(depsgraph, __func__, clip->id.name, clip); movieclip_selection_sync(clip, (MovieClip *)clip->id.orig_id); } + +/* -------------------------------------------------------------------- */ +/** \name GPU textures + * \{ */ + +static GPUTexture **movieclip_get_gputexture_ptr(MovieClip *clip, + MovieClipUser *cuser, + eGPUTextureTarget textarget) +{ + /* Check if we have an existing entry for that clip user. */ + MovieClip_RuntimeGPUTexture *tex; + for (tex = clip->runtime.gputextures.first; tex; tex = tex->next) { + if (memcmp(&tex->user, cuser, sizeof(MovieClipUser)) == 0) { + break; + } + } + + /* If not, allocate a new one. */ + if (tex == NULL) { + tex = (MovieClip_RuntimeGPUTexture *)MEM_mallocN(sizeof(MovieClip_RuntimeGPUTexture), + __func__); + + for (int i = 0; i < TEXTARGET_COUNT; i++) { + tex->gputexture[i] = NULL; + } + + memcpy(&tex->user, cuser, sizeof(MovieClipUser)); + BLI_addtail(&clip->runtime.gputextures, tex); + } + + return &tex->gputexture[textarget]; +} + +GPUTexture *BKE_movieclip_get_gpu_texture(MovieClip *clip, MovieClipUser *cuser) +{ + if (clip == NULL) { + return NULL; + } + + GPUTexture **tex = movieclip_get_gputexture_ptr(clip, cuser, TEXTARGET_2D); + if (*tex) { + return *tex; + } + + /* check if we have a valid image buffer */ + ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, cuser); + if (ibuf == NULL) { + *tex = GPU_texture_create_error(2, false); + return *tex; + } + + /* This only means RGBA16F instead of RGBA32F. */ + const bool high_bitdepth = false; + const bool store_premultiplied = ibuf->rect_float ? false : true; + *tex = IMB_create_gpu_texture(ibuf, high_bitdepth, store_premultiplied); + + /* Do not generate mips for movieclips... too slow. */ + GPU_texture_mipmap_mode(*tex, false, true); + + IMB_freeImBuf(ibuf); + + return *tex; +} + +void BKE_movieclip_free_gputexture(struct MovieClip *clip) +{ + /* number of gpu textures to keep around as cache + * We don't want to keep too many GPU textures for + * movie clips around, as they can be large.*/ + const int MOVIECLIP_NUM_GPUTEXTURES = 1; + + while (BLI_listbase_count(&clip->runtime.gputextures) > MOVIECLIP_NUM_GPUTEXTURES) { + MovieClip_RuntimeGPUTexture *tex = (MovieClip_RuntimeGPUTexture *)BLI_pophead( + &clip->runtime.gputextures); + for (int i = 0; i < TEXTARGET_COUNT; i++) { + /* free glsl image binding */ + if (tex->gputexture[i]) { + GPU_texture_free(tex->gputexture[i]); + tex->gputexture[i] = NULL; + } + } + MEM_freeN(tex); + } +} +/** \} */ diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 71d49dd1c19..392f95af917 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -241,7 +241,7 @@ static void multires_mdisps_subdivide_hidden(MDisps *md, int new_level) md->hidden = subd; } -static MDisps *multires_mdisps_initialize_hidden(Mesh *me, int level) +static MDisps *multires_mdisps_init_hidden(Mesh *me, int level) { MDisps *mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS, CD_CALLOC, NULL, me->totloop); int gridsize = BKE_ccg_gridsize(level); @@ -407,15 +407,14 @@ int multires_get_level(const Scene *scene, return (scene != NULL) ? get_render_subsurf_level(&scene->r, mmd->renderlvl, true) : mmd->renderlvl; } - else if (ob->mode == OB_MODE_SCULPT) { + if (ob->mode == OB_MODE_SCULPT) { return mmd->sculptlvl; } - else if (ignore_simplify) { + if (ignore_simplify) { return mmd->lvl; } - else { - return (scene != NULL) ? get_render_subsurf_level(&scene->r, mmd->lvl, false) : mmd->lvl; - } + + return (scene != NULL) ? get_render_subsurf_level(&scene->r, mmd->lvl, false) : mmd->lvl; } void multires_set_tot_level(Object *ob, MultiresModifierData *mmd, int lvl) @@ -553,7 +552,7 @@ static int get_levels_from_disps(Object *ob) if (md->totdisp == lvl_totdisp) { break; } - else if (md->totdisp < lvl_totdisp) { + if (md->totdisp < lvl_totdisp) { totlvl--; } else { @@ -868,7 +867,7 @@ static void multires_subdivide_legacy( mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS); if (!mdisps) { - mdisps = multires_mdisps_initialize_hidden(me, totlvl); + mdisps = multires_mdisps_init_hidden(me, totlvl); } if (mdisps->disps && !updateblock && lvl != 0) { diff --git a/source/blender/blenkernel/intern/multires_reshape_apply_base.c b/source/blender/blenkernel/intern/multires_reshape_apply_base.c index 105e56e4219..10a43a4c9b8 100644 --- a/source/blender/blenkernel/intern/multires_reshape_apply_base.c +++ b/source/blender/blenkernel/intern/multires_reshape_apply_base.c @@ -72,7 +72,7 @@ void multires_reshape_apply_base_update_mesh_coords(MultiresReshapeContext *resh /* Assumes no is normalized; return value's sign is negative if v is on the other side of the * plane. */ -static float v3_dist_from_plane(float v[3], float center[3], float no[3]) +static float v3_dist_from_plane(const float v[3], const float center[3], const float no[3]) { float s[3]; sub_v3_v3v3(s, v, center); diff --git a/source/blender/blenkernel/intern/multires_unsubdivide.c b/source/blender/blenkernel/intern/multires_unsubdivide.c index fa1a53f946e..c9bb9518230 100644 --- a/source/blender/blenkernel/intern/multires_unsubdivide.c +++ b/source/blender/blenkernel/intern/multires_unsubdivide.c @@ -111,7 +111,7 @@ static BMVert *unsubdivide_find_any_pole(BMesh *bm, int *elem_id, int elem) if (is_vertex_in_id(v, elem_id, elem) && is_vertex_pole_three(v)) { return v; } - else if (is_vertex_in_id(v, elem_id, elem) && is_vertex_pole(v)) { + if (is_vertex_in_id(v, elem_id, elem) && is_vertex_pole(v)) { pole = v; } } diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index 7012688686b..1ba82b352d1 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -480,46 +480,41 @@ static float nlastrip_get_frame_actionclip(NlaStrip *strip, float cframe, short if (mode == NLATIME_CONVERT_MAP) { return strip->end - scale * (cframe - strip->actstart); } - else if (mode == NLATIME_CONVERT_UNMAP) { + if (mode == NLATIME_CONVERT_UNMAP) { return (strip->end + (strip->actstart * scale - cframe)) / scale; } - else { /* if (mode == NLATIME_CONVERT_EVAL) */ - if (IS_EQF((float)cframe, strip->end) && IS_EQF(strip->repeat, floorf(strip->repeat))) { - /* This case prevents the motion snapping back to the first frame at the end of the strip - * by catching the case where repeats is a whole number, which means that the end of the - * strip could also be interpreted as the end of the start of a repeat. */ - return strip->actstart; - } - else { - /* - the 'fmod(..., actlength * scale)' is needed to get the repeats working - * - the '/ scale' is needed to ensure that scaling influences the timing within the repeat - */ - return strip->actend - fmodf(cframe - strip->start, actlength * scale) / scale; - } + /* if (mode == NLATIME_CONVERT_EVAL) */ + if (IS_EQF((float)cframe, strip->end) && IS_EQF(strip->repeat, floorf(strip->repeat))) { + /* This case prevents the motion snapping back to the first frame at the end of the strip + * by catching the case where repeats is a whole number, which means that the end of the + * strip could also be interpreted as the end of the start of a repeat. */ + return strip->actstart; } + + /* - the 'fmod(..., actlength * scale)' is needed to get the repeats working + * - the '/ scale' is needed to ensure that scaling influences the timing within the repeat + */ + return strip->actend - fmodf(cframe - strip->start, actlength * scale) / scale; } - else { - if (mode == NLATIME_CONVERT_MAP) { - return strip->start + scale * (cframe - strip->actstart); - } - else if (mode == NLATIME_CONVERT_UNMAP) { - return strip->actstart + (cframe - strip->start) / scale; - } - else { /* if (mode == NLATIME_CONVERT_EVAL) */ - if (IS_EQF(cframe, strip->end) && IS_EQF(strip->repeat, floorf(strip->repeat))) { - /* This case prevents the motion snapping back to the first frame at the end of the strip - * by catching the case where repeats is a whole number, which means that the end of the - * strip could also be interpreted as the end of the start of a repeat. */ - return strip->actend; - } - else { - /* - the 'fmod(..., actlength * scale)' is needed to get the repeats working - * - the '/ scale' is needed to ensure that scaling influences the timing within the repeat - */ - return strip->actstart + fmodf(cframe - strip->start, actlength * scale) / scale; - } - } + + if (mode == NLATIME_CONVERT_MAP) { + return strip->start + scale * (cframe - strip->actstart); + } + if (mode == NLATIME_CONVERT_UNMAP) { + return strip->actstart + (cframe - strip->start) / scale; + } + /* if (mode == NLATIME_CONVERT_EVAL) */ + if (IS_EQF(cframe, strip->end) && IS_EQF(strip->repeat, floorf(strip->repeat))) { + /* This case prevents the motion snapping back to the first frame at the end of the strip + * by catching the case where repeats is a whole number, which means that the end of the + * strip could also be interpreted as the end of the start of a repeat. */ + return strip->actend; } + + /* - the 'fmod(..., actlength * scale)' is needed to get the repeats working + * - the '/ scale' is needed to ensure that scaling influences the timing within the repeat + */ + return strip->actstart + fmodf(cframe - strip->start, actlength * scale) / scale; } /* non clipped mapping for strip-time <-> global time (for Transitions) @@ -537,18 +532,15 @@ static float nlastrip_get_frame_transition(NlaStrip *strip, float cframe, short if (mode == NLATIME_CONVERT_MAP) { return strip->end - (length * cframe); } - else { - return (strip->end - cframe) / length; - } + + return (strip->end - cframe) / length; } - else { - if (mode == NLATIME_CONVERT_MAP) { - return (length * cframe) + strip->start; - } - else { - return (cframe - strip->start) / length; - } + + if (mode == NLATIME_CONVERT_MAP) { + return (length * cframe) + strip->start; } + + return (cframe - strip->start) / length; } /* non clipped mapping for strip-time <-> global time @@ -882,11 +874,10 @@ bool BKE_nlameta_add_strip(NlaStrip *mstrip, NlaStrip *strip) return true; } - else { /* failed... no room before */ - return false; - } + /* failed... no room before */ + return false; } - else if (strip->end > mstrip->end) { + if (strip->end > mstrip->end) { /* check if strip to the right (if it exists) starts before the * end of the strip we're trying to add */ @@ -897,14 +888,12 @@ bool BKE_nlameta_add_strip(NlaStrip *mstrip, NlaStrip *strip) return true; } - else { /* failed... no room after */ - return false; - } - } - else { - /* just try to add to the meta-strip (no dimension changes needed) */ - return BKE_nlastrips_add_strip(&mstrip->strips, strip); + /* failed... no room after */ + return false; } + + /* just try to add to the meta-strip (no dimension changes needed) */ + return BKE_nlastrips_add_strip(&mstrip->strips, strip); } /* Adjust the settings of NLA-Strips contained within a Meta-Strip (recursively), @@ -1034,7 +1023,7 @@ NlaTrack *BKE_nlatrack_find_tweaked(AnimData *adt) if (BLI_findindex(&nlt->strips, adt->actstrip) != -1) { return nlt; } - else if (G.debug & G_DEBUG) { + if (G.debug & G_DEBUG) { printf("%s: Active strip (%p, %s) not in NLA track found (%p, %s)\n", __func__, adt->actstrip, diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 20d65e52b09..d77e7cf862d 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -61,6 +61,7 @@ #include "BKE_lib_query.h" #include "BKE_main.h" #include "BKE_node.h" +#include "BKE_simulation.h" #include "BLI_ghash.h" #include "BLI_threads.h" @@ -845,12 +846,12 @@ static void socket_id_user_increment(bNodeSocket *sock) switch ((eNodeSocketDatatype)sock->type) { case SOCK_OBJECT: { bNodeSocketValueObject *default_value = sock->default_value; - id_us_plus(&default_value->value->id); + id_us_plus((ID *)default_value->value); break; } case SOCK_IMAGE: { bNodeSocketValueImage *default_value = sock->default_value; - id_us_plus(&default_value->value->id); + id_us_plus((ID *)default_value->value); break; } case SOCK_FLOAT: @@ -1265,9 +1266,8 @@ bNode *nodeFindRootParent(bNode *node) if (node->parent) { return nodeFindRootParent(node->parent); } - else { - return node->type == NODE_FRAME ? node : NULL; - } + + return node->type == NODE_FRAME ? node : NULL; } /** @@ -1279,7 +1279,7 @@ bool nodeIsChildOf(const bNode *parent, const bNode *child) if (parent == child) { return true; } - else if (child->parent) { + if (child->parent) { return nodeIsChildOf(parent, child->parent); } return false; @@ -1338,9 +1338,8 @@ static void iter_backwards_ex(const bNodeTree *ntree, if (link->fromnode->iter_flag & recursion_mask) { continue; } - else { - link->fromnode->iter_flag |= recursion_mask; - } + + link->fromnode->iter_flag |= recursion_mask; if (!callback(link->fromnode, link->tonode, userdata)) { return; @@ -2493,6 +2492,7 @@ ID *BKE_node_tree_find_owner_ID(Main *bmain, struct bNodeTree *ntree) &bmain->textures, &bmain->scenes, &bmain->linestyles, + &bmain->simulations, NULL}; for (int i = 0; lists[i] != NULL; i++) { @@ -2580,9 +2580,8 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree) return ltree; } - else { - return NULL; - } + + return NULL; } /* sync local composite with real tree */ @@ -2987,9 +2986,8 @@ bNode *nodeGetActiveID(bNodeTree *ntree, short idtype) return node_get_active_id_recursive( ntree->active_viewer_key, NODE_INSTANCE_KEY_BASE, ntree, idtype); } - else { - return NULL; - } + + return NULL; } bool nodeSetActiveID(bNodeTree *ntree, short idtype, ID *id) @@ -3125,9 +3123,8 @@ int nodeSocketLinkLimit(struct bNodeSocket *sock) int limit = (sock->in_out == SOCK_IN) ? stype->input_link_limit : stype->output_link_limit; return limit; } - else { - return sock->limit; - } + + return sock->limit; } /* ************** Node Clipboard *********** */ @@ -3417,9 +3414,8 @@ bool BKE_node_instance_hash_tag_key(bNodeInstanceHash *hash, bNodeInstanceKey ke entry->tag = 1; return true; } - else { - return false; - } + + return false; } void BKE_node_instance_hash_remove_untagged(bNodeInstanceHash *hash, @@ -3637,6 +3633,16 @@ void ntreeUpdateAllUsers(Main *main, ID *ngroup) FOREACH_NODETREE_END; } +static void ntreeUpdateSimulationDependencies(Main *main, bNodeTree *simulation_ntree) +{ + FOREACH_NODETREE_BEGIN (main, ntree, owner_id) { + if (GS(owner_id->name) == ID_SIM && ntree == simulation_ntree) { + BKE_simulation_update_dependencies((Simulation *)owner_id, main); + } + } + FOREACH_NODETREE_END; +} + void ntreeUpdateTree(Main *bmain, bNodeTree *ntree) { bNode *node; @@ -3679,7 +3685,6 @@ void ntreeUpdateTree(Main *bmain, bNodeTree *ntree) ntreeInterfaceTypeUpdate(ntree); } - /* XXX hack, should be done by depsgraph!! */ if (bmain) { ntreeUpdateAllUsers(bmain, &ntree->id); } @@ -3695,6 +3700,11 @@ void ntreeUpdateTree(Main *bmain, bNodeTree *ntree) ntree_validate_links(ntree); } + if (bmain != NULL && ntree->typeinfo == ntreeType_Simulation && + (ntree->id.flag & LIB_EMBEDDED_DATA)) { + ntreeUpdateSimulationDependencies(bmain, ntree); + } + /* clear update flags */ for (node = ntree->nodes.first; node; node = node->next) { node->update = 0; @@ -3819,6 +3829,7 @@ static bool node_poll_instance_default(bNode *node, bNodeTree *ntree) return node->typeinfo->poll(node->typeinfo, ntree); } +/* NOLINTNEXTLINE: readability-function-size */ void node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag) { /* Use static type info header to map static int type to identifier string and RNA struct type. @@ -4336,6 +4347,8 @@ static void registerSimulationNodes(void) register_node_type_sim_emit_particles(); register_node_type_sim_time(); register_node_type_sim_particle_attribute(); + register_node_type_sim_age_reached_event(); + register_node_type_sim_kill_particle(); } static void registerFunctionNodes(void) @@ -4346,6 +4359,7 @@ static void registerFunctionNodes(void) register_node_type_fn_group_instance_id(); register_node_type_fn_combine_strings(); register_node_type_fn_object_transforms(); + register_node_type_fn_random_float(); } void init_nodesystem(void) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index ecb2256d080..024e60ea989 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -666,14 +666,14 @@ bool BKE_object_support_modifier_type_check(const Object *ob, int modifier_type) if (ob->type == OB_HAIR) { return (mti->modifyHair != NULL) || (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly); } - else if (ob->type == OB_POINTCLOUD) { + if (ob->type == OB_POINTCLOUD) { return (mti->modifyPointCloud != NULL) || (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly); } - else if (ob->type == OB_VOLUME) { + if (ob->type == OB_VOLUME) { return (mti->modifyVolume != NULL); } - else if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { + if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { if (ob->type == OB_LATTICE && (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly) == 0) { return false; } @@ -1597,9 +1597,8 @@ bool BKE_object_pose_context_check(const Object *ob) if ((ob) && (ob->type == OB_ARMATURE) && (ob->pose) && (ob->mode & OB_MODE_POSE)) { return true; } - else { - return false; - } + + return false; } Object *BKE_object_pose_armature_get(Object *ob) @@ -2409,7 +2408,7 @@ static bool ob_parcurve(Object *ob, Object *par, float r_mat[4][4]) /* ctime is now a proper var setting of Curve which gets set by Animato like any other var * that's animated, but this will only work if it actually is animated. * - * We divide the curvetime calculated in the previous step by the length of the path, + * We divide the curve-time calculated in the previous step by the length of the path, * to get a time factor, which then gets clamped to lie within 0.0 - 1.0 range. */ if (cu->pathlen) { @@ -3207,9 +3206,8 @@ bool BKE_object_empty_image_frame_is_visible_in_view3d(const Object *ob, const R if (rv3d->is_persp) { return (visibility_flag & OB_EMPTY_IMAGE_HIDE_PERSPECTIVE) == 0; } - else { - return (visibility_flag & OB_EMPTY_IMAGE_HIDE_ORTHOGRAPHIC) == 0; - } + + return (visibility_flag & OB_EMPTY_IMAGE_HIDE_ORTHOGRAPHIC) == 0; } bool BKE_object_empty_image_data_is_visible_in_view3d(const Object *ob, const RegionView3D *rv3d) @@ -3269,31 +3267,30 @@ bool BKE_object_minmax_dupli(Depsgraph *depsgraph, if ((ob->transflag & OB_DUPLI) == 0) { return ok; } - else { - ListBase *lb; - DupliObject *dob; - lb = object_duplilist(depsgraph, scene, ob); - for (dob = lb->first; dob; dob = dob->next) { - if ((use_hidden == false) && (dob->no_draw != 0)) { - /* pass */ - } - else { - BoundBox *bb = BKE_object_boundbox_get(dob->ob); - - if (bb) { - int i; - for (i = 0; i < 8; i++) { - float vec[3]; - mul_v3_m4v3(vec, dob->mat, bb->vec[i]); - minmax_v3v3_v3(r_min, r_max, vec); - } - ok = true; + ListBase *lb; + DupliObject *dob; + lb = object_duplilist(depsgraph, scene, ob); + for (dob = lb->first; dob; dob = dob->next) { + if ((use_hidden == false) && (dob->no_draw != 0)) { + /* pass */ + } + else { + BoundBox *bb = BKE_object_boundbox_get(dob->ob); + + if (bb) { + int i; + for (i = 0; i < 8; i++) { + float vec[3]; + mul_v3_m4v3(vec, dob->mat, bb->vec[i]); + minmax_v3v3_v3(r_min, r_max, vec); } + + ok = true; } } - free_object_duplilist(lb); /* does restore */ } + free_object_duplilist(lb); /* does restore */ return ok; } @@ -3636,9 +3633,8 @@ static int pc_cmp(const void *a, const void *b) if (POINTER_AS_INT(ad->data) > POINTER_AS_INT(bd->data)) { return 1; } - else { - return 0; - } + + return 0; } int BKE_object_insert_ptcache(Object *ob) @@ -3917,12 +3913,11 @@ bool BKE_object_flag_test_recursive(const Object *ob, short flag) if (ob->flag & flag) { return true; } - else if (ob->parent) { + if (ob->parent) { return BKE_object_flag_test_recursive(ob->parent, flag); } - else { - return false; - } + + return false; } bool BKE_object_is_child_recursive(const Object *ob_parent, const Object *ob_child) @@ -3970,15 +3965,20 @@ int BKE_object_is_modified(Scene *scene, Object *ob) return flag; } -/* Check of objects moves in time. */ -/* NOTE: This function is currently optimized for usage in combination - * with mti->canDeform, so modifiers can quickly check if their target - * objects moves (causing deformation motion blur) or not. +/** + * Check of objects moves in time. + * + * \note This function is currently optimized for usage in combination + * with modifier deformation checks (#eModifierTypeType_OnlyDeform), + * so modifiers can quickly check if their target objects moves + * (causing deformation motion blur) or not. * * This makes it possible to give some degree of false-positives here, * but it's currently an acceptable tradeoff between complexity and check * speed. In combination with checks of modifier stack and real life usage - * percentage of false-positives shouldn't be that height. + * percentage of false-positives shouldn't be that high. + * + * \note This function does not consider physics systems. */ bool BKE_object_moves_in_time(const Object *object, bool recurse_parent) { @@ -4024,15 +4024,15 @@ static bool constructive_modifier_is_deform_modified(ModifierData *md) (amd->curve_ob != NULL && object_moves_in_time(amd->curve_ob)) || (amd->offset_ob != NULL && object_moves_in_time(amd->offset_ob)); } - else if (md->type == eModifierType_Mirror) { + if (md->type == eModifierType_Mirror) { MirrorModifierData *mmd = (MirrorModifierData *)md; return mmd->mirror_ob != NULL && object_moves_in_time(mmd->mirror_ob); } - else if (md->type == eModifierType_Screw) { + if (md->type == eModifierType_Screw) { ScrewModifierData *smd = (ScrewModifierData *)md; return smd->ob_axis != NULL && object_moves_in_time(smd->ob_axis); } - else if (md->type == eModifierType_MeshSequenceCache) { + if (md->type == eModifierType_MeshSequenceCache) { /* NOTE: Not ideal because it's unknown whether topology changes or not. * This will be detected later, so by assuming it's only deformation * going on here we allow to bake deform-only mesh to Alembic and have diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c index 51ec89cf77d..04f7529c6cd 100644 --- a/source/blender/blenkernel/intern/object_deform.c +++ b/source/blender/blenkernel/intern/object_deform.c @@ -145,7 +145,7 @@ MDeformVert *BKE_object_defgroup_data_create(ID *id) me->dvert = CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert); return me->dvert; } - else if (GS(id->name) == ID_LT) { + if (GS(id->name) == ID_LT) { Lattice *lt = (Lattice *)id; lt->dvert = MEM_callocN(sizeof(MDeformVert) * lt->pntsu * lt->pntsv * lt->pntsw, "lattice deformVert"); diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c index f498e147110..f485f3d2419 100644 --- a/source/blender/blenkernel/intern/object_dupli.c +++ b/source/blender/blenkernel/intern/object_dupli.c @@ -37,6 +37,7 @@ #include "DNA_collection_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_pointcloud_types.h" #include "DNA_scene_types.h" #include "DNA_vfont_types.h" @@ -143,7 +144,10 @@ static void copy_dupli_context( /* generate a dupli instance * mat is transform of the object relative to current context (including object obmat) */ -static DupliObject *make_dupli(const DupliContext *ctx, Object *ob, float mat[4][4], int index) +static DupliObject *make_dupli(const DupliContext *ctx, + Object *ob, + const float mat[4][4], + int index) { DupliObject *dob; int i; @@ -367,17 +371,13 @@ static void vertex_dupli(const VertexDupliData *vdd, DupliObject *dob; float obmat[4][4], space_mat[4][4]; - /* obmat is transform to vertex */ - get_duplivert_transform(co, no, vdd->use_rotation, inst_ob->trackflag, inst_ob->upflag, obmat); + /* space_mat is transform to vertex */ + get_duplivert_transform( + co, no, vdd->use_rotation, inst_ob->trackflag, inst_ob->upflag, space_mat); /* make offset relative to inst_ob using relative child transform */ - mul_mat3_m4_v3((float(*)[4])vdd->child_imat, obmat[3]); + mul_mat3_m4_v3((float(*)[4])vdd->child_imat, space_mat[3]); /* apply obmat _after_ the local vertex transform */ - mul_m4_m4m4(obmat, inst_ob->obmat, obmat); - - /* space matrix is constructed by removing obmat transform, - * this yields the worldspace transform for recursive duplis - */ - mul_m4_m4m4(space_mat, obmat, inst_ob->imat); + mul_m4_m4m4(obmat, inst_ob->obmat, space_mat); dob = make_dupli(vdd->ctx, vdd->inst_ob, obmat, index); @@ -523,7 +523,7 @@ static void make_duplis_font(const DupliContext *ctx) /* Safety check even if it might fail badly when called for original object. */ const bool is_eval_curve = DEG_is_evaluated_id(&cu->id); - /* advance matching BLI_strncpy_wchar_from_utf8 */ + /* Advance matching BLI_str_utf8_as_utf32. */ for (a = 0; a < text_len; a++, ct++) { /* XXX That G.main is *really* ugly, but not sure what to do here... @@ -573,6 +573,63 @@ static const DupliGenerator gen_dupli_verts_font = { make_duplis_font /* make_duplis */ }; +/* OB_DUPLIVERTS - PointCloud */ +static void make_child_duplis_pointcloud(const DupliContext *ctx, + void *UNUSED(userdata), + Object *child) +{ + const Object *parent = ctx->object; + const PointCloud *pointcloud = parent->data; + const float(*co)[3] = pointcloud->co; + const float *radius = pointcloud->radius; + const float(*rotation)[4] = NULL; /* TODO: add optional rotation attribute. */ + const float(*orco)[3] = NULL; /* TODO: add optional texture coordinate attribute. */ + + /* Relative transform from parent to child space. */ + float child_imat[4][4]; + mul_m4_m4m4(child_imat, child->imat, parent->obmat); + + for (int i = 0; i < pointcloud->totpoint; i++) { + /* Transform matrix from point position, radius and rotation. */ + float quat[4] = {1.0f, 0.0f, 0.0f, 0.0f}; + float size[3] = {1.0f, 1.0f, 1.0f}; + if (radius) { + copy_v3_fl(size, radius[i]); + } + if (rotation) { + copy_v4_v4(quat, rotation[i]); + } + + float space_mat[4][4]; + loc_quat_size_to_mat4(space_mat, co[i], quat, size); + + /* Make offset relative to child object using relative child transform, + * and apply object matrix after local vertex transform. */ + mul_mat3_m4_v3(child_imat, space_mat[3]); + + /* Create dupli object. */ + float obmat[4][4]; + mul_m4_m4m4(obmat, child->obmat, space_mat); + DupliObject *dob = make_dupli(ctx, child, obmat, i); + if (orco) { + copy_v3_v3(dob->orco, orco[i]); + } + + /* Recursion. */ + make_recursive_duplis(ctx, child, space_mat, i); + } +} + +static void make_duplis_pointcloud(const DupliContext *ctx) +{ + make_child_duplis(ctx, NULL, make_child_duplis_pointcloud); +} + +static const DupliGenerator gen_dupli_verts_pointcloud = { + OB_DUPLIVERTS, /* type */ + make_duplis_pointcloud /* make_duplis */ +}; + /* OB_DUPLIFACES */ typedef struct FaceDupliData { Mesh *me_eval; @@ -955,13 +1012,12 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem if (psys_get_particle_state(&sim, a, &state, 0) == 0) { continue; } - else { - float tquat[4]; - normalize_qt_qt(tquat, state.rot); - quat_to_mat4(pamat, tquat); - copy_v3_v3(pamat[3], state.co); - pamat[3][3] = 1.0f; - } + + float tquat[4]; + normalize_qt_qt(tquat, state.rot); + quat_to_mat4(pamat, tquat); + copy_v3_v3(pamat[3], state.co); + pamat[3][3] = 1.0f; } if (part->ren_as == PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) { @@ -1098,13 +1154,16 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx) if (transflag & OB_DUPLIPARTS) { return &gen_dupli_particles; } - else if (transflag & OB_DUPLIVERTS) { + if (transflag & OB_DUPLIVERTS) { if (ctx->object->type == OB_MESH) { return &gen_dupli_verts; } - else if (ctx->object->type == OB_FONT) { + if (ctx->object->type == OB_FONT) { return &gen_dupli_verts_font; } + if (ctx->object->type == OB_POINTCLOUD) { + return &gen_dupli_verts_pointcloud; + } } else if (transflag & OB_DUPLIFACES) { if (ctx->object->type == OB_MESH) { diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c index f94ef946851..ff7cbff06bf 100644 --- a/source/blender/blenkernel/intern/ocean.c +++ b/source/blender/blenkernel/intern/ocean.c @@ -753,18 +753,25 @@ struct Ocean *BKE_ocean_add(void) return oc; } -bool BKE_ocean_ensure(struct OceanModifierData *omd) +bool BKE_ocean_ensure(struct OceanModifierData *omd, const int resolution) { if (omd->ocean) { - return false; + /* Check that the ocean has the same resolution than we want now. */ + if (omd->ocean->_M == resolution * resolution) { + return false; + } + + BKE_ocean_free(omd->ocean); } omd->ocean = BKE_ocean_add(); - BKE_ocean_init_from_modifier(omd->ocean, omd); + BKE_ocean_init_from_modifier(omd->ocean, omd, resolution); return true; } -void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData const *omd) +void BKE_ocean_init_from_modifier(struct Ocean *ocean, + struct OceanModifierData const *omd, + const int resolution) { short do_heightfield, do_chop, do_normals, do_jacobian; @@ -774,9 +781,10 @@ void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData do_jacobian = (omd->flag & MOD_OCEAN_GENERATE_FOAM); BKE_ocean_free_data(ocean); + BKE_ocean_init(ocean, - omd->resolution * omd->resolution, - omd->resolution * omd->resolution, + resolution * resolution, + resolution * resolution, omd->spatial_size, omd->spatial_size, omd->wind_velocity, @@ -1607,7 +1615,8 @@ void BKE_ocean_bake(struct Ocean *UNUSED(o), } void BKE_ocean_init_from_modifier(struct Ocean *UNUSED(ocean), - struct OceanModifierData const *UNUSED(omd)) + struct OceanModifierData const *UNUSED(omd), + int UNUSED(resolution)) { } diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index 2cd5588ccb8..3f3eaae697b 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -415,11 +415,10 @@ enum ePF_FileCompare BKE_packedfile_compare_to_file(const char *ref_file_name, ret_val = PF_CMP_DIFFERS; break; } - else { - if (memcmp(buf, ((char *)pf->data) + i, len)) { - ret_val = PF_CMP_DIFFERS; - break; - } + + if (memcmp(buf, ((char *)pf->data) + i, len)) { + ret_val = PF_CMP_DIFFERS; + break; } } diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 0ba5ec43318..19d5c34ad73 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -426,7 +426,7 @@ Paint *BKE_paint_get_active_from_context(const bContext *C) if (sima->mode == SI_MODE_PAINT) { return &ts->imapaint.paint; } - else if (sima->mode == SI_MODE_UV) { + if (sima->mode == SI_MODE_UV) { return &ts->uvsculpt->paint; } } @@ -460,7 +460,7 @@ ePaintMode BKE_paintmode_get_active_from_context(const bContext *C) if (sima->mode == SI_MODE_PAINT) { return PAINT_MODE_TEXTURE_2D; } - else if (sima->mode == SI_MODE_UV) { + if (sima->mode == SI_MODE_UV) { return PAINT_MODE_SCULPT_UV; } } @@ -715,7 +715,7 @@ static int palettecolor_compare_hsv(const void *a1, const void *a2) if (ps1->h > ps2->h) { return 1; } - else if (ps1->h < ps2->h) { + if (ps1->h < ps2->h) { return -1; } @@ -723,7 +723,7 @@ static int palettecolor_compare_hsv(const void *a1, const void *a2) if (ps1->s > ps2->s) { return 1; } - else if (ps1->s < ps2->s) { + if (ps1->s < ps2->s) { return -1; } @@ -731,7 +731,7 @@ static int palettecolor_compare_hsv(const void *a1, const void *a2) if (1.0f - ps1->v > 1.0f - ps2->v) { return 1; } - else if (1.0f - ps1->v < 1.0f - ps2->v) { + if (1.0f - ps1->v < 1.0f - ps2->v) { return -1; } @@ -747,7 +747,7 @@ static int palettecolor_compare_svh(const void *a1, const void *a2) if (ps1->s > ps2->s) { return 1; } - else if (ps1->s < ps2->s) { + if (ps1->s < ps2->s) { return -1; } @@ -755,7 +755,7 @@ static int palettecolor_compare_svh(const void *a1, const void *a2) if (1.0f - ps1->v > 1.0f - ps2->v) { return 1; } - else if (1.0f - ps1->v < 1.0f - ps2->v) { + if (1.0f - ps1->v < 1.0f - ps2->v) { return -1; } @@ -763,7 +763,7 @@ static int palettecolor_compare_svh(const void *a1, const void *a2) if (ps1->h > ps2->h) { return 1; } - else if (ps1->h < ps2->h) { + if (ps1->h < ps2->h) { return -1; } @@ -778,7 +778,7 @@ static int palettecolor_compare_vhs(const void *a1, const void *a2) if (1.0f - ps1->v > 1.0f - ps2->v) { return 1; } - else if (1.0f - ps1->v < 1.0f - ps2->v) { + if (1.0f - ps1->v < 1.0f - ps2->v) { return -1; } @@ -786,7 +786,7 @@ static int palettecolor_compare_vhs(const void *a1, const void *a2) if (ps1->h > ps2->h) { return 1; } - else if (ps1->h < ps2->h) { + if (ps1->h < ps2->h) { return -1; } @@ -794,7 +794,7 @@ static int palettecolor_compare_vhs(const void *a1, const void *a2) if (ps1->s > ps2->s) { return 1; } - else if (ps1->s < ps2->s) { + if (ps1->s < ps2->s) { return -1; } @@ -811,7 +811,7 @@ static int palettecolor_compare_luminance(const void *a1, const void *a2) if (lumi1 > lumi2) { return -1; } - else if (lumi1 < lumi2) { + if (lumi1 < lumi2) { return 1; } @@ -1424,9 +1424,8 @@ MultiresModifierData *BKE_sculpt_multires_active(Scene *scene, Object *ob) if (mmd->sculptlvl > 0) { return mmd; } - else { - return NULL; - } + + return NULL; } } @@ -1468,7 +1467,7 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob) if (mti->type == eModifierTypeType_OnlyDeform) { return true; } - else if ((sd->flags & SCULPT_ONLY_DEFORM) == 0) { + if ((sd->flags & SCULPT_ONLY_DEFORM) == 0) { return true; } } @@ -1493,6 +1492,8 @@ static void sculpt_update_object(Depsgraph *depsgraph, MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob); const bool use_face_sets = (ob->mode & OB_MODE_SCULPT) != 0; + ss->depsgraph = depsgraph; + ss->deform_modifiers_active = sculpt_modifiers_active(scene, sd, ob); ss->show_mask = (sd->flags & SCULPT_HIDE_MASK) == 0; ss->show_face_sets = (sd->flags & SCULPT_HIDE_FACE_SETS) == 0; @@ -1691,7 +1692,6 @@ void BKE_sculpt_color_layer_create_if_needed(struct Object *object) CustomData_add_layer(&orig_me->vdata, CD_PROP_COLOR, CD_DEFAULT, NULL, orig_me->totvert); BKE_mesh_update_customdata_pointers(orig_me, true); DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY); - return; } void BKE_sculpt_update_object_for_edit( @@ -2029,8 +2029,7 @@ bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const View3D *v3d) const bool full_shading = (v3d && (v3d->shading.type > OB_SOLID)); return !(ss->shapekey_active || ss->deform_modifiers_active || full_shading); } - else { - /* Multires and dyntopo always draw directly from the PBVH. */ - return true; - } + + /* Multires and dyntopo always draw directly from the PBVH. */ + return true; } diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index a003daf1042..363706ca969 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -512,9 +512,8 @@ bool psys_check_edited(ParticleSystem *psys) if (psys->part && psys->part->type == PART_HAIR) { return (psys->flag & PSYS_EDITED || (psys->edit && psys->edit->edited)); } - else { - return (psys->pointcache->edit && psys->pointcache->edit->edited); - } + + return (psys->pointcache->edit && psys->pointcache->edit->edited); } void psys_find_group_weights(ParticleSettings *part) @@ -1653,12 +1652,11 @@ int psys_particle_dm_face_lookup(Mesh *mesh_final, // printf("\tNO CD_ORIGSPACE, assuming not needed\n"); return findex_orig; } - else { - printf("\tNO CD_ORIGSPACE, error out of range\n"); - return DMCACHE_NOTFOUND; - } + + printf("\tNO CD_ORIGSPACE, error out of range\n"); + return DMCACHE_NOTFOUND; } - else if (findex_orig >= mesh_original->totface) { + if (findex_orig >= mesh_original->totface) { return DMCACHE_NOTFOUND; /* index not in the original mesh */ } @@ -1919,7 +1917,7 @@ static void psys_particle_on_shape(int UNUSED(distr), float orco[3]) { /* TODO */ - float zerovec[3] = {0.0f, 0.0f, 0.0f}; + const float zerovec[3] = {0.0f, 0.0f, 0.0f}; if (vec) { copy_v3_v3(vec, zerovec); } @@ -2170,10 +2168,10 @@ int do_guides(Depsgraph *depsgraph, { ParticleKey key; - float par_co[3] = {0.0f, 0.0f, 0.0f}; - float par_vel[3] = {0.0f, 0.0f, 0.0f}; - float par_rot[4] = {1.0f, 0.0f, 0.0f, 0.0f}; - float orco_offset[3] = {0.0f, 0.0f, 0.0f}; + const float par_co[3] = {0.0f, 0.0f, 0.0f}; + const float par_vel[3] = {0.0f, 0.0f, 0.0f}; + const float par_rot[4] = {1.0f, 0.0f, 0.0f, 0.0f}; + const float orco_offset[3] = {0.0f, 0.0f, 0.0f}; copy_v3_v3(key.co, vec_to_point); do_kink(&key, @@ -2555,9 +2553,8 @@ static void psys_thread_create_path(ParticleTask *task, if (!needupdate) { return; } - else { - memset(child_keys, 0, sizeof(*child_keys) * (ctx->segments + 1)); - } + + memset(child_keys, 0, sizeof(*child_keys) * (ctx->segments + 1)); } /* get parent paths */ @@ -3871,7 +3868,7 @@ void BKE_particlesettings_clump_curve_init(ParticleSettings *part) cumap->cm[0].curve[1].x = 1.0f; cumap->cm[0].curve[1].y = 1.0f; - BKE_curvemapping_initialize(cumap); + BKE_curvemapping_init(cumap); part->clumpcurve = cumap; } @@ -3885,7 +3882,7 @@ void BKE_particlesettings_rough_curve_init(ParticleSettings *part) cumap->cm[0].curve[1].x = 1.0f; cumap->cm[0].curve[1].y = 1.0f; - BKE_curvemapping_initialize(cumap); + BKE_curvemapping_init(cumap); part->roughcurve = cumap; } @@ -3899,7 +3896,7 @@ void BKE_particlesettings_twist_curve_init(ParticleSettings *part) cumap->cm[0].curve[1].x = 1.0f; cumap->cm[0].curve[1].y = 1.0f; - BKE_curvemapping_initialize(cumap); + BKE_curvemapping_init(cumap); part->twistcurve = cumap; } @@ -4666,10 +4663,9 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta psys_get_particle_on_path(sim, p, state, 1); return 1; } - else { - cpa = sim->psys->child + p - totpart; - pa = sim->psys->particles + cpa->parent; - } + + cpa = sim->psys->child + p - totpart; + pa = sim->psys->particles + cpa->parent; } else { pa = sim->psys->particles + p; @@ -4691,106 +4687,105 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta psys_get_particle_on_path(sim, p, state, 1); return 1; } - else { - if (cpa) { - float mat[4][4]; - ParticleKey *key1; - float t = (cfra - pa->time) / pa->lifetime; - float par_orco[3] = {0.0f, 0.0f, 0.0f}; - key1 = &pa->state; - offset_child(cpa, key1, key1->rot, state, part->childflat, part->childrad); + if (cpa) { + float mat[4][4]; + ParticleKey *key1; + float t = (cfra - pa->time) / pa->lifetime; + const float par_orco[3] = {0.0f, 0.0f, 0.0f}; - CLAMP(t, 0.0f, 1.0f); + key1 = &pa->state; + offset_child(cpa, key1, key1->rot, state, part->childflat, part->childrad); - unit_m4(mat); - 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; + CLAMP(t, 0.0f, 1.0f); - do_child_modifiers(&modifier_ctx, mat, state, t); + unit_m4(mat); + 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; - if (psys->lattice_deform_data) { - BKE_lattice_deform_data_eval_co( - psys->lattice_deform_data, state->co, psys->lattice_strength); - } + do_child_modifiers(&modifier_ctx, mat, state, t); + + if (psys->lattice_deform_data) { + BKE_lattice_deform_data_eval_co( + psys->lattice_deform_data, state->co, psys->lattice_strength); + } + } + else { + if (pa->state.time == cfra || ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED)) { + copy_particle_key(state, &pa->state, 1); + } + else if (pa->prev_state.time == cfra) { + copy_particle_key(state, &pa->prev_state, 1); } else { - if (pa->state.time == cfra || ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED)) { - copy_particle_key(state, &pa->state, 1); - } - else if (pa->prev_state.time == cfra) { - copy_particle_key(state, &pa->prev_state, 1); - } - else { - float dfra, frs_sec = sim->scene->r.frs_sec; - /* let's interpolate to try to be as accurate as possible */ - if (pa->state.time + 2.f >= state->time && pa->prev_state.time - 2.f <= state->time) { - if (pa->prev_state.time >= pa->state.time || pa->prev_state.time < 0.f) { - /* prev_state is wrong so let's not use it, - * this can happen at frames 1, 0 or particle birth. */ - dfra = state->time - pa->state.time; + float dfra, frs_sec = sim->scene->r.frs_sec; + /* let's interpolate to try to be as accurate as possible */ + if (pa->state.time + 2.f >= state->time && pa->prev_state.time - 2.f <= state->time) { + if (pa->prev_state.time >= pa->state.time || pa->prev_state.time < 0.f) { + /* prev_state is wrong so let's not use it, + * this can happen at frames 1, 0 or particle birth. */ + dfra = state->time - pa->state.time; - copy_particle_key(state, &pa->state, 1); + copy_particle_key(state, &pa->state, 1); - madd_v3_v3v3fl(state->co, state->co, state->vel, dfra / frs_sec); - } - else { - ParticleKey keys[4]; - float keytime; + madd_v3_v3v3fl(state->co, state->co, state->vel, dfra / frs_sec); + } + else { + ParticleKey keys[4]; + float keytime; - copy_particle_key(keys + 1, &pa->prev_state, 1); - copy_particle_key(keys + 2, &pa->state, 1); + copy_particle_key(keys + 1, &pa->prev_state, 1); + copy_particle_key(keys + 2, &pa->state, 1); - dfra = keys[2].time - keys[1].time; + dfra = keys[2].time - keys[1].time; - keytime = (state->time - keys[1].time) / dfra; + keytime = (state->time - keys[1].time) / dfra; - /* convert velocity to timestep size */ - mul_v3_fl(keys[1].vel, dfra * timestep); - mul_v3_fl(keys[2].vel, dfra * timestep); + /* convert velocity to timestep size */ + mul_v3_fl(keys[1].vel, dfra * timestep); + mul_v3_fl(keys[2].vel, dfra * timestep); - psys_interpolate_particle(-1, keys, keytime, state, 1); + psys_interpolate_particle(-1, keys, keytime, state, 1); - /* convert back to real velocity */ - mul_v3_fl(state->vel, 1.f / (dfra * timestep)); + /* convert back to real velocity */ + mul_v3_fl(state->vel, 1.f / (dfra * timestep)); - interp_v3_v3v3(state->ave, keys[1].ave, keys[2].ave, keytime); - interp_qt_qtqt(state->rot, keys[1].rot, keys[2].rot, keytime); - } + interp_v3_v3v3(state->ave, keys[1].ave, keys[2].ave, keytime); + interp_qt_qtqt(state->rot, keys[1].rot, keys[2].rot, keytime); } - else if (pa->state.time + 1.f >= state->time && pa->state.time - 1.f <= state->time) { - /* linear interpolation using only pa->state */ + } + else if (pa->state.time + 1.f >= state->time && pa->state.time - 1.f <= state->time) { + /* linear interpolation using only pa->state */ - dfra = state->time - pa->state.time; + dfra = state->time - pa->state.time; - copy_particle_key(state, &pa->state, 1); + copy_particle_key(state, &pa->state, 1); - madd_v3_v3v3fl(state->co, state->co, state->vel, dfra / frs_sec); - } - else { - /* Extrapolating over big ranges is not accurate - * so let's just give something close to reasonable back. */ - copy_particle_key(state, &pa->state, 0); - } + madd_v3_v3v3fl(state->co, state->co, state->vel, dfra / frs_sec); } - - if (sim->psys->lattice_deform_data) { - BKE_lattice_deform_data_eval_co( - sim->psys->lattice_deform_data, state->co, psys->lattice_strength); + else { + /* Extrapolating over big ranges is not accurate + * so let's just give something close to reasonable back. */ + copy_particle_key(state, &pa->state, 0); } } - return 1; + if (sim->psys->lattice_deform_data) { + BKE_lattice_deform_data_eval_co( + sim->psys->lattice_deform_data, state->co, psys->lattice_strength); + } } + + return 1; } void psys_get_dupli_texture(ParticleSystem *psys, @@ -4844,9 +4839,8 @@ void psys_get_dupli_texture(ParticleSystem *psys, orco); return; } - else { - pa = psys->particles + cpa->pa[0]; - } + + pa = psys->particles + cpa->pa[0]; } if ((part->from == PART_FROM_FACE) && (psmd->mesh_final != NULL) && !is_grid) { diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c index dcd2a0b8fae..da5fdc85561 100644 --- a/source/blender/blenkernel/intern/particle_child.c +++ b/source/blender/blenkernel/intern/particle_child.c @@ -305,10 +305,9 @@ static bool check_path_length(int k, /* something over the maximum step value */ return false; } - else { - *cur_length += step_length; - return true; - } + + *cur_length += step_length; + return true; } void psys_apply_child_modifiers(ParticleThreadContext *ctx, @@ -685,7 +684,7 @@ static void do_rough(const float loc[3], } static void do_rough_end( - const float loc[3], float mat[4][4], float t, float fac, float shape, ParticleKey *state) + const float loc[3], const float mat[4][4], float t, float fac, float shape, ParticleKey *state) { float rough[2]; float roughfac; diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index e0dccd4d14a..dc6d5e974ed 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -829,22 +829,20 @@ static int distribute_compare_orig_index(const void *p1, const void *p2, void *u if (index1 < index2) { return -1; } - else if (index1 == index2) { + if (index1 == index2) { /* this pointer comparison appears to make qsort stable for glibc, * and apparently on solaris too, makes the renders reproducible */ if (p1 < p2) { return -1; } - else if (p1 == p2) { + if (p1 == p2) { return 0; } - else { - return 1; - } - } - else { + return 1; } + + return 1; } static void distribute_invalid(ParticleSimulationData *sim, int from) diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index bec9cbbad79..7bfc0ca764f 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -106,9 +106,8 @@ static int particles_are_dynamic(ParticleSystem *psys) if (psys->part->type == PART_HAIR) { return psys->flag & PSYS_HAIR_DYNAMICS; } - else { - return ELEM(psys->part->phystype, PART_PHYS_NEWTON, PART_PHYS_BOIDS, PART_PHYS_FLUID); - } + + return ELEM(psys->part->phystype, PART_PHYS_NEWTON, PART_PHYS_BOIDS, PART_PHYS_FLUID); } float psys_get_current_display_percentage(ParticleSystem *psys, const bool use_render_params) @@ -131,12 +130,11 @@ static int tot_particles(ParticleSystem *psys, PTCacheID *pid) if (pid && psys->pointcache->flag & PTCACHE_EXTERNAL) { return pid->cache->totpoint; } - else if (psys->part->distr == PART_DISTR_GRID && psys->part->from != PART_FROM_VERT) { + if (psys->part->distr == PART_DISTR_GRID && psys->part->from != PART_FROM_VERT) { return psys->part->grid_res * psys->part->grid_res * psys->part->grid_res - psys->totunexist; } - else { - return psys->part->totpart - psys->totunexist; - } + + return psys->part->totpart - psys->totunexist; } void psys_reset(ParticleSystem *psys, int mode) @@ -570,7 +568,7 @@ void psys_thread_context_free(ParticleThreadContext *ctx) } } -static void initialize_particle_texture(ParticleSimulationData *sim, ParticleData *pa, int p) +static void init_particle_texture(ParticleSimulationData *sim, ParticleData *pa, int p) { ParticleSystem *psys = sim->psys; ParticleSettings *part = psys->part; @@ -595,7 +593,7 @@ static void initialize_particle_texture(ParticleSimulationData *sim, ParticleDat } /* set particle parameters that don't change during particle's life */ -void initialize_particle(ParticleSimulationData *sim, ParticleData *pa) +void init_particle(ParticleSimulationData *sim, ParticleData *pa) { ParticleSettings *part = sim->psys->part; float birth_time = (float)(pa - sim->psys->particles) / (float)sim->psys->totpart; @@ -629,7 +627,7 @@ static void initialize_all_particles(ParticleSimulationData *sim) LOOP_PARTICLES { if (!(emit_from_volume_grid && (pa->flag & PARS_UNEXIST) != 0)) { - initialize_particle(sim, pa); + init_particle(sim, pa); } } } @@ -1092,7 +1090,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, * We could only do it now because we'll need to know coordinate * before sampling the texture. */ - initialize_particle_texture(sim, pa, p); + init_particle_texture(sim, pa, p); if (part->phystype == PART_PHYS_BOIDS && pa->boid) { BoidParticle *bpa = pa->boid; @@ -1709,13 +1707,12 @@ static void sph_evaluate_func(BVHTree *tree, BLI_bvhtree_range_query(tree, co, interaction_radius, callback, pfr); break; } - else { - BLI_rw_mutex_lock(&psys_bvhtree_rwlock, THREAD_LOCK_READ); - BLI_bvhtree_range_query(psys[i]->bvhtree, co, interaction_radius, callback, pfr); + BLI_rw_mutex_lock(&psys_bvhtree_rwlock, THREAD_LOCK_READ); - BLI_rw_mutex_unlock(&psys_bvhtree_rwlock); - } + BLI_bvhtree_range_query(psys[i]->bvhtree, co, interaction_radius, callback, pfr); + + BLI_rw_mutex_unlock(&psys_bvhtree_rwlock); } } static void sph_density_accum_cb(void *userdata, int index, const float co[3], float squared_dist) @@ -2612,9 +2609,8 @@ static float collision_newton_rhapson(ParticleCollision *col, d1 = 0.f; continue; } - else { - return -1.f; - } + + return -1.f; } dd = (t1 - t0) / (d1 - d0); @@ -2634,7 +2630,7 @@ static float collision_newton_rhapson(ParticleCollision *col, d1 = 0.f; continue; } - else if (iter == 1 && (t1 < -COLLISION_ZERO || t1 > 1.f)) { + if (iter == 1 && (t1 < -COLLISION_ZERO || t1 > 1.f)) { return -1.f; } @@ -2648,9 +2644,8 @@ static float collision_newton_rhapson(ParticleCollision *col, return t1; } - else { - return -1.f; - } + + return -1.f; } } return -1.0; @@ -2927,164 +2922,163 @@ static int collision_response(ParticleSimulationData *sim, return 0; } /* figure out velocity and other data after collision */ - else { - /* velocity directly before collision to be modified into velocity directly after collision */ - float v0[3]; - /* normal component of v0 */ - float v0_nor[3]; - /* tangential component of v0 */ - float v0_tan[3]; - /* tangential component of collision surface velocity */ - float vc_tan[3]; - float v0_dot, vc_dot; - float damp = pd->pdef_damp + pd->pdef_rdamp * 2 * (BLI_rng_get_float(rng) - 0.5f); - float frict = pd->pdef_frict + pd->pdef_rfrict * 2 * (BLI_rng_get_float(rng) - 0.5f); - float distance, nor[3], dot; - - CLAMP(damp, 0.0f, 1.0f); - CLAMP(frict, 0.0f, 1.0f); - - /* get exact velocity right before collision */ - madd_v3_v3v3fl(v0, col->ve1, col->acc, dt1); - - /* Convert collider velocity from `1/frame_step` to `1/s` TODO: - * here we assume 1 frame step for collision modifier. */ - mul_v3_fl(pce->vel, col->inv_timestep); - - /* calculate tangential particle velocity */ - v0_dot = dot_v3v3(pce->nor, v0); - madd_v3_v3v3fl(v0_tan, v0, pce->nor, -v0_dot); - - /* calculate tangential collider velocity */ - vc_dot = dot_v3v3(pce->nor, pce->vel); - madd_v3_v3v3fl(vc_tan, pce->vel, pce->nor, -vc_dot); - - /* handle friction effects (tangential and angular velocity) */ - if (frict > 0.0f) { - /* angular <-> linear velocity */ - if (dynamic_rotation) { - float vr_tan[3], v1_tan[3], ave[3]; - - /* linear velocity of particle surface */ - cross_v3_v3v3(vr_tan, pce->nor, pa->state.ave); - mul_v3_fl(vr_tan, pa->size); - - /* change to coordinates that move with the collision plane */ - sub_v3_v3v3(v1_tan, v0_tan, vc_tan); - - /* The resulting velocity is a weighted average of particle cm & surface - * velocity. This weight (related to particle's moment of inertia) could - * be made a parameter for angular <-> linear conversion. - */ - madd_v3_v3fl(v1_tan, vr_tan, -0.4); - mul_v3_fl(v1_tan, 1.0f / 1.4f); /* 1/(1+0.4) */ - /* rolling friction is around 0.01 of sliding friction - * (could be made a parameter) */ - mul_v3_fl(v1_tan, 1.0f - 0.01f * frict); - - /* surface_velocity is opposite to cm velocity */ - negate_v3_v3(vr_tan, v1_tan); - - /* get back to global coordinates */ - add_v3_v3(v1_tan, vc_tan); - - /* convert to angular velocity*/ - cross_v3_v3v3(ave, vr_tan, pce->nor); - mul_v3_fl(ave, 1.0f / MAX2(pa->size, 0.001f)); - - /* only friction will cause change in linear & angular velocity */ - interp_v3_v3v3(pa->state.ave, pa->state.ave, ave, frict); - interp_v3_v3v3(v0_tan, v0_tan, v1_tan, frict); - } - else { - /* just basic friction (unphysical due to the friction model used in Blender) */ - interp_v3_v3v3(v0_tan, v0_tan, vc_tan, frict); - } + /* velocity directly before collision to be modified into velocity directly after collision */ + float v0[3]; + /* normal component of v0 */ + float v0_nor[3]; + /* tangential component of v0 */ + float v0_tan[3]; + /* tangential component of collision surface velocity */ + float vc_tan[3]; + float v0_dot, vc_dot; + float damp = pd->pdef_damp + pd->pdef_rdamp * 2 * (BLI_rng_get_float(rng) - 0.5f); + float frict = pd->pdef_frict + pd->pdef_rfrict * 2 * (BLI_rng_get_float(rng) - 0.5f); + float distance, nor[3], dot; + + CLAMP(damp, 0.0f, 1.0f); + CLAMP(frict, 0.0f, 1.0f); + + /* get exact velocity right before collision */ + madd_v3_v3v3fl(v0, col->ve1, col->acc, dt1); + + /* Convert collider velocity from `1/frame_step` to `1/s` TODO: + * here we assume 1 frame step for collision modifier. */ + mul_v3_fl(pce->vel, col->inv_timestep); + + /* calculate tangential particle velocity */ + v0_dot = dot_v3v3(pce->nor, v0); + madd_v3_v3v3fl(v0_tan, v0, pce->nor, -v0_dot); + + /* calculate tangential collider velocity */ + vc_dot = dot_v3v3(pce->nor, pce->vel); + madd_v3_v3v3fl(vc_tan, pce->vel, pce->nor, -vc_dot); + + /* handle friction effects (tangential and angular velocity) */ + if (frict > 0.0f) { + /* angular <-> linear velocity */ + if (dynamic_rotation) { + float vr_tan[3], v1_tan[3], ave[3]; + + /* linear velocity of particle surface */ + cross_v3_v3v3(vr_tan, pce->nor, pa->state.ave); + mul_v3_fl(vr_tan, pa->size); + + /* change to coordinates that move with the collision plane */ + sub_v3_v3v3(v1_tan, v0_tan, vc_tan); + + /* The resulting velocity is a weighted average of particle cm & surface + * velocity. This weight (related to particle's moment of inertia) could + * be made a parameter for angular <-> linear conversion. + */ + madd_v3_v3fl(v1_tan, vr_tan, -0.4); + mul_v3_fl(v1_tan, 1.0f / 1.4f); /* 1/(1+0.4) */ + + /* rolling friction is around 0.01 of sliding friction + * (could be made a parameter) */ + mul_v3_fl(v1_tan, 1.0f - 0.01f * frict); + + /* surface_velocity is opposite to cm velocity */ + negate_v3_v3(vr_tan, v1_tan); + + /* get back to global coordinates */ + add_v3_v3(v1_tan, vc_tan); + + /* convert to angular velocity*/ + cross_v3_v3v3(ave, vr_tan, pce->nor); + mul_v3_fl(ave, 1.0f / MAX2(pa->size, 0.001f)); + + /* only friction will cause change in linear & angular velocity */ + interp_v3_v3v3(pa->state.ave, pa->state.ave, ave, frict); + interp_v3_v3v3(v0_tan, v0_tan, v1_tan, frict); } + else { + /* just basic friction (unphysical due to the friction model used in Blender) */ + interp_v3_v3v3(v0_tan, v0_tan, vc_tan, frict); + } + } - /* Stickiness was possibly added before, - * so cancel that before calculating new normal velocity. - * Otherwise particles go flying out of the surface - * because of high reversed sticky velocity. */ - if (v0_dot < 0.0f) { - v0_dot += pd->pdef_stickness; - if (v0_dot > 0.0f) { - v0_dot = 0.0f; - } + /* Stickiness was possibly added before, + * so cancel that before calculating new normal velocity. + * Otherwise particles go flying out of the surface + * because of high reversed sticky velocity. */ + if (v0_dot < 0.0f) { + v0_dot += pd->pdef_stickness; + if (v0_dot > 0.0f) { + v0_dot = 0.0f; } + } - /* damping and flipping of velocity around normal */ - v0_dot *= 1.0f - damp; - vc_dot *= through ? damp : 1.0f; + /* damping and flipping of velocity around normal */ + v0_dot *= 1.0f - damp; + vc_dot *= through ? damp : 1.0f; - /* calculate normal particle velocity */ - /* special case for object hitting the particle from behind */ - if (through == 0 && ((vc_dot > 0.0f && v0_dot > 0.0f && vc_dot > v0_dot) || - (vc_dot < 0.0f && v0_dot < 0.0f && vc_dot < v0_dot))) { - mul_v3_v3fl(v0_nor, pce->nor, vc_dot); - } - else if (v0_dot > 0.f) { - mul_v3_v3fl(v0_nor, pce->nor, vc_dot + v0_dot); - } - else { - mul_v3_v3fl(v0_nor, pce->nor, vc_dot + (through ? 1.0f : -1.0f) * v0_dot); - } + /* calculate normal particle velocity */ + /* special case for object hitting the particle from behind */ + if (through == 0 && ((vc_dot > 0.0f && v0_dot > 0.0f && vc_dot > v0_dot) || + (vc_dot < 0.0f && v0_dot < 0.0f && vc_dot < v0_dot))) { + mul_v3_v3fl(v0_nor, pce->nor, vc_dot); + } + else if (v0_dot > 0.f) { + mul_v3_v3fl(v0_nor, pce->nor, vc_dot + v0_dot); + } + else { + mul_v3_v3fl(v0_nor, pce->nor, vc_dot + (through ? 1.0f : -1.0f) * v0_dot); + } - /* combine components together again */ - add_v3_v3v3(v0, v0_nor, v0_tan); + /* combine components together again */ + add_v3_v3v3(v0, v0_nor, v0_tan); - if (col->boid) { - /* keep boids above ground */ - BoidParticle *bpa = pa->boid; - if (bpa->data.mode == eBoidMode_OnLand || co[2] <= col->boid_z) { - co[2] = col->boid_z; - v0[2] = 0.0f; - } + if (col->boid) { + /* keep boids above ground */ + BoidParticle *bpa = pa->boid; + if (bpa->data.mode == eBoidMode_OnLand || co[2] <= col->boid_z) { + co[2] = col->boid_z; + v0[2] = 0.0f; } + } - /* re-apply acceleration to final location and velocity */ - madd_v3_v3v3fl(pa->state.co, co, v0, dt2); - madd_v3_v3fl(pa->state.co, col->acc, 0.5f * dt2 * dt2); - madd_v3_v3v3fl(pa->state.vel, v0, col->acc, dt2); + /* re-apply acceleration to final location and velocity */ + madd_v3_v3v3fl(pa->state.co, co, v0, dt2); + madd_v3_v3fl(pa->state.co, col->acc, 0.5f * dt2 * dt2); + madd_v3_v3v3fl(pa->state.vel, v0, col->acc, dt2); - /* make sure particle stays on the right side of the surface */ - if (!through) { - distance = collision_point_distance_with_normal(co, pce, -1.f, col, nor); + /* make sure particle stays on the right side of the surface */ + if (!through) { + distance = collision_point_distance_with_normal(co, pce, -1.f, col, nor); - if (distance < col->radius + COLLISION_MIN_DISTANCE) { - madd_v3_v3fl(co, nor, col->radius + COLLISION_MIN_DISTANCE - distance); - } + if (distance < col->radius + COLLISION_MIN_DISTANCE) { + madd_v3_v3fl(co, nor, col->radius + COLLISION_MIN_DISTANCE - distance); + } - dot = dot_v3v3(nor, v0); - if (dot < 0.f) { - madd_v3_v3fl(v0, nor, -dot); - } + dot = dot_v3v3(nor, v0); + if (dot < 0.f) { + madd_v3_v3fl(v0, nor, -dot); + } - distance = collision_point_distance_with_normal(pa->state.co, pce, 1.f, col, nor); + distance = collision_point_distance_with_normal(pa->state.co, pce, 1.f, col, nor); - if (distance < col->radius + COLLISION_MIN_DISTANCE) { - madd_v3_v3fl(pa->state.co, nor, col->radius + COLLISION_MIN_DISTANCE - distance); - } + if (distance < col->radius + COLLISION_MIN_DISTANCE) { + madd_v3_v3fl(pa->state.co, nor, col->radius + COLLISION_MIN_DISTANCE - distance); + } - dot = dot_v3v3(nor, pa->state.vel); - if (dot < 0.f) { - madd_v3_v3fl(pa->state.vel, nor, -dot); - } + dot = dot_v3v3(nor, pa->state.vel); + if (dot < 0.f) { + madd_v3_v3fl(pa->state.vel, nor, -dot); } + } - /* add stickiness to surface */ - madd_v3_v3fl(pa->state.vel, pce->nor, -pd->pdef_stickness); + /* add stickiness to surface */ + madd_v3_v3fl(pa->state.vel, pce->nor, -pd->pdef_stickness); - /* set coordinates for next iteration */ - copy_v3_v3(col->co1, co); - copy_v3_v3(col->co2, pa->state.co); + /* set coordinates for next iteration */ + copy_v3_v3(col->co1, co); + copy_v3_v3(col->co2, pa->state.co); - copy_v3_v3(col->ve1, v0); - copy_v3_v3(col->ve2, pa->state.vel); + copy_v3_v3(col->ve1, v0); + copy_v3_v3(col->ve2, pa->state.vel); - col->f = f; - } + col->f = f; /* if permeability random roll succeeded, disable collider for this sim step */ if (through) { @@ -3676,12 +3670,11 @@ static float sync_timestep(ParticleSystem *psys, float t_frac) if (t_frac == 1.0f) { return psys->dt_frac; } - else if (t_frac + (psys->dt_frac * TIMESTEP_EXPANSION_TOLERANCE) >= 1.0f) { + if (t_frac + (psys->dt_frac * TIMESTEP_EXPANSION_TOLERANCE) >= 1.0f) { return 1.0f - t_frac; } - else { - return psys->dt_frac; - } + + return psys->dt_frac; } /************************************************/ @@ -4372,7 +4365,7 @@ static void particles_fluid_step(ParticleSimulationData *sim, max_size = MAX3(size[0] / (float)upres, size[1] / (float)upres, size[2] / (float)upres); /* Set particle position. */ - float posParticle[3] = {posX, posY, posZ}; + const float posParticle[3] = {posX, posY, posZ}; copy_v3_v3(pa->state.co, posParticle); /* Normalize to unit cube around 0. */ @@ -4405,7 +4398,7 @@ static void particles_fluid_step(ParticleSimulationData *sim, pa->state.co[0], pa->state.co[1], pa->state.co[2]); # endif /* Set particle velocity. */ - float velParticle[3] = {velX, velY, velZ}; + const float velParticle[3] = {velX, velY, velZ}; copy_v3_v3(pa->state.vel, velParticle); mul_v3_fl(pa->state.vel, fds->dx); # if 0 @@ -4537,11 +4530,11 @@ static void system_step(ParticleSimulationData *sim, float cfra, const bool use_ return; } /* Cache is supposed to be baked, but no data was found so bail out */ - else if (cache->flag & PTCACHE_BAKED) { + if (cache->flag & PTCACHE_BAKED) { psys_reset(psys, PSYS_RESET_CACHE_MISS); return; } - else if (cache_result == PTCACHE_READ_OLD) { + if (cache_result == PTCACHE_READ_OLD) { psys->cfra = (float)cache->simframe; cached_step(sim, psys->cfra, use_render_params); } @@ -4584,7 +4577,7 @@ static void system_step(ParticleSimulationData *sim, float cfra, const bool use_ psys->dt_frac = get_base_time_step(part); } else if ((int)cfra == startframe) { - /* Variable time step; initialise to subframes */ + /* Variable time step; initialize to sub-frames. */ psys->dt_frac = get_base_time_step(part); } else if (psys->dt_frac < MIN_TIMESTEP) { diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 92a47f24240..1dd22a0a28d 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -109,18 +109,15 @@ int BB_widest_axis(const BB *bb) if (dim[0] > dim[2]) { return 0; } - else { - return 2; - } + + return 2; } - else { - if (dim[1] > dim[2]) { - return 1; - } - else { - return 2; - } + + if (dim[1] > dim[2]) { + return 1; } + + return 2; } void BBC_update_centroid(BBC *bbc) @@ -275,9 +272,8 @@ static int map_insert_vert( *value_p = POINTER_FROM_INT(value_i); return value_i; } - else { - return POINTER_AS_INT(*value_p); - } + + return POINTER_AS_INT(*value_p); } /* Find vertices used by the faces in this node and update the draw buffers */ @@ -804,14 +800,13 @@ static PBVHNode *pbvh_iter_next(PBVHIter *iter) /* immediately hit leaf node */ return node; } - else { - /* come back later when children are done */ - pbvh_stack_push(iter, node, true); - /* push two child nodes on the stack */ - pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset + 1, false); - pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset, false); - } + /* come back later when children are done */ + pbvh_stack_push(iter, node, true); + + /* push two child nodes on the stack */ + pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset + 1, false); + pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset, false); } return NULL; @@ -838,10 +833,9 @@ static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter) /* immediately hit leaf node */ return node; } - else { - pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset + 1, false); - pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset, false); - } + + pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset + 1, false); + pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset, false); } return NULL; @@ -1391,16 +1385,15 @@ static int pbvh_flush_bb(PBVH *pbvh, PBVHNode *node, int flag) return update; } - else { - update |= pbvh_flush_bb(pbvh, pbvh->nodes + node->children_offset, flag); - update |= pbvh_flush_bb(pbvh, pbvh->nodes + node->children_offset + 1, flag); - if (update & PBVH_UpdateBB) { - update_node_vb(pbvh, node); - } - if (update & PBVH_UpdateOriginalBB) { - node->orig_vb = node->vb; - } + update |= pbvh_flush_bb(pbvh, pbvh->nodes + node->children_offset, flag); + update |= pbvh_flush_bb(pbvh, pbvh->nodes + node->children_offset + 1, flag); + + if (update & PBVH_UpdateBB) { + update_node_vb(pbvh, node); + } + if (update & PBVH_UpdateOriginalBB) { + node->orig_vb = node->vb; } return update; @@ -1667,9 +1660,8 @@ bool BKE_pbvh_has_faces(const PBVH *pbvh) if (pbvh->type == PBVH_BMESH) { return (pbvh->bm->totface != 0); } - else { - return (pbvh->totprim != 0); - } + + return (pbvh->totprim != 0); } void BKE_pbvh_bounding_box(const PBVH *pbvh, float min[3], float max[3]) @@ -2029,9 +2021,8 @@ bool ray_face_intersection_quad(const float ray_start[3], *depth = depth_test; return true; } - else { - return false; - } + + return false; } bool ray_face_intersection_tri(const float ray_start[3], @@ -2047,9 +2038,8 @@ bool ray_face_intersection_tri(const float ray_start[3], *depth = depth_test; return true; } - else { - return false; - } + + return false; } /* Take advantage of the fact we know this wont be an intersection. @@ -2100,9 +2090,8 @@ bool ray_face_nearest_quad(const float ray_start[3], } return true; } - else { - return false; - } + + return false; } bool ray_face_nearest_tri(const float ray_start[3], @@ -2122,9 +2111,8 @@ bool ray_face_nearest_tri(const float ray_start[3], *depth = depth_test; return true; } - else { - return false; - } + + return false; } static bool pbvh_faces_node_raycast(PBVH *pbvh, @@ -2357,7 +2345,7 @@ void BKE_pbvh_raycast_project_ray_root( struct IsectRayAABB_Precalc ray; float ray_normal_inv[3]; float offset = 1.0f + 1e-3f; - float offset_vec[3] = {1e-3f, 1e-3f, 1e-3f}; + const float offset_vec[3] = {1e-3f, 1e-3f, 1e-3f}; if (original) { BKE_pbvh_node_get_original_BB(pbvh->nodes, bb_min_root, bb_max_root); @@ -2617,7 +2605,7 @@ static PlaneAABBIsect test_frustum_aabb(const float bb_min[3], if (dot_v3v3(planes[i], vmin) + planes[i][3] < 0) { return ISECT_OUTSIDE; } - else if (dot_v3v3(planes[i], vmax) + planes[i][3] <= 0) { + if (dot_v3v3(planes[i], vmax) + planes[i][3] <= 0) { ret = ISECT_INTERSECT; } } diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c index e87c7c8d46d..a04fa1506d0 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.c +++ b/source/blender/blenkernel/intern/pbvh_bmesh.c @@ -184,14 +184,13 @@ static BMVert *bm_vert_hash_lookup_chain(GHash *deleted_verts, BMVert *v) /* not remapped*/ return v; } - else if (*v_next_p == NULL) { + if (*v_next_p == NULL) { /* removed and not remapped */ return NULL; } - else { - /* remapped */ - v = *v_next_p; - } + + /* remapped */ + v = *v_next_p; } } @@ -1738,9 +1737,8 @@ static void pbvh_bmesh_node_limit_ensure_fast( candidate = i_iter; break; } - else { - num_child2++; - } + + num_child2++; } if (candidate != -1) { diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 4b09f7542c7..ae18f3289e4 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -1404,9 +1404,8 @@ static int ptcache_dynamicpaint_totpoint(void *sd, int UNUSED(cfra)) if (!surface->data) { return 0; } - else { - return surface->data->total_points; - } + + return surface->data->total_points; } static void ptcache_dynamicpaint_error(void *UNUSED(sd), const char *UNUSED(message)) @@ -1511,7 +1510,7 @@ static int ptcache_rigidbody_write(int index, void *rb_v, void **data, int UNUSE if (ob && ob->rigidbody_object) { RigidBodyOb *rbo = ob->rigidbody_object; - if (rbo->type == RBO_TYPE_ACTIVE) { + if (rbo->type == RBO_TYPE_ACTIVE && rbo->shared->physics_object != NULL) { #ifdef WITH_BULLET RB_body_get_position(rbo->shared->physics_object, rbo->pos); RB_body_get_orientation(rbo->shared->physics_object, rbo->orn); @@ -2128,7 +2127,7 @@ static int ptcache_path(PTCacheID *pid, char *filename) return BLI_path_slash_ensure(filename); /* new strlen() */ } - else if (G.relbase_valid || lib) { + if (G.relbase_valid || lib) { char file[MAX_PTCACHE_PATH]; /* we don't want the dir, only the file */ BLI_split_file_part(blendfilename, file, sizeof(file)); @@ -2521,9 +2520,8 @@ int BKE_ptcache_mem_index_find(PTCacheMem *pm, unsigned int index) return -1; } - else { - return (index < pm->totpoint ? index : -1); - } + + return (index < pm->totpoint ? index : -1); } void BKE_ptcache_mem_pointers_init(PTCacheMem *pm) @@ -2627,10 +2625,10 @@ static int ptcache_old_elemsize(PTCacheID *pid) if (pid->type == PTCACHE_TYPE_SOFTBODY) { return 6 * sizeof(float); } - else if (pid->type == PTCACHE_TYPE_PARTICLES) { + if (pid->type == PTCACHE_TYPE_PARTICLES) { return sizeof(ParticleKey); } - else if (pid->type == PTCACHE_TYPE_CLOTH) { + if (pid->type == PTCACHE_TYPE_CLOTH) { return 9 * sizeof(float); } @@ -3585,16 +3583,15 @@ int BKE_ptcache_id_exist(PTCacheID *pid, int cfra) return BLI_exists(filename); } - else { - PTCacheMem *pm = pid->cache->mem_cache.first; - for (; pm; pm = pm->next) { - if (pm->frame == cfra) { - return 1; - } + PTCacheMem *pm = pid->cache->mem_cache.first; + + for (; pm; pm = pm->next) { + if (pm->frame == cfra) { + return 1; } - return 0; } + return 0; } void BKE_ptcache_id_time( PTCacheID *pid, Scene *scene, float cfra, int *startframe, int *endframe, float *timescale) diff --git a/source/blender/blenkernel/intern/pointcloud.c b/source/blender/blenkernel/intern/pointcloud.c index df5d93beccb..21889acba3c 100644 --- a/source/blender/blenkernel/intern/pointcloud.c +++ b/source/blender/blenkernel/intern/pointcloud.c @@ -169,8 +169,8 @@ BoundBox *BKE_pointcloud_boundbox_get(Object *ob) for (int a = 0; a < pointcloud->totpoint; a++) { float *co = pointcloud_co[a]; float radius = (pointcloud_radius) ? pointcloud_radius[a] : 0.0f; - float co_min[3] = {co[0] - radius, co[1] - radius, co[2] - radius}; - float co_max[3] = {co[0] + radius, co[1] + radius, co[2] + radius}; + const float co_min[3] = {co[0] - radius, co[1] - radius, co[2] - radius}; + const float co_max[3] = {co[0] + radius, co[1] + radius, co[2] + radius}; DO_MIN(co_min, min); DO_MAX(co_max, max); } diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index 4752782eaeb..ece7d0f9136 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -466,10 +466,10 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob) return shape; } -/* Create new physics sim collision shape for object and store it, - * or remove the existing one first and replace... +/* Helper function to create physics collision shape for object. + * Returns a new collision shape. */ -static void rigidbody_validate_sim_shape(Object *ob, bool rebuild) +static rbCollisionShape *rigidbody_validate_sim_shape_helper(RigidBodyWorld *rbw, Object *ob) { RigidBodyOb *rbo = ob->rigidbody_object; rbCollisionShape *new_shape = NULL; @@ -484,12 +484,7 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild) /* sanity check */ if (rbo == NULL) { - return; - } - - /* don't create a new shape if we already have one and don't want to rebuild it */ - if (rbo->shared->physics_shape && !rebuild) { - return; + return NULL; } /* if automatically determining dimensions, use the Object's boundbox @@ -539,7 +534,7 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild) break; case RB_SHAPE_CONVEXH: - /* try to emged collision margin */ + /* try to embed collision margin */ has_volume = (MIN3(size[0], size[1], size[2]) > 0.0f); if (!(rbo->flag & RBO_FLAG_USE_MARGIN) && has_volume) { @@ -555,18 +550,69 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild) case RB_SHAPE_TRIMESH: new_shape = rigidbody_get_shape_trimesh_from_mesh(ob); break; + case RB_SHAPE_COMPOUND: + new_shape = RB_shape_new_compound(); + rbCollisionShape *childShape = NULL; + float loc[3], rot[4]; + float mat[4][4]; + /* Add children to the compound shape */ + FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, childObject) { + if (childObject->parent == ob) { + childShape = rigidbody_validate_sim_shape_helper(rbw, childObject); + if (childShape) { + BKE_object_matrix_local_get(childObject, mat); + mat4_to_loc_quat(loc, rot, mat); + RB_compound_add_child_shape(new_shape, childShape, loc, rot); + } + } + } + FOREACH_COLLECTION_OBJECT_RECURSIVE_END; + + break; } - /* use box shape if we can't fall back to old shape */ - if (new_shape == NULL && rbo->shared->physics_shape == NULL) { + /* use box shape if it failed to create new shape */ + if (new_shape == NULL) { new_shape = RB_shape_new_box(size[0], size[1], size[2]); } + if (new_shape) { + RB_shape_set_margin(new_shape, RBO_GET_MARGIN(rbo)); + } + + return new_shape; +} + +/* Create new physics sim collision shape for object and store it, + * or remove the existing one first and replace... + */ +static void rigidbody_validate_sim_shape(RigidBodyWorld *rbw, Object *ob, bool rebuild) +{ + RigidBodyOb *rbo = ob->rigidbody_object; + rbCollisionShape *new_shape = NULL; + + /* sanity check */ + if (rbo == NULL) { + return; + } + + /* don't create a new shape if we already have one and don't want to rebuild it */ + if (rbo->shared->physics_shape && !rebuild) { + return; + } + + /* Also don't create a shape if this object is parent of a compound shape */ + if (ob->parent != NULL && ob->parent->rigidbody_object != NULL && + ob->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND) { + return; + } + + new_shape = rigidbody_validate_sim_shape_helper(rbw, ob); + /* assign new collision shape if creation was successful */ if (new_shape) { if (rbo->shared->physics_shape) { RB_shape_delete(rbo->shared->physics_shape); } rbo->shared->physics_shape = new_shape; - RB_shape_set_margin(rbo->shared->physics_shape, RBO_GET_MARGIN(rbo)); } } @@ -750,7 +796,7 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool /* FIXME we shouldn't always have to rebuild collision shapes when rebuilding objects, * but it's needed for constraints to update correctly. */ if (rbo->shared->physics_shape == NULL || rebuild) { - rigidbody_validate_sim_shape(ob, true); + rigidbody_validate_sim_shape(rbw, ob, true); } if (rbo->shared->physics_object) { @@ -760,6 +806,12 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool /* remove rigid body if it already exists before creating a new one */ if (rbo->shared->physics_object) { RB_body_delete(rbo->shared->physics_object); + rbo->shared->physics_object = NULL; + } + /* Don't create rigid body object if the parent is a compound shape */ + if (ob->parent != NULL && ob->parent->rigidbody_object != NULL && + ob->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND) { + return; } mat4_to_loc_quat(loc, rot, ob->obmat); @@ -793,7 +845,7 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED); } - if (rbw && rbw->shared->physics_world) { + if (rbw && rbw->shared->physics_world && rbo->shared->physics_object) { RB_dworld_add_body(rbw->shared->physics_world, rbo->shared->physics_object, rbo->col_groups); } } @@ -1179,9 +1231,12 @@ RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type) * - object must exist * - cannot add rigid body if it already exists */ - if (ob == NULL || (ob->rigidbody_object != NULL)) { + if (ob == NULL) { return NULL; } + if (ob->rigidbody_object != NULL) { + return ob->rigidbody_object; + } /* create new settings data, and link it up */ rbo = MEM_callocN(sizeof(RigidBodyOb), "RigidBodyOb"); @@ -1530,7 +1585,11 @@ static void rigidbody_update_ob_array(RigidBodyWorld *rbw) int n = 0; FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, object) { (void)object; - n++; + /* Ignore if this object is the direct child of an object with a compound shape */ + if (object->parent == NULL || object->parent->rigidbody_object == NULL || + object->parent->rigidbody_object->shape != RB_SHAPE_COMPOUND) { + n++; + } } FOREACH_COLLECTION_OBJECT_RECURSIVE_END; @@ -1541,8 +1600,12 @@ static void rigidbody_update_ob_array(RigidBodyWorld *rbw) int i = 0; FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, object) { - rbw->objects[i] = object; - i++; + /* Ignore if this object is the direct child of an object with a compound shape */ + if (object->parent == NULL || object->parent->rigidbody_object == NULL || + object->parent->rigidbody_object->shape != RB_SHAPE_COMPOUND) { + rbw->objects[i] = object; + i++; + } } FOREACH_COLLECTION_OBJECT_RECURSIVE_END; } @@ -1754,11 +1817,13 @@ static void rigidbody_update_simulation(Depsgraph *depsgraph, /* refresh shape... */ if (rbo->flag & RBO_FLAG_NEEDS_RESHAPE) { /* mesh/shape data changed, so force shape refresh */ - rigidbody_validate_sim_shape(ob, true); + rigidbody_validate_sim_shape(rbw, ob, true); /* now tell RB sim about it */ /* XXX: we assume that this can only get applied for active/passive shapes * that will be included as rigidbodies. */ - RB_body_set_collision_shape(rbo->shared->physics_object, rbo->shared->physics_shape); + if (rbo->shared->physics_object != NULL && rbo->shared->physics_shape != NULL) { + RB_body_set_collision_shape(rbo->shared->physics_object, rbo->shared->physics_shape); + } } } rbo->flag &= ~(RBO_FLAG_NEEDS_VALIDATE | RBO_FLAG_NEEDS_RESHAPE); @@ -1817,7 +1882,8 @@ static void rigidbody_update_simulation_post_step(Depsgraph *depsgraph, RigidBod Base *base = BKE_view_layer_base_find(view_layer, ob); RigidBodyOb *rbo = ob->rigidbody_object; /* Reset kinematic state for transformed objects. */ - if (rbo && base && (base->flag & BASE_SELECTED) && (G.moving & G_TRANSFORM_OBJ)) { + if (rbo && base && (base->flag & BASE_SELECTED) && (G.moving & G_TRANSFORM_OBJ) && + rbo->shared->physics_object) { RB_body_set_kinematic_state(rbo->shared->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED); RB_body_set_mass(rbo->shared->physics_object, RBO_GET_MASS(rbo)); @@ -1840,8 +1906,13 @@ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) { RigidBodyOb *rbo = ob->rigidbody_object; + /* True if the shape of this object's parent is of type compound */ + bool obCompoundParent = (ob->parent != NULL && ob->parent->rigidbody_object != NULL && + ob->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND); + /* keep original transform for kinematic and passive objects */ - if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE) { + if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE || + obCompoundParent) { return; } @@ -1963,7 +2034,11 @@ void BKE_rigidbody_rebuild_world(Depsgraph *depsgraph, Scene *scene, float ctime int n = 0; FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, object) { (void)object; - n++; + /* Ignore if this object is the direct child of an object with a compound shape */ + if (object->parent == NULL || object->parent->rigidbody_object == NULL || + object->parent->rigidbody_object->shape != RB_SHAPE_COMPOUND) { + n++; + } } FOREACH_COLLECTION_OBJECT_RECURSIVE_END; @@ -2000,7 +2075,7 @@ void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime return; } /* make sure we don't go out of cache frame range */ - else if (ctime > endframe) { + if (ctime > endframe) { ctime = endframe; } @@ -2008,7 +2083,7 @@ void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime if (rbw->shared->physics_world == NULL && !(cache->flag & PTCACHE_BAKED)) { return; } - else if (rbw->objects == NULL) { + if (rbw->objects == NULL) { rigidbody_update_ob_array(rbw); } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 5ae2f4b9005..bdda03bab12 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -127,7 +127,7 @@ static void scene_init_data(ID *id) mblur_shutter_curve = &scene->r.mblur_shutter_curve; BKE_curvemapping_set_defaults(mblur_shutter_curve, 1, 0.0f, 0.0f, 1.0f, 1.0f); - BKE_curvemapping_initialize(mblur_shutter_curve); + BKE_curvemapping_init(mblur_shutter_curve); BKE_curvemap_reset(mblur_shutter_curve->cm, &mblur_shutter_curve->clipr, CURVE_PRESET_MAX, @@ -140,13 +140,13 @@ static void scene_init_data(ID *id) /* grease pencil multiframe falloff curve */ scene->toolsettings->gp_sculpt.cur_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); CurveMapping *gp_falloff_curve = scene->toolsettings->gp_sculpt.cur_falloff; - BKE_curvemapping_initialize(gp_falloff_curve); + BKE_curvemapping_init(gp_falloff_curve); BKE_curvemap_reset( gp_falloff_curve->cm, &gp_falloff_curve->clipr, CURVE_PRESET_GAUSS, CURVEMAP_SLOPE_POSITIVE); scene->toolsettings->gp_sculpt.cur_primitive = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); CurveMapping *gp_primitive_curve = scene->toolsettings->gp_sculpt.cur_primitive; - BKE_curvemapping_initialize(gp_primitive_curve); + BKE_curvemapping_init(gp_primitive_curve); BKE_curvemap_reset(gp_primitive_curve->cm, &gp_primitive_curve->clipr, CURVE_PRESET_BELL, @@ -839,83 +839,78 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type) return sce_copy; } - else { - eDupli_ID_Flags duplicate_flags = U.dupflag | USER_DUP_OBJECT; - BKE_id_copy(bmain, (ID *)sce, (ID **)&sce_copy); - id_us_min(&sce_copy->id); - id_us_ensure_real(&sce_copy->id); + eDupli_ID_Flags duplicate_flags = U.dupflag | USER_DUP_OBJECT; - BKE_animdata_duplicate_id_action(bmain, &sce_copy->id, duplicate_flags); + BKE_id_copy(bmain, (ID *)sce, (ID **)&sce_copy); + id_us_min(&sce_copy->id); + id_us_ensure_real(&sce_copy->id); - /* Extra actions, most notably SCE_FULL_COPY also duplicates several 'children' datablocks. */ + BKE_animdata_duplicate_id_action(bmain, &sce_copy->id, duplicate_flags); - if (type == SCE_COPY_FULL) { - /* Scene duplication is always root of duplication currently. */ - const bool is_subprocess = false; + /* Extra actions, most notably SCE_FULL_COPY also duplicates several 'children' datablocks. */ - if (!is_subprocess) { - BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false); - BKE_main_id_clear_newpoins(bmain); - /* In case root duplicated ID is linked, assume we want to get a local copy of it and - * duplicate all expected linked data. */ - if (ID_IS_LINKED(sce)) { - duplicate_flags |= USER_DUP_LINKED_ID; - } + if (type == SCE_COPY_FULL) { + /* Scene duplication is always root of duplication currently. */ + const bool is_subprocess = false; + + if (!is_subprocess) { + BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false); + BKE_main_id_clear_newpoins(bmain); + /* In case root duplicated ID is linked, assume we want to get a local copy of it and + * duplicate all expected linked data. */ + if (ID_IS_LINKED(sce)) { + duplicate_flags |= USER_DUP_LINKED_ID; } + } - /* Copy Freestyle LineStyle datablocks. */ - LISTBASE_FOREACH (ViewLayer *, view_layer_dst, &sce_copy->view_layers) { - LISTBASE_FOREACH ( - FreestyleLineSet *, lineset, &view_layer_dst->freestyle_config.linesets) { - BKE_id_copy_for_duplicate(bmain, (ID *)lineset->linestyle, duplicate_flags); - } + /* Copy Freestyle LineStyle datablocks. */ + LISTBASE_FOREACH (ViewLayer *, view_layer_dst, &sce_copy->view_layers) { + LISTBASE_FOREACH (FreestyleLineSet *, lineset, &view_layer_dst->freestyle_config.linesets) { + BKE_id_copy_for_duplicate(bmain, (ID *)lineset->linestyle, duplicate_flags); } + } - /* Full copy of world (included animations) */ - BKE_id_copy_for_duplicate(bmain, (ID *)sce->world, duplicate_flags); + /* Full copy of world (included animations) */ + BKE_id_copy_for_duplicate(bmain, (ID *)sce->world, duplicate_flags); - /* Full copy of GreasePencil. */ - BKE_id_copy_for_duplicate(bmain, (ID *)sce->gpd, duplicate_flags); + /* Full copy of GreasePencil. */ + BKE_id_copy_for_duplicate(bmain, (ID *)sce->gpd, duplicate_flags); - /* Deep-duplicate collections and objects (using preferences' settings for which sub-data to - * duplicate along the object itself). */ - BKE_collection_duplicate(bmain, - NULL, - sce_copy->master_collection, - duplicate_flags, - LIB_ID_DUPLICATE_IS_SUBPROCESS); + /* Deep-duplicate collections and objects (using preferences' settings for which sub-data to + * duplicate along the object itself). */ + BKE_collection_duplicate( + bmain, NULL, sce_copy->master_collection, duplicate_flags, LIB_ID_DUPLICATE_IS_SUBPROCESS); - if (!is_subprocess) { - /* This code will follow into all ID links using an ID tagged with LIB_TAG_NEW.*/ - BKE_libblock_relink_to_newid(&sce_copy->id); + if (!is_subprocess) { + /* This code will follow into all ID links using an ID tagged with LIB_TAG_NEW.*/ + BKE_libblock_relink_to_newid(&sce_copy->id); #ifndef NDEBUG - /* Call to `BKE_libblock_relink_to_newid` above is supposed to have cleared all those - * flags. */ - ID *id_iter; - FOREACH_MAIN_ID_BEGIN (bmain, id_iter) { - BLI_assert((id_iter->tag & LIB_TAG_NEW) == 0); - } - FOREACH_MAIN_ID_END; + /* Call to `BKE_libblock_relink_to_newid` above is supposed to have cleared all those + * flags. */ + ID *id_iter; + FOREACH_MAIN_ID_BEGIN (bmain, id_iter) { + BLI_assert((id_iter->tag & LIB_TAG_NEW) == 0); + } + FOREACH_MAIN_ID_END; #endif - /* Cleanup. */ - BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false); - BKE_main_id_clear_newpoins(bmain); + /* Cleanup. */ + BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false); + BKE_main_id_clear_newpoins(bmain); - BKE_main_collection_sync(bmain); - } + BKE_main_collection_sync(bmain); } - else { - /* Remove sequencer if not full copy */ - /* XXX Why in Hell? :/ */ - remove_sequencer_fcurves(sce_copy); - BKE_sequencer_editing_free(sce_copy, true); - } - - return sce_copy; } + else { + /* Remove sequencer if not full copy */ + /* XXX Why in Hell? :/ */ + remove_sequencer_fcurves(sce_copy); + BKE_sequencer_editing_free(sce_copy, true); + } + + return sce_copy; } void BKE_scene_groups_relink(Scene *sce) @@ -1642,7 +1637,7 @@ bool BKE_scene_remove_render_view(Scene *scene, SceneRenderView *srv) if (act == -1) { return false; } - else if (scene->r.views.first == scene->r.views.last) { + if (scene->r.views.first == scene->r.views.last) { /* ensure 1 view is kept */ return false; } @@ -1663,13 +1658,11 @@ int get_render_subsurf_level(const RenderData *r, int lvl, bool for_render) if (for_render) { return min_ii(r->simplify_subsurf_render, lvl); } - else { - return min_ii(r->simplify_subsurf, lvl); - } - } - else { - return lvl; + + return min_ii(r->simplify_subsurf, lvl); } + + return lvl; } int get_render_child_particle_number(const RenderData *r, int num, bool for_render) @@ -1678,13 +1671,11 @@ int get_render_child_particle_number(const RenderData *r, int num, bool for_rend if (for_render) { return (int)(r->simplify_particles_render * num); } - else { - return (int)(r->simplify_particles * num); - } - } - else { - return num; + + return (int)(r->simplify_particles * num); } + + return num; } /** @@ -1699,7 +1690,7 @@ Base *_setlooper_base_step(Scene **sce_iter, ViewLayer *view_layer, Base *base) /* Common case, step to the next. */ return base->next; } - else if ((base == NULL) && (view_layer != NULL)) { + if ((base == NULL) && (view_layer != NULL)) { /* First time looping, return the scenes first base. */ /* For the first loop we should get the layer from workspace when available. */ if (view_layer->object_bases.first) { @@ -2018,9 +2009,8 @@ const char *BKE_scene_multiview_render_view_name_get(const RenderData *rd, const if (srv) { return srv->name; } - else { - return ""; - } + + return ""; } int BKE_scene_multiview_view_id_get(const RenderData *rd, const char *viewname) @@ -2041,9 +2031,8 @@ int BKE_scene_multiview_view_id_get(const RenderData *rd, const char *viewname) if (STREQ(viewname, srv->name)) { return nr; } - else { - nr += 1; - } + + nr += 1; } } @@ -2094,9 +2083,8 @@ const char *BKE_scene_multiview_view_suffix_get(const RenderData *rd, const char if (srv) { return srv->suffix; } - else { - return viewname; - } + + return viewname; } const char *BKE_scene_multiview_view_id_suffix_get(const RenderData *rd, const int view_id) @@ -2104,10 +2092,9 @@ const char *BKE_scene_multiview_view_id_suffix_get(const RenderData *rd, const i if ((rd->scemode & R_MULTIVIEW) == 0) { return ""; } - else { - const char *viewname = BKE_scene_multiview_render_view_name_get(rd, view_id); - return BKE_scene_multiview_view_suffix_get(rd, viewname); - } + + const char *viewname = BKE_scene_multiview_render_view_name_get(rd, view_id); + return BKE_scene_multiview_view_suffix_get(rd, viewname); } void BKE_scene_multiview_view_prefix_get(Scene *scene, @@ -2175,10 +2162,9 @@ int BKE_scene_multiview_num_videos_get(const RenderData *rd) if (rd->im_format.views_format == R_IMF_VIEWS_STEREO_3D) { return 1; } - else { - /* R_IMF_VIEWS_INDIVIDUAL */ - return BKE_scene_multiview_num_views_get(rd); - } + + /* R_IMF_VIEWS_INDIVIDUAL */ + return BKE_scene_multiview_num_views_get(rd); } /* Manipulation of depsgraph storage. */ diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c index 5c2d5b0087f..be35c7b161b 100644 --- a/source/blender/blenkernel/intern/seqcache.c +++ b/source/blender/blenkernel/intern/seqcache.c @@ -483,10 +483,9 @@ static size_t deflate_imbuf_to_file(ImBuf *ibuf, return BLI_gzip_mem_to_file_at_pos( ibuf->rect, header_entry->size_raw, file, header_entry->offset, level); } - else { - return BLI_gzip_mem_to_file_at_pos( - ibuf->rect_float, header_entry->size_raw, file, header_entry->offset, level); - } + + return BLI_gzip_mem_to_file_at_pos( + ibuf->rect_float, header_entry->size_raw, file, header_entry->offset, level); } static size_t inflate_file_to_imbuf(ImBuf *ibuf, FILE *file, DiskCacheHeaderEntry *header_entry) @@ -495,10 +494,9 @@ static size_t inflate_file_to_imbuf(ImBuf *ibuf, FILE *file, DiskCacheHeaderEntr return BLI_ungzip_file_to_mem_at_pos( ibuf->rect, header_entry->size_raw, file, header_entry->offset); } - else { - return BLI_ungzip_file_to_mem_at_pos( - ibuf->rect_float, header_entry->size_raw, file, header_entry->offset); - } + + return BLI_ungzip_file_to_mem_at_pos( + ibuf->rect_float, header_entry->size_raw, file, header_entry->offset); } static void seq_disk_cache_read_header(FILE *file, DiskCacheHeader *header) @@ -1304,11 +1302,10 @@ bool BKE_sequencer_cache_put_if_possible(const SeqRenderData *context, BKE_sequencer_cache_put(context, seq, cfra, type, ibuf, cost, skip_disk_cache); return true; } - else { - seq_cache_set_temp_cache_linked(scene, scene->ed->cache->last_key); - scene->ed->cache->last_key = NULL; - return false; - } + + seq_cache_set_temp_cache_linked(scene, scene->ed->cache->last_key); + scene->ed->cache->last_key = NULL; + return false; } void BKE_sequencer_cache_put(const SeqRenderData *context, diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index 4a2ad88bb28..55de375ce1e 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -3269,9 +3269,8 @@ float BKE_sequencer_speed_effect_target_frame_get(const SeqRenderData *context, if (input == 0) { /* Current frame. */ return floor(seq->start + s->frameMap[nr]); } - else { /* Next frame. */ - return ceil(seq->start + s->frameMap[nr]); - } + /* Next frame. */ + return ceil(seq->start + s->frameMap[nr]); } static float speed_effect_interpolation_ratio_get(SpeedControlVars *s, Sequence *seq, float cfra) @@ -4024,7 +4023,7 @@ static int early_out_fade(Sequence *UNUSED(seq), float facf0, float facf1) if (facf0 == 0.0f && facf1 == 0.0f) { return EARLY_USE_INPUT_1; } - else if (facf0 == 1.0f && facf1 == 1.0f) { + if (facf0 == 1.0f && facf1 == 1.0f) { return EARLY_USE_INPUT_2; } return EARLY_DO_EFFECT; diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c index a630170d6d5..a38fe252731 100644 --- a/source/blender/blenkernel/intern/seqmodifier.c +++ b/source/blender/blenkernel/intern/seqmodifier.c @@ -393,10 +393,10 @@ static void curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *m { CurvesModifierData *cmd = (CurvesModifierData *)smd; - float black[3] = {0.0f, 0.0f, 0.0f}; - float white[3] = {1.0f, 1.0f, 1.0f}; + const float black[3] = {0.0f, 0.0f, 0.0f}; + const float white[3] = {1.0f, 1.0f, 1.0f}; - BKE_curvemapping_initialize(&cmd->curve_mapping); + BKE_curvemapping_init(&cmd->curve_mapping); BKE_curvemapping_premultiply(&cmd->curve_mapping, 0); BKE_curvemapping_set_black_white(&cmd->curve_mapping, black, white); @@ -525,7 +525,7 @@ static void hue_correct_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImB { HueCorrectModifierData *hcmd = (HueCorrectModifierData *)smd; - BKE_curvemapping_initialize(&hcmd->curve_mapping); + BKE_curvemapping_init(&hcmd->curve_mapping); modifier_apply_threaded(ibuf, mask, hue_correct_apply_threaded, &hcmd->curve_mapping); } diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 5481cfe8193..6cdebcab904 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -1356,9 +1356,8 @@ const char *BKE_sequence_give_name(Sequence *seq) if (!(seq->type & SEQ_TYPE_EFFECT)) { return seq->strip->dir; } - else { - return "Effect"; - } + + return "Effect"; } return name; } @@ -1662,13 +1661,12 @@ static int seq_num_files(Scene *scene, char views_format, const bool is_multivie if (!is_multiview) { return 1; } - else if (views_format == R_IMF_VIEWS_STEREO_3D) { + if (views_format == R_IMF_VIEWS_STEREO_3D) { return 1; } /* R_IMF_VIEWS_INDIVIDUAL */ - else { - return BKE_scene_multiview_num_views_get(&scene->r); - } + + return BKE_scene_multiview_num_views_get(&scene->r); } static void seq_proxy_index_dir_set(struct anim *anim, const char *base_dir) @@ -1959,9 +1957,8 @@ static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int c return ibuf; } - else { - return NULL; - } + + return NULL; } static void seq_proxy_build_frame(const SeqRenderData *context, @@ -2056,9 +2053,8 @@ static bool seq_proxy_multiview_context_invalid(Sequence *seq, Scene *scene, con if (BLI_access(str, R_OK) == 0) { return false; } - else { - return view_id != 0; - } + + return view_id != 0; } return false; } @@ -2426,7 +2422,7 @@ static void color_balance_byte_float(StripColorBalance *cb_, while (p < e) { if (m) { - float t[3] = {m[0] / 255.0f, m[1] / 255.0f, m[2] / 255.0f}; + const float t[3] = {m[0] / 255.0f, m[1] / 255.0f, m[2] / 255.0f}; p[0] = p[0] * (1.0f - t[0]) + t[0] * cb_tab[0][p[0]]; p[1] = p[1] * (1.0f - t[1]) + t[1] * cb_tab[1][p[1]]; @@ -3351,35 +3347,34 @@ static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr if (!mask) { return NULL; } - else { - AnimData *adt; - Mask *mask_temp; - MaskRasterHandle *mr_handle; - mask_temp = BKE_mask_copy_nolib(mask); + AnimData *adt; + Mask *mask_temp; + MaskRasterHandle *mr_handle; - BKE_mask_evaluate(mask_temp, mask->sfra + nr, true); + mask_temp = BKE_mask_copy_nolib(mask); - /* anim-data */ - adt = BKE_animdata_from_id(&mask->id); - const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct( - context->depsgraph, mask->sfra + nr); - BKE_animsys_evaluate_animdata(&mask_temp->id, adt, &anim_eval_context, ADT_RECALC_ANIM, false); + BKE_mask_evaluate(mask_temp, mask->sfra + nr, true); - maskbuf = MEM_mallocN(sizeof(float) * context->rectx * context->recty, __func__); + /* anim-data */ + adt = BKE_animdata_from_id(&mask->id); + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct( + context->depsgraph, mask->sfra + nr); + BKE_animsys_evaluate_animdata(&mask_temp->id, adt, &anim_eval_context, ADT_RECALC_ANIM, false); - mr_handle = BKE_maskrasterize_handle_new(); + maskbuf = MEM_mallocN(sizeof(float) * context->rectx * context->recty, __func__); - BKE_maskrasterize_handle_init( - mr_handle, mask_temp, context->rectx, context->recty, true, true, true); + mr_handle = BKE_maskrasterize_handle_new(); - BKE_mask_free(mask_temp); - MEM_freeN(mask_temp); + BKE_maskrasterize_handle_init( + mr_handle, mask_temp, context->rectx, context->recty, true, true, true); - BKE_maskrasterize_buffer(mr_handle, context->rectx, context->recty, maskbuf); + BKE_mask_free(mask_temp); + MEM_freeN(mask_temp); - BKE_maskrasterize_handle_free(mr_handle); - } + BKE_maskrasterize_buffer(mr_handle, context->rectx, context->recty, maskbuf); + + BKE_maskrasterize_handle_free(mr_handle); if (make_float) { /* pixels */ @@ -3823,9 +3818,8 @@ static float seq_estimate_render_cost_end(Scene *scene, clock_t begin) if (time_max != 0) { return time_spent / time_max; } - else { - return 1; - } + + return 1; } static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context, @@ -3926,7 +3920,7 @@ static int seq_get_early_out_for_blend_mode(Sequence *seq) if (early_out == EARLY_USE_INPUT_2) { return EARLY_USE_INPUT_1; } - else if (early_out == EARLY_USE_INPUT_1) { + if (early_out == EARLY_USE_INPUT_1) { return EARLY_USE_INPUT_2; } } @@ -4429,9 +4423,8 @@ int BKE_sequence_tx_get_final_left(Sequence *seq, bool metaclip) return max_ii(BKE_sequence_tx_get_final_left(seq, false), BKE_sequence_tx_get_final_left((Sequence *)seq->tmp, true)); } - else { - return (seq->start - seq->startstill) + seq->startofs; - } + + return (seq->start - seq->startstill) + seq->startofs; } int BKE_sequence_tx_get_final_right(Sequence *seq, bool metaclip) { @@ -4440,9 +4433,8 @@ int BKE_sequence_tx_get_final_right(Sequence *seq, bool metaclip) return min_ii(BKE_sequence_tx_get_final_right(seq, false), BKE_sequence_tx_get_final_right((Sequence *)seq->tmp, true)); } - else { - return ((seq->start + seq->len) + seq->endstill) - seq->endofs; - } + + return ((seq->start + seq->len) + seq->endstill) - seq->endofs; } void BKE_sequence_tx_set_final_left(Sequence *seq, int val) @@ -4734,9 +4726,8 @@ bool BKE_sequence_base_shuffle_ex(ListBase *seqbasep, BKE_sequence_calc(evil_scene, test); return false; } - else { - return true; - } + + return true; } bool BKE_sequence_base_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_scene) @@ -4981,7 +4972,7 @@ ListBase *BKE_sequence_seqbase(ListBase *seqbase, Sequence *seq) if (seq == iseq) { return seqbase; } - else if (iseq->seqbase.first && (lb = BKE_sequence_seqbase(&iseq->seqbase, seq))) { + if (iseq->seqbase.first && (lb = BKE_sequence_seqbase(&iseq->seqbase, seq))) { return lb; } } @@ -4999,7 +4990,7 @@ Sequence *BKE_sequence_metastrip(ListBase *seqbase, Sequence *meta, Sequence *se if (seq == iseq) { return meta; } - else if (iseq->seqbase.first && (rval = BKE_sequence_metastrip(&iseq->seqbase, iseq, seq))) { + if (iseq->seqbase.first && (rval = BKE_sequence_metastrip(&iseq->seqbase, iseq, seq))) { return rval; } } @@ -5184,8 +5175,8 @@ Sequence *BKE_sequence_get_by_name(ListBase *seqbase, const char *name, bool rec if (STREQ(name, iseq->name + 2)) { return iseq; } - else if (recursive && (iseq->seqbase.first) && - (rseq = BKE_sequence_get_by_name(&iseq->seqbase, name, 1))) { + if (recursive && (iseq->seqbase.first) && + (rseq = BKE_sequence_get_by_name(&iseq->seqbase, name, 1))) { return rseq; } } @@ -5207,7 +5198,7 @@ Sequence *BKE_sequencer_from_elem(ListBase *seqbase, StripElem *se) (ARRAY_HAS_ITEM(se, iseq->strip->stripdata, iseq->len))) { break; } - else if ((seq_found = BKE_sequencer_from_elem(&iseq->seqbase, se))) { + if ((seq_found = BKE_sequencer_from_elem(&iseq->seqbase, se))) { iseq = seq_found; break; } @@ -5247,24 +5238,22 @@ int BKE_sequencer_active_get_pair(Scene *scene, Sequence **seq_act, Sequence **s if (*seq_act == NULL) { return 0; } - else { - Sequence *seq; - *seq_other = NULL; + Sequence *seq; - for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if (seq->flag & SELECT && (seq != (*seq_act))) { - if (*seq_other) { - return 0; - } - else { - *seq_other = seq; - } + *seq_other = NULL; + + for (seq = ed->seqbasep->first; seq; seq = seq->next) { + if (seq->flag & SELECT && (seq != (*seq_act))) { + if (*seq_other) { + return 0; } - } - return (*seq_other != NULL); + *seq_other = seq; + } } + + return (*seq_other != NULL); } Mask *BKE_sequencer_mask_get(Scene *scene) @@ -5274,9 +5263,8 @@ Mask *BKE_sequencer_mask_get(Scene *scene) if (seq_act && seq_act->type == SEQ_TYPE_MASK) { return seq_act->mask; } - else { - return NULL; - } + + return NULL; } /* api like funcs for adding */ @@ -6082,6 +6070,64 @@ bool BKE_sequencer_render_loop_check(Sequence *seq_main, Sequence *seq) return false; } +static void sequencer_flag_users_for_removal(Scene *scene, ListBase *seqbase, Sequence *seq) +{ + LISTBASE_FOREACH (Sequence *, user_seq, seqbase) { + /* Look in metas for usage of seq. */ + if (user_seq->type == SEQ_TYPE_META) { + sequencer_flag_users_for_removal(scene, &user_seq->seqbase, seq); + } + + /* Clear seq from modifiers. */ + SequenceModifierData *smd; + for (smd = user_seq->modifiers.first; smd; smd = smd->next) { + if (smd->mask_sequence == seq) { + smd->mask_sequence = NULL; + } + } + + /* Remove effects, that use seq. */ + if ((user_seq->seq1 && user_seq->seq1 == seq) || (user_seq->seq2 && user_seq->seq2 == seq) || + (user_seq->seq3 && user_seq->seq3 == seq)) { + user_seq->flag |= SEQ_FLAG_DELETE; + /* Strips can be used as mask even if not in same seqbase. */ + sequencer_flag_users_for_removal(scene, &scene->ed->seqbase, user_seq); + } + } +} + +/* Flag seq and its users (effects) for removal. */ +void BKE_sequencer_flag_for_removal(Scene *scene, ListBase *seqbase, Sequence *seq) +{ + if (seq == NULL || (seq->flag & SEQ_FLAG_DELETE) != 0) { + return; + } + + /* Flag and remove meta children. */ + if (seq->type == SEQ_TYPE_META) { + LISTBASE_FOREACH (Sequence *, meta_child, &seq->seqbase) { + BKE_sequencer_flag_for_removal(scene, &seq->seqbase, meta_child); + } + } + + seq->flag |= SEQ_FLAG_DELETE; + sequencer_flag_users_for_removal(scene, seqbase, seq); +} + +/* Remove all flagged sequences, return true if sequence is removed. */ +void BKE_sequencer_remove_flagged_sequences(Scene *scene, ListBase *seqbase) +{ + LISTBASE_FOREACH_MUTABLE (Sequence *, seq, seqbase) { + if (seq->flag & SEQ_FLAG_DELETE) { + if (seq->type == SEQ_TYPE_META) { + BKE_sequencer_remove_flagged_sequences(scene, &seq->seqbase); + } + BLI_remlink(seqbase, seq); + BKE_sequence_free(scene, seq, true); + } + } +} + void BKE_sequencer_check_uuids_unique_and_report(const Scene *scene) { if (scene->ed == NULL) { diff --git a/source/blender/blenkernel/intern/shader_fx.c b/source/blender/blenkernel/intern/shader_fx.c index 2923298c5d5..b3d350f5ccd 100644 --- a/source/blender/blenkernel/intern/shader_fx.c +++ b/source/blender/blenkernel/intern/shader_fx.c @@ -160,9 +160,8 @@ const ShaderFxTypeInfo *BKE_shaderfx_get_info(ShaderFxType type) if (type < NUM_SHADER_FX_TYPES && type > 0 && shader_fx_types[type]->name[0] != '\0') { return shader_fx_types[type]; } - else { - return NULL; - } + + return NULL; } /** diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 29f4c7dc6c1..0ff5bdda9e9 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -136,30 +136,29 @@ bool BKE_shrinkwrap_init_tree( return data->bvh != NULL; } - else { - if (mesh->totpoly <= 0) { - return false; - } - data->bvh = BKE_bvhtree_from_mesh_get(&data->treeData, mesh, BVHTREE_FROM_LOOPTRI, 4); + if (mesh->totpoly <= 0) { + return false; + } - if (data->bvh == NULL) { - return false; - } + data->bvh = BKE_bvhtree_from_mesh_get(&data->treeData, mesh, BVHTREE_FROM_LOOPTRI, 4); - if (force_normals || BKE_shrinkwrap_needs_normals(shrinkType, shrinkMode)) { - data->pnors = CustomData_get_layer(&mesh->pdata, CD_NORMAL); - if ((mesh->flag & ME_AUTOSMOOTH) != 0) { - data->clnors = CustomData_get_layer(&mesh->ldata, CD_NORMAL); - } - } + if (data->bvh == NULL) { + return false; + } - if (shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) { - data->boundary = mesh->runtime.shrinkwrap_data; + if (force_normals || BKE_shrinkwrap_needs_normals(shrinkType, shrinkMode)) { + data->pnors = CustomData_get_layer(&mesh->pdata, CD_NORMAL); + if ((mesh->flag & ME_AUTOSMOOTH) != 0) { + data->clnors = CustomData_get_layer(&mesh->ldata, CD_NORMAL); } + } - return true; + if (shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) { + data->boundary = mesh->runtime.shrinkwrap_data; } + + return true; } /* Frees the tree data if necessary. */ @@ -761,7 +760,7 @@ static void target_project_tri_deviation(void *userdata, const float x[3], float { TargetProjectTriData *data = userdata; - float w[3] = {x[0], x[1], 1.0f - x[0] - x[1]}; + const float w[3] = {x[0], x[1], 1.0f - x[0] - x[1]}; interp_v3_v3v3v3(data->co_interp, data->vtri_co[0], data->vtri_co[1], data->vtri_co[2], w); interp_v3_v3v3v3(data->no_interp, data->vtri_no[0], data->vtri_no[1], data->vtri_no[2], w); diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc index 95340e4e29c..c0fc8fcb464 100644 --- a/source/blender/blenkernel/intern/simulation.cc +++ b/source/blender/blenkernel/intern/simulation.cc @@ -112,8 +112,8 @@ static void simulation_copy_data(Main *bmain, ID *id_dst, const ID *id_src, cons BKE_simulation_state_copy_data(state_src, state_dst); } - BLI_duplicatelist(&simulation_dst->persistent_data_handles, - &simulation_src->persistent_data_handles); + BLI_listbase_clear(&simulation_dst->dependencies); + BLI_duplicatelist(&simulation_dst->dependencies, &simulation_src->dependencies); } static void simulation_free_data(ID *id) @@ -130,7 +130,7 @@ static void simulation_free_data(ID *id) BKE_simulation_state_remove_all(simulation); - BLI_freelistN(&simulation->persistent_data_handles); + BLI_freelistN(&simulation->dependencies); } static void simulation_foreach_id(ID *id, LibraryForeachIDData *data) @@ -140,9 +140,8 @@ static void simulation_foreach_id(ID *id, LibraryForeachIDData *data) /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */ BKE_library_foreach_ID_embedded(data, (ID **)&simulation->nodetree); } - LISTBASE_FOREACH ( - PersistentDataHandleItem *, handle_item, &simulation->persistent_data_handles) { - BKE_LIB_FOREACHID_PROCESS_ID(data, handle_item->id, IDWALK_CB_USER); + LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) { + BKE_LIB_FOREACHID_PROCESS_ID(data, dependency->id, IDWALK_CB_USER); } } @@ -284,6 +283,14 @@ void BKE_simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulation * blender::sim::update_simulation_in_depsgraph(depsgraph, scene, simulation); } +void BKE_simulation_update_dependencies(Simulation *simulation, Main *bmain) +{ + bool dependencies_changed = blender::sim::update_simulation_dependencies(simulation); + if (dependencies_changed) { + DEG_relations_tag_update(bmain); + } +} + using StateTypeMap = blender::Map<std::string, std::unique_ptr<SimulationStateType>>; template<typename T> diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index b7b325644ca..1d56db3779a 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -1051,7 +1051,7 @@ static int sb_detect_aabb_collisionCached(float UNUSED(force[3]), /* --- the aabb section*/ /* +++ the face external section*/ -static int sb_detect_face_pointCached(float face_v1[3], +static int sb_detect_face_pointCached(const float face_v1[3], const float face_v2[3], const float face_v3[3], float *damp, @@ -1149,7 +1149,7 @@ static int sb_detect_face_pointCached(float face_v1[3], return deflected; } -static int sb_detect_face_collisionCached(float face_v1[3], +static int sb_detect_face_collisionCached(const float face_v1[3], const float face_v2[3], const float face_v3[3], float *damp, @@ -1328,7 +1328,7 @@ static void scan_for_ext_face_forces(Object *ob, float timenow) /* +++ the spring external section*/ -static int sb_detect_edge_collisionCached(float edge_v1[3], +static int sb_detect_edge_collisionCached(const float edge_v1[3], const float edge_v2[3], float *damp, float force[3], @@ -3211,12 +3211,11 @@ static int object_has_edges(Object *ob) if (ob->type == OB_MESH) { return ((Mesh *)ob->data)->totedge; } - else if (ob->type == OB_LATTICE) { + if (ob->type == OB_LATTICE) { return 1; } - else { - return 0; - } + + return 0; } /* SB global visible functions */ @@ -3563,7 +3562,7 @@ void sbObjectStep(struct Depsgraph *depsgraph, BKE_ptcache_invalidate(cache); return; } - else if (framenr > endframe) { + if (framenr > endframe) { framenr = endframe; } @@ -3631,7 +3630,7 @@ void sbObjectStep(struct Depsgraph *depsgraph, return; } - else if (cache_result == PTCACHE_READ_OLD) { + if (cache_result == PTCACHE_READ_OLD) { /* pass */ } else if (/*ob->id.lib || */ diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 1fcfc9b060f..060174c94a5 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -898,9 +898,8 @@ double BKE_sound_sync_scene(Scene *scene) if (scene->audio.flag & AUDIO_SYNC) { return AUD_getSynchronizerPosition(scene->playback_handle); } - else { - return AUD_Handle_getPosition(scene->playback_handle); - } + + return AUD_Handle_getPosition(scene->playback_handle); } return NAN_FLT; } @@ -922,9 +921,8 @@ int BKE_sound_scene_playing(Scene *scene) if (scene->audio.flag & AUDIO_SYNC) { return AUD_isSynchronizerPlaying(); } - else { - return -1; - } + + return -1; } void BKE_sound_free_waveform(bSound *sound) diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c index 46341652544..68626bdc8dd 100644 --- a/source/blender/blenkernel/intern/studiolight.c +++ b/source/blender/blenkernel/intern/studiolight.c @@ -366,23 +366,22 @@ static float *studiolight_multilayer_convert_pass(ImBuf *ibuf, if (channels == 4) { return rect; } - else { - float *new_rect = MEM_callocN(sizeof(float[4]) * ibuf->x * ibuf->y, __func__); - - IMB_buffer_float_from_float(new_rect, - rect, - channels, - IB_PROFILE_LINEAR_RGB, - IB_PROFILE_LINEAR_RGB, - false, - ibuf->x, - ibuf->y, - ibuf->x, - ibuf->x); - MEM_freeN(rect); - return new_rect; - } + float *new_rect = MEM_callocN(sizeof(float[4]) * ibuf->x * ibuf->y, __func__); + + IMB_buffer_float_from_float(new_rect, + rect, + channels, + IB_PROFILE_LINEAR_RGB, + IB_PROFILE_LINEAR_RGB, + false, + ibuf->x, + ibuf->y, + ibuf->x, + ibuf->x); + + MEM_freeN(rect); + return new_rect; } static void studiolight_multilayer_addpass(void *base, @@ -1229,12 +1228,11 @@ static int studiolight_cmp(const void *a, const void *b) if (flagorder1 < flagorder2) { return -1; } - else if (flagorder1 > flagorder2) { + if (flagorder1 > flagorder2) { return 1; } - else { - return BLI_strcasecmp(sl1->name, sl2->name); - } + + return BLI_strcasecmp(sl1->name, sl2->name); } /* icons */ @@ -1245,7 +1243,7 @@ static int studiolight_cmp(const void *a, const void *b) static uint alpha_circle_mask(float u, float v, float inner_edge, float outer_edge) { /* Coords from center. */ - float co[2] = {u - 0.5f, v - 0.5f}; + const float co[2] = {u - 0.5f, v - 0.5f}; float dist = len_v2(co); float alpha = 1.0f + (inner_edge - dist) / (outer_edge - inner_edge); uint mask = (uint)floorf(255.0f * min_ff(max_ff(alpha, 0.0f), 1.0f)); @@ -1277,7 +1275,7 @@ static void studiolight_radiance_preview(uint *icon_buffer, StudioLight *sl) uint alphamask = alpha_circle_mask(dx, dy, 0.5f - texel_size[0], 0.5f); if (alphamask != 0) { float normal[3], direction[3], color[4]; - float incoming[3] = {0.0f, 0.0f, -1.0f}; + const float incoming[3] = {0.0f, 0.0f, -1.0f}; sphere_normal_from_uv(normal, dx, dy); reflect_v3_v3v3(direction, incoming, normal); /* We want to see horizon not poles. */ @@ -1496,10 +1494,9 @@ struct StudioLight *BKE_studiolight_find(const char *name, int flag) if ((sl->flag & flag)) { return sl; } - else { - /* flags do not match, so use default */ - return BKE_studiolight_find_default(flag); - } + + /* flags do not match, so use default */ + return BKE_studiolight_find_default(flag); } } /* When not found, use the default studio light */ diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c index bc1b79f62c5..c992990e0a0 100644 --- a/source/blender/blenkernel/intern/subdiv_ccg.c +++ b/source/blender/blenkernel/intern/subdiv_ccg.c @@ -1618,7 +1618,7 @@ static int prev_adjacent_edge_point_index(const SubdivCCG *subdiv_ccg, const int return point_index - 1; } -/* When the point index corresponds to a grid corner, returs the point index which corresponds to +/* When the point index corresponds to a grid corner, returns the point index which corresponds to * the corner of the adjacent grid, as the adjacent edge has two separate points for each grid * corner at the middle of the edge. */ static int adjacent_grid_corner_point_index_on_edge(const SubdivCCG *subdiv_ccg, @@ -1650,7 +1650,7 @@ static void neighbor_coords_edge_get(const SubdivCCG *subdiv_ccg, if (include_duplicates) { num_duplicates += num_adjacent_faces - 1; if (is_corner) { - /* When the coord is a grid corner, add an extra duplicate per adajacent grid in all adjacent + /* When the coord is a grid corner, add an extra duplicate per adjacent grid in all adjacent * faces to the edge. */ num_duplicates += num_adjacent_faces; } diff --git a/source/blender/blenkernel/intern/subdiv_displacement_multires.c b/source/blender/blenkernel/intern/subdiv_displacement_multires.c index 617f37834f9..a63c2994687 100644 --- a/source/blender/blenkernel/intern/subdiv_displacement_multires.c +++ b/source/blender/blenkernel/intern/subdiv_displacement_multires.c @@ -128,10 +128,10 @@ BLI_INLINE eAverageWith read_displacement_grid(const MDisps *displacement_grid, if (x == 0 && y == 0) { return AVERAGE_WITH_ALL; } - else if (x == 0) { + if (x == 0) { return AVERAGE_WITH_PREV; } - else if (y == 0) { + if (y == 0) { return AVERAGE_WITH_NEXT; } return AVERAGE_WITH_NONE; @@ -321,9 +321,8 @@ static int displacement_get_face_corner(MultiresDisplacementData *data, float dummy_corner_u, dummy_corner_v; return BKE_subdiv_rotate_quad_to_corner(u, v, &dummy_corner_u, &dummy_corner_v); } - else { - return poly_corner->corner; - } + + return poly_corner->corner; } static void initialize(SubdivDisplacement *displacement) diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c index 1c10a9a1935..baee8a80f5a 100644 --- a/source/blender/blenkernel/intern/subdiv_eval.c +++ b/source/blender/blenkernel/intern/subdiv_eval.c @@ -46,7 +46,7 @@ bool BKE_subdiv_eval_begin(Subdiv *subdiv) * or when OpenSubdiv is disabled */ return false; } - else if (subdiv->evaluator == NULL) { + if (subdiv->evaluator == NULL) { BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE); subdiv->evaluator = openSubdiv_createEvaluatorFromTopologyRefiner(subdiv->topology_refiner); BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE); diff --git a/source/blender/blenkernel/intern/subdiv_foreach.c b/source/blender/blenkernel/intern/subdiv_foreach.c index ff7f6fad5f0..37cca12721a 100644 --- a/source/blender/blenkernel/intern/subdiv_foreach.c +++ b/source/blender/blenkernel/intern/subdiv_foreach.c @@ -1040,7 +1040,7 @@ static void subdiv_foreach_boundary_edges(SubdivForeachTaskContext *ctx, static void rotate_indices(const int rot, int *a, int *b, int *c, int *d) { - int values[4] = {*a, *b, *c, *d}; + const int values[4] = {*a, *b, *c, *d}; *a = values[(0 - rot + 4) % 4]; *b = values[(1 - rot + 4) % 4]; *c = values[(2 - rot + 4) % 4]; @@ -1123,10 +1123,10 @@ static int subdiv_foreach_loops_corner_index(const float u, if (u + du <= 0.5f && v + dv <= 0.5f) { return 0; } - else if (u >= 0.5f && v + dv <= 0.5f) { + if (u >= 0.5f && v + dv <= 0.5f) { return 1; } - else if (u >= 0.5f && v >= 0.5f) { + if (u >= 0.5f && v >= 0.5f) { return 2; } return 3; diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 7a0a5645b80..98386a3356a 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -203,12 +203,11 @@ static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize) if (x == 0) { return v0idx; } - else if (x == edgeSize - 1) { + if (x == edgeSize - 1) { return v1idx; } - else { - return edgeBase + x - 1; - } + + return edgeBase + x - 1; } static int getFaceIndex( @@ -221,42 +220,39 @@ static int getFaceIndex( CCGVert *v = ccgSubSurf_getFaceVert(f, S); return *((int *)ccgSubSurf_getVertUserData(ss, v)); } - else if (x == gridSize - 1) { + if (x == gridSize - 1) { CCGVert *v = ccgSubSurf_getFaceVert(f, S); CCGEdge *e = ccgSubSurf_getFaceEdge(f, S); int edgeBase = *((int *)ccgSubSurf_getEdgeUserData(ss, e)); if (v == ccgSubSurf_getEdgeVert0(e)) { return edgeBase + (gridSize - 1 - y) - 1; } - else { - return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - y) - 1); - } + + return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - y) - 1); } - else if (y == gridSize - 1) { + if (y == gridSize - 1) { CCGVert *v = ccgSubSurf_getFaceVert(f, S); CCGEdge *e = ccgSubSurf_getFaceEdge(f, (S + numVerts - 1) % numVerts); int edgeBase = *((int *)ccgSubSurf_getEdgeUserData(ss, e)); if (v == ccgSubSurf_getEdgeVert0(e)) { return edgeBase + (gridSize - 1 - x) - 1; } - else { - return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - x) - 1); - } + + return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - x) - 1); } - else if (x == 0 && y == 0) { + if (x == 0 && y == 0) { return faceBase; } - else if (x == 0) { + if (x == 0) { S = (S + numVerts - 1) % numVerts; return faceBase + 1 + (gridSize - 2) * S + (y - 1); } - else if (y == 0) { + if (y == 0) { return faceBase + 1 + (gridSize - 2) * S + (x - 1); } - else { - return faceBase + 1 + (gridSize - 2) * numVerts + S * (gridSize - 2) * (gridSize - 2) + - (y - 1) * (gridSize - 2) + (x - 1); - } + + return faceBase + 1 + (gridSize - 2) * numVerts + S * (gridSize - 2) * (gridSize - 2) + + (y - 1) * (gridSize - 2) + (x - 1); } static void get_face_uv_map_vert( diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 5f85e1a1664..8a055423d6f 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -812,9 +812,8 @@ int txt_calc_tab_right(TextLine *tl, int ch) return i - ch; } - else { - return 0; - } + + return 0; } void txt_move_left(Text *text, const bool sel) @@ -1664,9 +1663,8 @@ int txt_find_string(Text *text, const char *findstr, int wrap, int match_case) txt_move_to(text, newl, newc + strlen(findstr), 1); return 1; } - else { - return 0; - } + + return 0; } /** \} */ @@ -1797,7 +1795,7 @@ void txt_delete_char(Text *text) txt_make_dirty(text); return; } - else if (text->curc == text->curl->len) { /* Appending two lines */ + if (text->curc == text->curl->len) { /* Appending two lines */ if (text->curl->next) { txt_combine_lines(text, text->curl, text->curl->next); txt_pop_sel(text); @@ -1844,7 +1842,7 @@ void txt_backspace_char(Text *text) txt_make_dirty(text); return; } - else if (text->curc == 0) { /* Appending two lines */ + if (text->curc == 0) { /* Appending two lines */ if (!text->curl->prev) { return; } @@ -2052,10 +2050,9 @@ static void txt_select_prefix(Text *text, const char *add, bool skip_blank_lines } break; } - else { - text->curl = text->curl->next; - num++; - } + + text->curl = text->curl->next; + num++; } while (num > 0) { @@ -2140,10 +2137,9 @@ static bool txt_select_unprefix(Text *text, const char *remove, const bool requi } break; } - else { - text->curl = text->curl->next; - num++; - } + + text->curl = text->curl->next; + num++; } if (unindented_first) { @@ -2253,9 +2249,8 @@ int txt_setcurr_tab_spaces(Text *text, int space) if (i == text->curc) { return i; } - else { - i++; - } + + i++; } if (strstr(text->curl->line, word)) { /* if we find a ':' on this line, then add a tab but not if it is: @@ -2270,7 +2265,7 @@ int txt_setcurr_tab_spaces(Text *text, int space) if (ch == '#') { break; } - else if (ch == ':') { + if (ch == ':') { is_indent = 1; } else if (ch != ' ' && ch != '\t') { @@ -2309,7 +2304,7 @@ int text_check_bracket(const char ch) if (ch == opens[a]) { return a + 1; } - else if (ch == close[a]) { + if (ch == close[a]) { return -(a + 1); } } diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index e2c3c20e36e..8d5a0497e28 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -664,11 +664,11 @@ bool BKE_texture_dependsOnTime(const struct Tex *texture) if (texture->ima && BKE_image_is_animated(texture->ima)) { return true; } - else if (texture->adt) { + if (texture->adt) { /* assume anything in adt means the texture is animated */ return true; } - else if (texture->type == TEX_NOISE) { + if (texture->type == TEX_NOISE) { /* noise always varies with time */ return true; } diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index f17467e4a26..8a1ebaf722b 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1188,38 +1188,36 @@ MovieTrackingMarker *BKE_tracking_marker_insert(MovieTrackingTrack *track, return old_marker; } - else { - int a = track->markersnr; - /* find position in array where to add new marker */ - while (a--) { - if (track->markers[a].framenr < marker->framenr) { - break; - } + int a = track->markersnr; + + /* find position in array where to add new marker */ + while (a--) { + if (track->markers[a].framenr < marker->framenr) { + break; } + } - track->markersnr++; + track->markersnr++; - if (track->markers) { - track->markers = MEM_reallocN(track->markers, - sizeof(MovieTrackingMarker) * track->markersnr); - } - else { - track->markers = MEM_callocN(sizeof(MovieTrackingMarker), "MovieTracking markers"); - } + if (track->markers) { + track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr); + } + else { + track->markers = MEM_callocN(sizeof(MovieTrackingMarker), "MovieTracking markers"); + } - /* shift array to "free" space for new marker */ - memmove(track->markers + a + 2, - track->markers + a + 1, - (track->markersnr - a - 2) * sizeof(MovieTrackingMarker)); + /* shift array to "free" space for new marker */ + memmove(track->markers + a + 2, + track->markers + a + 1, + (track->markersnr - a - 2) * sizeof(MovieTrackingMarker)); - /* put new marker */ - track->markers[a + 1] = *marker; + /* put new marker */ + track->markers[a + 1] = *marker; - track->last_marker = a + 1; + track->last_marker = a + 1; - return &track->markers[a + 1]; - } + return &track->markers[a + 1]; } void BKE_tracking_marker_delete(MovieTrackingTrack *track, int framenr) @@ -1337,21 +1335,20 @@ MovieTrackingMarker *BKE_tracking_marker_get(MovieTrackingTrack *track, int fram /* if there's no marker for exact position, use nearest marker from left side */ return &track->markers[a - 1]; } - else { - while (a >= 0 && track->markers[a].framenr >= framenr) { - if (track->markers[a].framenr == framenr) { - track->last_marker = a; - return &track->markers[a]; - } + while (a >= 0 && track->markers[a].framenr >= framenr) { + if (track->markers[a].framenr == framenr) { + track->last_marker = a; - a--; + return &track->markers[a]; } - /* if there's no marker for exact position, use nearest marker from left side */ - return &track->markers[a]; + a--; } + /* if there's no marker for exact position, use nearest marker from left side */ + return &track->markers[a]; + return NULL; } @@ -1655,32 +1652,31 @@ MovieTrackingPlaneMarker *BKE_tracking_plane_marker_insert(MovieTrackingPlaneTra return old_plane_marker; } - else { - int a = plane_track->markersnr; - /* Find position in array where to add new marker. */ - /* TODO(sergey): we could use bisect to speed things up. */ - while (a--) { - if (plane_track->markers[a].framenr < plane_marker->framenr) { - break; - } + int a = plane_track->markersnr; + + /* Find position in array where to add new marker. */ + /* TODO(sergey): we could use bisect to speed things up. */ + while (a--) { + if (plane_track->markers[a].framenr < plane_marker->framenr) { + break; } + } - plane_track->markersnr++; - plane_track->markers = MEM_reallocN(plane_track->markers, - sizeof(MovieTrackingPlaneMarker) * plane_track->markersnr); + plane_track->markersnr++; + plane_track->markers = MEM_reallocN(plane_track->markers, + sizeof(MovieTrackingPlaneMarker) * plane_track->markersnr); - /* Shift array to "free" space for new marker. */ - memmove(plane_track->markers + a + 2, - plane_track->markers + a + 1, - (plane_track->markersnr - a - 2) * sizeof(MovieTrackingPlaneMarker)); + /* Shift array to "free" space for new marker. */ + memmove(plane_track->markers + a + 2, + plane_track->markers + a + 1, + (plane_track->markersnr - a - 2) * sizeof(MovieTrackingPlaneMarker)); - /* Put new marker to an array. */ - plane_track->markers[a + 1] = *plane_marker; - plane_track->last_marker = a + 1; + /* Put new marker to an array. */ + plane_track->markers[a + 1] = *plane_marker; + plane_track->last_marker = a + 1; - return &plane_track->markers[a + 1]; - } + return &plane_track->markers[a + 1]; } void BKE_tracking_plane_marker_delete(MovieTrackingPlaneTrack *plane_track, int framenr) @@ -1748,21 +1744,20 @@ MovieTrackingPlaneMarker *BKE_tracking_plane_marker_get(MovieTrackingPlaneTrack /* If there's no marker for exact position, use nearest marker from left side. */ return &plane_track->markers[a - 1]; } - else { - while (a >= 0 && plane_track->markers[a].framenr >= framenr) { - if (plane_track->markers[a].framenr == framenr) { - plane_track->last_marker = a; - return &plane_track->markers[a]; - } + while (a >= 0 && plane_track->markers[a].framenr >= framenr) { + if (plane_track->markers[a].framenr == framenr) { + plane_track->last_marker = a; - a--; + return &plane_track->markers[a]; } - /* If there's no marker for exact position, use nearest marker from left side. */ - return &plane_track->markers[a]; + a--; } + /* If there's no marker for exact position, use nearest marker from left side. */ + return &plane_track->markers[a]; + return NULL; } @@ -1988,18 +1983,16 @@ static int reconstructed_camera_index_get(MovieTrackingReconstruction *reconstru if (nearest) { return 0; } - else { - return -1; - } + + return -1; } if (framenr > cameras[reconstruction->camnr - 1].framenr) { if (nearest) { return reconstruction->camnr - 1; } - else { - return -1; - } + + return -1; } if (reconstruction->last_camera < reconstruction->camnr) { @@ -2020,9 +2013,8 @@ static int reconstructed_camera_index_get(MovieTrackingReconstruction *reconstru if (nearest) { return a - 1; } - else { - break; - } + + break; } if (d < 0 && cfra < framenr) { @@ -2030,9 +2022,8 @@ static int reconstructed_camera_index_get(MovieTrackingReconstruction *reconstru if (nearest) { return a; } - else { - break; - } + + break; } if (cfra == framenr) { @@ -2705,9 +2696,8 @@ static int channels_alpha_sort(const void *a, const void *b) if (BLI_strcasecmp(channel_a->track->name, channel_b->track->name) > 0) { return 1; } - else { - return 0; - } + + return 0; } static int channels_total_track_sort(const void *a, const void *b) @@ -2718,9 +2708,8 @@ static int channels_total_track_sort(const void *a, const void *b) if (channel_a->total_frames > channel_b->total_frames) { return 1; } - else { - return 0; - } + + return 0; } static int channels_longest_segment_sort(const void *a, const void *b) @@ -2731,9 +2720,8 @@ static int channels_longest_segment_sort(const void *a, const void *b) if (channel_a->max_segment > channel_b->max_segment) { return 1; } - else { - return 0; - } + + return 0; } static int channels_average_error_sort(const void *a, const void *b) @@ -2744,9 +2732,8 @@ static int channels_average_error_sort(const void *a, const void *b) if (channel_a->track->error > channel_b->track->error) { return 1; } - else { - return 0; - } + + return 0; } static int channels_alpha_inverse_sort(const void *a, const void *b) @@ -2754,9 +2741,8 @@ static int channels_alpha_inverse_sort(const void *a, const void *b) if (channels_alpha_sort(a, b)) { return 0; } - else { - return 1; - } + + return 1; } static int channels_total_track_inverse_sort(const void *a, const void *b) @@ -2764,9 +2750,8 @@ static int channels_total_track_inverse_sort(const void *a, const void *b) if (channels_total_track_sort(a, b)) { return 0; } - else { - return 1; - } + + return 1; } static int channels_longest_segment_inverse_sort(const void *a, const void *b) @@ -2774,9 +2759,8 @@ static int channels_longest_segment_inverse_sort(const void *a, const void *b) if (channels_longest_segment_sort(a, b)) { return 0; } - else { - return 1; - } + + return 1; } static int channels_average_error_inverse_sort(const void *a, const void *b) @@ -2787,9 +2771,8 @@ static int channels_average_error_inverse_sort(const void *a, const void *b) if (channel_a->track->error < channel_b->track->error) { return 1; } - else { - return 0; - } + + return 0; } /* Calculate frames segments at which track is tracked continuously. */ @@ -2965,7 +2948,7 @@ static int coverage_from_count(int count) if (count < 8) { return TRACKING_COVERAGE_BAD; } - else if (count < 16) { + if (count < 16) { return TRACKING_COVERAGE_ACCEPTABLE; } return TRACKING_COVERAGE_OK; diff --git a/source/blender/blenkernel/intern/tracking_solver.c b/source/blender/blenkernel/intern/tracking_solver.c index 46870a03e62..7df8bf62b16 100644 --- a/source/blender/blenkernel/intern/tracking_solver.c +++ b/source/blender/blenkernel/intern/tracking_solver.c @@ -335,7 +335,7 @@ bool BKE_tracking_reconstruction_check(MovieTracking *tracking, /* TODO: check for number of tracks? */ return true; } - else if ((tracking->settings.reconstruction_flag & TRACKING_USE_KEYFRAME_SELECTION) == 0) { + if ((tracking->settings.reconstruction_flag & TRACKING_USE_KEYFRAME_SELECTION) == 0) { /* automatic keyframe selection does not require any pre-process checks */ if (reconstruct_count_tracks_on_both_keyframes(tracking, object) < 8) { BLI_strncpy(error_msg, diff --git a/source/blender/blenkernel/intern/tracking_stabilize.c b/source/blender/blenkernel/intern/tracking_stabilize.c index e09e92588c6..46e3e10b01b 100644 --- a/source/blender/blenkernel/intern/tracking_stabilize.c +++ b/source/blender/blenkernel/intern/tracking_stabilize.c @@ -215,7 +215,7 @@ static void use_values_from_fcurves(StabContext *ctx, bool toggle) /* Prepare per call private working area. * Used for access to possibly animated values: retrieve available F-curves. */ -static StabContext *initialize_stabilization_working_context(MovieClip *clip) +static StabContext *init_stabilization_working_context(MovieClip *clip) { StabContext *ctx = MEM_callocN(sizeof(StabContext), "2D stabilization animation runtime data"); ctx->clip = clip; @@ -357,9 +357,8 @@ static MovieTrackingMarker *get_closest_marker(StabContext *ctx, if ((next_higher - ref_frame) < (ref_frame - next_lower)) { return BKE_tracking_marker_get_exact(track, next_higher); } - else { - return BKE_tracking_marker_get_exact(track, next_lower); - } + + return BKE_tracking_marker_get_exact(track, next_lower); } /* Retrieve tracking data, if available and applicable for this frame. @@ -377,11 +376,10 @@ static MovieTrackingMarker *get_tracking_data_point(StabContext *ctx, *r_weight = get_animated_weight(ctx, track, framenr); return marker; } - else { - /* No marker at this frame (=gap) or marker disabled. */ - *r_weight = 0.0f; - return NULL; - } + + /* No marker at this frame (=gap) or marker disabled. */ + *r_weight = 0.0f; + return NULL; } /* Define the reference point for rotation/scale measurement and compensation. @@ -841,14 +839,14 @@ static int establish_track_initialization_order(StabContext *ctx, TrackInitOrder * * NOTE: when done, this track is marked as initialized */ -static void initialize_track_for_stabilization(StabContext *ctx, - MovieTrackingTrack *track, - int reference_frame, - float aspect, - const float average_translation[2], - const float pivot[2], - const float average_angle, - const float average_scale_step) +static void init_track_for_stabilization(StabContext *ctx, + MovieTrackingTrack *track, + int reference_frame, + float aspect, + const float average_translation[2], + const float pivot[2], + const float average_angle, + const float average_scale_step) { float pos[2], angle, len; TrackStabilizationBase *local_data = access_stabilization_baseline_data(ctx, track); @@ -876,7 +874,7 @@ static void initialize_track_for_stabilization(StabContext *ctx, local_data->is_init_for_stabilization = true; } -static void initialize_all_tracks(StabContext *ctx, float aspect) +static void init_all_tracks(StabContext *ctx, float aspect) { size_t track_len = 0; MovieClip *clip = ctx->clip; @@ -936,14 +934,14 @@ static void initialize_all_tracks(StabContext *ctx, float aspect) &average_angle, &average_scale_step); } - initialize_track_for_stabilization(ctx, - track, - reference_frame, - aspect, - average_translation, - pivot, - average_angle, - average_scale_step); + init_track_for_stabilization(ctx, + track, + reference_frame, + aspect, + average_translation, + pivot, + average_angle, + average_scale_step); } cleanup: @@ -1094,7 +1092,7 @@ static void stabilization_data_to_mat4(float pixel_aspect, { float translation_mat[4][4], rotation_mat[4][4], scale_mat[4][4], pivot_mat[4][4], inv_pivot_mat[4][4], aspect_mat[4][4], inv_aspect_mat[4][4]; - float scale_vector[3] = {scale, scale, 1.0f}; + const float scale_vector[3] = {scale, scale, 1.0f}; unit_m4(translation_mat); unit_m4(rotation_mat); @@ -1257,9 +1255,9 @@ static float calculate_autoscale_factor(StabContext *ctx, int size, float aspect */ static StabContext *init_stabilizer(MovieClip *clip, int size, float aspect) { - StabContext *ctx = initialize_stabilization_working_context(clip); + StabContext *ctx = init_stabilization_working_context(clip); BLI_assert(ctx != NULL); - initialize_all_tracks(ctx, aspect); + init_all_tracks(ctx, aspect); if (ctx->stab->flag & TRACKING_AUTOSCALE) { ctx->stab->scale = 1.0; ctx->stab->scale = calculate_autoscale_factor(ctx, size, aspect); diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c index 0809e8dda6d..0a0f81f7829 100644 --- a/source/blender/blenkernel/intern/undo_system.c +++ b/source/blender/blenkernel/intern/undo_system.c @@ -476,9 +476,8 @@ UndoStep *BKE_undosys_step_push_init_with_type(UndoStack *ustack, undosys_stack_validate(ustack, false); return us; } - else { - return NULL; - } + + return NULL; } UndoStep *BKE_undosys_step_push_init(UndoStack *ustack, bContext *C, const char *name) diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index efe10b02940..b8d86f0dc5b 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -970,9 +970,8 @@ double bUnit_PreferredInputUnitScalar(const struct UnitSettings *settings, int t if (unit) { return unit->scalar; } - else { - return bUnit_BaseScalar(units.system, type); - } + + return bUnit_BaseScalar(units.system, type); } /* make a copy of the string that replaces the units with numbers @@ -1155,9 +1154,8 @@ double bUnit_BaseScalar(int system, int type) if (usys) { return unit_default(usys)->scalar; } - else { - return 1.0; - } + + return 1.0; } /* external access */ diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc index 633ad250a67..54fb0f612d1 100644 --- a/source/blender/blenkernel/intern/volume.cc +++ b/source/blender/blenkernel/intern/volume.cc @@ -367,9 +367,8 @@ struct VolumeGrid { if (is_loaded && entry && !entry->error_msg.empty()) { return entry->error_msg.c_str(); } - else { - return NULL; - } + + return NULL; } const bool grid_is_loaded() const @@ -1087,34 +1086,34 @@ VolumeGridType BKE_volume_grid_type(const VolumeGrid *volume_grid) if (grid->isType<openvdb::FloatGrid>()) { return VOLUME_GRID_FLOAT; } - else if (grid->isType<openvdb::Vec3fGrid>()) { + if (grid->isType<openvdb::Vec3fGrid>()) { return VOLUME_GRID_VECTOR_FLOAT; } - else if (grid->isType<openvdb::BoolGrid>()) { + if (grid->isType<openvdb::BoolGrid>()) { return VOLUME_GRID_BOOLEAN; } - else if (grid->isType<openvdb::DoubleGrid>()) { + if (grid->isType<openvdb::DoubleGrid>()) { return VOLUME_GRID_DOUBLE; } - else if (grid->isType<openvdb::Int32Grid>()) { + if (grid->isType<openvdb::Int32Grid>()) { return VOLUME_GRID_INT; } - else if (grid->isType<openvdb::Int64Grid>()) { + if (grid->isType<openvdb::Int64Grid>()) { return VOLUME_GRID_INT64; } - else if (grid->isType<openvdb::Vec3IGrid>()) { + if (grid->isType<openvdb::Vec3IGrid>()) { return VOLUME_GRID_VECTOR_INT; } - else if (grid->isType<openvdb::Vec3dGrid>()) { + if (grid->isType<openvdb::Vec3dGrid>()) { return VOLUME_GRID_VECTOR_DOUBLE; } - else if (grid->isType<openvdb::StringGrid>()) { + if (grid->isType<openvdb::StringGrid>()) { return VOLUME_GRID_STRING; } - else if (grid->isType<openvdb::MaskGrid>()) { + if (grid->isType<openvdb::MaskGrid>()) { return VOLUME_GRID_MASK; } - else if (grid->isType<openvdb::points::PointDataGrid>()) { + if (grid->isType<openvdb::points::PointDataGrid>()) { return VOLUME_GRID_POINTS; } #else diff --git a/source/blender/blenkernel/intern/volume_render.cc b/source/blender/blenkernel/intern/volume_render.cc index 135c6f78fef..98d3617c822 100644 --- a/source/blender/blenkernel/intern/volume_render.cc +++ b/source/blender/blenkernel/intern/volume_render.cc @@ -363,7 +363,6 @@ float BKE_volume_density_scale(const Volume *volume, const float matrix[4][4]) mul_mat3_m4_v3(matrix, unit); return 1.0f / len_v3(unit); } - else { - return 1.0f; - } + + return 1.0f; } diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c index 4625fd76293..f653a190704 100644 --- a/source/blender/blenkernel/intern/workspace.c +++ b/source/blender/blenkernel/intern/workspace.c @@ -157,9 +157,8 @@ static void *workspace_relation_get_data_matching_parent(const ListBase *relatio if (relation != NULL) { return relation->value; } - else { - return NULL; - } + + return NULL; } /** @@ -397,10 +396,9 @@ bool BKE_workspace_owner_id_check(const WorkSpace *workspace, const char *owner_ if ((*owner_id == '\0') || ((workspace->flags & WORKSPACE_USE_FILTER_BY_ORIGIN) == 0)) { return true; } - else { - /* We could use hash lookup, for now this list is highly likely under < ~16 items. */ - return BLI_findstring(&workspace->owner_ids, owner_id, offsetof(wmOwnerID, name)) != NULL; - } + + /* We could use hash lookup, for now this list is highly likely under < ~16 items. */ + return BLI_findstring(&workspace->owner_ids, owner_id, offsetof(wmOwnerID, name)) != NULL; } void BKE_workspace_id_tag_all_visible(Main *bmain, int tag) diff --git a/source/blender/blenlib/BLI_dial_2d.h b/source/blender/blenlib/BLI_dial_2d.h index f43237f6b75..fdbc3d4430b 100644 --- a/source/blender/blenlib/BLI_dial_2d.h +++ b/source/blender/blenlib/BLI_dial_2d.h @@ -37,7 +37,7 @@ * float angle; * Dial *dial; * - * dial = BLI_dial_initialize(start_position, threshold); + * dial = BLI_dial_init(start_position, threshold); * * angle = BLI_dial_angle(dial, current_position); * @@ -51,7 +51,7 @@ extern "C" { typedef struct Dial Dial; -Dial *BLI_dial_initialize(const float start_position[2], float threshold); +Dial *BLI_dial_init(const float start_position[2], float threshold); float BLI_dial_angle(Dial *dial, const float current_position[2]); diff --git a/source/blender/blenlib/BLI_dot_export.hh b/source/blender/blenlib/BLI_dot_export.hh index 2d6dbb1f600..a026a85dd62 100644 --- a/source/blender/blenlib/BLI_dot_export.hh +++ b/source/blender/blenlib/BLI_dot_export.hh @@ -43,9 +43,8 @@ class NodePort; class DirectedEdge; class UndirectedEdge; class Cluster; -class AttributeList; -class AttributeList { +class Attributes { private: Map<std::string, std::string> attributes_; @@ -56,11 +55,15 @@ class AttributeList { { attributes_.add_overwrite(key, value); } + + void set(StringRef key, float value) + { + attributes_.add_overwrite(key, std::to_string(value)); + } }; class Graph { private: - AttributeList attributes_; Vector<std::unique_ptr<Node>> nodes_; Vector<std::unique_ptr<Cluster>> clusters_; @@ -71,19 +74,17 @@ class Graph { friend Node; public: + Attributes attributes; + + public: Node &new_node(StringRef label); Cluster &new_cluster(StringRef label = ""); void export__declare_nodes_and_clusters(std::stringstream &ss) const; - void set_attribute(StringRef key, StringRef value) - { - attributes_.set(key, value); - } - void set_rankdir(Attr_rankdir rankdir) { - this->set_attribute("rankdir", rankdir_to_string(rankdir)); + attributes.set("rankdir", rankdir_to_string(rankdir)); } void set_random_cluster_bgcolors(); @@ -91,7 +92,6 @@ class Graph { class Cluster { private: - AttributeList attributes_; Graph &graph_; Cluster *parent_ = nullptr; Set<Cluster *> children_; @@ -100,6 +100,9 @@ class Cluster { friend Graph; friend Node; + public: + Attributes attributes; + Cluster(Graph &graph) : graph_(graph) { } @@ -107,9 +110,9 @@ class Cluster { public: void export__declare_nodes_and_clusters(std::stringstream &ss) const; - void set_attribute(StringRef key, StringRef value) + std::string name() const { - attributes_.set(key, value); + return "cluster_" + std::to_string((uintptr_t)this); } void set_parent_cluster(Cluster *cluster); @@ -118,53 +121,52 @@ class Cluster { this->set_parent_cluster(&cluster); } + Cluster *parent_cluster() + { + return parent_; + } + void set_random_cluster_bgcolors(); + + bool contains(Node &node) const; }; class Node { private: - AttributeList attributes_; Graph &graph_; Cluster *cluster_ = nullptr; friend Graph; - Node(Graph &graph) : graph_(graph) - { - } - public: - const AttributeList &attributes() const - { - return attributes_; - } + Attributes attributes; - AttributeList &attributes() + Node(Graph &graph) : graph_(graph) { - return attributes_; } + public: void set_parent_cluster(Cluster *cluster); void set_parent_cluster(Cluster &cluster) { this->set_parent_cluster(&cluster); } - void set_attribute(StringRef key, StringRef value) + Cluster *parent_cluster() { - attributes_.set(key, value); + return cluster_; } void set_shape(Attr_shape shape) { - this->set_attribute("shape", shape_to_string(shape)); + attributes.set("shape", shape_to_string(shape)); } /* See https://www.graphviz.org/doc/info/attrs.html#k:color. */ void set_background_color(StringRef name) { - this->set_attribute("fillcolor", name); - this->set_attribute("style", "filled"); + attributes.set("fillcolor", name); + attributes.set("style", "filled"); } void export__as_id(std::stringstream &ss) const; @@ -208,33 +210,35 @@ class NodePort { class Edge : blender::NonCopyable, blender::NonMovable { protected: - AttributeList attributes_; NodePort a_; NodePort b_; public: - Edge(NodePort a, NodePort b) : a_(std::move(a)), b_(std::move(b)) - { - } + Attributes attributes; - void set_attribute(StringRef key, StringRef value) + public: + Edge(NodePort a, NodePort b) : a_(std::move(a)), b_(std::move(b)) { - attributes_.set(key, value); } void set_arrowhead(Attr_arrowType type) { - this->set_attribute("arrowhead", arrowType_to_string(type)); + attributes.set("arrowhead", arrowType_to_string(type)); } void set_arrowtail(Attr_arrowType type) { - this->set_attribute("arrowtail", arrowType_to_string(type)); + attributes.set("arrowtail", arrowType_to_string(type)); } void set_dir(Attr_dirType type) { - this->set_attribute("dir", dirType_to_string(type)); + attributes.set("dir", dirType_to_string(type)); + } + + void set_label(StringRef label) + { + attributes.set("label", label); } }; diff --git a/source/blender/blenlib/BLI_float3.hh b/source/blender/blenlib/BLI_float3.hh index 85575f65365..a976e909738 100644 --- a/source/blender/blenlib/BLI_float3.hh +++ b/source/blender/blenlib/BLI_float3.hh @@ -62,11 +62,12 @@ struct float3 { return {a.x + b.x, a.y + b.y, a.z + b.z}; } - void operator+=(const float3 &b) + float3 &operator+=(const float3 &b) { this->x += b.x; this->y += b.y; this->z += b.z; + return *this; } friend float3 operator-(const float3 &a, const float3 &b) @@ -79,25 +80,28 @@ struct float3 { return {-a.x, -a.y, -a.z}; } - void operator-=(const float3 &b) + float3 &operator-=(const float3 &b) { this->x -= b.x; this->y -= b.y; this->z -= b.z; + return *this; } - void operator*=(float scalar) + float3 &operator*=(float scalar) { this->x *= scalar; this->y *= scalar; this->z *= scalar; + return *this; } - void operator*=(const float3 &other) + float3 &operator*=(const float3 &other) { this->x *= other.x; this->y *= other.y; this->z *= other.z; + return *this; } friend float3 operator*(const float3 &a, const float3 &b) @@ -142,6 +146,17 @@ struct float3 { return normalize_v3(*this); } + /** + * Normalizes the vector in place. + */ + void normalize() + { + normalize_v3(*this); + } + + /** + * Returns a normalized vector. The original vector is not changed. + */ float3 normalized() const { float3 result; diff --git a/source/blender/blenlib/BLI_float4x4.hh b/source/blender/blenlib/BLI_float4x4.hh index a8b939ed32e..85d38149bb9 100644 --- a/source/blender/blenlib/BLI_float4x4.hh +++ b/source/blender/blenlib/BLI_float4x4.hh @@ -70,8 +70,8 @@ struct float4x4 { float4x4 inverted() const { - float result[4][4]; - invert_m4_m4(result, values); + float4x4 result; + invert_m4_m4(result.values, values); return result; } @@ -85,6 +85,18 @@ struct float4x4 { return this->inverted(); } + float4x4 transposed() const + { + float4x4 result; + transpose_m4_m4(result.values, values); + return result; + } + + float4x4 inverted_transposed_affine() const + { + return this->inverted_affine().transposed(); + } + struct float3x3_ref { const float4x4 &data; diff --git a/source/blender/blenlib/BLI_multi_value_map.hh b/source/blender/blenlib/BLI_multi_value_map.hh new file mode 100644 index 00000000000..018f080e633 --- /dev/null +++ b/source/blender/blenlib/BLI_multi_value_map.hh @@ -0,0 +1,131 @@ +/* + * 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. + */ + +#pragma once + +/** \file + * \ingroup bli + * + * A `blender::MultiValueMap<Key, Value>` is an unordered associative container that stores + * key-value pairs. It is different from `blender::Map` in that it can store multiple values for + * the same key. The list of values that corresponds to a specific key can contain duplicates + * and their order is maintained. + * + * This data structure is different from a `std::multi_map`, because multi_map can store the same + * key more than once and MultiValueMap can't. + * + * Currently, this class exists mainly for convenience. There are no performance benefits over + * using Map<Key, Vector<Value>>. In the future, a better implementation for this data structure + * can be developed. + */ + +#include "BLI_map.hh" +#include "BLI_vector.hh" + +namespace blender { + +template<typename Key, typename Value> class MultiValueMap { + private: + using MapType = Map<Key, Vector<Value>>; + MapType map_; + + public: + /** + * Add a new value for the given key. If the map contains the key already, the value will be + * appended to the list of corresponding values. + */ + void add(const Key &key, const Value &value) + { + this->add_as(key, value); + } + void add(const Key &key, Value &&value) + { + this->add_as(key, std::move(value)); + } + void add(Key &&key, const Value &value) + { + this->add_as(std::move(key), value); + } + void add(Key &&key, Value &&value) + { + this->add_as(std::move(key), std::move(value)); + } + template<typename ForwardKey, typename ForwardValue> + void add_as(ForwardKey &&key, ForwardValue &&value) + { + Vector<Value> &vector = map_.lookup_or_add_default_as(std::forward<ForwardKey>(key)); + vector.append(std::forward<ForwardValue>(value)); + } + + /** + * Add all given values to the key. + */ + void add_multiple(const Key &key, Span<Value> values) + { + this->add_multiple_as(key, values); + } + void add_multiple(Key &&key, Span<Value> values) + { + this->add_multiple_as(std::move(key), values); + } + template<typename ForwardKey> void add_multiple_as(ForwardKey &&key, Span<Value> values) + { + Vector<Value> &vector = map_.lookup_or_add_default_as(std::forward<ForwardKey>(key)); + vector.extend(values); + } + + /** + * Get a span to all the values that are stored for the given key. + */ + Span<Value> lookup(const Key &key) const + { + return this->lookup_as(key); + } + template<typename ForwardKey> Span<Value> lookup_as(const ForwardKey &key) const + { + const Vector<Value> *vector = map_.lookup_ptr_as(key); + if (vector != nullptr) { + return vector->as_span(); + } + return {}; + } + + /** + * Note: This signature will change when the implementation changes. + */ + typename MapType::ItemIterator items() const + { + return map_.items(); + } + + /** + * Note: This signature will change when the implementation changes. + */ + typename MapType::KeyIterator keys() const + { + return map_.keys(); + } + + /** + * Note: This signature will change when the implementation changes. + */ + typename MapType::ValueIterator values() const + { + return map_.values(); + } +}; + +} // namespace blender diff --git a/source/blender/blenlib/BLI_rand.hh b/source/blender/blenlib/BLI_rand.hh index 72c750d9fa2..b3c9c376141 100644 --- a/source/blender/blenlib/BLI_rand.hh +++ b/source/blender/blenlib/BLI_rand.hh @@ -62,6 +62,15 @@ class RandomNumberGenerator { } /** + * \return Random value (0..N), but never N. + */ + int32_t get_int32(int32_t max_exclusive) + { + BLI_assert(max_exclusive > 0); + return this->get_int32() % max_exclusive; + } + + /** * \return Random value (0..1), but never 1.0. */ double get_double() @@ -77,6 +86,35 @@ class RandomNumberGenerator { return (float)this->get_int32() / 0x80000000; } + template<typename T> void shuffle(MutableSpan<T> values) + { + /* Cannot shuffle arrays of this size yet. */ + BLI_assert(values.size() <= INT32_MAX); + + for (int i = values.size() - 1; i >= 2; i--) { + int j = this->get_int32(i); + if (i != j) { + std::swap(values[i], values[j]); + } + } + } + + /** + * Compute uniformly distributed barycentric coordinates. + */ + float3 get_barycentric_coordinates() + { + float rand1 = this->get_float(); + float rand2 = this->get_float(); + + if (rand1 + rand2 > 1.0f) { + rand1 = 1.0f - rand1; + rand2 = 1.0f - rand2; + } + + return float3(rand1, rand2, 1.0f - rand1 - rand2); + } + float2 get_unit_float2(); float3 get_unit_float3(); float2 get_triangle_sample(float2 v1, float2 v2, float2 v3); diff --git a/source/blender/blenlib/BLI_resource_collector.hh b/source/blender/blenlib/BLI_resource_collector.hh index 9c8fefc1202..20180f3b2c9 100644 --- a/source/blender/blenlib/BLI_resource_collector.hh +++ b/source/blender/blenlib/BLI_resource_collector.hh @@ -78,6 +78,12 @@ class ResourceCollector : NonCopyable, NonMovable { */ template<typename T> void add(destruct_ptr<T> resource, const char *name) { + /* There is no need to keep track of such types. */ + if (std::is_trivially_destructible_v<T>) { + resource.release(); + return; + } + BLI_assert(resource.get() != nullptr); this->add( resource.release(), diff --git a/source/blender/blenlib/BLI_span.hh b/source/blender/blenlib/BLI_span.hh index a2de76e080e..5aee0028846 100644 --- a/source/blender/blenlib/BLI_span.hh +++ b/source/blender/blenlib/BLI_span.hh @@ -86,7 +86,7 @@ namespace blender { */ template<typename T> class Span { private: - const T *start_ = nullptr; + const T *data_ = nullptr; int64_t size_ = 0; public: @@ -95,13 +95,13 @@ template<typename T> class Span { */ Span() = default; - Span(const T *start, int64_t size) : start_(start), size_(size) + Span(const T *start, int64_t size) : data_(start), size_(size) { BLI_assert(size >= 0); } template<typename U, typename std::enable_if_t<is_convertible_pointer_v<U, T>> * = nullptr> - Span(const U *start, int64_t size) : start_((const T *)start), size_(size) + Span(const U *start, int64_t size) : data_((const T *)start), size_(size) { BLI_assert(size >= 0); } @@ -135,7 +135,7 @@ template<typename T> class Span { * Span<Derived *> -> Span<Base *> */ template<typename U, typename std::enable_if_t<is_convertible_pointer_v<U, T>> * = nullptr> - Span(Span<U> array) : start_((T *)array.data()), size_(array.size()) + Span(Span<U> array) : data_((T *)array.data()), size_(array.size()) { } @@ -148,7 +148,7 @@ template<typename T> class Span { BLI_assert(start >= 0); BLI_assert(size >= 0); BLI_assert(start + size <= this->size() || size == 0); - return Span(start_ + start, size); + return Span(data_ + start, size); } Span slice(IndexRange range) const @@ -206,17 +206,17 @@ template<typename T> class Span { */ const T *data() const { - return start_; + return data_; } const T *begin() const { - return start_; + return data_; } const T *end() const { - return start_ + size_; + return data_ + size_; } /** @@ -227,7 +227,7 @@ template<typename T> class Span { { BLI_assert(index >= 0); BLI_assert(index < size_); - return start_[index]; + return data_[index]; } /** @@ -299,7 +299,7 @@ template<typename T> class Span { const T &first() const { BLI_assert(size_ > 0); - return start_[0]; + return data_[0]; } /** @@ -309,7 +309,7 @@ template<typename T> class Span { const T &last() const { BLI_assert(size_ > 0); - return start_[size_ - 1]; + return data_[size_ - 1]; } /** @@ -319,7 +319,7 @@ template<typename T> class Span { T get(int64_t index, const T &fallback) const { if (index < size_ && index >= 0) { - return start_[index]; + return data_[index]; } return fallback; } @@ -335,9 +335,9 @@ template<typename T> class Span { BLI_assert(size_ < 1000); for (int64_t i = 0; i < size_; i++) { - const T &value = start_[i]; + const T &value = data_[i]; for (int64_t j = i + 1; j < size_; j++) { - if (value == start_[j]) { + if (value == data_[j]) { return true; } } @@ -357,7 +357,7 @@ template<typename T> class Span { BLI_assert(size_ < 1000); for (int64_t i = 0; i < size_; i++) { - const T &value = start_[i]; + const T &value = data_[i]; if (other.contains(value)) { return true; } @@ -382,7 +382,7 @@ template<typename T> class Span { int64_t first_index_try(const T &search_value) const { for (int64_t i = 0; i < size_; i++) { - if (start_[i] == search_value) { + if (data_[i] == search_value) { return i; } } @@ -405,7 +405,7 @@ template<typename T> class Span { { BLI_assert((size_ * sizeof(T)) % sizeof(NewT) == 0); int64_t new_size = size_ * sizeof(T) / sizeof(NewT); - return Span<NewT>(reinterpret_cast<const NewT *>(start_), new_size); + return Span<NewT>(reinterpret_cast<const NewT *>(data_), new_size); } /** @@ -438,13 +438,13 @@ template<typename T> class Span { */ template<typename T> class MutableSpan { private: - T *start_; + T *data_; int64_t size_; public: MutableSpan() = default; - MutableSpan(T *start, const int64_t size) : start_(start), size_(size) + MutableSpan(T *start, const int64_t size) : data_(start), size_(size) { } @@ -458,7 +458,7 @@ template<typename T> class MutableSpan { operator Span<T>() const { - return Span<T>(start_, size_); + return Span<T>(data_, size_); } /** @@ -474,7 +474,7 @@ template<typename T> class MutableSpan { */ void fill(const T &value) { - initialized_fill_n(start_, size_, value); + initialized_fill_n(data_, size_, value); } /** @@ -485,7 +485,7 @@ template<typename T> class MutableSpan { { for (int64_t i : indices) { BLI_assert(i < size_); - start_[i] = value; + data_[i] = value; } } @@ -495,23 +495,23 @@ template<typename T> class MutableSpan { */ T *data() const { - return start_; + return data_; } T *begin() const { - return start_; + return data_; } T *end() const { - return start_ + size_; + return data_ + size_; } T &operator[](const int64_t index) const { BLI_assert(index < this->size()); - return start_[index]; + return data_[index]; } /** @@ -521,7 +521,7 @@ template<typename T> class MutableSpan { MutableSpan slice(const int64_t start, const int64_t length) const { BLI_assert(start + length <= this->size()); - return MutableSpan(start_ + start, length); + return MutableSpan(data_ + start, length); } /** @@ -570,7 +570,7 @@ template<typename T> class MutableSpan { */ Span<T> as_span() const { - return Span<T>(start_, size_); + return Span<T>(data_, size_); } /** @@ -589,7 +589,7 @@ template<typename T> class MutableSpan { T &last() const { BLI_assert(size_ > 0); - return start_[size_ - 1]; + return data_[size_ - 1]; } /** @@ -608,13 +608,24 @@ template<typename T> class MutableSpan { } /** + * Copy all values from another span into this span. This invokes undefined behavior when the + * destination contains uninitialized data and T is not trivially copy constructible. + * The size of both spans is expected to be the same. + */ + void copy_from(Span<T> values) + { + BLI_assert(size_ == values.size()); + initialized_copy_n(values.data(), size_, data_); + } + + /** * Returns a new span to the same underlying memory buffer. No conversions are done. */ template<typename NewT> MutableSpan<NewT> cast() const { BLI_assert((size_ * sizeof(T)) % sizeof(NewT) == 0); int64_t new_size = size_ * sizeof(T) / sizeof(NewT); - return MutableSpan<NewT>(reinterpret_cast<NewT *>(start_), new_size); + return MutableSpan<NewT>(reinterpret_cast<NewT *>(data_), new_size); } }; diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index bc35e969e6a..2699f2498ac 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -755,6 +755,43 @@ extern bool BLI_memory_is_zero(const void *arr, const size_t arr_size); /** \} */ /* -------------------------------------------------------------------- */ +/** \name C++ Macros + * \{ */ + +#ifdef __cplusplus + +/* Useful to port C code using enums to C++ where enums are strongly typed. + * To use after the enum declaration. */ +# define ENUM_OPERATORS(_enum_type) \ + inline constexpr _enum_type operator|(_enum_type a, _enum_type b) \ + { \ + return a = static_cast<_enum_type>(static_cast<int>(a) | b); \ + } \ + inline constexpr _enum_type operator&(_enum_type a, _enum_type b) \ + { \ + return a = static_cast<_enum_type>(static_cast<int>(a) & b); \ + } \ + inline constexpr _enum_type operator~(_enum_type a) \ + { \ + return a = static_cast<_enum_type>(~static_cast<int>(a)); \ + } \ + inline _enum_type &operator|=(_enum_type &a, _enum_type b) \ + { \ + return a = static_cast<_enum_type>(static_cast<int>(a) | b); \ + } \ + inline _enum_type &operator&=(_enum_type &a, _enum_type b) \ + { \ + return a = static_cast<_enum_type>(static_cast<int>(a) & b); \ + } + +#else +/* Output nothing. */ +# define ENUM_OPERATORS(_type) +#endif + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Misc Macros * \{ */ diff --git a/source/blender/blenlib/BLI_vector.hh b/source/blender/blenlib/BLI_vector.hh index df577660f4e..52e966267b5 100644 --- a/source/blender/blenlib/BLI_vector.hh +++ b/source/blender/blenlib/BLI_vector.hh @@ -560,7 +560,7 @@ class Vector { /** * Return a reference to the last element in the vector. - * This will assert when the vector is empty. + * This invokes undefined behavior when the vector is empty. */ const T &last() const { diff --git a/source/blender/blenlib/BLI_vector_adaptor.hh b/source/blender/blenlib/BLI_vector_adaptor.hh new file mode 100644 index 00000000000..9c805f242e4 --- /dev/null +++ b/source/blender/blenlib/BLI_vector_adaptor.hh @@ -0,0 +1,102 @@ +/* + * 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. + */ + +#pragma once + +/** \file + * \ingroup bli + * + * A `blender::VectorAdaptor` is a container with a fixed maximum size and does not own the + * underlying memory. When an adaptor is constructed, you have to provide it with an uninitialized + * array that will be filled when elements are added to the vector. The vector adaptor is not able + * to grow. Therefore, it is undefined behavior to add more elements than fit into the provided + * buffer. + */ + +#include "BLI_span.hh" + +namespace blender { + +template<typename T> class VectorAdaptor { + private: + T *begin_; + T *end_; + T *capacity_end_; + + public: + VectorAdaptor() : begin_(nullptr), end_(nullptr), capacity_end_(nullptr) + { + } + + VectorAdaptor(T *data, int64_t capacity, int64_t size = 0) + : begin_(data), end_(data + size), capacity_end_(data + capacity) + { + } + + VectorAdaptor(MutableSpan<T> span) : VectorAdaptor(span.data(), span.size(), 0) + { + } + + void append(const T &value) + { + BLI_assert(end_ < capacity_end_); + new (end_) T(value); + end_++; + } + + void append(T &&value) + { + BLI_assert(end_ < capacity_end_); + new (end_) T(std::move(value)); + end_++; + } + + void append_n_times(const T &value, int64_t n) + { + BLI_assert(end_ + n <= capacity_end_); + uninitialized_fill_n(end_, n, value); + end_ += n; + } + + void extend(Span<T> values) + { + BLI_assert(end_ + values.size() <= capacity_end_); + uninitialized_copy_n(values.data(), values.size(), end_); + end_ += values.size(); + } + + int64_t capacity() const + { + return capacity_end_ - begin_; + } + + int64_t size() const + { + return end_ - begin_; + } + + bool is_empty() const + { + return begin_ == end_; + } + + bool is_full() const + { + return end_ == capacity_end_; + } +}; + +} // namespace blender diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 9703c78e19c..a5af517ecca 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -270,6 +270,7 @@ set(SRC BLI_utility_mixins.hh BLI_uvproject.h BLI_vector.hh + BLI_vector_adaptor.hh BLI_vector_set.hh BLI_vector_set_slots.hh BLI_vfontdata.h @@ -343,3 +344,29 @@ set_source_files_properties( ) blender_add_lib(bf_blenlib "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") + +if(WITH_GTESTS) + set(TEST_SRC + tests/BLI_array_test.cc + tests/BLI_disjoint_set_test.cc + tests/BLI_edgehash_test.cc + tests/BLI_index_mask_test.cc + tests/BLI_index_range_test.cc + tests/BLI_linear_allocator_test.cc + tests/BLI_map_test.cc + tests/BLI_math_base_safe_test.cc + tests/BLI_memory_utils_test.cc + tests/BLI_multi_value_map_test.cc + tests/BLI_set_test.cc + tests/BLI_span_test.cc + tests/BLI_stack_cxx_test.cc + tests/BLI_string_ref_test.cc + tests/BLI_vector_set_test.cc + tests/BLI_vector_test.cc + ) + set(TEST_LIB + bf_blenlib + ) + include(GTestTesting) + blender_add_test_lib(bf_bli_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}") +endif() diff --git a/source/blender/blenlib/intern/BLI_args.c b/source/blender/blenlib/intern/BLI_args.c index 2b078b3bae5..91aabca7747 100644 --- a/source/blender/blenlib/intern/BLI_args.c +++ b/source/blender/blenlib/intern/BLI_args.c @@ -92,13 +92,9 @@ static bool keycmp(const void *a, const void *b) if (ka->case_str == 1 || kb->case_str == 1) { return (BLI_strcasecmp(ka->arg, kb->arg) != 0); } - else { - return (!STREQ(ka->arg, kb->arg)); - } - } - else { - return BLI_ghashutil_intcmp((const void *)ka->pass, (const void *)kb->pass); + return (!STREQ(ka->arg, kb->arg)); } + return BLI_ghashutil_intcmp((const void *)ka->pass, (const void *)kb->pass); } static bArgument *lookUp(struct bArgs *ba, const char *arg, int pass, int case_str) diff --git a/source/blender/blenlib/intern/BLI_dial_2d.c b/source/blender/blenlib/intern/BLI_dial_2d.c index c6d28e20f35..7363233d573 100644 --- a/source/blender/blenlib/intern/BLI_dial_2d.c +++ b/source/blender/blenlib/intern/BLI_dial_2d.c @@ -45,7 +45,7 @@ struct Dial { bool initialized; }; -Dial *BLI_dial_initialize(const float start_position[2], float threshold) +Dial *BLI_dial_init(const float start_position[2], float threshold) { Dial *dial = MEM_callocN(sizeof(Dial), "dial"); diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index 09dbf18acd0..69602cd4209 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -538,10 +538,8 @@ BLI_INLINE bool ghash_insert_safe(GHash *gh, } return false; } - else { - ghash_insert_ex(gh, key, val, bucket_index); - return true; - } + ghash_insert_ex(gh, key, val, bucket_index); + return true; } BLI_INLINE bool ghash_insert_safe_keyonly(GHash *gh, @@ -564,10 +562,8 @@ BLI_INLINE bool ghash_insert_safe_keyonly(GHash *gh, } return false; } - else { - ghash_insert_ex_keyonly(gh, key, bucket_index); - return true; - } + ghash_insert_ex_keyonly(gh, key, bucket_index); + return true; } /** @@ -792,9 +788,7 @@ void *BLI_ghash_replace_key(GHash *gh, void *key) e->e.key = key; return key_prev; } - else { - return NULL; - } + return NULL; } /** @@ -915,9 +909,7 @@ bool BLI_ghash_remove(GHash *gh, BLI_mempool_free(gh->entrypool, e); return true; } - else { - return false; - } + return false; } /* same as above but return the value, @@ -940,9 +932,7 @@ void *BLI_ghash_popkey(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp) BLI_mempool_free(gh->entrypool, e); return val; } - else { - return NULL; - } + return NULL; } /** @@ -975,10 +965,9 @@ bool BLI_ghash_pop(GHash *gh, GHashIterState *state, void **r_key, void **r_val) BLI_mempool_free(gh->entrypool, e); return true; } - else { - *r_key = *r_val = NULL; - return false; - } + + *r_key = *r_val = NULL; + return false; } /** @@ -1246,10 +1235,9 @@ bool BLI_gset_pop(GSet *gs, GSetIterState *state, void **r_key) BLI_mempool_free(((GHash *)gs)->entrypool, e); return true; } - else { - *r_key = NULL; - return false; - } + + *r_key = NULL; + return false; } void BLI_gset_clear_ex(GSet *gs, GSetKeyFreeFP keyfreefp, const uint nentries_reserve) @@ -1309,9 +1297,7 @@ void *BLI_gset_pop_key(GSet *gs, const void *key) BLI_mempool_free(((GHash *)gs)->entrypool, e); return key_ret; } - else { - return NULL; - } + return NULL; } /** \} */ diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index a3f93ccc753..f63a523ca60 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -284,28 +284,19 @@ static BVHNode *bvh_medianof3(BVHNode **a, int lo, int mid, int hi, int axis) if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) { return a[mid]; } - else { - if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) { - return a[hi]; - } - else { - return a[lo]; - } + if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) { + return a[hi]; } + return a[lo]; } - else { - if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) { - if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) { - return a[lo]; - } - else { - return a[hi]; - } - } - else { - return a[mid]; + + if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) { + if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) { + return a[lo]; } + return a[hi]; } + return a[mid]; } /** @@ -422,18 +413,12 @@ static char get_largest_axis(const float *bv) if (middle_point[0] > middle_point[2]) { return 1; /* max x axis */ } - else { - return 5; /* max z axis */ - } + return 5; /* max z axis */ } - else { - if (middle_point[1] > middle_point[2]) { - return 3; /* max y axis */ - } - else { - return 5; /* max z axis */ - } + if (middle_point[1] > middle_point[2]) { + return 3; /* max y axis */ } + return 5; /* max z axis */ } /** @@ -619,13 +604,11 @@ static int implicit_leafs_index(const BVHBuildHelper *data, const int depth, con if (min_leaf_index <= data->remain_leafs) { return min_leaf_index; } - else if (data->leafs_per_child[depth]) { + if (data->leafs_per_child[depth]) { return data->totleafs - (data->branches_on_level[depth - 1] - child_index) * data->leafs_per_child[depth]; } - else { - return data->remain_leafs; - } + return data->remain_leafs; } /** @@ -1668,10 +1651,8 @@ static bool dfs_find_duplicate_fast_dfs(BVHNearestData *data, BVHNode *node) data->callback(data->userdata, node->index, data->co, &data->nearest); return (data->nearest.dist_sq < dist_sq); } - else { - data->nearest.index = node->index; - return true; - } + data->nearest.index = node->index; + return true; } } else { @@ -1805,9 +1786,7 @@ static float fast_ray_nearest_hit(const BVHRayCastData *data, const BVHNode *nod (t1x > data->hit.dist || t1y > data->hit.dist || t1z > data->hit.dist)) { return FLT_MAX; } - else { - return max_fff(t1x, t1y, t1z); - } + return max_fff(t1x, t1y, t1z); } static void dfs_raycast(BVHRayCastData *data, BVHNode *node) @@ -2354,26 +2333,25 @@ static bool bvhtree_walk_dfs_recursive(BVHTree_WalkData *walk_data, const BVHNod return walk_data->walk_leaf_cb( (const BVHTreeAxisRange *)node->bv, node->index, walk_data->userdata); } - else { - /* First pick the closest node to recurse into */ - if (walk_data->walk_order_cb( - (const BVHTreeAxisRange *)node->bv, node->main_axis, walk_data->userdata)) { - for (int i = 0; i != node->totnode; i++) { - if (walk_data->walk_parent_cb((const BVHTreeAxisRange *)node->children[i]->bv, - walk_data->userdata)) { - if (!bvhtree_walk_dfs_recursive(walk_data, node->children[i])) { - return false; - } + + /* First pick the closest node to recurse into */ + if (walk_data->walk_order_cb( + (const BVHTreeAxisRange *)node->bv, node->main_axis, walk_data->userdata)) { + for (int i = 0; i != node->totnode; i++) { + if (walk_data->walk_parent_cb((const BVHTreeAxisRange *)node->children[i]->bv, + walk_data->userdata)) { + if (!bvhtree_walk_dfs_recursive(walk_data, node->children[i])) { + return false; } } } - else { - for (int i = node->totnode - 1; i >= 0; i--) { - if (walk_data->walk_parent_cb((const BVHTreeAxisRange *)node->children[i]->bv, - walk_data->userdata)) { - if (!bvhtree_walk_dfs_recursive(walk_data, node->children[i])) { - return false; - } + } + else { + for (int i = node->totnode - 1; i >= 0; i--) { + if (walk_data->walk_parent_cb((const BVHTreeAxisRange *)node->children[i]->bv, + walk_data->userdata)) { + if (!bvhtree_walk_dfs_recursive(walk_data, node->children[i])) { + return false; } } } diff --git a/source/blender/blenlib/intern/BLI_linklist.c b/source/blender/blenlib/intern/BLI_linklist.c index dc5d20ece99..4cac526088b 100644 --- a/source/blender/blenlib/intern/BLI_linklist.c +++ b/source/blender/blenlib/intern/BLI_linklist.c @@ -147,7 +147,7 @@ void BLI_linklist_move_item(LinkNode **listp, int curr_index, int new_index) lnk_pdst = lnk; break; } - else if (i == curr_index - 1) { + if (i == curr_index - 1) { lnk_psrc = lnk; } } diff --git a/source/blender/blenlib/intern/BLI_memiter.c b/source/blender/blenlib/intern/BLI_memiter.c index 1b9509e36d8..428dd1e2ad8 100644 --- a/source/blender/blenlib/intern/BLI_memiter.c +++ b/source/blender/blenlib/intern/BLI_memiter.c @@ -269,9 +269,7 @@ void *BLI_memiter_elem_first(BLI_memiter *mi) BLI_memiter_elem *elem = (BLI_memiter_elem *)chunk->data; return elem->data; } - else { - return NULL; - } + return NULL; } void *BLI_memiter_elem_first_size(BLI_memiter *mi, uint *r_size) @@ -282,9 +280,7 @@ void *BLI_memiter_elem_first_size(BLI_memiter *mi, uint *r_size) *r_size = (uint)elem->size; return elem->data; } - else { - return NULL; - } + return NULL; } /** \} */ @@ -334,9 +330,7 @@ void *BLI_memiter_iter_step_size(BLI_memiter_handle *iter, uint *r_size) iter->elem = (BLI_memiter_elem *)&data[data_offset_from_size(size)]; return (void *)data; } - else { - return NULL; - } + return NULL; } void *BLI_memiter_iter_step(BLI_memiter_handle *iter) @@ -352,9 +346,7 @@ void *BLI_memiter_iter_step(BLI_memiter_handle *iter) iter->elem = (BLI_memiter_elem *)&data[data_offset_from_size(size)]; return (void *)data; } - else { - return NULL; - } + return NULL; } /** \} */ diff --git a/source/blender/blenlib/intern/DLRB_tree.c b/source/blender/blenlib/intern/DLRB_tree.c index 6810601d527..b0c3379ac97 100644 --- a/source/blender/blenlib/intern/DLRB_tree.c +++ b/source/blender/blenlib/intern/DLRB_tree.c @@ -299,9 +299,7 @@ static DLRBT_Node *get_grandparent(DLRBT_Node *node) if (node && node->parent) { return node->parent->parent; } - else { - return NULL; - } + return NULL; } /* get the sibling node (e.g. if node is left child of parent, return right child of parent) */ @@ -311,9 +309,7 @@ static DLRBT_Node *get_sibling(DLRBT_Node *node) if (node == node->parent->left) { return node->parent->right; } - else { - return node->parent->left; - } + return node->parent->left; } /* sibling not found */ diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c index 85fbe7ece0f..387f9837159 100644 --- a/source/blender/blenlib/intern/array_store.c +++ b/source/blender/blenlib/intern/array_store.c @@ -355,9 +355,7 @@ static bool bchunk_data_compare(const BChunk *chunk, if (offset + (size_t)chunk->data_len <= data_base_len) { return (memcmp(&data_base[offset], chunk->data, chunk->data_len) == 0); } - else { - return false; - } + return false; } /** \} */ @@ -893,20 +891,18 @@ static hash_key key_from_chunk_ref(const BArrayInfo *info, # endif return key; } - else { - /* corner case - we're too small, calculate the key each time. */ + /* corner case - we're too small, calculate the key each time. */ - hash_array_from_cref(info, cref, info->accum_read_ahead_bytes, hash_store); - hash_accum_single(hash_store, hash_store_len, info->accum_steps); - hash_key key = hash_store[0]; + hash_array_from_cref(info, cref, info->accum_read_ahead_bytes, hash_store); + hash_accum_single(hash_store, hash_store_len, info->accum_steps); + hash_key key = hash_store[0]; # ifdef USE_HASH_TABLE_KEY_CACHE - if (UNLIKELY(key == HASH_TABLE_KEY_UNSET)) { - key = HASH_TABLE_KEY_FALLBACK; - } -# endif - return key; + if (UNLIKELY(key == HASH_TABLE_KEY_UNSET)) { + key = HASH_TABLE_KEY_FALLBACK; } +# endif + return key; } static const BChunkRef *table_lookup(const BArrayInfo *info, @@ -1083,9 +1079,7 @@ static BChunkList *bchunk_list_from_data_merge(const BArrayInfo *info, if (cref == cref_match_first) { break; } - else { - cref = cref->next; - } + cref = cref->next; } /* happens when bytes are removed from the end of the array */ if (chunk_size_step == data_len_original) { diff --git a/source/blender/blenlib/intern/array_utils.c b/source/blender/blenlib/intern/array_utils.c index 5dec10a5756..e9ef5e2a927 100644 --- a/source/blender/blenlib/intern/array_utils.c +++ b/source/blender/blenlib/intern/array_utils.c @@ -208,7 +208,7 @@ bool _bli_array_iter_span(const void *arr, if (arr_len == 0) { return false; } - else if (use_wrap && (span_step[0] != arr_len) && (span_step[0] > span_step[1])) { + if (use_wrap && (span_step[0] != arr_len) && (span_step[0] > span_step[1])) { return false; } diff --git a/source/blender/blenlib/intern/bitmap_draw_2d.c b/source/blender/blenlib/intern/bitmap_draw_2d.c index 17debb38326..33250105c79 100644 --- a/source/blender/blenlib/intern/bitmap_draw_2d.c +++ b/source/blender/blenlib/intern/bitmap_draw_2d.c @@ -316,27 +316,25 @@ static int draw_poly_v2i_n__span_y_sort(const void *a_p, const void *b_p, void * if (co_a[1] < co_b[1]) { return -1; } - else if (co_a[1] > co_b[1]) { + if (co_a[1] > co_b[1]) { return 1; } - else if (co_a[0] < co_b[0]) { + if (co_a[0] < co_b[0]) { return -1; } - else if (co_a[0] > co_b[0]) { + if (co_a[0] > co_b[0]) { return 1; } - else { - /* co_a & co_b are identical, use the line closest to the x-min */ - const int *co = co_a; - co_a = verts[a[1]]; - co_b = verts[b[1]]; - int ord = (((co_b[0] - co[0]) * (co_a[1] - co[1])) - ((co_a[0] - co[0]) * (co_b[1] - co[1]))); - if (ord > 0) { - return -1; - } - if (ord < 0) { - return 1; - } + /* co_a & co_b are identical, use the line closest to the x-min */ + const int *co = co_a; + co_a = verts[a[1]]; + co_b = verts[b[1]]; + int ord = (((co_b[0] - co[0]) * (co_a[1] - co[1])) - ((co_a[0] - co[0]) * (co_b[1] - co[1]))); + if (ord > 0) { + return -1; + } + if (ord < 0) { + return 1; } return 0; } diff --git a/source/blender/blenlib/intern/boxpack_2d.c b/source/blender/blenlib/intern/boxpack_2d.c index 83866f766df..5bcb0c0322a 100644 --- a/source/blender/blenlib/intern/boxpack_2d.c +++ b/source/blender/blenlib/intern/boxpack_2d.c @@ -216,7 +216,7 @@ static int box_areasort(const void *p1, const void *p2) if (a1 < a2) { return 1; } - else if (a1 > a2) { + if (a1 > a2) { return -1; } return 0; @@ -246,10 +246,10 @@ static int vertex_sort(const void *p1, const void *p2, void *vs_ctx_p) if (UNLIKELY(v1->free == 0 && v2->free == 0)) { return 0; } - else if (UNLIKELY(v1->free == 0)) { + if (UNLIKELY(v1->free == 0)) { return 1; } - else if (UNLIKELY(v2->free == 0)) { + if (UNLIKELY(v2->free == 0)) { return -1; } #endif @@ -266,7 +266,7 @@ static int vertex_sort(const void *p1, const void *p2, void *vs_ctx_p) if (a1 > a2) { return 1; } - else if (a1 < a2) { + if (a1 < a2) { return -1; } return 0; diff --git a/source/blender/blenlib/intern/convexhull_2d.c b/source/blender/blenlib/intern/convexhull_2d.c index b37dc73db29..6e4a8623077 100644 --- a/source/blender/blenlib/intern/convexhull_2d.c +++ b/source/blender/blenlib/intern/convexhull_2d.c @@ -115,9 +115,7 @@ int BLI_convexhull_2d_sorted(const float (*points)[2], const int n, int r_points if (is_left(points[r_points[top - 1]], points[r_points[top]], points[i]) > 0.0f) { break; /* points[i] is a new hull vertex */ } - else { - top--; /* pop top point off stack */ - } + top--; /* pop top point off stack */ } r_points[++top] = i; /* push points[i] onto stack */ @@ -141,9 +139,7 @@ int BLI_convexhull_2d_sorted(const float (*points)[2], const int n, int r_points if (is_left(points[r_points[top - 1]], points[r_points[top]], points[i]) > 0.0f) { break; /* points[i] is a new hull vertex */ } - else { - top--; /* pop top point off stack */ - } + top--; /* pop top point off stack */ } if (points[i][0] == points[r_points[0]][0] && points[i][1] == points[r_points[0]][1]) { @@ -172,20 +168,17 @@ static int pointref_cmp_yx(const void *a_, const void *b_) if (a->pt[1] > b->pt[1]) { return 1; } - else if (a->pt[1] < b->pt[1]) { + if (a->pt[1] < b->pt[1]) { return -1; } if (a->pt[0] > b->pt[0]) { return 1; } - else if (a->pt[0] < b->pt[0]) { + if (a->pt[0] < b->pt[0]) { return -1; } - - else { - return 0; - } + return 0; } /** diff --git a/source/blender/blenlib/intern/delaunay_2d.c b/source/blender/blenlib/intern/delaunay_2d.c index 5f663dcb2e1..28d9ddaef28 100644 --- a/source/blender/blenlib/intern/delaunay_2d.c +++ b/source/blender/blenlib/intern/delaunay_2d.c @@ -600,19 +600,19 @@ static int site_lexicographic_cmp(const void *a, const void *b) if (co1[0] < co2[0]) { return -1; } - else if (co1[0] > co2[0]) { + if (co1[0] > co2[0]) { return 1; } - else if (co1[1] < co2[1]) { + if (co1[1] < co2[1]) { return -1; } - else if (co1[1] > co2[1]) { + if (co1[1] > co2[1]) { return 1; } - else if (s1->orig_index < s2->orig_index) { + if (s1->orig_index < s2->orig_index) { return -1; } - else if (s1->orig_index > s2->orig_index) { + if (s1->orig_index > s2->orig_index) { return 1; } return 0; @@ -974,7 +974,7 @@ static void initial_triangulation(CDT_state *cdt) if (jco[0] > xend) { break; /* No more j's to process. */ } - else if (jco[1] > yend) { + if (jco[1] > yend) { /* Get past any string of v's with the same x and too-big y. */ xcur = jco[0]; while (++j < n) { @@ -1414,7 +1414,7 @@ static bool get_next_crossing_from_vert(CDT_state *cdt, ok = true; break; } - else if (t->face != cdt->outer_face) { + if (t->face != cdt->outer_face) { orient2 = orient2d(vcur->co, vb->co, v2->co); #ifdef DEBUG_CDT if (dbg_level > 1) { @@ -1683,14 +1683,12 @@ static void add_edge_constraint( (cd_prev->lambda != 0.0 && cd_prev->in->vert != v && cd_prev->in->next->vert != v)) { break; } - else { - cd_prev->lambda = -1.0; /* Mark cd_prev as 'deleted'. */ + cd_prev->lambda = -1.0; /* Mark cd_prev as 'deleted'. */ #ifdef DEBUG_CDT - if (dbg_level > 0) { - fprintf(stderr, "deleted crossing %d\n", j); - } -#endif + if (dbg_level > 0) { + fprintf(stderr, "deleted crossing %d\n", j); } +#endif } if (j < i - 1) { /* Some crossings were deleted. Fix the in and out edges across gap. */ @@ -2002,19 +2000,19 @@ static int evl_cmp(const void *a, const void *b) if (area->e_id < sb->e_id) { return -1; } - else if (area->e_id > sb->e_id) { + if (area->e_id > sb->e_id) { return 1; } - else if (area->lambda < sb->lambda) { + if (area->lambda < sb->lambda) { return -1; } - else if (area->lambda > sb->lambda) { + if (area->lambda > sb->lambda) { return 1; } - else if (area->v_id < sb->v_id) { + if (area->v_id < sb->v_id) { return -1; } - else if (area->v_id > sb->v_id) { + if (area->v_id > sb->v_id) { return 1; } return 0; @@ -2386,9 +2384,7 @@ static const CDT_input *modify_input_for_near_edge_ends(const CDT_input *input, if (new_input != NULL) { return (const CDT_input *)new_input; } - else { - return input; - } + return input; } static void free_modified_input(CDT_input *input) @@ -2745,7 +2741,7 @@ static int edge_to_sort_cmp(const void *a, const void *b) if (e1->len_squared > e2->len_squared) { return -1; } - else if (e1->len_squared < e2->len_squared) { + if (e1->len_squared < e2->len_squared) { return 1; } return 0; @@ -4570,17 +4566,13 @@ static double orient2d(const double *pa, const double *pb, const double *pc) if (detright <= 0.0) { return det; } - else { - detsum = detleft + detright; - } + detsum = detleft + detright; } else if (detleft < 0.0) { if (detright >= 0.0) { return det; } - else { - detsum = -detleft - detright; - } + detsum = -detleft - detright; } else { return det; @@ -4609,8 +4601,13 @@ static double orient2d(const double *pa, const double *pb, const double *pc) * returned value has the correct sign. Hence, incircle() is usually quite * fast, but will run more slowly when the input points are cocircular or * nearly so. - */ - + * + * This function is allowed to be long for two reasons. Firstly, it was taken + * from an external source and only slightly adapted, and keeping its original + * form will make integration of upstream changes easier. Secondly, it is very + * sensitive to floating point errors, and refactoring may break it in subtle + * and hard to detect ways. + * NOLINTNEXTLINE: readability-function-size */ static double incircleadapt( const double *pa, const double *pb, const double *pc, const double *pd, double permanent) { diff --git a/source/blender/blenlib/intern/dot_export.cc b/source/blender/blenlib/intern/dot_export.cc index 48b6dc826d0..9ffb1895d04 100644 --- a/source/blender/blenlib/intern/dot_export.cc +++ b/source/blender/blenlib/intern/dot_export.cc @@ -28,7 +28,7 @@ Node &Graph::new_node(StringRef label) Node *node = new Node(*this); nodes_.append(std::unique_ptr<Node>(node)); top_level_nodes_.add_new(node); - node->set_attribute("label", label); + node->attributes.set("label", label); return *node; } @@ -37,7 +37,7 @@ Cluster &Graph::new_cluster(StringRef label) Cluster *cluster = new Cluster(*this); clusters_.append(std::unique_ptr<Cluster>(cluster)); top_level_clusters_.add_new(cluster); - cluster->set_attribute("label", label); + cluster->attributes.set("label", label); return *cluster; } @@ -60,7 +60,7 @@ void Cluster::set_parent_cluster(Cluster *new_parent) if (parent_ == new_parent) { return; } - else if (parent_ == nullptr) { + if (parent_ == nullptr) { graph_.top_level_clusters_.remove(this); new_parent->children_.add_new(this); } @@ -80,7 +80,7 @@ void Node::set_parent_cluster(Cluster *cluster) if (cluster_ == cluster) { return; } - else if (cluster_ == nullptr) { + if (cluster_ == nullptr) { graph_.top_level_nodes_.remove(this); cluster->nodes_.add_new(this); } @@ -110,13 +110,25 @@ void Cluster::set_random_cluster_bgcolors() float hue = rand() / (float)RAND_MAX; float staturation = 0.3f; float value = 0.8f; - this->set_attribute("bgcolor", color_attr_from_hsv(hue, staturation, value)); + this->attributes.set("bgcolor", color_attr_from_hsv(hue, staturation, value)); for (Cluster *cluster : children_) { cluster->set_random_cluster_bgcolors(); } } +bool Cluster::contains(Node &node) const +{ + Cluster *current = node.parent_cluster(); + while (current != nullptr) { + if (current == this) { + return true; + } + current = current->parent_; + } + return false; +} + /* Dot Generation **********************************************/ @@ -155,7 +167,7 @@ std::string UndirectedGraph::to_dot_string() const void Graph::export__declare_nodes_and_clusters(std::stringstream &ss) const { ss << "graph "; - attributes_.export__as_bracket_list(ss); + attributes.export__as_bracket_list(ss); ss << "\n\n"; for (Node *node : top_level_nodes_) { @@ -169,10 +181,10 @@ void Graph::export__declare_nodes_and_clusters(std::stringstream &ss) const void Cluster::export__declare_nodes_and_clusters(std::stringstream &ss) const { - ss << "subgraph cluster_" << (uintptr_t)this << " {\n"; + ss << "subgraph " << this->name() << " {\n"; ss << "graph "; - attributes_.export__as_bracket_list(ss); + attributes.export__as_bracket_list(ss); ss << "\n\n"; for (Node *node : nodes_) { @@ -192,7 +204,7 @@ void DirectedEdge::export__as_edge_statement(std::stringstream &ss) const ss << " -> "; b_.to_dot_string(ss); ss << " "; - attributes_.export__as_bracket_list(ss); + attributes.export__as_bracket_list(ss); } void UndirectedEdge::export__as_edge_statement(std::stringstream &ss) const @@ -201,10 +213,10 @@ void UndirectedEdge::export__as_edge_statement(std::stringstream &ss) const ss << " -- "; b_.to_dot_string(ss); ss << " "; - attributes_.export__as_bracket_list(ss); + attributes.export__as_bracket_list(ss); } -void AttributeList::export__as_bracket_list(std::stringstream &ss) const +void Attributes::export__as_bracket_list(std::stringstream &ss) const { ss << "["; attributes_.foreach_item([&](StringRef key, StringRef value) { @@ -228,7 +240,7 @@ void Node::export__as_declaration(std::stringstream &ss) const { this->export__as_id(ss); ss << " "; - attributes_.export__as_bracket_list(ss); + attributes.export__as_bracket_list(ss); ss << "\n"; } @@ -296,7 +308,7 @@ NodeWithSocketsRef::NodeWithSocketsRef(Node &node, ss << "</table>>"; - node_->set_attribute("label", ss.str()); + node_->attributes.set("label", ss.str()); node_->set_shape(Attr_shape::Rectangle); } diff --git a/source/blender/blenlib/intern/easing.c b/source/blender/blenlib/intern/easing.c index 9532f78bd44..07aafc1b57b 100644 --- a/source/blender/blenlib/intern/easing.c +++ b/source/blender/blenlib/intern/easing.c @@ -72,18 +72,16 @@ float BLI_easing_bounce_ease_out(float time, float begin, float change, float du if (time < (1 / 2.75f)) { return change * (7.5625f * time * time) + begin; } - else if (time < (2 / 2.75f)) { + if (time < (2 / 2.75f)) { time -= (1.5f / 2.75f); return change * ((7.5625f * time) * time + 0.75f) + begin; } - else if (time < (2.5f / 2.75f)) { + if (time < (2.5f / 2.75f)) { time -= (2.25f / 2.75f); return change * ((7.5625f * time) * time + 0.9375f) + begin; } - else { - time -= (2.625f / 2.75f); - return change * ((7.5625f * time) * time + 0.984375f) + begin; - } + time -= (2.625f / 2.75f); + return change * ((7.5625f * time) * time + 0.984375f) + begin; } float BLI_easing_bounce_ease_in(float time, float begin, float change, float duration) @@ -96,10 +94,8 @@ float BLI_easing_bounce_ease_in_out(float time, float begin, float change, float if (time < duration / 2) { return BLI_easing_bounce_ease_in(time * 2, 0, change, duration) * 0.5f + begin; } - else { - return BLI_easing_bounce_ease_out(time * 2 - duration, 0, change, duration) * 0.5f + - change * 0.5f + begin; - } + return BLI_easing_bounce_ease_out(time * 2 - duration, 0, change, duration) * 0.5f + + change * 0.5f + begin; } float BLI_easing_circ_ease_in(float time, float begin, float change, float duration) @@ -271,13 +267,12 @@ float BLI_easing_elastic_ease_in_out( sinf((time * duration - s) * (2 * (float)M_PI) / period))) + begin; } - else { - time = -time; - f *= 0.5f; - return (f * (amplitude * powf(2, 10 * time) * - sinf((time * duration - s) * (2 * (float)M_PI) / period))) + - change + begin; - } + + time = -time; + f *= 0.5f; + return (f * (amplitude * powf(2, 10 * time) * + sinf((time * duration - s) * (2 * (float)M_PI) / period))) + + change + begin; } static const float pow_min = 0.0009765625f; /* = 2^(-10) */ @@ -306,10 +301,8 @@ float BLI_easing_expo_ease_in_out(float time, float begin, float change, float d if (time <= duration_half) { return BLI_easing_expo_ease_in(time, begin, change_half, duration_half); } - else { - return BLI_easing_expo_ease_out( - time - duration_half, begin + change_half, change_half, duration_half); - } + return BLI_easing_expo_ease_out( + time - duration_half, begin + change_half, change_half, duration_half); } float BLI_easing_linear_ease(float time, float begin, float change, float duration) diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c index 56529581dd3..05ee02ad869 100644 --- a/source/blender/blenlib/intern/edgehash.c +++ b/source/blender/blenlib/intern/edgehash.c @@ -185,7 +185,7 @@ BLI_INLINE EdgeHashEntry *edgehash_insert(EdgeHash *eh, Edge edge, void *value) if (index == SLOT_EMPTY) { return edgehash_insert_at_slot(eh, slot, edge, value); } - else if (index == SLOT_DUMMY) { + if (index == SLOT_DUMMY) { eh->dummy_count--; return edgehash_insert_at_slot(eh, slot, edge, value); } @@ -200,7 +200,7 @@ BLI_INLINE EdgeHashEntry *edgehash_lookup_entry(EdgeHash *eh, uint v0, uint v1) if (EH_INDEX_HAS_EDGE(eh, index, edge)) { return &eh->entries[index]; } - else if (index == SLOT_EMPTY) { + if (index == SLOT_EMPTY) { return NULL; } } @@ -294,7 +294,7 @@ bool BLI_edgehash_reinsert(EdgeHash *eh, uint v0, uint v1, void *value) eh->entries[index].value = value; return false; } - else if (index == SLOT_EMPTY) { + if (index == SLOT_EMPTY) { if (edgehash_ensure_can_insert(eh)) { edgehash_insert(eh, edge, value); } @@ -360,7 +360,7 @@ bool BLI_edgehash_ensure_p(EdgeHash *eh, uint v0, uint v1, void ***r_value) *r_value = &eh->entries[index].value; return true; } - else if (index == SLOT_EMPTY) { + if (index == SLOT_EMPTY) { if (edgehash_ensure_can_insert(eh)) { *r_value = &edgehash_insert(eh, edge, NULL)->value; } @@ -413,7 +413,7 @@ void *BLI_edgehash_popkey(EdgeHash *eh, uint v0, uint v1) } return value; } - else if (index == SLOT_EMPTY) { + if (index == SLOT_EMPTY) { return NULL; } } @@ -583,7 +583,7 @@ bool BLI_edgeset_add(EdgeSet *es, uint v0, uint v1) if (ES_INDEX_HAS_EDGE(es, index, edge)) { return false; } - else if (index == SLOT_EMPTY) { + if (index == SLOT_EMPTY) { edgeset_insert_at_slot(es, slot, edge); return true; } @@ -615,7 +615,7 @@ bool BLI_edgeset_haskey(EdgeSet *es, uint v0, uint v1) if (ES_INDEX_HAS_EDGE(es, index, edge)) { return true; } - else if (index == SLOT_EMPTY) { + if (index == SLOT_EMPTY) { return false; } } diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index e61cbd318fc..6c7383bc297 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -980,7 +980,7 @@ static int delete_soft(const char *file, const char **error_message) "Blender may not support moving files or directories to trash on your system."; return -1; } - else if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus)) { + if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus)) { *error_message = process_failed; return -1; } @@ -1036,12 +1036,10 @@ int BLI_delete(const char *file, bool dir, bool recursive) if (recursive) { return recursive_operation(file, NULL, NULL, delete_single_file, delete_callback_post); } - else if (dir) { + if (dir) { return rmdir(file); } - else { - return remove(file); - } + return remove(file); } /** @@ -1184,8 +1182,7 @@ static int copy_single_file(const char *from, const char *to) return RecursiveOp_Callback_OK; } - else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) || S_ISFIFO(st.st_mode) || - S_ISSOCK(st.st_mode)) { + if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) || S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) { /* copy special type of file */ if (mknod(to, st.st_mode, st.st_rdev)) { perror("mknod"); @@ -1198,7 +1195,7 @@ static int copy_single_file(const char *from, const char *to) return RecursiveOp_Callback_OK; } - else if (!S_ISREG(st.st_mode)) { + if (!S_ISREG(st.st_mode)) { fprintf(stderr, "Copying of this kind of files isn't supported yet\n"); return RecursiveOp_Callback_Error; } @@ -1337,7 +1334,7 @@ bool BLI_dir_create_recursive(const char *dirname) if (BLI_is_dir(dirname)) { return true; } - else if (BLI_exists(dirname)) { + if (BLI_exists(dirname)) { return false; } diff --git a/source/blender/blenlib/intern/lasso_2d.c b/source/blender/blenlib/intern/lasso_2d.c index a01adf4fa6a..a3b111cf0f2 100644 --- a/source/blender/blenlib/intern/lasso_2d.c +++ b/source/blender/blenlib/intern/lasso_2d.c @@ -60,10 +60,9 @@ bool BLI_lasso_is_point_inside(const int mcoords[][2], if (sx == error_value || mcoords_len == 0) { return false; } - else { - int pt[2] = {sx, sy}; - return isect_point_poly_v2_int(pt, mcoords, mcoords_len, true); - } + + const int pt[2] = {sx, sy}; + return isect_point_poly_v2_int(pt, mcoords, mcoords_len, true); } /* edge version for lasso select. we assume boundbox check was done */ diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index 892eca768b3..5e88f8f3e44 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -162,9 +162,8 @@ bool BLI_remlink_safe(ListBase *listbase, void *vlink) BLI_remlink(listbase, vlink); return true; } - else { - return false; - } + + return false; } /** diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c index 651a062e3d5..09bb7ea5711 100644 --- a/source/blender/blenlib/intern/math_color.c +++ b/source/blender/blenlib/intern/math_color.c @@ -439,9 +439,8 @@ float srgb_to_linearrgb(float c) if (c < 0.04045f) { return (c < 0.0f) ? 0.0f : c * (1.0f / 12.92f); } - else { - return powf((c + 0.055f) * (1.0f / 1.055f), 2.4f); - } + + return powf((c + 0.055f) * (1.0f / 1.055f), 2.4f); } float linearrgb_to_srgb(float c) @@ -449,9 +448,8 @@ float linearrgb_to_srgb(float c) if (c < 0.0031308f) { return (c < 0.0f) ? 0.0f : c * 12.92f; } - else { - return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f; - } + + return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f; } void minmax_rgb(short c[3]) diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 7c187679ad1..7717c2f26ff 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -231,9 +231,8 @@ float cotangent_tri_weight_v3(const float v1[3], const float v2[3], const float if (c_len > FLT_EPSILON) { return dot_v3v3(a, b) / c_len; } - else { - return 0.0f; - } + + return 0.0f; } /********************************* Planes **********************************/ @@ -589,9 +588,8 @@ float dist_signed_squared_to_corner_v3v3v3(const float p[3], if (flip) { return min_ff(dist_a, dist_b); } - else { - return max_ff(dist_a, dist_b); - } + + return max_ff(dist_a, dist_b); } /** @@ -1146,9 +1144,8 @@ int isect_line_line_v2_point( return ISECT_LINE_LINE_CROSS; } - else { - return ISECT_LINE_LINE_COLINEAR; - } + + return ISECT_LINE_LINE_COLINEAR; } /* intersect Line-Line, floats */ @@ -1304,55 +1301,54 @@ int isect_seg_seg_v2_point_ex(const float v0[2], /* out of segment intersection */ return -1; } - else { - if ((cross_v2v2(s10, s30) == 0.0f) && (cross_v2v2(s32, s30) == 0.0f)) { - /* equal lines */ - float s20[2]; - float u_a, u_b; - - if (equals_v2v2(v0, v1)) { - if (len_squared_v2v2(v2, v3) > square_f(eps)) { - /* use non-point segment as basis */ - SWAP(const float *, v0, v2); - SWAP(const float *, v1, v3); - - sub_v2_v2v2(s10, v1, v0); - sub_v2_v2v2(s30, v3, v0); - } - else { /* both of segments are points */ - if (equals_v2v2(v0, v2)) { /* points are equal */ - copy_v2_v2(r_vi, v0); - return 1; - } - /* two different points */ - return -1; - } - } + if ((cross_v2v2(s10, s30) == 0.0f) && (cross_v2v2(s32, s30) == 0.0f)) { + /* equal lines */ + float s20[2]; + float u_a, u_b; - sub_v2_v2v2(s20, v2, v0); + if (equals_v2v2(v0, v1)) { + if (len_squared_v2v2(v2, v3) > square_f(eps)) { + /* use non-point segment as basis */ + SWAP(const float *, v0, v2); + SWAP(const float *, v1, v3); - u_a = dot_v2v2(s20, s10) / dot_v2v2(s10, s10); - u_b = dot_v2v2(s30, s10) / dot_v2v2(s10, s10); - - if (u_a > u_b) { - SWAP(float, u_a, u_b); + sub_v2_v2v2(s10, v1, v0); + sub_v2_v2v2(s30, v3, v0); } + else { /* both of segments are points */ + if (equals_v2v2(v0, v2)) { /* points are equal */ + copy_v2_v2(r_vi, v0); + return 1; + } - if (u_a > endpoint_max || u_b < endpoint_min) { - /* non-overlapping segments */ + /* two different points */ return -1; } - else if (max_ff(0.0f, u_a) == min_ff(1.0f, u_b)) { - /* one common point: can return result */ - madd_v2_v2v2fl(r_vi, v0, s10, max_ff(0, u_a)); - return 1; - } } - /* lines are collinear */ - return -1; + sub_v2_v2v2(s20, v2, v0); + + u_a = dot_v2v2(s20, s10) / dot_v2v2(s10, s10); + u_b = dot_v2v2(s30, s10) / dot_v2v2(s10, s10); + + if (u_a > u_b) { + SWAP(float, u_a, u_b); + } + + if (u_a > endpoint_max || u_b < endpoint_min) { + /* non-overlapping segments */ + return -1; + } + if (max_ff(0.0f, u_a) == min_ff(1.0f, u_b)) { + /* one common point: can return result */ + madd_v2_v2v2fl(r_vi, v0, s10, max_ff(0, u_a)); + return 1; + } } + + /* lines are collinear */ + return -1; } int isect_seg_seg_v2_point( @@ -1472,13 +1468,13 @@ int isect_line_sphere_v3(const float l1[3], /* no intersections */ return 0; } - else if (i == 0.0f) { + if (i == 0.0f) { /* one intersection */ mu = -b / (2.0f * a); madd_v3_v3v3fl(r_p1, l1, ldir, mu); return 1; } - else if (i > 0.0f) { + if (i > 0.0f) { const float i_sqrt = sqrtf(i); /* avoid calc twice */ /* first intersection */ @@ -1490,10 +1486,9 @@ int isect_line_sphere_v3(const float l1[3], madd_v3_v3v3fl(r_p2, l1, ldir, mu); return 2; } - else { - /* math domain error - nan */ - return -1; - } + + /* math domain error - nan */ + return -1; } /* keep in sync with isect_line_sphere_v3 */ @@ -1520,13 +1515,13 @@ int isect_line_sphere_v2(const float l1[2], /* no intersections */ return 0; } - else if (i == 0.0f) { + if (i == 0.0f) { /* one intersection */ mu = -b / (2.0f * a); madd_v2_v2v2fl(r_p1, l1, ldir, mu); return 1; } - else if (i > 0.0f) { + if (i > 0.0f) { const float i_sqrt = sqrtf(i); /* avoid calc twice */ /* first intersection */ @@ -1538,10 +1533,9 @@ int isect_line_sphere_v2(const float l1[2], madd_v2_v2v2fl(r_p2, l1, ldir, mu); return 2; } - else { - /* math domain error - nan */ - return -1; - } + + /* math domain error - nan */ + return -1; } /* point in polygon (keep float and int versions in sync) */ @@ -1957,34 +1951,32 @@ bool isect_ray_tri_watertight_v3(const float ray_origin[3], if (UNLIKELY(det == 0.0f || !isfinite(det))) { return false; } - else { - /* Calculate scaled z-coordinates of vertices and use them to calculate - * the hit distance. - */ - const int sign_det = (float_as_int(det) & (int)0x80000000); - const float t = (u * a_kz + v * b_kz + w * c_kz) * sz; - const float sign_t = xor_fl(t, sign_det); - if ((sign_t < 0.0f) - /* Differ from Cycles, don't read r_lambda's original value - * otherwise we won't match any of the other intersect functions here... - * which would be confusing. */ + + /* Calculate scaled z-coordinates of vertices and use them to calculate + * the hit distance. + */ + const int sign_det = (float_as_int(det) & (int)0x80000000); + const float t = (u * a_kz + v * b_kz + w * c_kz) * sz; + const float sign_t = xor_fl(t, sign_det); + if ((sign_t < 0.0f) + /* Differ from Cycles, don't read r_lambda's original value + * otherwise we won't match any of the other intersect functions here... + * which would be confusing. */ #if 0 || (sign_T > *r_lambda * xor_signmask(det, sign_mask)) #endif - ) { - return false; - } - else { - /* Normalize u, v and t. */ - const float inv_det = 1.0f / det; - if (r_uv) { - r_uv[0] = u * inv_det; - r_uv[1] = v * inv_det; - } - *r_lambda = t * inv_det; - return true; - } + ) { + return false; + } + + /* Normalize u, v and t. */ + const float inv_det = 1.0f / det; + if (r_uv) { + r_uv[0] = u * inv_det; + r_uv[1] = v * inv_det; } + *r_lambda = t * inv_det; + return true; } bool isect_ray_tri_watertight_v3_simple(const float ray_origin[3], @@ -2102,7 +2094,7 @@ bool isect_ray_seg_v2(const float ray_origin[2], det = cross_v2v2(ray_direction, s10); if (det != 0.0f) { const float v = cross_v2v2(v0_local, v1_local); - float p[2] = {(ray_direction[0] * v) / det, (ray_direction[1] * v) / det}; + const float p[2] = {(ray_direction[0] * v) / det, (ray_direction[1] * v) / det}; const float t = (dot_v2v2(p, ray_direction) / dot_v2v2(ray_direction, ray_direction)); if ((t >= 0.0f) == 0) { @@ -2215,10 +2207,9 @@ bool isect_line_plane_v3(float r_isect_co[3], madd_v3_v3v3fl(r_isect_co, l1, u, lambda); return true; } - else { - /* The segment is parallel to plane */ - return false; - } + + /* The segment is parallel to plane */ + return false; } /** @@ -2257,9 +2248,8 @@ bool isect_plane_plane_plane_v3(const float plane_a[4], return true; } - else { - return false; - } + + return false; } /** @@ -2303,9 +2293,8 @@ bool isect_plane_plane_v3(const float plane_a[4], return true; } - else { - return false; - } + + return false; } /** @@ -2436,65 +2425,54 @@ static bool isect_tri_tri_v2_impl_vert(const float t_a0[2], if (line_point_side_v2(t_a0, t_b1, t_a1) <= 0.0f) { return 1; } - else { - return 0; - } + + return 0; } - else { - if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) { - if (line_point_side_v2(t_a1, t_a2, t_b0) >= 0.0f) { - return 1; - } - else { - return 0; - } - } - else { - return 0; + + if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) { + if (line_point_side_v2(t_a1, t_a2, t_b0) >= 0.0f) { + return 1; } + + return 0; } + + return 0; } - else if (line_point_side_v2(t_a0, t_b1, t_a1) <= 0.0f) { + if (line_point_side_v2(t_a0, t_b1, t_a1) <= 0.0f) { if (line_point_side_v2(t_b2, t_b1, t_a2) <= 0.0f) { if (line_point_side_v2(t_a1, t_a2, t_b1) >= 0.0f) { return 1; } - else { - return 0; - } - } - else { + return 0; } - } - else { + return 0; } + + return 0; } - else if (line_point_side_v2(t_b2, t_b0, t_a2) >= 0.0f) { + if (line_point_side_v2(t_b2, t_b0, t_a2) >= 0.0f) { if (line_point_side_v2(t_a1, t_a2, t_b2) >= 0.0f) { if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) { return 1; } - else { - return 0; - } + + return 0; } - else if (line_point_side_v2(t_a1, t_a2, t_b1) >= 0.0f) { + if (line_point_side_v2(t_a1, t_a2, t_b1) >= 0.0f) { if (line_point_side_v2(t_b2, t_a2, t_b1) >= 0.0f) { return 1; } - else { - return 0; - } - } - else { + return 0; } - } - else { + return 0; } + + return 0; } static bool isect_tri_tri_v2_impl_edge(const float t_a0[2], @@ -2511,47 +2489,38 @@ static bool isect_tri_tri_v2_impl_edge(const float t_a0[2], if (line_point_side_v2(t_a0, t_a1, t_b2) >= 0.0f) { return 1; } - else { - return 0; - } + + return 0; } - else { - if (line_point_side_v2(t_a1, t_a2, t_b0) >= 0.0f) { - if (line_point_side_v2(t_a2, t_a0, t_b0) >= 0.0f) { - return 1; - } - else { - return 0; - } - } - else { - return 0; + + if (line_point_side_v2(t_a1, t_a2, t_b0) >= 0.0f) { + if (line_point_side_v2(t_a2, t_a0, t_b0) >= 0.0f) { + return 1; } + + return 0; } + + return 0; } - else { - if (line_point_side_v2(t_b2, t_b0, t_a2) >= 0.0f) { - if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) { - if (line_point_side_v2(t_a0, t_a2, t_b2) >= 0.0f) { - return 1; - } - else { - if (line_point_side_v2(t_a1, t_a2, t_b2) >= 0.0f) { - return 1; - } - else { - return 0; - } - } + + if (line_point_side_v2(t_b2, t_b0, t_a2) >= 0.0f) { + if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) { + if (line_point_side_v2(t_a0, t_a2, t_b2) >= 0.0f) { + return 1; } - else { - return 0; + + if (line_point_side_v2(t_a1, t_a2, t_b2) >= 0.0f) { + return 1; } - } - else { + return 0; } + + return 0; } + + return 0; } static int isect_tri_tri_impl_ccw_v2(const float t_a0[2], @@ -2566,32 +2535,26 @@ static int isect_tri_tri_impl_ccw_v2(const float t_a0[2], if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) { return 1; } - else { - return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2); - } + + return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2); } - else { - if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) { - return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b2, t_b0, t_b1); - } - else { - return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2); - } + + if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) { + return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b2, t_b0, t_b1); } + + return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2); } - else { - if (line_point_side_v2(t_b1, t_b2, t_a0) >= 0.0f) { - if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) { - return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b1, t_b2, t_b0); - } - else { - return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b1, t_b2, t_b0); - } - } - else { - return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b2, t_b0, t_b1); + + if (line_point_side_v2(t_b1, t_b2, t_a0) >= 0.0f) { + if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) { + return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b1, t_b2, t_b0); } + + return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b1, t_b2, t_b0); } + + return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b2, t_b0, t_b1); } bool isect_tri_tri_v2(const float t_a0[2], @@ -2605,18 +2568,15 @@ bool isect_tri_tri_v2(const float t_a0[2], if (line_point_side_v2(t_b0, t_b1, t_b2) < 0.0f) { return isect_tri_tri_impl_ccw_v2(t_a0, t_a2, t_a1, t_b0, t_b2, t_b1); } - else { - return isect_tri_tri_impl_ccw_v2(t_a0, t_a2, t_a1, t_b0, t_b1, t_b2); - } + + return isect_tri_tri_impl_ccw_v2(t_a0, t_a2, t_a1, t_b0, t_b1, t_b2); } - else { - if (line_point_side_v2(t_b0, t_b1, t_b2) < 0.0f) { - return isect_tri_tri_impl_ccw_v2(t_a0, t_a1, t_a2, t_b0, t_b2, t_b1); - } - else { - return isect_tri_tri_impl_ccw_v2(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2); - } + + if (line_point_side_v2(t_b0, t_b1, t_b2) < 0.0f) { + return isect_tri_tri_impl_ccw_v2(t_a0, t_a1, t_a2, t_b0, t_b2, t_b1); } + + return isect_tri_tri_impl_ccw_v2(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2); } /** \} */ @@ -2682,8 +2642,7 @@ int isect_aabb_planes_v3(const float (*planes)[4], if (plane_point_side_v3(planes[i], bb_far) < 0.0f) { return ISECT_AABB_PLANE_BEHIND_ANY; } - else if ((ret != ISECT_AABB_PLANE_CROSS_ANY) && - (plane_point_side_v3(planes[i], bb_near) < 0.0f)) { + if ((ret != ISECT_AABB_PLANE_CROSS_ANY) && (plane_point_side_v3(planes[i], bb_near) < 0.0f)) { ret = ISECT_AABB_PLANE_CROSS_ANY; } } @@ -2967,7 +2926,7 @@ int isect_line_line_epsilon_v3(const float v1[3], return 0; } /* test if the two lines are coplanar */ - else if (UNLIKELY(fabsf(d) <= epsilon)) { + if (UNLIKELY(fabsf(d) <= epsilon)) { cross_v3_v3v3(cb, c, b); mul_v3_fl(a, dot_v3v3(cb, ab) / div); @@ -2977,34 +2936,33 @@ int isect_line_line_epsilon_v3(const float v1[3], return 1; /* one intersection only */ } /* if not */ - else { - float n[3], t[3]; - float v3t[3], v4t[3]; - sub_v3_v3v3(t, v1, v3); - /* offset between both plane where the lines lies */ - cross_v3_v3v3(n, a, b); - project_v3_v3v3(t, t, n); + float n[3], t[3]; + float v3t[3], v4t[3]; + sub_v3_v3v3(t, v1, v3); - /* for the first line, offset the second line until it is coplanar */ - add_v3_v3v3(v3t, v3, t); - add_v3_v3v3(v4t, v4, t); + /* offset between both plane where the lines lies */ + cross_v3_v3v3(n, a, b); + project_v3_v3v3(t, t, n); - sub_v3_v3v3(c, v3t, v1); - sub_v3_v3v3(a, v2, v1); - sub_v3_v3v3(b, v4t, v3t); + /* for the first line, offset the second line until it is coplanar */ + add_v3_v3v3(v3t, v3, t); + add_v3_v3v3(v4t, v4, t); - cross_v3_v3v3(ab, a, b); - cross_v3_v3v3(cb, c, b); + sub_v3_v3v3(c, v3t, v1); + sub_v3_v3v3(a, v2, v1); + sub_v3_v3v3(b, v4t, v3t); - mul_v3_fl(a, dot_v3v3(cb, ab) / dot_v3v3(ab, ab)); - add_v3_v3v3(r_i1, v1, a); + cross_v3_v3v3(ab, a, b); + cross_v3_v3v3(cb, c, b); - /* for the second line, just subtract the offset from the first intersection point */ - sub_v3_v3v3(r_i2, r_i1, t); + mul_v3_fl(a, dot_v3v3(cb, ab) / dot_v3v3(ab, ab)); + add_v3_v3v3(r_i1, v1, a); - return 2; /* two nearest points */ - } + /* for the second line, just subtract the offset from the first intersection point */ + sub_v3_v3v3(r_i2, r_i1, t); + + return 2; /* two nearest points */ } int isect_line_line_v3(const float v1[3], @@ -3047,31 +3005,29 @@ bool isect_line_line_strict_v3(const float v1[3], return false; } /* test if the two lines are coplanar */ - else if (UNLIKELY(fabsf(d) < epsilon)) { + if (UNLIKELY(fabsf(d) < epsilon)) { return false; } - else { - float f1, f2; - cross_v3_v3v3(cb, c, b); - cross_v3_v3v3(ca, c, a); - f1 = dot_v3v3(cb, ab) / div; - f2 = dot_v3v3(ca, ab) / div; + float f1, f2; + cross_v3_v3v3(cb, c, b); + cross_v3_v3v3(ca, c, a); - if (f1 >= 0 && f1 <= 1 && f2 >= 0 && f2 <= 1) { - mul_v3_fl(a, f1); - add_v3_v3v3(vi, v1, a); + f1 = dot_v3v3(cb, ab) / div; + f2 = dot_v3v3(ca, ab) / div; - if (r_lambda) { - *r_lambda = f1; - } + if (f1 >= 0 && f1 <= 1 && f2 >= 0 && f2 <= 1) { + mul_v3_fl(a, f1); + add_v3_v3v3(vi, v1, a); - return true; /* intersection found */ - } - else { - return false; + if (r_lambda) { + *r_lambda = f1; } + + return true; /* intersection found */ } + + return false; } /** @@ -3237,15 +3193,14 @@ bool isect_ray_aabb_v3_simple(const float orig[3], if ((hit_dist[1] < 0.0f || hit_dist[0] > hit_dist[1])) { return false; } - else { - if (tmin) { - *tmin = hit_dist[0]; - } - if (tmax) { - *tmax = hit_dist[1]; - } - return true; + + if (tmin) { + *tmin = hit_dist[0]; + } + if (tmax) { + *tmax = hit_dist[1]; } + return true; } float closest_to_ray_v3(float r_close[3], @@ -3463,7 +3418,7 @@ static bool point_in_slice(const float p[3], /* adult sister defining the slice planes by the origin and the normal * NOTE |normal| may not be 1 but defining the thickness of the slice */ -static bool point_in_slice_as(float p[3], float origin[3], float normal[3]) +static bool point_in_slice_as(const float p[3], const float origin[3], const float normal[3]) { float h, rp[3]; sub_v3_v3v3(rp, p, origin); @@ -3522,9 +3477,8 @@ bool isect_point_tri_v3( return true; } - else { - return false; - } + + return false; } bool clip_segment_v3_plane( @@ -3547,7 +3501,7 @@ bool clip_segment_v3_plane( if (t >= div) { return false; } - else if (t > 0.0f) { + if (t > 0.0f) { const float p1_copy[3] = {UNPACK3(p1)}; copy_v3_v3(r_p2, p2); madd_v3_v3v3fl(r_p1, p1_copy, dp, t / div); @@ -3559,7 +3513,7 @@ bool clip_segment_v3_plane( if (t >= 0.0f) { return false; } - else if (t > div) { + if (t > div) { const float p1_copy[3] = {UNPACK3(p1)}; copy_v3_v3(r_p1, p1); madd_v3_v3v3fl(r_p2, p1_copy, dp, t / div); @@ -3598,7 +3552,7 @@ bool clip_segment_v3_plane_n(const float p1[3], if (t >= div) { return false; } - else if (t > 0.0f) { + if (t > 0.0f) { t /= div; if (t > p1_fac) { p1_fac = t; @@ -3613,7 +3567,7 @@ bool clip_segment_v3_plane_n(const float p1[3], if (t >= 0.0f) { return false; } - else if (t > div) { + if (t > div) { t /= div; if (t < p2_fac) { p2_fac = t; @@ -3797,8 +3751,8 @@ int barycentric_inside_triangle_v2(const float w[3]) if (IN_RANGE(w[0], 0.0f, 1.0f) && IN_RANGE(w[1], 0.0f, 1.0f) && IN_RANGE(w[2], 0.0f, 1.0f)) { return 1; } - else if (IN_RANGE_INCL(w[0], 0.0f, 1.0f) && IN_RANGE_INCL(w[1], 0.0f, 1.0f) && - IN_RANGE_INCL(w[2], 0.0f, 1.0f)) { + if (IN_RANGE_INCL(w[0], 0.0f, 1.0f) && IN_RANGE_INCL(w[1], 0.0f, 1.0f) && + IN_RANGE_INCL(w[2], 0.0f, 1.0f)) { return 2; } @@ -4095,68 +4049,67 @@ int interp_sparse_array(float *array, const int list_size, const float skipval) if (found_valid == 0) { return -1; } - else if (found_invalid == 0) { + if (found_invalid == 0) { return 0; } - else { - /* found invalid depths, interpolate */ - float valid_last = skipval; - int valid_ofs = 0; - float *array_up = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up"); - float *array_down = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up"); + /* found invalid depths, interpolate */ + float valid_last = skipval; + int valid_ofs = 0; - int *ofs_tot_up = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tup"); - int *ofs_tot_down = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tdown"); + float *array_up = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up"); + float *array_down = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up"); - for (i = 0; i < list_size; i++) { - if (array[i] == skipval) { - array_up[i] = valid_last; - ofs_tot_up[i] = ++valid_ofs; - } - else { - valid_last = array[i]; - valid_ofs = 0; - } + int *ofs_tot_up = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tup"); + int *ofs_tot_down = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tdown"); + + for (i = 0; i < list_size; i++) { + if (array[i] == skipval) { + array_up[i] = valid_last; + ofs_tot_up[i] = ++valid_ofs; + } + else { + valid_last = array[i]; + valid_ofs = 0; } + } - valid_last = skipval; - valid_ofs = 0; + valid_last = skipval; + valid_ofs = 0; - for (i = list_size - 1; i >= 0; i--) { - if (array[i] == skipval) { - array_down[i] = valid_last; - ofs_tot_down[i] = ++valid_ofs; - } - else { - valid_last = array[i]; - valid_ofs = 0; - } + for (i = list_size - 1; i >= 0; i--) { + if (array[i] == skipval) { + array_down[i] = valid_last; + ofs_tot_down[i] = ++valid_ofs; + } + else { + valid_last = array[i]; + valid_ofs = 0; } + } - /* now blend */ - for (i = 0; i < list_size; i++) { - if (array[i] == skipval) { - if (array_up[i] != skipval && array_down[i] != skipval) { - array[i] = ((array_up[i] * (float)ofs_tot_down[i]) + - (array_down[i] * (float)ofs_tot_up[i])) / - (float)(ofs_tot_down[i] + ofs_tot_up[i]); - } - else if (array_up[i] != skipval) { - array[i] = array_up[i]; - } - else if (array_down[i] != skipval) { - array[i] = array_down[i]; - } + /* now blend */ + for (i = 0; i < list_size; i++) { + if (array[i] == skipval) { + if (array_up[i] != skipval && array_down[i] != skipval) { + array[i] = ((array_up[i] * (float)ofs_tot_down[i]) + + (array_down[i] * (float)ofs_tot_up[i])) / + (float)(ofs_tot_down[i] + ofs_tot_up[i]); + } + else if (array_up[i] != skipval) { + array[i] = array_up[i]; + } + else if (array_down[i] != skipval) { + array[i] = array_down[i]; } } + } - MEM_freeN(array_up); - MEM_freeN(array_down); + MEM_freeN(array_up); + MEM_freeN(array_down); - MEM_freeN(ofs_tot_up); - MEM_freeN(ofs_tot_down); - } + MEM_freeN(ofs_tot_up); + MEM_freeN(ofs_tot_down); return 1; } @@ -4279,7 +4232,7 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[ ix_flag = IS_POINT_IX; break; } - else if (UNLIKELY(dist_squared_to_line_segment_v3(co, v_curr, v_next) < eps_sq)) { + if (UNLIKELY(dist_squared_to_line_segment_v3(co, v_curr, v_next) < eps_sq)) { ix_flag = IS_SEGMENT_IX; break; } @@ -4364,7 +4317,7 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[ ix_flag = IS_POINT_IX; break; } - else if (UNLIKELY(dist_squared_to_line_segment_v2(co, v_curr, v_next) < eps_sq)) { + if (UNLIKELY(dist_squared_to_line_segment_v2(co, v_curr, v_next) < eps_sq)) { ix_flag = IS_SEGMENT_IX; break; } @@ -4647,17 +4600,15 @@ float resolve_quad_u_v2(const float st[2], if (IS_ZERO(fDen) == 0) { return (float)(a / fDen); } - else { - return 0.0f; - } - } - else { - const double desc_sq = b * b - a * fC; - const double desc = sqrt(desc_sq < 0.0 ? 0.0 : desc_sq); - const double s = signed_area > 0 ? (-1.0) : 1.0; - return (float)(((a - b) + s * desc) / denom); + return 0.0f; } + + const double desc_sq = b * b - a * fC; + const double desc = sqrt(desc_sq < 0.0 ? 0.0 : desc_sq); + const double s = signed_area > 0 ? (-1.0) : 1.0; + + return (float)(((a - b) + s * desc) / denom); } #undef IS_ZERO @@ -4959,7 +4910,7 @@ void projmat_from_subregion(const float projmat[4][4], } } -static void i_multmatrix(float icand[4][4], float Vm[4][4]) +static void i_multmatrix(const float icand[4][4], float Vm[4][4]) { int row, col; float temp[4][4]; @@ -5155,7 +5106,7 @@ void map_to_sphere(float *r_u, float *r_v, const float x, const float y, const f void map_to_plane_v2_v3v3(float r_co[2], const float co[3], const float no[3]) { - float target[3] = {0.0f, 0.0f, 1.0f}; + const float target[3] = {0.0f, 0.0f, 1.0f}; float axis[3]; cross_v3_v3v3(axis, no, target); @@ -6139,17 +6090,16 @@ float cubic_tangent_factor_circle_v3(const float tan_l[3], const float tan_r[3]) /* no angle difference (use fallback, length wont make any difference) */ return (1.0f / 3.0f) * 0.75f; } - else if (tan_dot < -1.0f + eps) { + if (tan_dot < -1.0f + eps) { /* parallele tangents (half-circle) */ return (1.0f / 2.0f); } - else { - /* non-aligned tangents, calculate handle length */ - const float angle = acosf(tan_dot) / 2.0f; - /* could also use 'angle_sin = len_vnvn(tan_l, tan_r, dims) / 2.0' */ - const float angle_sin = sinf(angle); - const float angle_cos = cosf(angle); - return ((1.0f - angle_cos) / (angle_sin * 2.0f)) / angle_sin; - } + /* non-aligned tangents, calculate handle length */ + const float angle = acosf(tan_dot) / 2.0f; + + /* could also use 'angle_sin = len_vnvn(tan_l, tan_r, dims) / 2.0' */ + const float angle_sin = sinf(angle); + const float angle_cos = cosf(angle); + return ((1.0f - angle_cos) / (angle_sin * 2.0f)) / angle_sin; } diff --git a/source/blender/blenlib/intern/math_interp.c b/source/blender/blenlib/intern/math_interp.c index 6277b1cd9dc..13a1816f1bd 100644 --- a/source/blender/blenlib/intern/math_interp.c +++ b/source/blender/blenlib/intern/math_interp.c @@ -286,7 +286,7 @@ BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer, if (float_output) { const float *row1, *row2, *row3, *row4; - float empty[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float empty[4] = {0.0f, 0.0f, 0.0f, 0.0f}; /* pixel value must be already wrapped, however values at boundaries may flip */ if (wrap_x) { diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index a2f7cc24dd3..a6368981050 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -644,9 +644,8 @@ float angle_signed_normalized_qt(const float q[4]) if (q[0] >= 0.0f) { return 2.0f * saacos(q[0]); } - else { - return -2.0f * saacos(-q[0]); - } + + return -2.0f * saacos(-q[0]); } float angle_signed_normalized_qtqt(const float q1[4], const float q2[4]) @@ -654,11 +653,10 @@ float angle_signed_normalized_qtqt(const float q1[4], const float q2[4]) if (dot_qtqt(q1, q2) >= 0.0f) { return angle_normalized_qtqt(q1, q2); } - else { - float q2_copy[4]; - negate_v4_v4(q2_copy, q2); - return -angle_normalized_qtqt(q1, q2_copy); - } + + float q2_copy[4]; + negate_v4_v4(q2_copy, q2); + return -angle_normalized_qtqt(q1, q2_copy); } float angle_signed_qt(const float q[4]) @@ -675,11 +673,10 @@ float angle_signed_qtqt(const float q1[4], const float q2[4]) if (dot_qtqt(q1, q2) >= 0.0f) { return angle_qtqt(q1, q2); } - else { - float q2_copy[4]; - negate_v4_v4(q2_copy, q2); - return -angle_qtqt(q1, q2_copy); - } + + float q2_copy[4]; + negate_v4_v4(q2_copy, q2); + return -angle_qtqt(q1, q2_copy); } /** \} */ @@ -1594,12 +1591,11 @@ static const RotOrderInfo *get_rotation_order_info(const short order) if (order < 1) { return &rotOrders[0]; } - else if (order < 6) { + if (order < 6) { return &rotOrders[order - 1]; } - else { - return &rotOrders[5]; - } + + return &rotOrders[5]; } /* Construct quaternion from Euler angles (in radians). */ diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 7f1840228e2..909d508e262 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -506,11 +506,10 @@ float angle_normalized_v3v3(const float v1[3], const float v2[3]) if (dot_v3v3(v1, v2) >= 0.0f) { return 2.0f * saasin(len_v3v3(v1, v2) / 2.0f); } - else { - float v2_n[3]; - negate_v3_v3(v2_n, v2); - return (float)M_PI - 2.0f * saasin(len_v3v3(v1, v2_n) / 2.0f); - } + + float v2_n[3]; + negate_v3_v3(v2_n, v2); + return (float)M_PI - 2.0f * saasin(len_v3v3(v1, v2_n) / 2.0f); } float angle_normalized_v2v2(const float v1[2], const float v2[2]) @@ -523,11 +522,10 @@ float angle_normalized_v2v2(const float v1[2], const float v2[2]) if (dot_v2v2(v1, v2) >= 0.0f) { return 2.0f * saasin(len_v2v2(v1, v2) / 2.0f); } - else { - float v2_n[2]; - negate_v2_v2(v2_n, v2); - return (float)M_PI - 2.0f * saasin(len_v2v2(v1, v2_n) / 2.0f); - } + + float v2_n[2]; + negate_v2_v2(v2_n, v2); + return (float)M_PI - 2.0f * saasin(len_v2v2(v1, v2_n) / 2.0f); } /** diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index d912cb8d464..67d41ffb779 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -427,9 +427,8 @@ static int BLI_path_unc_prefix_len(const char *path) /* we assume long UNC path like \\?\server\share\folder etc... */ return 4; } - else { - return 2; - } + + return 2; } return 0; @@ -683,7 +682,7 @@ bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char has_extension = true; break; } - else if (ELEM(string[a], '/', '\\')) { + if (ELEM(string[a], '/', '\\')) { break; } } @@ -713,9 +712,8 @@ bool BLI_path_parent_dir(char *path) strcpy(path, tmp); /* We assume pardir is always shorter... */ return true; } - else { - return false; - } + + return false; } /** @@ -764,11 +762,10 @@ static bool stringframe_chars(const char *path, int *char_start, int *char_end) *char_end = ch_end; return true; } - else { - *char_start = -1; - *char_end = -1; - return false; - } + + *char_start = -1; + *char_end = -1; + return false; } /** @@ -1731,9 +1728,8 @@ void BLI_join_dirfile(char *__restrict dst, dst[dirlen - 1] = '\0'; return; /* dir fills the path */ } - else { - memcpy(dst, dir, dirlen + 1); - } + + memcpy(dst, dir, dirlen + 1); if (dirlen + 1 >= maxlen) { return; /* fills the path */ @@ -1891,32 +1887,31 @@ bool BLI_path_name_at_index(const char *__restrict path, } return false; } - else { - /* negative number, reverse where -1 is the last element */ - int index_step = -1; - int prev = strlen(path); - int i = prev - 1; - while (true) { - const char c = i >= 0 ? path[i] : '\0'; - if (ELEM(c, SEP, ALTSEP, '\0')) { - if (prev - 1 != i) { - i += 1; - if (index_step == index) { - *r_offset = i; - *r_len = prev - i; - return true; - } - index_step -= 1; - } - if (c == '\0') { - break; + + /* negative number, reverse where -1 is the last element */ + int index_step = -1; + int prev = strlen(path); + int i = prev - 1; + while (true) { + const char c = i >= 0 ? path[i] : '\0'; + if (ELEM(c, SEP, ALTSEP, '\0')) { + if (prev - 1 != i) { + i += 1; + if (index_step == index) { + *r_offset = i; + *r_len = prev - i; + return true; } - prev = i; + index_step -= 1; } - i -= 1; + if (c == '\0') { + break; + } + prev = i; } - return false; + i -= 1; } + return false; } /** @@ -1930,7 +1925,7 @@ const char *BLI_path_slash_find(const char *string) if (!ffslash) { return fbslash; } - else if (!fbslash) { + if (!fbslash) { return ffslash; } @@ -1948,7 +1943,7 @@ const char *BLI_path_slash_rfind(const char *string) if (!lfslash) { return lbslash; } - else if (!lbslash) { + if (!lbslash) { return lfslash; } diff --git a/source/blender/blenlib/intern/polyfill_2d.c b/source/blender/blenlib/intern/polyfill_2d.c index 90a4a4f4c2d..d1e2bd58909 100644 --- a/source/blender/blenlib/intern/polyfill_2d.c +++ b/source/blender/blenlib/intern/polyfill_2d.c @@ -177,12 +177,11 @@ BLI_INLINE eSign signum_enum(float a) if (UNLIKELY(a == 0.0f)) { return 0; } - else if (a > 0.0f) { + if (a > 0.0f) { return 1; } - else { - return -1; - } + + return -1; } /** @@ -250,7 +249,7 @@ static uint kdtree2d_balance_recursive( if (totnode <= 0) { return KDNODE_UNSET; } - else if (totnode == 1) { + if (totnode == 1) { return 0 + ofs; } @@ -330,9 +329,8 @@ static void kdtree2d_node_remove(struct KDTree2D *tree, uint index) if (node_index == KDNODE_UNSET) { return; } - else { - tree->nodes_map[index] = KDNODE_UNSET; - } + + tree->nodes_map[index] = KDNODE_UNSET; node = &tree->nodes[node_index]; tree->totnode -= 1; diff --git a/source/blender/blenlib/intern/polyfill_2d_beautify.c b/source/blender/blenlib/intern/polyfill_2d_beautify.c index 41364c5a3a9..7bfca149ffb 100644 --- a/source/blender/blenlib/intern/polyfill_2d_beautify.c +++ b/source/blender/blenlib/intern/polyfill_2d_beautify.c @@ -64,14 +64,14 @@ static int oedge_cmp(const void *a1, const void *a2) if (x1->verts[0] > x2->verts[0]) { return 1; } - else if (x1->verts[0] < x2->verts[0]) { + if (x1->verts[0] < x2->verts[0]) { return -1; } if (x1->verts[1] > x2->verts[1]) { return 1; } - else if (x1->verts[1] < x2->verts[1]) { + if (x1->verts[1] < x2->verts[1]) { return -1; } @@ -79,7 +79,7 @@ static int oedge_cmp(const void *a1, const void *a2) if (x1->e_half > x2->e_half) { return 1; } - else if (x1->e_half < x2->e_half) { + if (x1->e_half < x2->e_half) { return -1; } /* Should never get here, no two edges should be the same. */ @@ -141,7 +141,7 @@ float BLI_polyfill_beautify_quad_rotate_calc_ex(const float v1[2], if ((area_2x_123 >= 0.0f) != (area_2x_134 >= 0.0f)) { break; } - else if ((fabsf(area_2x_123) <= eps_zero_area) || (fabsf(area_2x_134) <= eps_zero_area)) { + if ((fabsf(area_2x_123) <= eps_zero_area) || (fabsf(area_2x_134) <= eps_zero_area)) { break; } @@ -150,11 +150,10 @@ float BLI_polyfill_beautify_quad_rotate_calc_ex(const float v1[2], if (lock_degenerate) { break; } - else { - return -FLT_MAX; /* always rotate */ - } + + return -FLT_MAX; /* always rotate */ } - else if ((fabsf(area_2x_234) <= eps_zero_area) || (fabsf(area_2x_241) <= eps_zero_area)) { + if ((fabsf(area_2x_234) <= eps_zero_area) || (fabsf(area_2x_241) <= eps_zero_area)) { return -FLT_MAX; /* always rotate */ } diff --git a/source/blender/blenlib/intern/quadric.c b/source/blender/blenlib/intern/quadric.c index 3ad1844cfe1..ac522171951 100644 --- a/source/blender/blenlib/intern/quadric.c +++ b/source/blender/blenlib/intern/quadric.c @@ -107,9 +107,8 @@ static bool quadric_to_tensor_m3_inverse(const Quadric *q, double m[3][3], doubl return true; } - else { - return false; - } + + return false; } void BLI_quadric_to_vector_v3(const Quadric *q, double v[3]) @@ -161,7 +160,6 @@ bool BLI_quadric_optimize(const Quadric *q, double v[3], const double epsilon) negate_v3_db(v); return true; } - else { - return false; - } + + return false; } diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index bf3c8730b01..f952b62cb61 100644 --- a/source/blender/blenlib/intern/rct.c +++ b/source/blender/blenlib/intern/rct.c @@ -238,15 +238,14 @@ static int isect_segments_i(const int v1[2], const int v2[2], const int v3[2], c if (div == 0.0) { return 1; /* co-linear */ } - else { - const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - - (v1[0] - v3[0]) * (v4[1] - v3[1])) / - div; - const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) - - (v1[0] - v3[0]) * (v2[1] - v1[1])) / - div; - return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0); - } + + const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - + (v1[0] - v3[0]) * (v4[1] - v3[1])) / + div; + const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) - + (v1[0] - v3[0]) * (v2[1] - v1[1])) / + div; + return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0); } static int isect_segments_fl(const float v1[2], const float v2[2], @@ -258,15 +257,14 @@ static int isect_segments_fl(const float v1[2], if (div == 0.0) { return 1; /* co-linear */ } - else { - const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - - (v1[0] - v3[0]) * (v4[1] - v3[1])) / - div; - const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) - - (v1[0] - v3[0]) * (v2[1] - v1[1])) / - div; - return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0); - } + + const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - + (v1[0] - v3[0]) * (v4[1] - v3[1])) / + div; + const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) - + (v1[0] - v3[0]) * (v2[1] - v1[1])) / + div; + return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0); } bool BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2]) @@ -289,31 +287,30 @@ bool BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2]) if (BLI_rcti_isect_pt_v(rect, s1) || BLI_rcti_isect_pt_v(rect, s2)) { return true; } - else { - /* both points are outside but may intersect the rect */ - int tvec1[2]; - int tvec2[2]; - /* diagonal: [/] */ - tvec1[0] = rect->xmin; - tvec1[1] = rect->ymin; - tvec2[0] = rect->xmin; - tvec2[1] = rect->ymax; - if (isect_segments_i(s1, s2, tvec1, tvec2)) { - return true; - } - /* diagonal: [\] */ - tvec1[0] = rect->xmin; - tvec1[1] = rect->ymax; - tvec2[0] = rect->xmax; - tvec2[1] = rect->ymin; - if (isect_segments_i(s1, s2, tvec1, tvec2)) { - return true; - } + /* both points are outside but may intersect the rect */ + int tvec1[2]; + int tvec2[2]; + /* diagonal: [/] */ + tvec1[0] = rect->xmin; + tvec1[1] = rect->ymin; + tvec2[0] = rect->xmin; + tvec2[1] = rect->ymax; + if (isect_segments_i(s1, s2, tvec1, tvec2)) { + return true; + } - /* no intersection */ - return false; + /* diagonal: [\] */ + tvec1[0] = rect->xmin; + tvec1[1] = rect->ymax; + tvec2[0] = rect->xmax; + tvec2[1] = rect->ymin; + if (isect_segments_i(s1, s2, tvec1, tvec2)) { + return true; } + + /* no intersection */ + return false; } bool BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[2]) @@ -336,31 +333,30 @@ bool BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[ if (BLI_rctf_isect_pt_v(rect, s1) || BLI_rctf_isect_pt_v(rect, s2)) { return true; } - else { - /* both points are outside but may intersect the rect */ - float tvec1[2]; - float tvec2[2]; - /* diagonal: [/] */ - tvec1[0] = rect->xmin; - tvec1[1] = rect->ymin; - tvec2[0] = rect->xmin; - tvec2[1] = rect->ymax; - if (isect_segments_fl(s1, s2, tvec1, tvec2)) { - return true; - } - /* diagonal: [\] */ - tvec1[0] = rect->xmin; - tvec1[1] = rect->ymax; - tvec2[0] = rect->xmax; - tvec2[1] = rect->ymin; - if (isect_segments_fl(s1, s2, tvec1, tvec2)) { - return true; - } + /* both points are outside but may intersect the rect */ + float tvec1[2]; + float tvec2[2]; + /* diagonal: [/] */ + tvec1[0] = rect->xmin; + tvec1[1] = rect->ymin; + tvec2[0] = rect->xmin; + tvec2[1] = rect->ymax; + if (isect_segments_fl(s1, s2, tvec1, tvec2)) { + return true; + } - /* no intersection */ - return false; + /* diagonal: [\] */ + tvec1[0] = rect->xmin; + tvec1[1] = rect->ymax; + tvec2[0] = rect->xmax; + tvec2[1] = rect->ymin; + if (isect_segments_fl(s1, s2, tvec1, tvec2)) { + return true; } + + /* no intersection */ + return false; } bool BLI_rcti_isect_circle(const rcti *rect, const float xy[2], const float radius) @@ -890,15 +886,14 @@ bool BLI_rctf_isect(const rctf *src1, const rctf *src2, rctf *dest) } return true; } - else { - if (dest) { - dest->xmin = 0; - dest->xmax = 0; - dest->ymin = 0; - dest->ymax = 0; - } - return false; + + if (dest) { + dest->xmin = 0; + dest->xmax = 0; + dest->ymin = 0; + dest->ymax = 0; } + return false; } bool BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest) @@ -920,15 +915,14 @@ bool BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest) } return true; } - else { - if (dest) { - dest->xmin = 0; - dest->xmax = 0; - dest->ymin = 0; - dest->ymax = 0; - } - return false; + + if (dest) { + dest->xmin = 0; + dest->xmax = 0; + dest->ymin = 0; + dest->ymax = 0; } + return false; } bool BLI_rctf_isect_rect_x(const rctf *src1, const rctf *src2, float range_x[2]) @@ -943,13 +937,12 @@ bool BLI_rctf_isect_rect_x(const rctf *src1, const rctf *src2, float range_x[2]) } return true; } - else { - if (range_x) { - range_x[0] = 0; - range_x[1] = 0; - } - return false; + + if (range_x) { + range_x[0] = 0; + range_x[1] = 0; } + return false; } bool BLI_rctf_isect_rect_y(const rctf *src1, const rctf *src2, float range_y[2]) @@ -964,13 +957,12 @@ bool BLI_rctf_isect_rect_y(const rctf *src1, const rctf *src2, float range_y[2]) } return true; } - else { - if (range_y) { - range_y[0] = 0; - range_y[1] = 0; - } - return false; + + if (range_y) { + range_y[0] = 0; + range_y[1] = 0; } + return false; } bool BLI_rcti_isect_rect_x(const rcti *src1, const rcti *src2, int range_x[2]) @@ -985,13 +977,12 @@ bool BLI_rcti_isect_rect_x(const rcti *src1, const rcti *src2, int range_x[2]) } return true; } - else { - if (range_x) { - range_x[0] = 0; - range_x[1] = 0; - } - return false; + + if (range_x) { + range_x[0] = 0; + range_x[1] = 0; } + return false; } bool BLI_rcti_isect_rect_y(const rcti *src1, const rcti *src2, int range_y[2]) @@ -1006,13 +997,12 @@ bool BLI_rcti_isect_rect_y(const rcti *src1, const rcti *src2, int range_y[2]) } return true; } - else { - if (range_y) { - range_y[0] = 0; - range_y[1] = 0; - } - return false; + + if (range_y) { + range_y[0] = 0; + range_y[1] = 0; } + return false; } void BLI_rcti_rctf_copy(rcti *dst, const rctf *src) diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c index 4723a3532ac..8b536354af2 100644 --- a/source/blender/blenlib/intern/scanfill.c +++ b/source/blender/blenlib/intern/scanfill.c @@ -91,13 +91,13 @@ static int vergscdata(const void *a1, const void *a2) if (x1->vert->xy[1] < x2->vert->xy[1]) { return 1; } - else if (x1->vert->xy[1] > x2->vert->xy[1]) { + if (x1->vert->xy[1] > x2->vert->xy[1]) { return -1; } - else if (x1->vert->xy[0] > x2->vert->xy[0]) { + if (x1->vert->xy[0] > x2->vert->xy[0]) { return 1; } - else if (x1->vert->xy[0] < x2->vert->xy[0]) { + if (x1->vert->xy[0] < x2->vert->xy[0]) { return -1; } @@ -111,13 +111,13 @@ static int vergpoly(const void *a1, const void *a2) if (x1->min_xy[0] > x2->min_xy[0]) { return 1; } - else if (x1->min_xy[0] < x2->min_xy[0]) { + if (x1->min_xy[0] < x2->min_xy[0]) { return -1; } - else if (x1->min_xy[1] > x2->min_xy[1]) { + if (x1->min_xy[1] > x2->min_xy[1]) { return 1; } - else if (x1->min_xy[1] < x2->min_xy[1]) { + if (x1->min_xy[1] < x2->min_xy[1]) { return -1; } @@ -259,7 +259,7 @@ static bool testedgeside(const float v1[2], const float v2[2], const float v3[2] if (inp < 0.0f) { return false; } - else if (inp == 0.0f) { + if (inp == 0.0f) { if (v1[0] == v3[0] && v1[1] == v3[1]) { return false; } @@ -417,25 +417,24 @@ static void testvertexnearedge(ScanFillContext *sf_ctx) eve->edge_tot = 0; break; } - else if (compare_v2v2(eve->xy, eed->v2->xy, SF_EPSILON)) { + if (compare_v2v2(eve->xy, eed->v2->xy, SF_EPSILON)) { ed1->v2 = eed->v2; eed->v2->edge_tot++; eve->edge_tot = 0; break; } - else { - if (boundinsideEV(eed, eve)) { - const float dist = dist_squared_to_line_v2(eed->v1->xy, eed->v2->xy, eve->xy); - if (dist < SF_EPSILON_SQ) { - /* new edge */ - ed1 = BLI_scanfill_edge_add(sf_ctx, eed->v1, eve); - - /* printf("fill: vertex near edge %x\n", eve); */ - ed1->poly_nr = eed->poly_nr; - eed->v1 = eve; - eve->edge_tot = 3; - break; - } + + if (boundinsideEV(eed, eve)) { + const float dist = dist_squared_to_line_v2(eed->v1->xy, eed->v2->xy, eve->xy); + if (dist < SF_EPSILON_SQ) { + /* new edge */ + ed1 = BLI_scanfill_edge_add(sf_ctx, eed->v1, eve); + + /* printf("fill: vertex near edge %x\n", eve); */ + ed1->poly_nr = eed->poly_nr; + eed->v1 = eve; + eve->edge_tot = 3; + break; } } } @@ -875,41 +874,40 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const if (UNLIKELY(eve == NULL)) { return 0; } + + float n[3]; + + if (nor_proj) { + copy_v3_v3(n, nor_proj); + } else { - float n[3]; + /* define projection: with 'best' normal */ + /* Newell's Method */ + /* Similar code used elsewhere, but this checks for double ups + * which historically this function supports so better not change */ - if (nor_proj) { - copy_v3_v3(n, nor_proj); - } - else { - /* define projection: with 'best' normal */ - /* Newell's Method */ - /* Similar code used elsewhere, but this checks for double ups - * which historically this function supports so better not change */ - - /* warning: this only gives stable direction with single polygons, - * ideally we'd calculate connectivity and each polys normal, see T41047 */ - const float *v_prev; - - zero_v3(n); - eve = sf_ctx->fillvertbase.last; - v_prev = eve->co; - - for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) { - if (LIKELY(!compare_v3v3(v_prev, eve->co, SF_EPSILON))) { - add_newell_cross_v3_v3v3(n, v_prev, eve->co); - v_prev = eve->co; - } - } - } + /* warning: this only gives stable direction with single polygons, + * ideally we'd calculate connectivity and each polys normal, see T41047 */ + const float *v_prev; - if (UNLIKELY(normalize_v3(n) == 0.0f)) { - return 0; + zero_v3(n); + eve = sf_ctx->fillvertbase.last; + v_prev = eve->co; + + for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) { + if (LIKELY(!compare_v3v3(v_prev, eve->co, SF_EPSILON))) { + add_newell_cross_v3_v3v3(n, v_prev, eve->co); + v_prev = eve->co; + } } + } - axis_dominant_v3_to_m3_negate(mat_2d, n); + if (UNLIKELY(normalize_v3(n) == 0.0f)) { + return 0; } + axis_dominant_v3_to_m3_negate(mat_2d, n); + /* STEP 1: COUNT POLYS */ if (sf_ctx->poly_nr != SF_POLY_UNSET) { poly = (unsigned short)(sf_ctx->poly_nr + 1); diff --git a/source/blender/blenlib/intern/scanfill_utils.c b/source/blender/blenlib/intern/scanfill_utils.c index 31b2bf85142..660d3dca807 100644 --- a/source/blender/blenlib/intern/scanfill_utils.c +++ b/source/blender/blenlib/intern/scanfill_utils.c @@ -139,9 +139,8 @@ static int edge_isect_ls_sort_cb(void *thunk, const void *def_a_ptr, const void if (a > b) { return -1; } - else { - return (a < b); - } + + return (a < b); } static ScanFillEdge *edge_step(PolyInfo *poly_info, diff --git a/source/blender/blenlib/intern/smallhash.c b/source/blender/blenlib/intern/smallhash.c index 6d1ce3c84cd..ab2b0fd2928 100644 --- a/source/blender/blenlib/intern/smallhash.c +++ b/source/blender/blenlib/intern/smallhash.c @@ -253,10 +253,9 @@ bool BLI_smallhash_reinsert(SmallHash *sh, uintptr_t key, void *item) e->val = item; return false; } - else { - BLI_smallhash_insert(sh, key, item); - return true; - } + + BLI_smallhash_insert(sh, key, item); + return true; } #ifdef USE_REMOVE diff --git a/source/blender/blenlib/intern/sort_utils.c b/source/blender/blenlib/intern/sort_utils.c index 09babd3d424..e02d77de0c7 100644 --- a/source/blender/blenlib/intern/sort_utils.c +++ b/source/blender/blenlib/intern/sort_utils.c @@ -44,12 +44,11 @@ int BLI_sortutil_cmp_float(const void *a_, const void *b_) if (a->sort_value > b->sort_value) { return 1; } - else if (a->sort_value < b->sort_value) { + if (a->sort_value < b->sort_value) { return -1; } - else { - return 0; - } + + return 0; } int BLI_sortutil_cmp_float_reverse(const void *a_, const void *b_) @@ -59,12 +58,11 @@ int BLI_sortutil_cmp_float_reverse(const void *a_, const void *b_) if (a->sort_value < b->sort_value) { return 1; } - else if (a->sort_value > b->sort_value) { + if (a->sort_value > b->sort_value) { return -1; } - else { - return 0; - } + + return 0; } int BLI_sortutil_cmp_int(const void *a_, const void *b_) @@ -74,12 +72,11 @@ int BLI_sortutil_cmp_int(const void *a_, const void *b_) if (a->sort_value > b->sort_value) { return 1; } - else if (a->sort_value < b->sort_value) { + if (a->sort_value < b->sort_value) { return -1; } - else { - return 0; - } + + return 0; } int BLI_sortutil_cmp_int_reverse(const void *a_, const void *b_) @@ -89,12 +86,11 @@ int BLI_sortutil_cmp_int_reverse(const void *a_, const void *b_) if (a->sort_value < b->sort_value) { return 1; } - else if (a->sort_value > b->sort_value) { + if (a->sort_value > b->sort_value) { return -1; } - else { - return 0; - } + + return 0; } int BLI_sortutil_cmp_ptr(const void *a_, const void *b_) @@ -104,12 +100,11 @@ int BLI_sortutil_cmp_ptr(const void *a_, const void *b_) if (a->sort_value > b->sort_value) { return 1; } - else if (a->sort_value < b->sort_value) { + if (a->sort_value < b->sort_value) { return -1; } - else { - return 0; - } + + return 0; } int BLI_sortutil_cmp_ptr_reverse(const void *a_, const void *b_) @@ -119,10 +114,9 @@ int BLI_sortutil_cmp_ptr_reverse(const void *a_, const void *b_) if (a->sort_value < b->sort_value) { return 1; } - else if (a->sort_value > b->sort_value) { + if (a->sort_value > b->sort_value) { return -1; } - else { - return 0; - } + + return 0; } diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index d3191148c90..fbd9e562b6a 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -96,9 +96,7 @@ char *BLI_current_working_dir(char *dir, const size_t maxncpy) memcpy(dir, pwd, srclen + 1); return dir; } - else { - return NULL; - } + return NULL; } return getcwd(dir, maxncpy); #endif diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index abdae06acd5..8b4720ca1e1 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -394,9 +394,7 @@ char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict if (LIKELY(*(endMatch - 1) != '\\')) { break; } - else { - endMatch++; - } + endMatch++; } if (endMatch) { @@ -470,11 +468,9 @@ char *BLI_str_replaceN(const char *__restrict str, return str_new; } - else { - /* Just create a new copy of the entire string - we avoid going through the assembly buffer - * for what should be a bit more efficiency. */ - return BLI_strdup(str); - } + /* Just create a new copy of the entire string - we avoid going through the assembly buffer + * for what should be a bit more efficiency. */ + return BLI_strdup(str); } /** @@ -574,10 +570,10 @@ int BLI_strcasecmp(const char *s1, const char *s2) if (c1 < c2) { return -1; } - else if (c1 > c2) { + if (c1 > c2) { return 1; } - else if (c1 == 0) { + if (c1 == 0) { break; } } @@ -597,10 +593,10 @@ int BLI_strncasecmp(const char *s1, const char *s2, size_t len) if (c1 < c2) { return -1; } - else if (c1 > c2) { + if (c1 > c2) { return 1; } - else if (c1 == 0) { + if (c1 == 0) { break; } } @@ -627,15 +623,13 @@ static int left_number_strcmp(const char *s1, const char *s2, int *tiebreaker) if (isdigit(*(p1 + numdigit)) && isdigit(*(p2 + numdigit))) { continue; } - else if (isdigit(*(p1 + numdigit))) { + if (isdigit(*(p1 + numdigit))) { return 1; /* s2 is bigger */ } - else if (isdigit(*(p2 + numdigit))) { + if (isdigit(*(p2 + numdigit))) { return -1; /* s1 is bigger */ } - else { - break; - } + break; } /* same number of digits, compare size of number */ @@ -759,14 +753,14 @@ int BLI_strcmp_ignore_pad(const char *str1, const char *str2, const char pad) if (str1_len == str2_len) { return strncmp(str1, str2, str2_len); } - else if (str1_len > str2_len) { + if (str1_len > str2_len) { int ret = strncmp(str1, str2, str2_len); if (ret == 0) { ret = 1; } return ret; } - else { + { int ret = strncmp(str1, str2, str1_len); if (ret == 0) { ret = -1; diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c index e9fdce83710..0a723a623f0 100644 --- a/source/blender/blenlib/intern/string_utf8.c +++ b/source/blender/blenlib/intern/string_utf8.c @@ -215,11 +215,9 @@ int BLI_utf8_invalid_strip(char *str, size_t length) tot++; break; } - else { - /* strip, keep looking */ - memmove(str, str + 1, length + 1); /* +1 for NULL char! */ - tot++; - } + /* strip, keep looking */ + memmove(str, str + 1, length + 1); /* +1 for NULL char! */ + tot++; } return tot; diff --git a/source/blender/blenlib/intern/string_utils.c b/source/blender/blenlib/intern/string_utils.c index fb9530b5cb5..dbeb75570fb 100644 --- a/source/blender/blenlib/intern/string_utils.c +++ b/source/blender/blenlib/intern/string_utils.c @@ -72,7 +72,7 @@ size_t BLI_split_name_num(char *left, int *nr, const char *name, const char deli } return a; } - else if (isdigit(name[a]) == 0) { + if (isdigit(name[a]) == 0) { /* non-numeric suffix - give up */ break; } diff --git a/source/blender/blenlib/intern/threads.cc b/source/blender/blenlib/intern/threads.cc index a8333d0c696..002b78bec39 100644 --- a/source/blender/blenlib/intern/threads.cc +++ b/source/blender/blenlib/intern/threads.cc @@ -309,7 +309,7 @@ int BLI_system_thread_count(void) if (num_threads_override != 0) { return num_threads_override; } - else if (LIKELY(t != -1)) { + if (LIKELY(t != -1)) { return t; } @@ -751,7 +751,7 @@ void *BLI_thread_queue_pop_timeout(ThreadQueue *queue, int ms) if (pthread_cond_timedwait(&queue->push_cond, &queue->mutex, &timeout) == ETIMEDOUT) { break; } - else if (PIL_check_seconds_timer() - t >= ms * 0.001) { + if (PIL_check_seconds_timer() - t >= ms * 0.001) { break; } } diff --git a/source/blender/blenlib/intern/voronoi_2d.c b/source/blender/blenlib/intern/voronoi_2d.c index bc11a2c7a1c..5b998973a20 100644 --- a/source/blender/blenlib/intern/voronoi_2d.c +++ b/source/blender/blenlib/intern/voronoi_2d.c @@ -83,7 +83,9 @@ static void voronoi_insertEvent(VoronoiProcess *process, VoronoiEvent *event) } /* edge */ -static VoronoiEdge *voronoiEdge_new(float start[2], float left[2], float right[2]) +static VoronoiEdge *voronoiEdge_new(const float start[2], + const float left[2], + const float right[2]) { VoronoiEdge *edge = MEM_callocN(sizeof(VoronoiEdge), "voronoi edge"); @@ -118,7 +120,7 @@ static VoronoiParabola *voronoiParabola_new(void) return parabola; } -static VoronoiParabola *voronoiParabola_newSite(float site[2]) +static VoronoiParabola *voronoiParabola_newSite(const float site[2]) { VoronoiParabola *parabola = MEM_callocN(sizeof(VoronoiParabola), "voronoi parabola site"); diff --git a/source/blender/blenlib/tests/BLI_array_test.cc b/source/blender/blenlib/tests/BLI_array_test.cc new file mode 100644 index 00000000000..7348a6f93f3 --- /dev/null +++ b/source/blender/blenlib/tests/BLI_array_test.cc @@ -0,0 +1,176 @@ +/* Apache License, Version 2.0 */ + +#include "BLI_array.hh" +#include "BLI_strict_flags.h" +#include "testing/testing.h" + +namespace blender::tests { + +TEST(array, DefaultConstructor) +{ + Array<int> array; + EXPECT_EQ(array.size(), 0); + EXPECT_TRUE(array.is_empty()); +} + +TEST(array, SizeConstructor) +{ + Array<int> array(5); + EXPECT_EQ(array.size(), 5); + EXPECT_FALSE(array.is_empty()); +} + +TEST(array, FillConstructor) +{ + Array<int> array(5, 8); + EXPECT_EQ(array.size(), 5); + EXPECT_EQ(array[0], 8); + EXPECT_EQ(array[1], 8); + EXPECT_EQ(array[2], 8); + EXPECT_EQ(array[3], 8); + EXPECT_EQ(array[4], 8); +} + +TEST(array, InitializerListConstructor) +{ + Array<int> array = {4, 5, 6, 7}; + EXPECT_EQ(array.size(), 4); + EXPECT_EQ(array[0], 4); + EXPECT_EQ(array[1], 5); + EXPECT_EQ(array[2], 6); + EXPECT_EQ(array[3], 7); +} + +TEST(array, SpanConstructor) +{ + int stackarray[4] = {6, 7, 8, 9}; + Span<int> span(stackarray, ARRAY_SIZE(stackarray)); + Array<int> array(span); + EXPECT_EQ(array.size(), 4); + EXPECT_EQ(array[0], 6); + EXPECT_EQ(array[1], 7); + EXPECT_EQ(array[2], 8); + EXPECT_EQ(array[3], 9); +} + +TEST(array, CopyConstructor) +{ + Array<int> array = {5, 6, 7, 8}; + Array<int> new_array(array); + + EXPECT_EQ(array.size(), 4); + EXPECT_EQ(new_array.size(), 4); + EXPECT_NE(array.data(), new_array.data()); + EXPECT_EQ(new_array[0], 5); + EXPECT_EQ(new_array[1], 6); + EXPECT_EQ(new_array[2], 7); + EXPECT_EQ(new_array[3], 8); +} + +TEST(array, MoveConstructor) +{ + Array<int> array = {5, 6, 7, 8}; + Array<int> new_array(std::move(array)); + + EXPECT_EQ(array.size(), 0); /* NOLINT: bugprone-use-after-move */ + EXPECT_EQ(new_array.size(), 4); + EXPECT_EQ(new_array[0], 5); + EXPECT_EQ(new_array[1], 6); + EXPECT_EQ(new_array[2], 7); + EXPECT_EQ(new_array[3], 8); +} + +TEST(array, CopyAssignment) +{ + Array<int> array = {1, 2, 3}; + Array<int> new_array = {4}; + EXPECT_EQ(new_array.size(), 1); + new_array = array; + EXPECT_EQ(new_array.size(), 3); + EXPECT_EQ(array.size(), 3); + EXPECT_NE(array.data(), new_array.data()); + EXPECT_EQ(new_array[0], 1); + EXPECT_EQ(new_array[1], 2); + EXPECT_EQ(new_array[2], 3); +} + +TEST(array, MoveAssignment) +{ + Array<int> array = {1, 2, 3}; + Array<int> new_array = {4}; + EXPECT_EQ(new_array.size(), 1); + new_array = std::move(array); + EXPECT_EQ(new_array.size(), 3); + EXPECT_EQ(array.size(), 0); /* NOLINT: bugprone-use-after-move */ + EXPECT_EQ(new_array[0], 1); + EXPECT_EQ(new_array[1], 2); + EXPECT_EQ(new_array[2], 3); +} + +/** + * Tests that the trivially constructible types are not zero-initialized. We do not want that for + * performance reasons. + */ +TEST(array, TrivialTypeSizeConstructor) +{ + Array<char, 1> *array = new Array<char, 1>(1); + char *ptr = &(*array)[0]; + array->~Array(); + + const char magic = 42; + *ptr = magic; + EXPECT_EQ(*ptr, magic); + + new (array) Array<char, 1>(1); + EXPECT_EQ((*array)[0], magic); + EXPECT_EQ(*ptr, magic); + delete array; +} + +struct ConstructibleType { + char value; + + ConstructibleType() + { + value = 42; + } +}; + +TEST(array, NoInitializationSizeConstructor) +{ + using MyArray = Array<ConstructibleType>; + + TypedBuffer<MyArray> buffer; + memset((void *)&buffer, 100, sizeof(MyArray)); + + /* Doing this to avoid some compiler optimization. */ + for (int64_t i : IndexRange(sizeof(MyArray))) { + EXPECT_EQ(((char *)buffer.ptr())[i], 100); + } + + { + MyArray &array = *new (buffer) MyArray(1, NoInitialization()); + EXPECT_EQ(array[0].value, 100); + array.clear_without_destruct(); + array.~Array(); + } + { + MyArray &array = *new (buffer) MyArray(1); + EXPECT_EQ(array[0].value, 42); + array.~Array(); + } +} + +TEST(array, Fill) +{ + Array<int> array(5); + array.fill(3); + EXPECT_EQ(array.size(), 5u); + EXPECT_EQ(array[0], 3); + EXPECT_EQ(array[1], 3); + EXPECT_EQ(array[2], 3); + EXPECT_EQ(array[3], 3); + EXPECT_EQ(array[4], 3); +} + +} // namespace blender::tests diff --git a/source/blender/blenlib/tests/BLI_disjoint_set_test.cc b/source/blender/blenlib/tests/BLI_disjoint_set_test.cc new file mode 100644 index 00000000000..f30ee610b2a --- /dev/null +++ b/source/blender/blenlib/tests/BLI_disjoint_set_test.cc @@ -0,0 +1,36 @@ +/* Apache License, Version 2.0 */ + +#include "BLI_disjoint_set.hh" +#include "BLI_strict_flags.h" + +#include "testing/testing.h" + +namespace blender::tests { + +TEST(disjoint_set, Test) +{ + DisjointSet disjoint_set(6); + EXPECT_FALSE(disjoint_set.in_same_set(1, 2)); + EXPECT_FALSE(disjoint_set.in_same_set(5, 3)); + EXPECT_TRUE(disjoint_set.in_same_set(2, 2)); + EXPECT_EQ(disjoint_set.find_root(3), 3); + + disjoint_set.join(1, 2); + + EXPECT_TRUE(disjoint_set.in_same_set(1, 2)); + EXPECT_FALSE(disjoint_set.in_same_set(0, 1)); + + disjoint_set.join(3, 4); + + EXPECT_FALSE(disjoint_set.in_same_set(2, 3)); + EXPECT_TRUE(disjoint_set.in_same_set(3, 4)); + + disjoint_set.join(1, 4); + + EXPECT_TRUE(disjoint_set.in_same_set(1, 4)); + EXPECT_TRUE(disjoint_set.in_same_set(1, 3)); + EXPECT_TRUE(disjoint_set.in_same_set(2, 4)); + EXPECT_FALSE(disjoint_set.in_same_set(0, 4)); +} + +} // namespace blender::tests diff --git a/source/blender/blenlib/tests/BLI_edgehash_test.cc b/source/blender/blenlib/tests/BLI_edgehash_test.cc new file mode 100644 index 00000000000..7106033df36 --- /dev/null +++ b/source/blender/blenlib/tests/BLI_edgehash_test.cc @@ -0,0 +1,408 @@ +/* Apache License, Version 2.0 */ + +#include "testing/testing.h" +#include <algorithm> +#include <random> +#include <vector> + +#include "BLI_edgehash.h" +#include "BLI_utildefines.h" + +#define VALUE_1 POINTER_FROM_INT(1) +#define VALUE_2 POINTER_FROM_INT(2) +#define VALUE_3 POINTER_FROM_INT(3) + +TEST(edgehash, InsertIncreasesLength) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + ASSERT_EQ(BLI_edgehash_len(eh), 0); + BLI_edgehash_insert(eh, 1, 2, VALUE_1); + ASSERT_EQ(BLI_edgehash_len(eh), 1); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, ReinsertNewIncreasesLength) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + ASSERT_EQ(BLI_edgehash_len(eh), 0); + BLI_edgehash_reinsert(eh, 1, 2, VALUE_1); + ASSERT_EQ(BLI_edgehash_len(eh), 1); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, ReinsertExistingDoesNotIncreaseLength) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + ASSERT_EQ(BLI_edgehash_len(eh), 0); + BLI_edgehash_reinsert(eh, 1, 2, VALUE_1); + ASSERT_EQ(BLI_edgehash_len(eh), 1); + BLI_edgehash_reinsert(eh, 1, 2, VALUE_2); + ASSERT_EQ(BLI_edgehash_len(eh), 1); + BLI_edgehash_reinsert(eh, 2, 1, VALUE_2); + ASSERT_EQ(BLI_edgehash_len(eh), 1); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, ReinsertCanChangeValue) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + BLI_edgehash_insert(eh, 1, 2, VALUE_1); + ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), VALUE_1); + BLI_edgehash_reinsert(eh, 2, 1, VALUE_2); + ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), VALUE_2); + BLI_edgehash_reinsert(eh, 1, 2, VALUE_3); + ASSERT_EQ(BLI_edgehash_lookup(eh, 2, 1), VALUE_3); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, LookupExisting) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + BLI_edgehash_insert(eh, 1, 2, VALUE_1); + ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), VALUE_1); + ASSERT_EQ(BLI_edgehash_lookup(eh, 2, 1), VALUE_1); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, LookupNonExisting) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), nullptr); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, LookupNonExistingWithDefault) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + ASSERT_EQ(BLI_edgehash_lookup_default(eh, 1, 2, VALUE_1), VALUE_1); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, LookupExistingWithDefault) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + BLI_edgehash_insert(eh, 1, 2, VALUE_1); + ASSERT_EQ(BLI_edgehash_lookup_default(eh, 1, 2, VALUE_2), VALUE_1); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, LookupPExisting) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + void *value = VALUE_1; + BLI_edgehash_insert(eh, 1, 2, value); + void **value_p = BLI_edgehash_lookup_p(eh, 1, 2); + ASSERT_EQ(*value_p, VALUE_1); + *value_p = VALUE_2; + ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), VALUE_2); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, LookupPNonExisting) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + ASSERT_EQ(BLI_edgehash_lookup_p(eh, 1, 2), nullptr); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, EnsurePNonExisting) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + void **value_p; + bool existed = BLI_edgehash_ensure_p(eh, 1, 2, &value_p); + ASSERT_FALSE(existed); + *value_p = VALUE_1; + ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), VALUE_1); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, EnsurePExisting) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + BLI_edgehash_insert(eh, 1, 2, VALUE_1); + void **value_p; + bool existed = BLI_edgehash_ensure_p(eh, 1, 2, &value_p); + ASSERT_TRUE(existed); + ASSERT_EQ(*value_p, VALUE_1); + *value_p = VALUE_2; + ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), VALUE_2); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, RemoveExistingDecreasesLength) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + BLI_edgehash_insert(eh, 1, 2, VALUE_1); + ASSERT_EQ(BLI_edgehash_len(eh), 1); + bool has_been_removed = BLI_edgehash_remove(eh, 1, 2, nullptr); + ASSERT_EQ(BLI_edgehash_len(eh), 0); + ASSERT_TRUE(has_been_removed); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, RemoveNonExistingDoesNotDecreaseLength) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + BLI_edgehash_insert(eh, 1, 2, VALUE_1); + ASSERT_EQ(BLI_edgehash_len(eh), 1); + bool has_been_removed = BLI_edgehash_remove(eh, 4, 5, nullptr); + ASSERT_EQ(BLI_edgehash_len(eh), 1); + ASSERT_FALSE(has_been_removed); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, PopKeyTwice) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + BLI_edgehash_insert(eh, 1, 2, VALUE_1); + ASSERT_EQ(BLI_edgehash_popkey(eh, 1, 2), VALUE_1); + ASSERT_EQ(BLI_edgehash_popkey(eh, 1, 2), nullptr); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, LookupInvertedIndices) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + BLI_edgehash_insert(eh, 1, 2, VALUE_1); + ASSERT_EQ(BLI_edgehash_lookup(eh, 2, 1), VALUE_1); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, HasKeyExisting) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + BLI_edgehash_insert(eh, 1, 2, VALUE_1); + ASSERT_TRUE(BLI_edgehash_haskey(eh, 1, 2)); + ASSERT_TRUE(BLI_edgehash_haskey(eh, 2, 1)); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, HasKeyNonExisting) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + ASSERT_FALSE(BLI_edgehash_haskey(eh, 1, 2)); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, ClearSetsLengthToZero) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + BLI_edgehash_insert(eh, 1, 2, VALUE_1); + BLI_edgehash_insert(eh, 1, 2, VALUE_2); + ASSERT_EQ(BLI_edgehash_len(eh), 2); + BLI_edgehash_clear(eh, nullptr); + ASSERT_EQ(BLI_edgehash_len(eh), 0); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, IteratorFindsAllValues) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + BLI_edgehash_insert(eh, 1, 2, VALUE_1); + BLI_edgehash_insert(eh, 1, 3, VALUE_2); + BLI_edgehash_insert(eh, 1, 4, VALUE_3); + + EdgeHashIterator *ehi = BLI_edgehashIterator_new(eh); + auto a = BLI_edgehashIterator_getValue(ehi); + BLI_edgehashIterator_step(ehi); + auto b = BLI_edgehashIterator_getValue(ehi); + BLI_edgehashIterator_step(ehi); + auto c = BLI_edgehashIterator_getValue(ehi); + BLI_edgehashIterator_step(ehi); + + ASSERT_NE(a, b); + ASSERT_NE(b, c); + ASSERT_NE(a, c); + ASSERT_TRUE(ELEM(a, VALUE_1, VALUE_2, VALUE_3)); + ASSERT_TRUE(ELEM(b, VALUE_1, VALUE_2, VALUE_3)); + ASSERT_TRUE(ELEM(c, VALUE_1, VALUE_2, VALUE_3)); + + BLI_edgehashIterator_free(ehi); + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, IterateIsDone) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + BLI_edgehash_insert(eh, 1, 2, VALUE_1); + BLI_edgehash_insert(eh, 1, 3, VALUE_2); + BLI_edgehash_insert(eh, 1, 4, VALUE_3); + + EdgeHashIterator *ehi = BLI_edgehashIterator_new(eh); + ASSERT_FALSE(BLI_edgehashIterator_isDone(ehi)); + BLI_edgehashIterator_step(ehi); + ASSERT_FALSE(BLI_edgehashIterator_isDone(ehi)); + BLI_edgehashIterator_step(ehi); + ASSERT_FALSE(BLI_edgehashIterator_isDone(ehi)); + BLI_edgehashIterator_step(ehi); + ASSERT_TRUE(BLI_edgehashIterator_isDone(ehi)); + + BLI_edgehashIterator_free(ehi); + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgehash, DoubleRemove) +{ + EdgeHash *eh = BLI_edgehash_new(__func__); + + BLI_edgehash_insert(eh, 1, 2, VALUE_1); + BLI_edgehash_insert(eh, 1, 3, VALUE_2); + BLI_edgehash_insert(eh, 1, 4, VALUE_3); + ASSERT_EQ(BLI_edgehash_len(eh), 3); + + BLI_edgehash_remove(eh, 1, 2, nullptr); + BLI_edgehash_remove(eh, 1, 3, nullptr); + ASSERT_EQ(BLI_edgehash_len(eh), 1); + + BLI_edgehash_free(eh, nullptr); +} + +struct Edge { + uint v1, v2; +}; + +TEST(edgehash, StressTest) +{ + std::srand(0); + int amount = 10000; + + std::vector<Edge> edges; + for (int i = 0; i < amount; i++) { + edges.push_back({(uint)i, amount + (uint)std::rand() % 12345}); + } + + EdgeHash *eh = BLI_edgehash_new(__func__); + + /* first insert all the edges */ + for (int i = 0; i < edges.size(); i++) { + BLI_edgehash_insert(eh, edges[i].v1, edges[i].v2, POINTER_FROM_INT(i)); + } + + std::vector<Edge> shuffled = edges; + std::shuffle(shuffled.begin(), shuffled.end(), std::default_random_engine()); + + /* then remove half of them */ + int remove_until = shuffled.size() / 2; + for (int i = 0; i < remove_until; i++) { + BLI_edgehash_remove(eh, shuffled[i].v2, shuffled[i].v1, nullptr); + } + + ASSERT_EQ(BLI_edgehash_len(eh), edges.size() - remove_until); + + /* check if the right ones have been removed */ + for (int i = 0; i < shuffled.size(); i++) { + bool haskey = BLI_edgehash_haskey(eh, shuffled[i].v1, shuffled[i].v2); + if (i < remove_until) { + ASSERT_FALSE(haskey); + } + else { + ASSERT_TRUE(haskey); + } + } + + /* reinsert all edges */ + for (int i = 0; i < edges.size(); i++) { + BLI_edgehash_reinsert(eh, edges[i].v1, edges[i].v2, POINTER_FROM_INT(i)); + } + + ASSERT_EQ(BLI_edgehash_len(eh), edges.size()); + + /* pop all edges */ + for (int i = 0; i < edges.size(); i++) { + int value = POINTER_AS_INT(BLI_edgehash_popkey(eh, edges[i].v1, edges[i].v2)); + ASSERT_EQ(i, value); + } + + ASSERT_EQ(BLI_edgehash_len(eh), 0); + + BLI_edgehash_free(eh, nullptr); +} + +TEST(edgeset, AddNonExistingIncreasesLength) +{ + EdgeSet *es = BLI_edgeset_new(__func__); + + ASSERT_EQ(BLI_edgeset_len(es), 0); + BLI_edgeset_add(es, 1, 2); + ASSERT_EQ(BLI_edgeset_len(es), 1); + BLI_edgeset_add(es, 1, 3); + ASSERT_EQ(BLI_edgeset_len(es), 2); + BLI_edgeset_add(es, 1, 4); + ASSERT_EQ(BLI_edgeset_len(es), 3); + + BLI_edgeset_free(es); +} + +TEST(edgeset, AddExistingDoesNotIncreaseLength) +{ + EdgeSet *es = BLI_edgeset_new(__func__); + + ASSERT_EQ(BLI_edgeset_len(es), 0); + BLI_edgeset_add(es, 1, 2); + ASSERT_EQ(BLI_edgeset_len(es), 1); + BLI_edgeset_add(es, 2, 1); + ASSERT_EQ(BLI_edgeset_len(es), 1); + BLI_edgeset_add(es, 1, 2); + ASSERT_EQ(BLI_edgeset_len(es), 1); + + BLI_edgeset_free(es); +} + +TEST(edgeset, HasKeyNonExisting) +{ + EdgeSet *es = BLI_edgeset_new(__func__); + + ASSERT_FALSE(BLI_edgeset_haskey(es, 1, 2)); + + BLI_edgeset_free(es); +} + +TEST(edgeset, HasKeyExisting) +{ + EdgeSet *es = BLI_edgeset_new(__func__); + + BLI_edgeset_insert(es, 1, 2); + ASSERT_TRUE(BLI_edgeset_haskey(es, 1, 2)); + + BLI_edgeset_free(es); +} diff --git a/source/blender/blenlib/tests/BLI_index_mask_test.cc b/source/blender/blenlib/tests/BLI_index_mask_test.cc new file mode 100644 index 00000000000..4d6060e51c9 --- /dev/null +++ b/source/blender/blenlib/tests/BLI_index_mask_test.cc @@ -0,0 +1,43 @@ +/* Apache License, Version 2.0 */ + +#include "BLI_index_mask.hh" +#include "testing/testing.h" + +namespace blender::tests { + +TEST(index_mask, DefaultConstructor) +{ + IndexMask mask; + EXPECT_EQ(mask.min_array_size(), 0); + EXPECT_EQ(mask.size(), 0); +} + +TEST(index_mask, ArrayConstructor) +{ + [](IndexMask mask) { + EXPECT_EQ(mask.size(), 4); + EXPECT_EQ(mask.min_array_size(), 8); + EXPECT_FALSE(mask.is_range()); + EXPECT_EQ(mask[0], 3); + EXPECT_EQ(mask[1], 5); + EXPECT_EQ(mask[2], 6); + EXPECT_EQ(mask[3], 7); + }({3, 5, 6, 7}); +} + +TEST(index_mask, RangeConstructor) +{ + IndexMask mask = IndexRange(3, 5); + EXPECT_EQ(mask.size(), 5); + EXPECT_EQ(mask.min_array_size(), 8); + EXPECT_EQ(mask.last(), 7); + EXPECT_TRUE(mask.is_range()); + EXPECT_EQ(mask.as_range().first(), 3); + EXPECT_EQ(mask.as_range().last(), 7); + Span<int64_t> indices = mask.indices(); + EXPECT_EQ(indices[0], 3); + EXPECT_EQ(indices[1], 4); + EXPECT_EQ(indices[2], 5); +} + +} // namespace blender::tests diff --git a/source/blender/blenlib/tests/BLI_index_range_test.cc b/source/blender/blenlib/tests/BLI_index_range_test.cc new file mode 100644 index 00000000000..d472ded0f18 --- /dev/null +++ b/source/blender/blenlib/tests/BLI_index_range_test.cc @@ -0,0 +1,143 @@ +/* Apache License, Version 2.0 */ + +#include "BLI_index_range.hh" +#include "BLI_strict_flags.h" +#include "BLI_vector.hh" +#include "testing/testing.h" + +namespace blender::tests { + +TEST(index_range, DefaultConstructor) +{ + IndexRange range; + EXPECT_EQ(range.size(), 0); + + Vector<int64_t> vector; + for (int64_t value : range) { + vector.append(value); + } + EXPECT_EQ(vector.size(), 0); +} + +TEST(index_range, SingleElementRange) +{ + IndexRange range(4, 1); + EXPECT_EQ(range.size(), 1); + EXPECT_EQ(*range.begin(), 4); + + Vector<int64_t> vector; + for (int64_t value : range) { + vector.append(value); + } + + EXPECT_EQ(vector.size(), 1); + EXPECT_EQ(vector[0], 4); +} + +TEST(index_range, MultipleElementRange) +{ + IndexRange range(6, 4); + EXPECT_EQ(range.size(), 4); + + Vector<int64_t> vector; + for (int64_t value : range) { + vector.append(value); + } + + EXPECT_EQ(vector.size(), 4); + for (int i = 0; i < 4; i++) { + EXPECT_EQ(vector[i], i + 6); + } +} + +TEST(index_range, SubscriptOperator) +{ + IndexRange range(5, 5); + EXPECT_EQ(range[0], 5); + EXPECT_EQ(range[1], 6); + EXPECT_EQ(range[2], 7); +} + +TEST(index_range, Before) +{ + IndexRange range = IndexRange(5, 5).before(3); + EXPECT_EQ(range[0], 2); + EXPECT_EQ(range[1], 3); + EXPECT_EQ(range[2], 4); + EXPECT_EQ(range.size(), 3); +} + +TEST(index_range, After) +{ + IndexRange range = IndexRange(5, 5).after(4); + EXPECT_EQ(range[0], 10); + EXPECT_EQ(range[1], 11); + EXPECT_EQ(range[2], 12); + EXPECT_EQ(range[3], 13); + EXPECT_EQ(range.size(), 4); +} + +TEST(index_range, Contains) +{ + IndexRange range = IndexRange(5, 3); + EXPECT_TRUE(range.contains(5)); + EXPECT_TRUE(range.contains(6)); + EXPECT_TRUE(range.contains(7)); + EXPECT_FALSE(range.contains(4)); + EXPECT_FALSE(range.contains(8)); +} + +TEST(index_range, First) +{ + IndexRange range = IndexRange(5, 3); + EXPECT_EQ(range.first(), 5); +} + +TEST(index_range, Last) +{ + IndexRange range = IndexRange(5, 3); + EXPECT_EQ(range.last(), 7); +} + +TEST(index_range, OneAfterEnd) +{ + IndexRange range = IndexRange(5, 3); + EXPECT_EQ(range.one_after_last(), 8); +} + +TEST(index_range, Start) +{ + IndexRange range = IndexRange(6, 2); + EXPECT_EQ(range.start(), 6); +} + +TEST(index_range, Slice) +{ + IndexRange range = IndexRange(5, 15); + IndexRange slice = range.slice(2, 6); + EXPECT_EQ(slice.size(), 6); + EXPECT_EQ(slice.first(), 7); + EXPECT_EQ(slice.last(), 12); +} + +TEST(index_range, SliceRange) +{ + IndexRange range = IndexRange(5, 15); + IndexRange slice = range.slice(IndexRange(3, 5)); + EXPECT_EQ(slice.size(), 5); + EXPECT_EQ(slice.first(), 8); + EXPECT_EQ(slice.last(), 12); +} + +TEST(index_range, AsSpan) +{ + IndexRange range = IndexRange(4, 6); + Span<int64_t> span = range.as_span(); + EXPECT_EQ(span.size(), 6); + EXPECT_EQ(span[0], 4); + EXPECT_EQ(span[1], 5); + EXPECT_EQ(span[2], 6); + EXPECT_EQ(span[3], 7); +} + +} // namespace blender::tests diff --git a/source/blender/blenlib/tests/BLI_linear_allocator_test.cc b/source/blender/blenlib/tests/BLI_linear_allocator_test.cc new file mode 100644 index 00000000000..44b70d1f55d --- /dev/null +++ b/source/blender/blenlib/tests/BLI_linear_allocator_test.cc @@ -0,0 +1,118 @@ +/* Apache License, Version 2.0 */ + +#include "BLI_linear_allocator.hh" +#include "BLI_strict_flags.h" +#include "testing/testing.h" + +namespace blender::tests { + +static bool is_aligned(void *ptr, uint alignment) +{ + BLI_assert(is_power_of_2_i((int)alignment)); + return (POINTER_AS_UINT(ptr) & (alignment - 1)) == 0; +} + +TEST(linear_allocator, AllocationAlignment) +{ + LinearAllocator<> allocator; + + EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4)); + EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4)); + EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4)); + EXPECT_TRUE(is_aligned(allocator.allocate(10, 8), 8)); + EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4)); + EXPECT_TRUE(is_aligned(allocator.allocate(10, 16), 16)); + EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4)); + EXPECT_TRUE(is_aligned(allocator.allocate(10, 64), 64)); + EXPECT_TRUE(is_aligned(allocator.allocate(10, 64), 64)); + EXPECT_TRUE(is_aligned(allocator.allocate(10, 8), 8)); + EXPECT_TRUE(is_aligned(allocator.allocate(10, 128), 128)); +} + +TEST(linear_allocator, PackedAllocation) +{ + LinearAllocator<> allocator; + blender::AlignedBuffer<256, 32> buffer; + allocator.provide_buffer(buffer); + + uintptr_t ptr1 = (uintptr_t)allocator.allocate(10, 4); /* 0 - 10 */ + uintptr_t ptr2 = (uintptr_t)allocator.allocate(10, 4); /* 12 - 22 */ + uintptr_t ptr3 = (uintptr_t)allocator.allocate(8, 32); /* 32 - 40 */ + uintptr_t ptr4 = (uintptr_t)allocator.allocate(16, 8); /* 40 - 56 */ + uintptr_t ptr5 = (uintptr_t)allocator.allocate(1, 8); /* 56 - 57 */ + uintptr_t ptr6 = (uintptr_t)allocator.allocate(1, 4); /* 60 - 61 */ + uintptr_t ptr7 = (uintptr_t)allocator.allocate(1, 1); /* 61 - 62 */ + + EXPECT_EQ(ptr2 - ptr1, 12); /* 12 - 0 = 12 */ + EXPECT_EQ(ptr3 - ptr2, 20); /* 32 - 12 = 20 */ + EXPECT_EQ(ptr4 - ptr3, 8); /* 40 - 32 = 8 */ + EXPECT_EQ(ptr5 - ptr4, 16); /* 56 - 40 = 16 */ + EXPECT_EQ(ptr6 - ptr5, 4); /* 60 - 56 = 4 */ + EXPECT_EQ(ptr7 - ptr6, 1); /* 61 - 60 = 1 */ +} + +TEST(linear_allocator, CopyString) +{ + LinearAllocator<> allocator; + blender::AlignedBuffer<256, 1> buffer; + allocator.provide_buffer(buffer); + + StringRefNull ref1 = allocator.copy_string("Hello"); + StringRefNull ref2 = allocator.copy_string("World"); + + EXPECT_EQ(ref1, "Hello"); + EXPECT_EQ(ref2, "World"); + EXPECT_EQ(ref2.data() - ref1.data(), 6); +} + +TEST(linear_allocator, AllocateArray) +{ + LinearAllocator<> allocator; + + MutableSpan<int> span = allocator.allocate_array<int>(5); + EXPECT_EQ(span.size(), 5); +} + +TEST(linear_allocator, Construct) +{ + LinearAllocator<> allocator; + + std::array<int, 5> values = {1, 2, 3, 4, 5}; + Vector<int> *vector = allocator.construct<Vector<int>>(values); + EXPECT_EQ(vector->size(), 5); + EXPECT_EQ((*vector)[3], 4); + vector->~Vector(); +} + +TEST(linear_allocator, ConstructElementsAndPointerArray) +{ + LinearAllocator<> allocator; + + std::array<int, 7> values = {1, 2, 3, 4, 5, 6, 7}; + Span<Vector<int> *> vectors = allocator.construct_elements_and_pointer_array<Vector<int>>( + 5, values); + + EXPECT_EQ(vectors.size(), 5); + EXPECT_EQ(vectors[3]->size(), 7); + EXPECT_EQ((*vectors[2])[5], 6); + + for (Vector<int> *vector : vectors) { + vector->~Vector(); + } +} + +TEST(linear_allocator, ConstructArrayCopy) +{ + LinearAllocator<> allocator; + + Vector<int> values = {1, 2, 3}; + MutableSpan<int> span1 = allocator.construct_array_copy(values.as_span()); + MutableSpan<int> span2 = allocator.construct_array_copy(values.as_span()); + EXPECT_NE(span1.data(), span2.data()); + EXPECT_EQ(span1.size(), 3); + EXPECT_EQ(span2.size(), 3); + EXPECT_EQ(span1[1], 2); + EXPECT_EQ(span2[2], 3); +} + +} // namespace blender::tests diff --git a/source/blender/blenlib/tests/BLI_map_test.cc b/source/blender/blenlib/tests/BLI_map_test.cc new file mode 100644 index 00000000000..fe7b0f01279 --- /dev/null +++ b/source/blender/blenlib/tests/BLI_map_test.cc @@ -0,0 +1,590 @@ +/* Apache License, Version 2.0 */ + +#include "BLI_map.hh" +#include "BLI_rand.h" +#include "BLI_set.hh" +#include "BLI_strict_flags.h" +#include "BLI_timeit.hh" +#include "BLI_vector.hh" +#include "testing/testing.h" + +namespace blender::tests { + +TEST(map, DefaultConstructor) +{ + Map<int, float> map; + EXPECT_EQ(map.size(), 0); + EXPECT_TRUE(map.is_empty()); +} + +TEST(map, AddIncreasesSize) +{ + Map<int, float> map; + EXPECT_EQ(map.size(), 0); + EXPECT_TRUE(map.is_empty()); + map.add(2, 5.0f); + EXPECT_EQ(map.size(), 1); + EXPECT_FALSE(map.is_empty()); + map.add(6, 2.0f); + EXPECT_EQ(map.size(), 2); + EXPECT_FALSE(map.is_empty()); +} + +TEST(map, Contains) +{ + Map<int, float> map; + EXPECT_FALSE(map.contains(4)); + map.add(5, 6.0f); + EXPECT_FALSE(map.contains(4)); + map.add(4, 2.0f); + EXPECT_TRUE(map.contains(4)); +} + +TEST(map, LookupExisting) +{ + Map<int, float> map; + map.add(2, 6.0f); + map.add(4, 1.0f); + EXPECT_EQ(map.lookup(2), 6.0f); + EXPECT_EQ(map.lookup(4), 1.0f); +} + +TEST(map, LookupNotExisting) +{ + Map<int, float> map; + map.add(2, 4.0f); + map.add(1, 1.0f); + EXPECT_EQ(map.lookup_ptr(0), nullptr); + EXPECT_EQ(map.lookup_ptr(5), nullptr); +} + +TEST(map, AddMany) +{ + Map<int, int> map; + for (int i = 0; i < 100; i++) { + map.add(i * 30, i); + map.add(i * 31, i); + } +} + +TEST(map, PopItem) +{ + Map<int, float> map; + map.add(2, 3.0f); + map.add(1, 9.0f); + EXPECT_TRUE(map.contains(2)); + EXPECT_TRUE(map.contains(1)); + + EXPECT_EQ(map.pop(1), 9.0f); + EXPECT_TRUE(map.contains(2)); + EXPECT_FALSE(map.contains(1)); + + EXPECT_EQ(map.pop(2), 3.0f); + EXPECT_FALSE(map.contains(2)); + EXPECT_FALSE(map.contains(1)); +} + +TEST(map, PopTry) +{ + Map<int, int> map; + map.add(1, 5); + map.add(2, 7); + EXPECT_EQ(map.size(), 2); + std::optional<int> value = map.pop_try(4); + EXPECT_EQ(map.size(), 2); + EXPECT_FALSE(value.has_value()); + value = map.pop_try(2); + EXPECT_EQ(map.size(), 1); + EXPECT_TRUE(value.has_value()); + EXPECT_EQ(*value, 7); + EXPECT_EQ(*map.pop_try(1), 5); + EXPECT_EQ(map.size(), 0); +} + +TEST(map, PopDefault) +{ + Map<int, int> map; + map.add(1, 4); + map.add(2, 7); + map.add(3, 8); + EXPECT_EQ(map.size(), 3); + EXPECT_EQ(map.pop_default(4, 10), 10); + EXPECT_EQ(map.size(), 3); + EXPECT_EQ(map.pop_default(1, 10), 4); + EXPECT_EQ(map.size(), 2); + EXPECT_EQ(map.pop_default(2, 20), 7); + EXPECT_EQ(map.size(), 1); + EXPECT_EQ(map.pop_default(2, 20), 20); + EXPECT_EQ(map.size(), 1); + EXPECT_EQ(map.pop_default(3, 0), 8); + EXPECT_EQ(map.size(), 0); +} + +TEST(map, PopItemMany) +{ + Map<int, int> map; + for (int i = 0; i < 100; i++) { + map.add_new(i, i); + } + for (int i = 25; i < 80; i++) { + EXPECT_EQ(map.pop(i), i); + } + for (int i = 0; i < 100; i++) { + EXPECT_EQ(map.contains(i), i < 25 || i >= 80); + } +} + +TEST(map, ValueIterator) +{ + Map<int, float> map; + map.add(3, 5.0f); + map.add(1, 2.0f); + map.add(7, -2.0f); + + blender::Set<float> values; + + int iterations = 0; + for (float value : map.values()) { + values.add(value); + iterations++; + } + + EXPECT_EQ(iterations, 3); + EXPECT_TRUE(values.contains(5.0f)); + EXPECT_TRUE(values.contains(-2.0f)); + EXPECT_TRUE(values.contains(2.0f)); +} + +TEST(map, KeyIterator) +{ + Map<int, float> map; + map.add(6, 3.0f); + map.add(2, 4.0f); + map.add(1, 3.0f); + + blender::Set<int> keys; + + int iterations = 0; + for (int key : map.keys()) { + keys.add(key); + iterations++; + } + + EXPECT_EQ(iterations, 3); + EXPECT_TRUE(keys.contains(1)); + EXPECT_TRUE(keys.contains(2)); + EXPECT_TRUE(keys.contains(6)); +} + +TEST(map, ItemIterator) +{ + Map<int, float> map; + map.add(5, 3.0f); + map.add(2, 9.0f); + map.add(1, 0.0f); + + blender::Set<int> keys; + blender::Set<float> values; + + int iterations = 0; + const Map<int, float> &const_map = map; + for (auto item : const_map.items()) { + keys.add(item.key); + values.add(item.value); + iterations++; + } + + EXPECT_EQ(iterations, 3); + EXPECT_TRUE(keys.contains(5)); + EXPECT_TRUE(keys.contains(2)); + EXPECT_TRUE(keys.contains(1)); + EXPECT_TRUE(values.contains(3.0f)); + EXPECT_TRUE(values.contains(9.0f)); + EXPECT_TRUE(values.contains(0.0f)); +} + +TEST(map, MutableValueIterator) +{ + Map<int, int> map; + map.add(3, 6); + map.add(2, 1); + + for (int &value : map.values()) { + value += 10; + } + + EXPECT_EQ(map.lookup(3), 16); + EXPECT_EQ(map.lookup(2), 11); +} + +TEST(map, MutableItemIterator) +{ + Map<int, int> map; + map.add(3, 6); + map.add(2, 1); + + for (auto item : map.items()) { + item.value += item.key; + } + + EXPECT_EQ(map.lookup(3), 9.0f); + EXPECT_EQ(map.lookup(2), 3.0f); +} + +TEST(map, MutableItemToItemConversion) +{ + Map<int, int> map; + map.add(3, 6); + map.add(2, 1); + + Vector<int> keys, values; + for (Map<int, int>::Item item : map.items()) { + keys.append(item.key); + values.append(item.value); + } + + EXPECT_EQ(keys.size(), 2); + EXPECT_EQ(values.size(), 2); + EXPECT_TRUE(keys.contains(3)); + EXPECT_TRUE(keys.contains(2)); + EXPECT_TRUE(values.contains(6)); + EXPECT_TRUE(values.contains(1)); +} + +static float return_42() +{ + return 42.0f; +} + +TEST(map, LookupOrAddCB_SeparateFunction) +{ + Map<int, float> map; + EXPECT_EQ(map.lookup_or_add_cb(0, return_42), 42.0f); + EXPECT_EQ(map.lookup(0), 42); + + map.keys(); +} + +TEST(map, LookupOrAddCB_Lambdas) +{ + Map<int, float> map; + auto lambda1 = []() { return 11.0f; }; + EXPECT_EQ(map.lookup_or_add_cb(0, lambda1), 11.0f); + auto lambda2 = []() { return 20.0f; }; + EXPECT_EQ(map.lookup_or_add_cb(1, lambda2), 20.0f); + + EXPECT_EQ(map.lookup_or_add_cb(0, lambda2), 11.0f); + EXPECT_EQ(map.lookup_or_add_cb(1, lambda1), 20.0f); +} + +TEST(map, AddOrModify) +{ + Map<int, float> map; + auto create_func = [](float *value) { + *value = 10.0f; + return true; + }; + auto modify_func = [](float *value) { + *value += 5; + return false; + }; + EXPECT_TRUE(map.add_or_modify(1, create_func, modify_func)); + EXPECT_EQ(map.lookup(1), 10.0f); + EXPECT_FALSE(map.add_or_modify(1, create_func, modify_func)); + EXPECT_EQ(map.lookup(1), 15.0f); +} + +TEST(map, AddOverwrite) +{ + Map<int, float> map; + EXPECT_FALSE(map.contains(3)); + EXPECT_TRUE(map.add_overwrite(3, 6.0f)); + EXPECT_EQ(map.lookup(3), 6.0f); + EXPECT_FALSE(map.add_overwrite(3, 7.0f)); + EXPECT_EQ(map.lookup(3), 7.0f); + EXPECT_FALSE(map.add(3, 8.0f)); + EXPECT_EQ(map.lookup(3), 7.0f); +} + +TEST(map, LookupOrAddDefault) +{ + Map<int, float> map; + map.lookup_or_add_default(3) = 6; + EXPECT_EQ(map.lookup(3), 6); + map.lookup_or_add_default(5) = 2; + EXPECT_EQ(map.lookup(5), 2); + map.lookup_or_add_default(3) += 4; + EXPECT_EQ(map.lookup(3), 10); +} + +TEST(map, LookupOrAdd) +{ + Map<int, int> map; + EXPECT_EQ(map.lookup_or_add(6, 4), 4); + EXPECT_EQ(map.lookup_or_add(6, 5), 4); + map.lookup_or_add(6, 4) += 10; + EXPECT_EQ(map.lookup(6), 14); +} + +TEST(map, MoveConstructorSmall) +{ + Map<int, float> map1; + map1.add(1, 2.0f); + map1.add(4, 1.0f); + Map<int, float> map2(std::move(map1)); + EXPECT_EQ(map2.size(), 2); + EXPECT_EQ(map2.lookup(1), 2.0f); + EXPECT_EQ(map2.lookup(4), 1.0f); + EXPECT_EQ(map1.size(), 0); /* NOLINT: bugprone-use-after-move */ + EXPECT_EQ(map1.lookup_ptr(4), nullptr); +} + +TEST(map, MoveConstructorLarge) +{ + Map<int, int> map1; + for (int i = 0; i < 100; i++) { + map1.add_new(i, i); + } + Map<int, int> map2(std::move(map1)); + EXPECT_EQ(map2.size(), 100); + EXPECT_EQ(map2.lookup(1), 1); + EXPECT_EQ(map2.lookup(4), 4); + EXPECT_EQ(map1.size(), 0); /* NOLINT: bugprone-use-after-move */ + EXPECT_EQ(map1.lookup_ptr(4), nullptr); +} + +TEST(map, MoveAssignment) +{ + Map<int, float> map1; + map1.add(1, 2.0f); + map1.add(4, 1.0f); + Map<int, float> map2; + map2 = std::move(map1); + EXPECT_EQ(map2.size(), 2); + EXPECT_EQ(map2.lookup(1), 2.0f); + EXPECT_EQ(map2.lookup(4), 1.0f); + EXPECT_EQ(map1.size(), 0); /* NOLINT: bugprone-use-after-move */ + EXPECT_EQ(map1.lookup_ptr(4), nullptr); +} + +TEST(map, CopyAssignment) +{ + Map<int, float> map1; + map1.add(1, 2.0f); + map1.add(4, 1.0f); + Map<int, float> map2; + map2 = map1; + EXPECT_EQ(map2.size(), 2); + EXPECT_EQ(map2.lookup(1), 2.0f); + EXPECT_EQ(map2.lookup(4), 1.0f); + EXPECT_EQ(map1.size(), 2); + EXPECT_EQ(*map1.lookup_ptr(4), 1.0f); +} + +TEST(map, Clear) +{ + Map<int, float> map; + map.add(1, 1.0f); + map.add(2, 5.0f); + + EXPECT_EQ(map.size(), 2); + EXPECT_TRUE(map.contains(1)); + EXPECT_TRUE(map.contains(2)); + + map.clear(); + + EXPECT_EQ(map.size(), 0); + EXPECT_FALSE(map.contains(1)); + EXPECT_FALSE(map.contains(2)); +} + +TEST(map, UniquePtrValue) +{ + auto value1 = std::unique_ptr<int>(new int()); + auto value2 = std::unique_ptr<int>(new int()); + auto value3 = std::unique_ptr<int>(new int()); + + int *value1_ptr = value1.get(); + + Map<int, std::unique_ptr<int>> map; + map.add_new(1, std::move(value1)); + map.add(2, std::move(value2)); + map.add_overwrite(3, std::move(value3)); + map.lookup_or_add_cb(4, []() { return std::unique_ptr<int>(new int()); }); + map.add_new(5, std::unique_ptr<int>(new int())); + map.add(6, std::unique_ptr<int>(new int())); + map.add_overwrite(7, std::unique_ptr<int>(new int())); + map.lookup_or_add(8, std::unique_ptr<int>(new int())); + map.pop_default(9, std::unique_ptr<int>(new int())); + + EXPECT_EQ(map.lookup(1).get(), value1_ptr); + EXPECT_EQ(map.lookup_ptr(100), nullptr); +} + +TEST(map, Remove) +{ + Map<int, int> map; + map.add(2, 4); + EXPECT_EQ(map.size(), 1); + EXPECT_FALSE(map.remove(3)); + EXPECT_EQ(map.size(), 1); + EXPECT_TRUE(map.remove(2)); + EXPECT_EQ(map.size(), 0); +} + +TEST(map, PointerKeys) +{ + char a, b, c, d; + + Map<char *, int> map; + EXPECT_TRUE(map.add(&a, 5)); + EXPECT_FALSE(map.add(&a, 4)); + map.add_new(&b, 1); + map.add_new(&c, 1); + EXPECT_EQ(map.size(), 3); + EXPECT_TRUE(map.remove(&b)); + EXPECT_TRUE(map.add(&b, 8)); + EXPECT_FALSE(map.remove(&d)); + EXPECT_TRUE(map.remove(&a)); + EXPECT_TRUE(map.remove(&b)); + EXPECT_TRUE(map.remove(&c)); + EXPECT_TRUE(map.is_empty()); +} + +TEST(map, ConstKeysAndValues) +{ + Map<const std::string, const std::string> map; + map.reserve(10); + map.add("45", "643"); + EXPECT_TRUE(map.contains("45")); + EXPECT_FALSE(map.contains("54")); +} + +TEST(map, ForeachItem) +{ + Map<int, int> map; + map.add(3, 4); + map.add(1, 8); + + Vector<int> keys; + Vector<int> values; + map.foreach_item([&](int key, int value) { + keys.append(key); + values.append(value); + }); + + EXPECT_EQ(keys.size(), 2); + EXPECT_EQ(values.size(), 2); + EXPECT_EQ(keys.first_index_of(3), values.first_index_of(4)); + EXPECT_EQ(keys.first_index_of(1), values.first_index_of(8)); +} + +/** + * Set this to 1 to activate the benchmark. It is disabled by default, because it prints a lot. + */ +#if 0 +template<typename MapT> +BLI_NOINLINE void benchmark_random_ints(StringRef name, int amount, int factor) +{ + RNG *rng = BLI_rng_new(0); + Vector<int> values; + for (int i = 0; i < amount; i++) { + values.append(BLI_rng_get_int(rng) * factor); + } + BLI_rng_free(rng); + + MapT map; + { + SCOPED_TIMER(name + " Add"); + for (int value : values) { + map.add(value, value); + } + } + int count = 0; + { + SCOPED_TIMER(name + " Contains"); + for (int value : values) { + count += map.contains(value); + } + } + { + SCOPED_TIMER(name + " Remove"); + for (int value : values) { + count += map.remove(value); + } + } + + /* Print the value for simple error checking and to avoid some compiler optimizations. */ + std::cout << "Count: " << count << "\n"; +} + +TEST(map, Benchmark) +{ + for (int i = 0; i < 3; i++) { + benchmark_random_ints<blender::Map<int, int>>("blender::Map ", 1000000, 1); + benchmark_random_ints<blender::StdUnorderedMapWrapper<int, int>>("std::unordered_map", 1000000, 1); + } + std::cout << "\n"; + for (int i = 0; i < 3; i++) { + uint32_t factor = (3 << 10); + benchmark_random_ints<blender::Map<int, int>>("blender::Map ", 1000000, factor); + benchmark_random_ints<blender::StdUnorderedMapWrapper<int, int>>( + "std::unordered_map", 1000000, factor); + } +} + +/** + * Timer 'blender::Map Add' took 61.7616 ms + * Timer 'blender::Map Contains' took 18.4989 ms + * Timer 'blender::Map Remove' took 20.5864 ms + * Count: 1999755 + * Timer 'std::unordered_map Add' took 188.674 ms + * Timer 'std::unordered_map Contains' took 44.3741 ms + * Timer 'std::unordered_map Remove' took 169.52 ms + * Count: 1999755 + * Timer 'blender::Map Add' took 37.9196 ms + * Timer 'blender::Map Contains' took 16.7361 ms + * Timer 'blender::Map Remove' took 20.9568 ms + * Count: 1999755 + * Timer 'std::unordered_map Add' took 166.09 ms + * Timer 'std::unordered_map Contains' took 40.6133 ms + * Timer 'std::unordered_map Remove' took 142.85 ms + * Count: 1999755 + * Timer 'blender::Map Add' took 37.3053 ms + * Timer 'blender::Map Contains' took 16.6731 ms + * Timer 'blender::Map Remove' took 18.8304 ms + * Count: 1999755 + * Timer 'std::unordered_map Add' took 170.964 ms + * Timer 'std::unordered_map Contains' took 38.1824 ms + * Timer 'std::unordered_map Remove' took 140.263 ms + * Count: 1999755 + * + * Timer 'blender::Map Add' took 50.1131 ms + * Timer 'blender::Map Contains' took 25.0491 ms + * Timer 'blender::Map Remove' took 32.4225 ms + * Count: 1889920 + * Timer 'std::unordered_map Add' took 150.129 ms + * Timer 'std::unordered_map Contains' took 34.6999 ms + * Timer 'std::unordered_map Remove' took 120.907 ms + * Count: 1889920 + * Timer 'blender::Map Add' took 50.4438 ms + * Timer 'blender::Map Contains' took 25.2677 ms + * Timer 'blender::Map Remove' took 32.3047 ms + * Count: 1889920 + * Timer 'std::unordered_map Add' took 144.015 ms + * Timer 'std::unordered_map Contains' took 36.3387 ms + * Timer 'std::unordered_map Remove' took 119.109 ms + * Count: 1889920 + * Timer 'blender::Map Add' took 48.6995 ms + * Timer 'blender::Map Contains' took 25.1846 ms + * Timer 'blender::Map Remove' took 33.0283 ms + * Count: 1889920 + * Timer 'std::unordered_map Add' took 143.494 ms + * Timer 'std::unordered_map Contains' took 34.8905 ms + * Timer 'std::unordered_map Remove' took 122.739 ms + * Count: 1889920 + */ + +#endif /* Benchmark */ + +} // namespace blender::tests diff --git a/source/blender/blenlib/tests/BLI_math_base_safe_test.cc b/source/blender/blenlib/tests/BLI_math_base_safe_test.cc new file mode 100644 index 00000000000..2e3e083cf92 --- /dev/null +++ b/source/blender/blenlib/tests/BLI_math_base_safe_test.cc @@ -0,0 +1,37 @@ +/* Apache License, Version 2.0 */ + +#include "testing/testing.h" + +#include "BLI_math_base_safe.h" + +TEST(math_base, SafePowf) +{ + EXPECT_FLOAT_EQ(safe_powf(4.0f, 3.0f), 64.0f); + EXPECT_FLOAT_EQ(safe_powf(3.2f, 5.6f), 674.2793796f); + EXPECT_FLOAT_EQ(safe_powf(4.0f, -2.0f), 0.0625f); + EXPECT_FLOAT_EQ(safe_powf(6.0f, -3.2f), 0.003235311f); + EXPECT_FLOAT_EQ(safe_powf(-4.0f, 6), 4096.0f); + EXPECT_FLOAT_EQ(safe_powf(-3.0f, 5.5), 0.0f); + EXPECT_FLOAT_EQ(safe_powf(-2.5f, -4.0f), 0.0256f); + EXPECT_FLOAT_EQ(safe_powf(-3.7f, -4.5f), 0.0f); +} + +TEST(math_base, SafeModf) +{ + EXPECT_FLOAT_EQ(safe_modf(3.4, 2.2f), 1.2f); + EXPECT_FLOAT_EQ(safe_modf(3.4, -2.2f), 1.2f); + EXPECT_FLOAT_EQ(safe_modf(-3.4, -2.2f), -1.2f); + EXPECT_FLOAT_EQ(safe_modf(-3.4, 0.0f), 0.0f); + EXPECT_FLOAT_EQ(safe_modf(0.0f, 3.0f), 0.0f); + EXPECT_FLOAT_EQ(safe_modf(55.0f, 10.0f), 5.0f); +} + +TEST(math_base, SafeLogf) +{ + EXPECT_FLOAT_EQ(safe_logf(3.3f, 2.5f), 1.302995247f); + EXPECT_FLOAT_EQ(safe_logf(0.0f, 3.0f), 0.0f); + EXPECT_FLOAT_EQ(safe_logf(3.0f, 0.0f), 0.0f); + EXPECT_FLOAT_EQ(safe_logf(-2.0f, 4.3f), 0.0f); + EXPECT_FLOAT_EQ(safe_logf(2.0f, -4.3f), 0.0f); + EXPECT_FLOAT_EQ(safe_logf(-2.0f, -4.3f), 0.0f); +} diff --git a/source/blender/blenlib/tests/BLI_memory_utils_test.cc b/source/blender/blenlib/tests/BLI_memory_utils_test.cc new file mode 100644 index 00000000000..f3cb02b63d7 --- /dev/null +++ b/source/blender/blenlib/tests/BLI_memory_utils_test.cc @@ -0,0 +1,159 @@ +/* Apache License, Version 2.0 */ + +#include "BLI_float3.hh" +#include "BLI_memory_utils.hh" +#include "BLI_strict_flags.h" +#include "testing/testing.h" + +namespace blender::tests { + +struct MyValue { + static inline int alive = 0; + + MyValue() + { + if (alive == 15) { + throw std::exception(); + } + + alive++; + } + + MyValue(const MyValue &UNUSED(other)) + { + if (alive == 15) { + throw std::exception(); + } + + alive++; + } + + ~MyValue() + { + alive--; + } +}; + +TEST(memory_utils, DefaultConstructN_ActuallyCallsConstructor) +{ + constexpr int amount = 10; + TypedBuffer<MyValue, amount> buffer; + + EXPECT_EQ(MyValue::alive, 0); + default_construct_n(buffer.ptr(), amount); + EXPECT_EQ(MyValue::alive, amount); + destruct_n(buffer.ptr(), amount); + EXPECT_EQ(MyValue::alive, 0); +} + +TEST(memory_utils, DefaultConstructN_StrongExceptionSafety) +{ + constexpr int amount = 20; + TypedBuffer<MyValue, amount> buffer; + + EXPECT_EQ(MyValue::alive, 0); + EXPECT_THROW(default_construct_n(buffer.ptr(), amount), std::exception); + EXPECT_EQ(MyValue::alive, 0); +} + +TEST(memory_utils, UninitializedCopyN_ActuallyCopies) +{ + constexpr int amount = 5; + TypedBuffer<MyValue, amount> buffer1; + TypedBuffer<MyValue, amount> buffer2; + + EXPECT_EQ(MyValue::alive, 0); + default_construct_n(buffer1.ptr(), amount); + EXPECT_EQ(MyValue::alive, amount); + uninitialized_copy_n(buffer1.ptr(), amount, buffer2.ptr()); + EXPECT_EQ(MyValue::alive, 2 * amount); + destruct_n(buffer1.ptr(), amount); + EXPECT_EQ(MyValue::alive, amount); + destruct_n(buffer2.ptr(), amount); + EXPECT_EQ(MyValue::alive, 0); +} + +TEST(memory_utils, UninitializedCopyN_StrongExceptionSafety) +{ + constexpr int amount = 10; + TypedBuffer<MyValue, amount> buffer1; + TypedBuffer<MyValue, amount> buffer2; + + EXPECT_EQ(MyValue::alive, 0); + default_construct_n(buffer1.ptr(), amount); + EXPECT_EQ(MyValue::alive, amount); + EXPECT_THROW(uninitialized_copy_n(buffer1.ptr(), amount, buffer2.ptr()), std::exception); + EXPECT_EQ(MyValue::alive, amount); + destruct_n(buffer1.ptr(), amount); + EXPECT_EQ(MyValue::alive, 0); +} + +TEST(memory_utils, UninitializedFillN_ActuallyCopies) +{ + constexpr int amount = 10; + TypedBuffer<MyValue, amount> buffer; + + EXPECT_EQ(MyValue::alive, 0); + { + MyValue value; + EXPECT_EQ(MyValue::alive, 1); + uninitialized_fill_n(buffer.ptr(), amount, value); + EXPECT_EQ(MyValue::alive, 1 + amount); + destruct_n(buffer.ptr(), amount); + EXPECT_EQ(MyValue::alive, 1); + } + EXPECT_EQ(MyValue::alive, 0); +} + +TEST(memory_utils, UninitializedFillN_StrongExceptionSafety) +{ + constexpr int amount = 20; + TypedBuffer<MyValue, amount> buffer; + + EXPECT_EQ(MyValue::alive, 0); + { + MyValue value; + EXPECT_EQ(MyValue::alive, 1); + EXPECT_THROW(uninitialized_fill_n(buffer.ptr(), amount, value), std::exception); + EXPECT_EQ(MyValue::alive, 1); + } + EXPECT_EQ(MyValue::alive, 0); +} + +class TestBaseClass { + virtual void mymethod(){}; +}; + +class TestChildClass : public TestBaseClass { + void mymethod() override + { + } +}; + +static_assert(is_convertible_pointer_v<int *, int *>); +static_assert(is_convertible_pointer_v<int *, const int *>); +static_assert(is_convertible_pointer_v<int *, int *const>); +static_assert(is_convertible_pointer_v<int *, const int *const>); +static_assert(!is_convertible_pointer_v<const int *, int *>); +static_assert(!is_convertible_pointer_v<int, int *>); +static_assert(!is_convertible_pointer_v<int *, int>); +static_assert(is_convertible_pointer_v<TestBaseClass *, const TestBaseClass *>); +static_assert(!is_convertible_pointer_v<const TestBaseClass *, TestBaseClass *>); +static_assert(is_convertible_pointer_v<TestChildClass *, TestBaseClass *>); +static_assert(!is_convertible_pointer_v<TestBaseClass *, TestChildClass *>); +static_assert(is_convertible_pointer_v<const TestChildClass *, const TestBaseClass *>); +static_assert(!is_convertible_pointer_v<TestBaseClass, const TestChildClass *>); +static_assert(!is_convertible_pointer_v<float3, float *>); +static_assert(!is_convertible_pointer_v<float *, float3>); +static_assert(!is_convertible_pointer_v<int **, int *>); +static_assert(!is_convertible_pointer_v<int *, int **>); +static_assert(is_convertible_pointer_v<int **, int **>); +static_assert(is_convertible_pointer_v<const int **, const int **>); +static_assert(!is_convertible_pointer_v<const int **, int **>); +static_assert(!is_convertible_pointer_v<int *const *, int **>); +static_assert(!is_convertible_pointer_v<int *const *const, int **>); +static_assert(is_convertible_pointer_v<int **, int **const>); +static_assert(is_convertible_pointer_v<int **, int *const *>); +static_assert(is_convertible_pointer_v<int **, int const *const *>); + +} // namespace blender::tests diff --git a/source/blender/blenlib/tests/BLI_multi_value_map_test.cc b/source/blender/blenlib/tests/BLI_multi_value_map_test.cc new file mode 100644 index 00000000000..7501fbe0d87 --- /dev/null +++ b/source/blender/blenlib/tests/BLI_multi_value_map_test.cc @@ -0,0 +1,109 @@ +/* Apache License, Version 2.0 */ + +#include "BLI_multi_value_map.hh" +#include "BLI_vector.hh" +#include "testing/testing.h" + +namespace blender::tests { + +TEST(multi_value_map, LookupNotExistant) +{ + MultiValueMap<int, int> map; + EXPECT_EQ(map.lookup(5).size(), 0); + map.add(2, 5); + EXPECT_EQ(map.lookup(5).size(), 0); +} + +TEST(multi_value_map, LookupExistant) +{ + MultiValueMap<int, int> map; + map.add(2, 4); + map.add(2, 5); + map.add(3, 6); + + EXPECT_EQ(map.lookup(2).size(), 2); + EXPECT_EQ(map.lookup(2)[0], 4); + EXPECT_EQ(map.lookup(2)[1], 5); + + EXPECT_EQ(map.lookup(3).size(), 1); + EXPECT_EQ(map.lookup(3)[0], 6); +} + +TEST(multi_value_map, AddMultiple) +{ + MultiValueMap<int, int> map; + map.add_multiple(2, {4, 5, 6}); + map.add_multiple(2, {1, 2}); + map.add_multiple(5, {7, 5, 3}); + + EXPECT_EQ(map.lookup(2).size(), 5); + EXPECT_EQ(map.lookup(2)[0], 4); + EXPECT_EQ(map.lookup(2)[1], 5); + EXPECT_EQ(map.lookup(2)[2], 6); + EXPECT_EQ(map.lookup(2)[3], 1); + EXPECT_EQ(map.lookup(2)[4], 2); + + EXPECT_EQ(map.lookup(5).size(), 3); + EXPECT_EQ(map.lookup(5)[0], 7); + EXPECT_EQ(map.lookup(5)[1], 5); + EXPECT_EQ(map.lookup(5)[2], 3); +} + +TEST(multi_value_map, Keys) +{ + MultiValueMap<int, int> map; + map.add(5, 7); + map.add(5, 7); + map.add_multiple(2, {6, 7, 8}); + + Vector<int> keys; + for (int key : map.keys()) { + keys.append(key); + } + + EXPECT_EQ(keys.size(), 2); + EXPECT_TRUE(keys.contains(5)); + EXPECT_TRUE(keys.contains(2)); +} + +TEST(multi_value_map, Values) +{ + MultiValueMap<int, int> map; + map.add(3, 5); + map.add_multiple(3, {1, 2}); + map.add(6, 1); + + Vector<Span<int>> values; + for (Span<int> value_span : map.values()) { + values.append(value_span); + } + + EXPECT_EQ(values.size(), 2); +} + +TEST(multi_value_map, Items) +{ + MultiValueMap<int, int> map; + map.add_multiple(4, {1, 2, 3}); + + for (auto &&item : map.items()) { + int key = item.key; + Span<int> values = item.value; + EXPECT_EQ(key, 4); + EXPECT_EQ(values.size(), 3); + EXPECT_EQ(values[0], 1); + EXPECT_EQ(values[1], 2); + EXPECT_EQ(values[2], 3); + } +} + +TEST(multi_value_map, UniquePtr) +{ + /* Mostly testing if it compiles here. */ + MultiValueMap<std::unique_ptr<int>, std::unique_ptr<int>> map; + map.add(std::make_unique<int>(4), std::make_unique<int>(6)); + map.add(std::make_unique<int>(4), std::make_unique<int>(7)); + EXPECT_EQ(map.lookup(std::make_unique<int>(10)).size(), 0); +} + +} // namespace blender::tests diff --git a/source/blender/blenlib/tests/BLI_set_test.cc b/source/blender/blenlib/tests/BLI_set_test.cc new file mode 100644 index 00000000000..7bd0b258df8 --- /dev/null +++ b/source/blender/blenlib/tests/BLI_set_test.cc @@ -0,0 +1,565 @@ +/* Apache License, Version 2.0 */ + +#include <set> +#include <unordered_set> + +#include "BLI_ghash.h" +#include "BLI_rand.h" +#include "BLI_set.hh" +#include "BLI_strict_flags.h" +#include "BLI_timeit.hh" +#include "BLI_vector.hh" +#include "testing/testing.h" + +namespace blender { +namespace tests { + +TEST(set, DefaultConstructor) +{ + Set<int> set; + EXPECT_EQ(set.size(), 0); + EXPECT_TRUE(set.is_empty()); +} + +TEST(set, ContainsNotExistant) +{ + Set<int> set; + EXPECT_FALSE(set.contains(3)); +} + +TEST(set, ContainsExistant) +{ + Set<int> set; + EXPECT_FALSE(set.contains(5)); + EXPECT_TRUE(set.is_empty()); + set.add(5); + EXPECT_TRUE(set.contains(5)); + EXPECT_FALSE(set.is_empty()); +} + +TEST(set, AddMany) +{ + Set<int> set; + for (int i = 0; i < 100; i++) { + set.add(i); + } + + for (int i = 50; i < 100; i++) { + EXPECT_TRUE(set.contains(i)); + } + for (int i = 100; i < 150; i++) { + EXPECT_FALSE(set.contains(i)); + } +} + +TEST(set, InitializerListConstructor) +{ + Set<int> set = {4, 5, 6}; + EXPECT_EQ(set.size(), 3); + EXPECT_TRUE(set.contains(4)); + EXPECT_TRUE(set.contains(5)); + EXPECT_TRUE(set.contains(6)); + EXPECT_FALSE(set.contains(2)); + EXPECT_FALSE(set.contains(3)); +} + +TEST(set, CopyConstructor) +{ + Set<int> set = {3}; + EXPECT_TRUE(set.contains(3)); + EXPECT_FALSE(set.contains(4)); + + Set<int> set2(set); + set2.add(4); + EXPECT_TRUE(set2.contains(3)); + EXPECT_TRUE(set2.contains(4)); + + EXPECT_FALSE(set.contains(4)); +} + +TEST(set, MoveConstructor) +{ + Set<int> set = {1, 2, 3}; + EXPECT_EQ(set.size(), 3); + Set<int> set2(std::move(set)); + EXPECT_EQ(set.size(), 0); /* NOLINT: bugprone-use-after-move */ + EXPECT_EQ(set2.size(), 3); +} + +TEST(set, CopyAssignment) +{ + Set<int> set = {3}; + EXPECT_TRUE(set.contains(3)); + EXPECT_FALSE(set.contains(4)); + + Set<int> set2; + set2 = set; + set2.add(4); + EXPECT_TRUE(set2.contains(3)); + EXPECT_TRUE(set2.contains(4)); + + EXPECT_FALSE(set.contains(4)); +} + +TEST(set, MoveAssignment) +{ + Set<int> set = {1, 2, 3}; + EXPECT_EQ(set.size(), 3); + Set<int> set2; + set2 = std::move(set); + EXPECT_EQ(set.size(), 0); /* NOLINT: bugprone-use-after-move */ + EXPECT_EQ(set2.size(), 3); +} + +TEST(set, RemoveContained) +{ + Set<int> set = {3, 4, 5}; + EXPECT_TRUE(set.contains(3)); + EXPECT_TRUE(set.contains(4)); + EXPECT_TRUE(set.contains(5)); + set.remove_contained(4); + EXPECT_TRUE(set.contains(3)); + EXPECT_FALSE(set.contains(4)); + EXPECT_TRUE(set.contains(5)); + set.remove_contained(3); + EXPECT_FALSE(set.contains(3)); + EXPECT_FALSE(set.contains(4)); + EXPECT_TRUE(set.contains(5)); + set.remove_contained(5); + EXPECT_FALSE(set.contains(3)); + EXPECT_FALSE(set.contains(4)); + EXPECT_FALSE(set.contains(5)); +} + +TEST(set, RemoveContainedMany) +{ + Set<int> set; + for (int i = 0; i < 1000; i++) { + set.add(i); + } + for (int i = 100; i < 1000; i++) { + set.remove_contained(i); + } + for (int i = 900; i < 1000; i++) { + set.add(i); + } + + for (int i = 0; i < 1000; i++) { + if (i < 100 || i >= 900) { + EXPECT_TRUE(set.contains(i)); + } + else { + EXPECT_FALSE(set.contains(i)); + } + } +} + +TEST(set, Intersects) +{ + Set<int> a = {3, 4, 5, 6}; + Set<int> b = {1, 2, 5}; + EXPECT_TRUE(Set<int>::Intersects(a, b)); + EXPECT_FALSE(Set<int>::Disjoint(a, b)); +} + +TEST(set, Disjoint) +{ + Set<int> a = {5, 6, 7, 8}; + Set<int> b = {2, 3, 4, 9}; + EXPECT_FALSE(Set<int>::Intersects(a, b)); + EXPECT_TRUE(Set<int>::Disjoint(a, b)); +} + +TEST(set, AddMultiple) +{ + Set<int> a; + a.add_multiple({5, 7}); + EXPECT_TRUE(a.contains(5)); + EXPECT_TRUE(a.contains(7)); + EXPECT_FALSE(a.contains(4)); + a.add_multiple({2, 4, 7}); + EXPECT_TRUE(a.contains(4)); + EXPECT_TRUE(a.contains(2)); + EXPECT_EQ(a.size(), 4); +} + +TEST(set, AddMultipleNew) +{ + Set<int> a; + a.add_multiple_new({5, 6}); + EXPECT_TRUE(a.contains(5)); + EXPECT_TRUE(a.contains(6)); +} + +TEST(set, Iterator) +{ + Set<int> set = {1, 3, 2, 5, 4}; + blender::Vector<int> vec; + for (int value : set) { + vec.append(value); + } + EXPECT_EQ(vec.size(), 5); + EXPECT_TRUE(vec.contains(1)); + EXPECT_TRUE(vec.contains(3)); + EXPECT_TRUE(vec.contains(2)); + EXPECT_TRUE(vec.contains(5)); + EXPECT_TRUE(vec.contains(4)); +} + +TEST(set, OftenAddRemoveContained) +{ + Set<int> set; + for (int i = 0; i < 100; i++) { + set.add(42); + EXPECT_EQ(set.size(), 1); + set.remove_contained(42); + EXPECT_EQ(set.size(), 0); + } +} + +TEST(set, UniquePtrValues) +{ + Set<std::unique_ptr<int>> set; + set.add_new(std::unique_ptr<int>(new int())); + auto value1 = std::unique_ptr<int>(new int()); + set.add_new(std::move(value1)); + set.add(std::unique_ptr<int>(new int())); + + EXPECT_EQ(set.size(), 3); +} + +TEST(set, Clear) +{ + Set<int> set = {3, 4, 6, 7}; + EXPECT_EQ(set.size(), 4); + set.clear(); + EXPECT_EQ(set.size(), 0); +} + +TEST(set, StringSet) +{ + Set<std::string> set; + set.add("hello"); + set.add("world"); + EXPECT_EQ(set.size(), 2); + EXPECT_TRUE(set.contains("hello")); + EXPECT_TRUE(set.contains("world")); + EXPECT_FALSE(set.contains("world2")); +} + +TEST(set, PointerSet) +{ + int a, b, c; + Set<int *> set; + set.add(&a); + set.add(&b); + EXPECT_EQ(set.size(), 2); + EXPECT_TRUE(set.contains(&a)); + EXPECT_TRUE(set.contains(&b)); + EXPECT_FALSE(set.contains(&c)); +} + +TEST(set, Remove) +{ + Set<int> set = {1, 2, 3, 4, 5, 6}; + EXPECT_EQ(set.size(), 6); + EXPECT_TRUE(set.remove(2)); + EXPECT_EQ(set.size(), 5); + EXPECT_FALSE(set.contains(2)); + EXPECT_FALSE(set.remove(2)); + EXPECT_EQ(set.size(), 5); + EXPECT_TRUE(set.remove(5)); + EXPECT_EQ(set.size(), 4); +} + +struct Type1 { + uint32_t value; +}; + +struct Type2 { + uint32_t value; +}; + +static bool operator==(const Type1 &a, const Type1 &b) +{ + return a.value == b.value; +} +static bool operator==(const Type2 &a, const Type1 &b) +{ + return a.value == b.value; +} + +} // namespace tests + +/* This has to be defined in ::blender namespace. */ +template<> struct DefaultHash<tests::Type1> { + uint32_t operator()(const tests::Type1 &value) const + { + return value.value; + } + + uint32_t operator()(const tests::Type2 &value) const + { + return value.value; + } +}; + +namespace tests { + +TEST(set, ContainsAs) +{ + Set<Type1> set; + set.add(Type1{5}); + EXPECT_TRUE(set.contains_as(Type1{5})); + EXPECT_TRUE(set.contains_as(Type2{5})); + EXPECT_FALSE(set.contains_as(Type1{6})); + EXPECT_FALSE(set.contains_as(Type2{6})); +} + +TEST(set, ContainsAsString) +{ + Set<std::string> set; + set.add("test"); + EXPECT_TRUE(set.contains_as("test")); + EXPECT_TRUE(set.contains_as(StringRef("test"))); + EXPECT_FALSE(set.contains_as("string")); + EXPECT_FALSE(set.contains_as(StringRef("string"))); +} + +TEST(set, RemoveContainedAs) +{ + Set<Type1> set; + set.add(Type1{5}); + EXPECT_TRUE(set.contains_as(Type2{5})); + set.remove_contained_as(Type2{5}); + EXPECT_FALSE(set.contains_as(Type2{5})); +} + +TEST(set, RemoveAs) +{ + Set<Type1> set; + set.add(Type1{5}); + EXPECT_TRUE(set.contains_as(Type2{5})); + set.remove_as(Type2{6}); + EXPECT_TRUE(set.contains_as(Type2{5})); + set.remove_as(Type2{5}); + EXPECT_FALSE(set.contains_as(Type2{5})); + set.remove_as(Type2{5}); + EXPECT_FALSE(set.contains_as(Type2{5})); +} + +TEST(set, AddAs) +{ + Set<std::string> set; + EXPECT_TRUE(set.add_as("test")); + EXPECT_TRUE(set.add_as(StringRef("qwe"))); + EXPECT_FALSE(set.add_as(StringRef("test"))); + EXPECT_FALSE(set.add_as("qwe")); +} + +template<uint N> struct EqualityIntModN { + bool operator()(uint a, uint b) const + { + return (a % N) == (b % N); + } +}; + +template<uint N> struct HashIntModN { + uint64_t operator()(uint value) const + { + return value % N; + } +}; + +TEST(set, CustomizeHashAndEquality) +{ + Set<uint, 0, DefaultProbingStrategy, HashIntModN<10>, EqualityIntModN<10>> set; + set.add(4); + EXPECT_TRUE(set.contains(4)); + EXPECT_TRUE(set.contains(14)); + EXPECT_TRUE(set.contains(104)); + EXPECT_FALSE(set.contains(5)); + set.add(55); + EXPECT_TRUE(set.contains(5)); + EXPECT_TRUE(set.contains(14)); + set.remove(1004); + EXPECT_FALSE(set.contains(14)); +} + +TEST(set, IntrusiveIntKey) +{ + Set<int, + 2, + DefaultProbingStrategy, + DefaultHash<int>, + DefaultEquality, + IntegerSetSlot<int, 100, 200>> + set; + EXPECT_TRUE(set.add(4)); + EXPECT_TRUE(set.add(3)); + EXPECT_TRUE(set.add(11)); + EXPECT_TRUE(set.add(8)); + EXPECT_FALSE(set.add(3)); + EXPECT_FALSE(set.add(4)); + EXPECT_TRUE(set.remove(4)); + EXPECT_FALSE(set.remove(7)); + EXPECT_TRUE(set.add(4)); + EXPECT_TRUE(set.remove(4)); +} + +struct MyKeyType { + uint32_t key; + int32_t attached_data; + + uint64_t hash() const + { + return key; + } + + friend bool operator==(const MyKeyType &a, const MyKeyType &b) + { + return a.key == b.key; + } +}; + +TEST(set, LookupKey) +{ + Set<MyKeyType> set; + set.add({1, 10}); + set.add({2, 20}); + EXPECT_EQ(set.lookup_key({1, 30}).attached_data, 10); + EXPECT_EQ(set.lookup_key({2, 0}).attached_data, 20); +} + +TEST(set, LookupKeyDefault) +{ + Set<MyKeyType> set; + set.add({1, 10}); + set.add({2, 20}); + + MyKeyType fallback{5, 50}; + EXPECT_EQ(set.lookup_key_default({1, 66}, fallback).attached_data, 10); + EXPECT_EQ(set.lookup_key_default({4, 40}, fallback).attached_data, 50); +} + +TEST(set, LookupKeyPtr) +{ + Set<MyKeyType> set; + set.add({1, 10}); + set.add({2, 20}); + EXPECT_EQ(set.lookup_key_ptr({1, 50})->attached_data, 10); + EXPECT_EQ(set.lookup_key_ptr({2, 50})->attached_data, 20); + EXPECT_EQ(set.lookup_key_ptr({3, 50}), nullptr); +} + +/** + * Set this to 1 to activate the benchmark. It is disabled by default, because it prints a lot. + */ +#if 0 +template<typename SetT> +BLI_NOINLINE void benchmark_random_ints(StringRef name, int amount, int factor) +{ + RNG *rng = BLI_rng_new(0); + Vector<int> values; + for (int i = 0; i < amount; i++) { + values.append(BLI_rng_get_int(rng) * factor); + } + BLI_rng_free(rng); + + SetT set; + { + SCOPED_TIMER(name + " Add"); + for (int value : values) { + set.add(value); + } + } + int count = 0; + { + SCOPED_TIMER(name + " Contains"); + for (int value : values) { + count += set.contains(value); + } + } + { + SCOPED_TIMER(name + " Remove"); + for (int value : values) { + count += set.remove(value); + } + } + + /* Print the value for simple error checking and to avoid some compiler optimizations. */ + std::cout << "Count: " << count << "\n"; +} + +TEST(set, Benchmark) +{ + for (int i = 0; i < 3; i++) { + benchmark_random_ints<blender::Set<int>>("blender::Set ", 100000, 1); + benchmark_random_ints<blender::StdUnorderedSetWrapper<int>>("std::unordered_set", 100000, 1); + } + std::cout << "\n"; + for (int i = 0; i < 3; i++) { + uint32_t factor = (3 << 10); + benchmark_random_ints<blender::Set<int>>("blender::Set ", 100000, factor); + benchmark_random_ints<blender::StdUnorderedSetWrapper<int>>("std::unordered_set", 100000, factor); + } +} + +/** + * Output of the rudimentary benchmark above on my hardware. + * + * Timer 'blender::Set Add' took 5.5573 ms + * Timer 'blender::Set Contains' took 0.807384 ms + * Timer 'blender::Set Remove' took 0.953436 ms + * Count: 199998 + * Timer 'std::unordered_set Add' took 12.551 ms + * Timer 'std::unordered_set Contains' took 2.3323 ms + * Timer 'std::unordered_set Remove' took 5.07082 ms + * Count: 199998 + * Timer 'blender::Set Add' took 2.62526 ms + * Timer 'blender::Set Contains' took 0.407499 ms + * Timer 'blender::Set Remove' took 0.472981 ms + * Count: 199998 + * Timer 'std::unordered_set Add' took 6.26945 ms + * Timer 'std::unordered_set Contains' took 1.17236 ms + * Timer 'std::unordered_set Remove' took 3.77402 ms + * Count: 199998 + * Timer 'blender::Set Add' took 2.59152 ms + * Timer 'blender::Set Contains' took 0.415254 ms + * Timer 'blender::Set Remove' took 0.477559 ms + * Count: 199998 + * Timer 'std::unordered_set Add' took 6.28129 ms + * Timer 'std::unordered_set Contains' took 1.17562 ms + * Timer 'std::unordered_set Remove' took 3.77811 ms + * Count: 199998 + * + * Timer 'blender::Set Add' took 3.16514 ms + * Timer 'blender::Set Contains' took 0.732895 ms + * Timer 'blender::Set Remove' took 1.08171 ms + * Count: 198790 + * Timer 'std::unordered_set Add' took 6.57377 ms + * Timer 'std::unordered_set Contains' took 1.17008 ms + * Timer 'std::unordered_set Remove' took 3.7946 ms + * Count: 198790 + * Timer 'blender::Set Add' took 3.11439 ms + * Timer 'blender::Set Contains' took 0.740159 ms + * Timer 'blender::Set Remove' took 1.06749 ms + * Count: 198790 + * Timer 'std::unordered_set Add' took 6.35597 ms + * Timer 'std::unordered_set Contains' took 1.17713 ms + * Timer 'std::unordered_set Remove' took 3.77826 ms + * Count: 198790 + * Timer 'blender::Set Add' took 3.09876 ms + * Timer 'blender::Set Contains' took 0.742072 ms + * Timer 'blender::Set Remove' took 1.06622 ms + * Count: 198790 + * Timer 'std::unordered_set Add' took 6.4469 ms + * Timer 'std::unordered_set Contains' took 1.16515 ms + * Timer 'std::unordered_set Remove' took 3.80639 ms + * Count: 198790 + */ + +#endif /* Benchmark */ + +} // namespace tests +} // namespace blender diff --git a/source/blender/blenlib/tests/BLI_span_test.cc b/source/blender/blenlib/tests/BLI_span_test.cc new file mode 100644 index 00000000000..587497624f4 --- /dev/null +++ b/source/blender/blenlib/tests/BLI_span_test.cc @@ -0,0 +1,311 @@ +/* Apache License, Version 2.0 */ + +#include "BLI_span.hh" +#include "BLI_strict_flags.h" +#include "BLI_vector.hh" +#include "testing/testing.h" + +namespace blender::tests { + +TEST(span, FromSmallVector) +{ + Vector<int> a = {1, 2, 3}; + Span<int> a_span = a; + EXPECT_EQ(a_span.size(), 3); + EXPECT_EQ(a_span[0], 1); + EXPECT_EQ(a_span[1], 2); + EXPECT_EQ(a_span[2], 3); +} + +TEST(span, AddConstToPointer) +{ + int a = 0; + std::vector<int *> vec = {&a}; + Span<int *> span = vec; + Span<const int *> const_span = span; + EXPECT_EQ(const_span.size(), 1); +} + +TEST(span, IsReferencing) +{ + int array[] = {3, 5, 8}; + MutableSpan<int> span(array, ARRAY_SIZE(array)); + EXPECT_EQ(span.size(), 3); + EXPECT_EQ(span[1], 5); + array[1] = 10; + EXPECT_EQ(span[1], 10); +} + +TEST(span, DropBack) +{ + Vector<int> a = {4, 5, 6, 7}; + auto slice = Span<int>(a).drop_back(2); + EXPECT_EQ(slice.size(), 2); + EXPECT_EQ(slice[0], 4); + EXPECT_EQ(slice[1], 5); +} + +TEST(span, DropBackAll) +{ + Vector<int> a = {4, 5, 6, 7}; + auto slice = Span<int>(a).drop_back(a.size()); + EXPECT_EQ(slice.size(), 0); +} + +TEST(span, DropFront) +{ + Vector<int> a = {4, 5, 6, 7}; + auto slice = Span<int>(a).drop_front(1); + EXPECT_EQ(slice.size(), 3); + EXPECT_EQ(slice[0], 5); + EXPECT_EQ(slice[1], 6); + EXPECT_EQ(slice[2], 7); +} + +TEST(span, DropFrontAll) +{ + Vector<int> a = {4, 5, 6, 7}; + auto slice = Span<int>(a).drop_front(a.size()); + EXPECT_EQ(slice.size(), 0); +} + +TEST(span, TakeFront) +{ + Vector<int> a = {4, 5, 6, 7}; + auto slice = Span<int>(a).take_front(2); + EXPECT_EQ(slice.size(), 2); + EXPECT_EQ(slice[0], 4); + EXPECT_EQ(slice[1], 5); +} + +TEST(span, TakeBack) +{ + Vector<int> a = {5, 6, 7, 8}; + auto slice = Span<int>(a).take_back(2); + EXPECT_EQ(slice.size(), 2); + EXPECT_EQ(slice[0], 7); + EXPECT_EQ(slice[1], 8); +} + +TEST(span, Slice) +{ + Vector<int> a = {4, 5, 6, 7}; + auto slice = Span<int>(a).slice(1, 2); + EXPECT_EQ(slice.size(), 2); + EXPECT_EQ(slice[0], 5); + EXPECT_EQ(slice[1], 6); +} + +TEST(span, SliceEmpty) +{ + Vector<int> a = {4, 5, 6, 7}; + auto slice = Span<int>(a).slice(2, 0); + EXPECT_EQ(slice.size(), 0); +} + +TEST(span, SliceRange) +{ + Vector<int> a = {1, 2, 3, 4, 5}; + auto slice = Span<int>(a).slice(IndexRange(2, 2)); + EXPECT_EQ(slice.size(), 2); + EXPECT_EQ(slice[0], 3); + EXPECT_EQ(slice[1], 4); +} + +TEST(span, Contains) +{ + Vector<int> a = {4, 5, 6, 7}; + Span<int> a_span = a; + EXPECT_TRUE(a_span.contains(4)); + EXPECT_TRUE(a_span.contains(5)); + EXPECT_TRUE(a_span.contains(6)); + EXPECT_TRUE(a_span.contains(7)); + EXPECT_FALSE(a_span.contains(3)); + EXPECT_FALSE(a_span.contains(8)); +} + +TEST(span, Count) +{ + Vector<int> a = {2, 3, 4, 3, 3, 2, 2, 2, 2}; + Span<int> a_span = a; + EXPECT_EQ(a_span.count(1), 0); + EXPECT_EQ(a_span.count(2), 5); + EXPECT_EQ(a_span.count(3), 3); + EXPECT_EQ(a_span.count(4), 1); + EXPECT_EQ(a_span.count(5), 0); +} + +static void test_ref_from_initializer_list(Span<int> span) +{ + EXPECT_EQ(span.size(), 4); + EXPECT_EQ(span[0], 3); + EXPECT_EQ(span[1], 6); + EXPECT_EQ(span[2], 8); + EXPECT_EQ(span[3], 9); +} + +TEST(span, FromInitializerList) +{ + test_ref_from_initializer_list({3, 6, 8, 9}); +} + +TEST(span, FromVector) +{ + std::vector<int> a = {1, 2, 3, 4}; + Span<int> a_span(a); + EXPECT_EQ(a_span.size(), 4); + EXPECT_EQ(a_span[0], 1); + EXPECT_EQ(a_span[1], 2); + EXPECT_EQ(a_span[2], 3); + EXPECT_EQ(a_span[3], 4); +} + +TEST(span, FromArray) +{ + std::array<int, 2> a = {5, 6}; + Span<int> a_span(a); + EXPECT_EQ(a_span.size(), 2); + EXPECT_EQ(a_span[0], 5); + EXPECT_EQ(a_span[1], 6); +} + +TEST(span, Fill) +{ + std::array<int, 5> a = {4, 5, 6, 7, 8}; + MutableSpan<int> a_span(a); + a_span.fill(1); + EXPECT_EQ(a[0], 1); + EXPECT_EQ(a[1], 1); + EXPECT_EQ(a[2], 1); + EXPECT_EQ(a[3], 1); + EXPECT_EQ(a[4], 1); +} + +TEST(span, FillIndices) +{ + std::array<int, 5> a = {0, 0, 0, 0, 0}; + MutableSpan<int> a_span(a); + a_span.fill_indices({0, 2, 3}, 1); + EXPECT_EQ(a[0], 1); + EXPECT_EQ(a[1], 0); + EXPECT_EQ(a[2], 1); + EXPECT_EQ(a[3], 1); + EXPECT_EQ(a[4], 0); +} + +TEST(span, SizeInBytes) +{ + std::array<int, 10> a; + Span<int> a_span(a); + EXPECT_EQ(a_span.size_in_bytes(), (int64_t)sizeof(a)); + EXPECT_EQ(a_span.size_in_bytes(), 40); +} + +TEST(span, FirstLast) +{ + std::array<int, 4> a = {6, 7, 8, 9}; + Span<int> a_span(a); + EXPECT_EQ(a_span.first(), 6); + EXPECT_EQ(a_span.last(), 9); +} + +TEST(span, FirstLast_OneElement) +{ + int a = 3; + Span<int> a_span(&a, 1); + EXPECT_EQ(a_span.first(), 3); + EXPECT_EQ(a_span.last(), 3); +} + +TEST(span, Get) +{ + std::array<int, 3> a = {5, 6, 7}; + Span<int> a_span(a); + EXPECT_EQ(a_span.get(0, 42), 5); + EXPECT_EQ(a_span.get(1, 42), 6); + EXPECT_EQ(a_span.get(2, 42), 7); + EXPECT_EQ(a_span.get(3, 42), 42); + EXPECT_EQ(a_span.get(4, 42), 42); +} + +TEST(span, ContainsPtr) +{ + std::array<int, 3> a = {5, 6, 7}; + int other = 10; + Span<int> a_span(a); + EXPECT_TRUE(a_span.contains_ptr(&a[0] + 0)); + EXPECT_TRUE(a_span.contains_ptr(&a[0] + 1)); + EXPECT_TRUE(a_span.contains_ptr(&a[0] + 2)); + EXPECT_FALSE(a_span.contains_ptr(&a[0] + 3)); + EXPECT_FALSE(a_span.contains_ptr(&a[0] - 1)); + EXPECT_FALSE(a_span.contains_ptr(&other)); +} + +TEST(span, FirstIndex) +{ + std::array<int, 5> a = {4, 5, 4, 2, 5}; + Span<int> a_span(a); + + EXPECT_EQ(a_span.first_index(4), 0); + EXPECT_EQ(a_span.first_index(5), 1); + EXPECT_EQ(a_span.first_index(2), 3); +} + +TEST(span, CastSameSize) +{ + int value = 0; + std::array<int *, 4> a = {&value, nullptr, nullptr, nullptr}; + Span<int *> a_span = a; + Span<float *> new_a_span = a_span.cast<float *>(); + + EXPECT_EQ(a_span.size(), 4); + EXPECT_EQ(new_a_span.size(), 4); + + EXPECT_EQ(a_span[0], &value); + EXPECT_EQ(new_a_span[0], (float *)&value); +} + +TEST(span, CastSmallerSize) +{ + std::array<uint32_t, 4> a = {3, 4, 5, 6}; + Span<uint32_t> a_span = a; + Span<uint16_t> new_a_span = a_span.cast<uint16_t>(); + + EXPECT_EQ(a_span.size(), 4); + EXPECT_EQ(new_a_span.size(), 8); +} + +TEST(span, CastLargerSize) +{ + std::array<uint16_t, 4> a = {4, 5, 6, 7}; + Span<uint16_t> a_span = a; + Span<uint32_t> new_a_span = a_span.cast<uint32_t>(); + + EXPECT_EQ(a_span.size(), 4); + EXPECT_EQ(new_a_span.size(), 2); +} + +TEST(span, VoidPointerSpan) +{ + int a; + float b; + double c; + + auto func1 = [](Span<void *> span) { EXPECT_EQ(span.size(), 3); }; + func1({&a, &b, &c}); +} + +TEST(span, CopyFrom) +{ + std::array<int, 4> src = {5, 6, 7, 8}; + std::array<int, 4> dst = {1, 2, 3, 4}; + + EXPECT_EQ(dst[2], 3); + MutableSpan(dst).copy_from(src); + EXPECT_EQ(dst[0], 5); + EXPECT_EQ(dst[1], 6); + EXPECT_EQ(dst[2], 7); + EXPECT_EQ(dst[3], 8); +} + +} // namespace blender::tests diff --git a/source/blender/blenlib/tests/BLI_stack_cxx_test.cc b/source/blender/blenlib/tests/BLI_stack_cxx_test.cc new file mode 100644 index 00000000000..3572e751b88 --- /dev/null +++ b/source/blender/blenlib/tests/BLI_stack_cxx_test.cc @@ -0,0 +1,188 @@ +/* Apache License, Version 2.0 */ + +#include "BLI_stack.hh" +#include "BLI_strict_flags.h" +#include "BLI_vector.hh" +#include "testing/testing.h" + +namespace blender::tests { + +TEST(stack, DefaultConstructor) +{ + Stack<int> stack; + EXPECT_EQ(stack.size(), 0); + EXPECT_TRUE(stack.is_empty()); +} + +TEST(stack, SpanConstructor) +{ + std::array<int, 3> array = {4, 7, 2}; + Stack<int> stack(array); + EXPECT_EQ(stack.size(), 3); + EXPECT_EQ(stack.pop(), 2); + EXPECT_EQ(stack.pop(), 7); + EXPECT_EQ(stack.pop(), 4); + EXPECT_TRUE(stack.is_empty()); +} + +TEST(stack, CopyConstructor) +{ + Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7}; + Stack<int> stack2 = stack1; + EXPECT_EQ(stack1.size(), 7); + EXPECT_EQ(stack2.size(), 7); + for (int i = 7; i >= 1; i--) { + EXPECT_FALSE(stack1.is_empty()); + EXPECT_FALSE(stack2.is_empty()); + EXPECT_EQ(stack1.pop(), i); + EXPECT_EQ(stack2.pop(), i); + } + EXPECT_TRUE(stack1.is_empty()); + EXPECT_TRUE(stack2.is_empty()); +} + +TEST(stack, MoveConstructor) +{ + Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7}; + Stack<int> stack2 = std::move(stack1); + EXPECT_EQ(stack1.size(), 0); /* NOLINT: bugprone-use-after-move */ + EXPECT_EQ(stack2.size(), 7); + for (int i = 7; i >= 1; i--) { + EXPECT_EQ(stack2.pop(), i); + } +} + +TEST(stack, CopyAssignment) +{ + Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7}; + Stack<int> stack2 = {2, 3, 4, 5, 6, 7}; + stack2 = stack1; + + EXPECT_EQ(stack1.size(), 7); + EXPECT_EQ(stack2.size(), 7); + for (int i = 7; i >= 1; i--) { + EXPECT_FALSE(stack1.is_empty()); + EXPECT_FALSE(stack2.is_empty()); + EXPECT_EQ(stack1.pop(), i); + EXPECT_EQ(stack2.pop(), i); + } + EXPECT_TRUE(stack1.is_empty()); + EXPECT_TRUE(stack2.is_empty()); +} + +TEST(stack, MoveAssignment) +{ + Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7}; + Stack<int> stack2 = {5, 3, 7, 2, 2}; + stack2 = std::move(stack1); + EXPECT_EQ(stack1.size(), 0); /* NOLINT: bugprone-use-after-move */ + EXPECT_EQ(stack2.size(), 7); + for (int i = 7; i >= 1; i--) { + EXPECT_EQ(stack2.pop(), i); + } +} + +TEST(stack, Push) +{ + Stack<int> stack; + EXPECT_EQ(stack.size(), 0); + stack.push(3); + EXPECT_EQ(stack.size(), 1); + stack.push(5); + EXPECT_EQ(stack.size(), 2); +} + +TEST(stack, PushMultiple) +{ + Stack<int> stack; + EXPECT_EQ(stack.size(), 0); + stack.push_multiple({1, 2, 3}); + EXPECT_EQ(stack.size(), 3); + EXPECT_EQ(stack.pop(), 3); + EXPECT_EQ(stack.pop(), 2); + EXPECT_EQ(stack.pop(), 1); +} + +TEST(stack, PushPopMany) +{ + Stack<int> stack; + for (int i = 0; i < 1000; i++) { + stack.push(i); + EXPECT_EQ(stack.size(), static_cast<unsigned int>(i + 1)); + } + for (int i = 999; i > 50; i--) { + EXPECT_EQ(stack.pop(), i); + EXPECT_EQ(stack.size(), static_cast<unsigned int>(i)); + } + for (int i = 51; i < 5000; i++) { + stack.push(i); + EXPECT_EQ(stack.size(), static_cast<unsigned int>(i + 1)); + } + for (int i = 4999; i >= 0; i--) { + EXPECT_EQ(stack.pop(), i); + EXPECT_EQ(stack.size(), static_cast<unsigned int>(i)); + } +} + +TEST(stack, PushMultipleAfterPop) +{ + Stack<int> stack; + for (int i = 0; i < 1000; i++) { + stack.push(i); + } + for (int i = 999; i >= 0; i--) { + EXPECT_EQ(stack.pop(), i); + } + + Vector<int> values; + for (int i = 0; i < 5000; i++) { + values.append(i); + } + stack.push_multiple(values); + EXPECT_EQ(stack.size(), 5000); + + for (int i = 4999; i >= 0; i--) { + EXPECT_EQ(stack.pop(), i); + } +} + +TEST(stack, Pop) +{ + Stack<int> stack; + stack.push(4); + stack.push(6); + EXPECT_EQ(stack.pop(), 6); + EXPECT_EQ(stack.pop(), 4); +} + +TEST(stack, Peek) +{ + Stack<int> stack; + stack.push(3); + stack.push(4); + EXPECT_EQ(stack.peek(), 4); + EXPECT_EQ(stack.peek(), 4); + stack.pop(); + EXPECT_EQ(stack.peek(), 3); +} + +TEST(stack, UniquePtrValues) +{ + Stack<std::unique_ptr<int>> stack; + stack.push(std::unique_ptr<int>(new int())); + stack.push(std::unique_ptr<int>(new int())); + std::unique_ptr<int> a = stack.pop(); + std::unique_ptr<int> &b = stack.peek(); + UNUSED_VARS(a, b); +} + +TEST(stack, OveralignedValues) +{ + Stack<AlignedBuffer<1, 512>, 2> stack; + for (int i = 0; i < 100; i++) { + stack.push({}); + EXPECT_EQ((uintptr_t)&stack.peek() % 512, 0); + } +} + +} // namespace blender::tests diff --git a/source/blender/blenlib/tests/BLI_string_ref_test.cc b/source/blender/blenlib/tests/BLI_string_ref_test.cc new file mode 100644 index 00000000000..d08c8a77455 --- /dev/null +++ b/source/blender/blenlib/tests/BLI_string_ref_test.cc @@ -0,0 +1,277 @@ +/* Apache License, Version 2.0 */ + +#include "BLI_strict_flags.h" +#include "BLI_string_ref.hh" +#include "BLI_vector.hh" +#include "testing/testing.h" + +namespace blender::tests { + +TEST(string_ref_null, DefaultConstructor) +{ + StringRefNull ref; + EXPECT_EQ(ref.size(), 0); + EXPECT_EQ(ref[0], '\0'); +} + +TEST(string_ref_null, CStringConstructor) +{ + const char *str = "Hello"; + StringRefNull ref(str); + EXPECT_EQ(ref.size(), 5); + EXPECT_EQ(ref.data(), str); +} + +TEST(string_ref_null, CStringLengthConstructor) +{ + const char *str = "Hello"; + StringRefNull ref(str, 5); + EXPECT_EQ(ref.size(), 5); + EXPECT_EQ(ref.data(), str); +} + +TEST(string_ref, DefaultConstructor) +{ + StringRef ref; + EXPECT_EQ(ref.size(), 0); +} + +TEST(string_ref, StartEndConstructor) +{ + const char *text = "hello world"; + StringRef ref(text, text + 5); + EXPECT_EQ(ref.size(), 5); + EXPECT_TRUE(ref == "hello"); + EXPECT_FALSE(ref == "hello "); +} + +TEST(string_ref, StartEndConstructorNullptr) +{ + StringRef ref(nullptr, nullptr); + EXPECT_EQ(ref.size(), 0); + EXPECT_TRUE(ref == ""); +} + +TEST(string_ref, StartEndConstructorSame) +{ + const char *text = "hello world"; + StringRef ref(text, text); + EXPECT_EQ(ref.size(), 0); + EXPECT_TRUE(ref == ""); +} + +TEST(string_ref, CStringConstructor) +{ + const char *str = "Test"; + StringRef ref(str); + EXPECT_EQ(ref.size(), 4); + EXPECT_EQ(ref.data(), str); +} + +TEST(string_ref, PointerWithLengthConstructor) +{ + const char *str = "Test"; + StringRef ref(str, 2); + EXPECT_EQ(ref.size(), 2); + EXPECT_EQ(ref.data(), str); +} + +TEST(string_ref, StdStringConstructor) +{ + std::string str = "Test"; + StringRef ref(str); + EXPECT_EQ(ref.size(), 4); + EXPECT_EQ(ref.data(), str.data()); +} + +TEST(string_ref, SubscriptOperator) +{ + StringRef ref("hello"); + EXPECT_EQ(ref.size(), 5); + EXPECT_EQ(ref[0], 'h'); + EXPECT_EQ(ref[1], 'e'); + EXPECT_EQ(ref[2], 'l'); + EXPECT_EQ(ref[3], 'l'); + EXPECT_EQ(ref[4], 'o'); +} + +TEST(string_ref, ToStdString) +{ + StringRef ref("test"); + std::string str = ref; + EXPECT_EQ(str.size(), 4); + EXPECT_EQ(str, "test"); +} + +TEST(string_ref, Print) +{ + StringRef ref("test"); + std::stringstream ss; + ss << ref; + ss << ref; + std::string str = ss.str(); + EXPECT_EQ(str.size(), 8); + EXPECT_EQ(str, "testtest"); +} + +TEST(string_ref, Add) +{ + StringRef a("qwe"); + StringRef b("asd"); + std::string result = a + b; + EXPECT_EQ(result, "qweasd"); +} + +TEST(string_ref, AddCharPtr1) +{ + StringRef ref("test"); + std::string result = ref + "qwe"; + EXPECT_EQ(result, "testqwe"); +} + +TEST(string_ref, AddCharPtr2) +{ + StringRef ref("test"); + std::string result = "qwe" + ref; + EXPECT_EQ(result, "qwetest"); +} + +TEST(string_ref, AddString1) +{ + StringRef ref("test"); + std::string result = ref + std::string("asd"); + EXPECT_EQ(result, "testasd"); +} + +TEST(string_ref, AddString2) +{ + StringRef ref("test"); + std::string result = std::string("asd") + ref; + EXPECT_EQ(result, "asdtest"); +} + +TEST(string_ref, CompareEqual) +{ + StringRef ref1("test"); + StringRef ref2("test"); + StringRef ref3("other"); + EXPECT_TRUE(ref1 == ref2); + EXPECT_FALSE(ref1 == ref3); + EXPECT_TRUE(ref1 != ref3); + EXPECT_FALSE(ref1 != ref2); +} + +TEST(string_ref, CompareEqualCharPtr1) +{ + StringRef ref("test"); + EXPECT_TRUE(ref == "test"); + EXPECT_FALSE(ref == "other"); + EXPECT_TRUE(ref != "other"); + EXPECT_FALSE(ref != "test"); +} + +TEST(string_ref, CompareEqualCharPtr2) +{ + StringRef ref("test"); + EXPECT_TRUE("test" == ref); + EXPECT_FALSE("other" == ref); + EXPECT_TRUE(ref != "other"); + EXPECT_FALSE(ref != "test"); +} + +TEST(string_ref, CompareEqualString1) +{ + StringRef ref("test"); + EXPECT_TRUE(ref == std::string("test")); + EXPECT_FALSE(ref == std::string("other")); + EXPECT_TRUE(ref != std::string("other")); + EXPECT_FALSE(ref != std::string("test")); +} + +TEST(string_ref, CompareEqualString2) +{ + StringRef ref("test"); + EXPECT_TRUE(std::string("test") == ref); + EXPECT_FALSE(std::string("other") == ref); + EXPECT_TRUE(std::string("other") != ref); + EXPECT_FALSE(std::string("test") != ref); +} + +TEST(string_ref, Iterate) +{ + StringRef ref("test"); + Vector<char> chars; + for (char c : ref) { + chars.append(c); + } + EXPECT_EQ(chars.size(), 4); + EXPECT_EQ(chars[0], 't'); + EXPECT_EQ(chars[1], 'e'); + EXPECT_EQ(chars[2], 's'); + EXPECT_EQ(chars[3], 't'); +} + +TEST(string_ref, StartsWith) +{ + StringRef ref("test"); + EXPECT_TRUE(ref.startswith("")); + EXPECT_TRUE(ref.startswith("t")); + EXPECT_TRUE(ref.startswith("te")); + EXPECT_TRUE(ref.startswith("tes")); + EXPECT_TRUE(ref.startswith("test")); + EXPECT_FALSE(ref.startswith("test ")); + EXPECT_FALSE(ref.startswith("a")); +} + +TEST(string_ref, EndsWith) +{ + StringRef ref("test"); + EXPECT_TRUE(ref.endswith("")); + EXPECT_TRUE(ref.endswith("t")); + EXPECT_TRUE(ref.endswith("st")); + EXPECT_TRUE(ref.endswith("est")); + EXPECT_TRUE(ref.endswith("test")); + EXPECT_FALSE(ref.endswith(" test")); + EXPECT_FALSE(ref.endswith("a")); +} + +TEST(string_ref, DropPrefixN) +{ + StringRef ref("test"); + StringRef ref2 = ref.drop_prefix(2); + StringRef ref3 = ref2.drop_prefix(2); + EXPECT_EQ(ref2.size(), 2); + EXPECT_EQ(ref3.size(), 0); + EXPECT_EQ(ref2, "st"); + EXPECT_EQ(ref3, ""); +} + +TEST(string_ref, DropPrefix) +{ + StringRef ref("test"); + StringRef ref2 = ref.drop_prefix("tes"); + EXPECT_EQ(ref2.size(), 1); + EXPECT_EQ(ref2, "t"); +} + +TEST(string_ref, Substr) +{ + StringRef ref("hello world"); + EXPECT_EQ(ref.substr(0, 5), "hello"); + EXPECT_EQ(ref.substr(4, 0), ""); + EXPECT_EQ(ref.substr(3, 4), "lo w"); + EXPECT_EQ(ref.substr(6, 5), "world"); +} + +TEST(string_ref, Copy) +{ + StringRef ref("hello"); + char dst[10]; + memset(dst, 0xFF, 10); + ref.copy(dst); + EXPECT_EQ(dst[5], '\0'); + EXPECT_EQ(dst[6], 0xFF); + EXPECT_EQ(ref, dst); +} + +} // namespace blender::tests diff --git a/source/blender/blenlib/tests/BLI_vector_set_test.cc b/source/blender/blenlib/tests/BLI_vector_set_test.cc new file mode 100644 index 00000000000..8f3db8d8403 --- /dev/null +++ b/source/blender/blenlib/tests/BLI_vector_set_test.cc @@ -0,0 +1,164 @@ +/* Apache License, Version 2.0 */ + +#include "BLI_strict_flags.h" +#include "BLI_vector_set.hh" +#include "testing/testing.h" + +namespace blender::tests { + +TEST(vector_set, DefaultConstructor) +{ + VectorSet<int> set; + EXPECT_EQ(set.size(), 0); + EXPECT_TRUE(set.is_empty()); +} + +TEST(vector_set, InitializerListConstructor_WithoutDuplicates) +{ + VectorSet<int> set = {1, 4, 5}; + EXPECT_EQ(set.size(), 3); + EXPECT_EQ(set[0], 1); + EXPECT_EQ(set[1], 4); + EXPECT_EQ(set[2], 5); +} + +TEST(vector_set, InitializerListConstructor_WithDuplicates) +{ + VectorSet<int> set = {1, 3, 3, 2, 1, 5}; + EXPECT_EQ(set.size(), 4); + EXPECT_EQ(set[0], 1); + EXPECT_EQ(set[1], 3); + EXPECT_EQ(set[2], 2); + EXPECT_EQ(set[3], 5); +} + +TEST(vector_set, Copy) +{ + VectorSet<int> set1 = {1, 2, 3}; + VectorSet<int> set2 = set1; + EXPECT_EQ(set1.size(), 3); + EXPECT_EQ(set2.size(), 3); + EXPECT_EQ(set1.index_of(2), 1); + EXPECT_EQ(set2.index_of(2), 1); +} + +TEST(vector_set, CopyAssignment) +{ + VectorSet<int> set1 = {1, 2, 3}; + VectorSet<int> set2 = {}; + set2 = set1; + EXPECT_EQ(set1.size(), 3); + EXPECT_EQ(set2.size(), 3); + EXPECT_EQ(set1.index_of(2), 1); + EXPECT_EQ(set2.index_of(2), 1); +} + +TEST(vector_set, Move) +{ + VectorSet<int> set1 = {1, 2, 3}; + VectorSet<int> set2 = std::move(set1); + EXPECT_EQ(set1.size(), 0); /* NOLINT: bugprone-use-after-move */ + EXPECT_EQ(set2.size(), 3); +} + +TEST(vector_set, MoveAssignment) +{ + VectorSet<int> set1 = {1, 2, 3}; + VectorSet<int> set2 = {}; + set2 = std::move(set1); + EXPECT_EQ(set1.size(), 0); /* NOLINT: bugprone-use-after-move */ + EXPECT_EQ(set2.size(), 3); +} + +TEST(vector_set, AddNewIncreasesSize) +{ + VectorSet<int> set; + EXPECT_TRUE(set.is_empty()); + EXPECT_EQ(set.size(), 0); + set.add(5); + EXPECT_FALSE(set.is_empty()); + EXPECT_EQ(set.size(), 1); +} + +TEST(vector_set, AddExistingDoesNotIncreaseSize) +{ + VectorSet<int> set; + EXPECT_EQ(set.size(), 0); + EXPECT_TRUE(set.add(5)); + EXPECT_EQ(set.size(), 1); + EXPECT_FALSE(set.add(5)); + EXPECT_EQ(set.size(), 1); +} + +TEST(vector_set, Index) +{ + VectorSet<int> set = {3, 6, 4}; + EXPECT_EQ(set.index_of(6), 1); + EXPECT_EQ(set.index_of(3), 0); + EXPECT_EQ(set.index_of(4), 2); +} + +TEST(vector_set, IndexTry) +{ + VectorSet<int> set = {3, 6, 4}; + EXPECT_EQ(set.index_of_try(5), -1); + EXPECT_EQ(set.index_of_try(3), 0); + EXPECT_EQ(set.index_of_try(6), 1); + EXPECT_EQ(set.index_of_try(2), -1); +} + +TEST(vector_set, RemoveContained) +{ + VectorSet<int> set = {4, 5, 6, 7}; + EXPECT_EQ(set.size(), 4); + set.remove_contained(5); + EXPECT_EQ(set.size(), 3); + EXPECT_EQ(set[0], 4); + EXPECT_EQ(set[1], 7); + EXPECT_EQ(set[2], 6); + set.remove_contained(6); + EXPECT_EQ(set.size(), 2); + EXPECT_EQ(set[0], 4); + EXPECT_EQ(set[1], 7); + set.remove_contained(4); + EXPECT_EQ(set.size(), 1); + EXPECT_EQ(set[0], 7); + set.remove_contained(7); + EXPECT_EQ(set.size(), 0); +} + +TEST(vector_set, AddMultipleTimes) +{ + VectorSet<int> set; + for (int i = 0; i < 100; i++) { + EXPECT_FALSE(set.contains(i * 13)); + set.add(i * 12); + set.add(i * 13); + EXPECT_TRUE(set.contains(i * 13)); + } +} + +TEST(vector_set, UniquePtrValue) +{ + VectorSet<std::unique_ptr<int>> set; + set.add_new(std::unique_ptr<int>(new int())); + set.add(std::unique_ptr<int>(new int())); + set.index_of_try(std::unique_ptr<int>(new int())); + std::unique_ptr<int> value = set.pop(); + UNUSED_VARS(value); +} + +TEST(vector_set, Remove) +{ + VectorSet<int> set; + EXPECT_TRUE(set.add(5)); + EXPECT_TRUE(set.contains(5)); + EXPECT_FALSE(set.remove(6)); + EXPECT_TRUE(set.contains(5)); + EXPECT_TRUE(set.remove(5)); + EXPECT_FALSE(set.contains(5)); + EXPECT_FALSE(set.remove(5)); + EXPECT_FALSE(set.contains(5)); +} + +} // namespace blender::tests diff --git a/source/blender/blenlib/tests/BLI_vector_test.cc b/source/blender/blenlib/tests/BLI_vector_test.cc new file mode 100644 index 00000000000..f72dfc5deb8 --- /dev/null +++ b/source/blender/blenlib/tests/BLI_vector_test.cc @@ -0,0 +1,639 @@ +/* Apache License, Version 2.0 */ + +#include "BLI_strict_flags.h" +#include "BLI_vector.hh" +#include "testing/testing.h" +#include <forward_list> + +namespace blender::tests { + +TEST(vector, DefaultConstructor) +{ + Vector<int> vec; + EXPECT_EQ(vec.size(), 0); +} + +TEST(vector, SizeConstructor) +{ + Vector<int> vec(3); + EXPECT_EQ(vec.size(), 3); +} + +/** + * Tests that the trivially constructible types are not zero-initialized. We do not want that for + * performance reasons. + */ +TEST(vector, TrivialTypeSizeConstructor) +{ + Vector<char, 1> *vec = new Vector<char, 1>(1); + char *ptr = &(*vec)[0]; + vec->~Vector(); + + const char magic = 42; + *ptr = magic; + EXPECT_EQ(*ptr, magic); + + new (vec) Vector<char, 1>(1); + EXPECT_EQ((*vec)[0], magic); + EXPECT_EQ(*ptr, magic); + delete vec; +} + +TEST(vector, SizeValueConstructor) +{ + Vector<int> vec(4, 10); + EXPECT_EQ(vec.size(), 4); + EXPECT_EQ(vec[0], 10); + EXPECT_EQ(vec[1], 10); + EXPECT_EQ(vec[2], 10); + EXPECT_EQ(vec[3], 10); +} + +TEST(vector, InitializerListConstructor) +{ + Vector<int> vec = {1, 3, 4, 6}; + EXPECT_EQ(vec.size(), 4); + EXPECT_EQ(vec[0], 1); + EXPECT_EQ(vec[1], 3); + EXPECT_EQ(vec[2], 4); + EXPECT_EQ(vec[3], 6); +} + +TEST(vector, ConvertingConstructor) +{ + std::array<float, 5> values = {5.4f, 7.3f, -8.1f, 5.0f, 0.0f}; + Vector<int> vec = values; + EXPECT_EQ(vec.size(), 5); + EXPECT_EQ(vec[0], 5); + EXPECT_EQ(vec[1], 7); + EXPECT_EQ(vec[2], -8); + EXPECT_EQ(vec[3], 5); + EXPECT_EQ(vec[4], 0); +} + +struct TestListValue { + TestListValue *next, *prev; + int value; +}; + +TEST(vector, ListBaseConstructor) +{ + TestListValue *value1 = new TestListValue{0, 0, 4}; + TestListValue *value2 = new TestListValue{0, 0, 5}; + TestListValue *value3 = new TestListValue{0, 0, 6}; + + ListBase list = {NULL, NULL}; + BLI_addtail(&list, value1); + BLI_addtail(&list, value2); + BLI_addtail(&list, value3); + Vector<TestListValue *> vec(list); + + EXPECT_EQ(vec.size(), 3); + EXPECT_EQ(vec[0]->value, 4); + EXPECT_EQ(vec[1]->value, 5); + EXPECT_EQ(vec[2]->value, 6); + + delete value1; + delete value2; + delete value3; +} + +TEST(vector, ContainerConstructor) +{ + std::forward_list<int> list; + list.push_front(3); + list.push_front(1); + list.push_front(5); + + Vector<int> vec = Vector<int>::FromContainer(list); + EXPECT_EQ(vec.size(), 3); + EXPECT_EQ(vec[0], 5); + EXPECT_EQ(vec[1], 1); + EXPECT_EQ(vec[2], 3); +} + +TEST(vector, CopyConstructor) +{ + Vector<int> vec1 = {1, 2, 3}; + Vector<int> vec2(vec1); + EXPECT_EQ(vec2.size(), 3); + EXPECT_EQ(vec2[0], 1); + EXPECT_EQ(vec2[1], 2); + EXPECT_EQ(vec2[2], 3); + + vec1[1] = 5; + EXPECT_EQ(vec1[1], 5); + EXPECT_EQ(vec2[1], 2); +} + +TEST(vector, CopyConstructor2) +{ + Vector<int, 2> vec1 = {1, 2, 3, 4}; + Vector<int, 3> vec2(vec1); + + EXPECT_EQ(vec1.size(), 4); + EXPECT_EQ(vec2.size(), 4); + EXPECT_NE(vec1.data(), vec2.data()); + EXPECT_EQ(vec2[0], 1); + EXPECT_EQ(vec2[1], 2); + EXPECT_EQ(vec2[2], 3); + EXPECT_EQ(vec2[3], 4); +} + +TEST(vector, CopyConstructor3) +{ + Vector<int, 20> vec1 = {1, 2, 3, 4}; + Vector<int, 1> vec2(vec1); + + EXPECT_EQ(vec1.size(), 4); + EXPECT_EQ(vec2.size(), 4); + EXPECT_NE(vec1.data(), vec2.data()); + EXPECT_EQ(vec2[2], 3); +} + +TEST(vector, CopyConstructor4) +{ + Vector<int, 5> vec1 = {1, 2, 3, 4}; + Vector<int, 6> vec2(vec1); + + EXPECT_EQ(vec1.size(), 4); + EXPECT_EQ(vec2.size(), 4); + EXPECT_NE(vec1.data(), vec2.data()); + EXPECT_EQ(vec2[3], 4); +} + +TEST(vector, MoveConstructor) +{ + Vector<int> vec1 = {1, 2, 3, 4}; + Vector<int> vec2(std::move(vec1)); + + EXPECT_EQ(vec1.size(), 0); /* NOLINT: bugprone-use-after-move */ + EXPECT_EQ(vec2.size(), 4); + EXPECT_EQ(vec2[0], 1); + EXPECT_EQ(vec2[1], 2); + EXPECT_EQ(vec2[2], 3); + EXPECT_EQ(vec2[3], 4); +} + +TEST(vector, MoveConstructor2) +{ + Vector<int, 2> vec1 = {1, 2, 3, 4}; + Vector<int, 3> vec2(std::move(vec1)); + + EXPECT_EQ(vec1.size(), 0); /* NOLINT: bugprone-use-after-move */ + EXPECT_EQ(vec2.size(), 4); + EXPECT_EQ(vec2[0], 1); + EXPECT_EQ(vec2[1], 2); + EXPECT_EQ(vec2[2], 3); + EXPECT_EQ(vec2[3], 4); +} + +TEST(vector, MoveConstructor3) +{ + Vector<int, 20> vec1 = {1, 2, 3, 4}; + Vector<int, 1> vec2(std::move(vec1)); + + EXPECT_EQ(vec1.size(), 0); /* NOLINT: bugprone-use-after-move */ + EXPECT_EQ(vec2.size(), 4); + EXPECT_EQ(vec2[2], 3); +} + +TEST(vector, MoveConstructor4) +{ + Vector<int, 5> vec1 = {1, 2, 3, 4}; + Vector<int, 6> vec2(std::move(vec1)); + + EXPECT_EQ(vec1.size(), 0); /* NOLINT: bugprone-use-after-move */ + EXPECT_EQ(vec2.size(), 4); + EXPECT_EQ(vec2[3], 4); +} + +TEST(vector, MoveAssignment) +{ + Vector<int> vec = {1, 2}; + EXPECT_EQ(vec.size(), 2); + EXPECT_EQ(vec[0], 1); + EXPECT_EQ(vec[1], 2); + + vec = Vector<int>({5}); + EXPECT_EQ(vec.size(), 1); + EXPECT_EQ(vec[0], 5); +} + +TEST(vector, CopyAssignment) +{ + Vector<int> vec1 = {1, 2, 3}; + Vector<int> vec2 = {4, 5}; + EXPECT_EQ(vec1.size(), 3); + EXPECT_EQ(vec2.size(), 2); + + vec2 = vec1; + EXPECT_EQ(vec2.size(), 3); + + vec1[0] = 7; + EXPECT_EQ(vec1[0], 7); + EXPECT_EQ(vec2[0], 1); +} + +TEST(vector, Append) +{ + Vector<int> vec; + vec.append(3); + vec.append(6); + vec.append(7); + EXPECT_EQ(vec.size(), 3); + EXPECT_EQ(vec[0], 3); + EXPECT_EQ(vec[1], 6); + EXPECT_EQ(vec[2], 7); +} + +TEST(vector, AppendAndGetIndex) +{ + Vector<int> vec; + EXPECT_EQ(vec.append_and_get_index(10), 0); + EXPECT_EQ(vec.append_and_get_index(10), 1); + EXPECT_EQ(vec.append_and_get_index(10), 2); + vec.append(10); + EXPECT_EQ(vec.append_and_get_index(10), 4); +} + +TEST(vector, AppendNonDuplicates) +{ + Vector<int> vec; + vec.append_non_duplicates(4); + EXPECT_EQ(vec.size(), 1); + vec.append_non_duplicates(5); + EXPECT_EQ(vec.size(), 2); + vec.append_non_duplicates(4); + EXPECT_EQ(vec.size(), 2); +} + +TEST(vector, ExtendNonDuplicates) +{ + Vector<int> vec; + vec.extend_non_duplicates({1, 2}); + EXPECT_EQ(vec.size(), 2); + vec.extend_non_duplicates({3, 4}); + EXPECT_EQ(vec.size(), 4); + vec.extend_non_duplicates({0, 1, 2, 3}); + EXPECT_EQ(vec.size(), 5); +} + +TEST(vector, Iterator) +{ + Vector<int> vec({1, 4, 9, 16}); + int i = 1; + for (int value : vec) { + EXPECT_EQ(value, i * i); + i++; + } +} + +TEST(vector, BecomeLarge) +{ + Vector<int, 4> vec; + for (int i = 0; i < 100; i++) { + vec.append(i * 5); + } + EXPECT_EQ(vec.size(), 100); + for (int i = 0; i < 100; i++) { + EXPECT_EQ(vec[i], static_cast<int>(i * 5)); + } +} + +static Vector<int> return_by_value_helper() +{ + return Vector<int>({3, 5, 1}); +} + +TEST(vector, ReturnByValue) +{ + Vector<int> vec = return_by_value_helper(); + EXPECT_EQ(vec.size(), 3); + EXPECT_EQ(vec[0], 3); + EXPECT_EQ(vec[1], 5); + EXPECT_EQ(vec[2], 1); +} + +TEST(vector, VectorOfVectors_Append) +{ + Vector<Vector<int>> vec; + EXPECT_EQ(vec.size(), 0); + + Vector<int> v({1, 2}); + vec.append(v); + vec.append({7, 8}); + EXPECT_EQ(vec.size(), 2); + EXPECT_EQ(vec[0][0], 1); + EXPECT_EQ(vec[0][1], 2); + EXPECT_EQ(vec[1][0], 7); + EXPECT_EQ(vec[1][1], 8); +} + +TEST(vector, RemoveLast) +{ + Vector<int> vec = {5, 6}; + EXPECT_EQ(vec.size(), 2); + vec.remove_last(); + EXPECT_EQ(vec.size(), 1); + vec.remove_last(); + EXPECT_EQ(vec.size(), 0); +} + +TEST(vector, IsEmpty) +{ + Vector<int> vec; + EXPECT_TRUE(vec.is_empty()); + vec.append(1); + EXPECT_FALSE(vec.is_empty()); + vec.remove_last(); + EXPECT_TRUE(vec.is_empty()); +} + +TEST(vector, RemoveReorder) +{ + Vector<int> vec = {4, 5, 6, 7}; + vec.remove_and_reorder(1); + EXPECT_EQ(vec[0], 4); + EXPECT_EQ(vec[1], 7); + EXPECT_EQ(vec[2], 6); + vec.remove_and_reorder(2); + EXPECT_EQ(vec[0], 4); + EXPECT_EQ(vec[1], 7); + vec.remove_and_reorder(0); + EXPECT_EQ(vec[0], 7); + vec.remove_and_reorder(0); + EXPECT_TRUE(vec.is_empty()); +} + +TEST(vector, RemoveFirstOccurrenceAndReorder) +{ + Vector<int> vec = {4, 5, 6, 7}; + vec.remove_first_occurrence_and_reorder(5); + EXPECT_EQ(vec[0], 4); + EXPECT_EQ(vec[1], 7); + EXPECT_EQ(vec[2], 6); + vec.remove_first_occurrence_and_reorder(6); + EXPECT_EQ(vec[0], 4); + EXPECT_EQ(vec[1], 7); + vec.remove_first_occurrence_and_reorder(4); + EXPECT_EQ(vec[0], 7); + vec.remove_first_occurrence_and_reorder(7); + EXPECT_EQ(vec.size(), 0); +} + +TEST(vector, Remove) +{ + Vector<int> vec = {1, 2, 3, 4, 5, 6}; + vec.remove(3); + EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({1, 2, 3, 5, 6}).begin())); + vec.remove(0); + EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2, 3, 5, 6}).begin())); + vec.remove(3); + EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2, 3, 5}).begin())); + vec.remove(1); + EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2, 5}).begin())); + vec.remove(1); + EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2}).begin())); + vec.remove(0); + EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({}).begin())); +} + +TEST(vector, ExtendSmallVector) +{ + Vector<int> a = {2, 3, 4}; + Vector<int> b = {11, 12}; + b.extend(a); + EXPECT_EQ(b.size(), 5); + EXPECT_EQ(b[0], 11); + EXPECT_EQ(b[1], 12); + EXPECT_EQ(b[2], 2); + EXPECT_EQ(b[3], 3); + EXPECT_EQ(b[4], 4); +} + +TEST(vector, ExtendArray) +{ + int array[] = {3, 4, 5, 6}; + + Vector<int> a; + a.extend(array, 2); + + EXPECT_EQ(a.size(), 2); + EXPECT_EQ(a[0], 3); + EXPECT_EQ(a[1], 4); +} + +TEST(vector, Last) +{ + Vector<int> a{3, 5, 7}; + EXPECT_EQ(a.last(), 7); +} + +TEST(vector, AppendNTimes) +{ + Vector<int> a; + a.append_n_times(5, 3); + a.append_n_times(2, 2); + EXPECT_EQ(a.size(), 5); + EXPECT_EQ(a[0], 5); + EXPECT_EQ(a[1], 5); + EXPECT_EQ(a[2], 5); + EXPECT_EQ(a[3], 2); + EXPECT_EQ(a[4], 2); +} + +TEST(vector, UniquePtrValue) +{ + Vector<std::unique_ptr<int>> vec; + vec.append(std::unique_ptr<int>(new int())); + vec.append(std::unique_ptr<int>(new int())); + vec.append(std::unique_ptr<int>(new int())); + vec.append(std::unique_ptr<int>(new int())); + EXPECT_EQ(vec.size(), 4); + + std::unique_ptr<int> &a = vec.last(); + std::unique_ptr<int> b = vec.pop_last(); + vec.remove_and_reorder(0); + vec.remove(0); + EXPECT_EQ(vec.size(), 1); + + UNUSED_VARS(a, b); +} + +class TypeConstructMock { + public: + bool default_constructed = false; + bool copy_constructed = false; + bool move_constructed = false; + bool copy_assigned = false; + bool move_assigned = false; + + TypeConstructMock() : default_constructed(true) + { + } + + TypeConstructMock(const TypeConstructMock &UNUSED(other)) : copy_constructed(true) + { + } + + TypeConstructMock(TypeConstructMock &&UNUSED(other)) noexcept : move_constructed(true) + { + } + + TypeConstructMock &operator=(const TypeConstructMock &other) + { + if (this == &other) { + return *this; + } + + copy_assigned = true; + return *this; + } + + TypeConstructMock &operator=(TypeConstructMock &&other) noexcept + { + if (this == &other) { + return *this; + } + + move_assigned = true; + return *this; + } +}; + +TEST(vector, SizeConstructorCallsDefaultConstructor) +{ + Vector<TypeConstructMock> vec(3); + EXPECT_TRUE(vec[0].default_constructed); + EXPECT_TRUE(vec[1].default_constructed); + EXPECT_TRUE(vec[2].default_constructed); +} + +TEST(vector, SizeValueConstructorCallsCopyConstructor) +{ + Vector<TypeConstructMock> vec(3, TypeConstructMock()); + EXPECT_TRUE(vec[0].copy_constructed); + EXPECT_TRUE(vec[1].copy_constructed); + EXPECT_TRUE(vec[2].copy_constructed); +} + +TEST(vector, AppendCallsCopyConstructor) +{ + Vector<TypeConstructMock> vec; + TypeConstructMock value; + vec.append(value); + EXPECT_TRUE(vec[0].copy_constructed); +} + +TEST(vector, AppendCallsMoveConstructor) +{ + Vector<TypeConstructMock> vec; + vec.append(TypeConstructMock()); + EXPECT_TRUE(vec[0].move_constructed); +} + +TEST(vector, SmallVectorCopyCallsCopyConstructor) +{ + Vector<TypeConstructMock, 2> src(2); + Vector<TypeConstructMock, 2> dst(src); + EXPECT_TRUE(dst[0].copy_constructed); + EXPECT_TRUE(dst[1].copy_constructed); +} + +TEST(vector, LargeVectorCopyCallsCopyConstructor) +{ + Vector<TypeConstructMock, 2> src(5); + Vector<TypeConstructMock, 2> dst(src); + EXPECT_TRUE(dst[0].copy_constructed); + EXPECT_TRUE(dst[1].copy_constructed); +} + +TEST(vector, SmallVectorMoveCallsMoveConstructor) +{ + Vector<TypeConstructMock, 2> src(2); + Vector<TypeConstructMock, 2> dst(std::move(src)); + EXPECT_TRUE(dst[0].move_constructed); + EXPECT_TRUE(dst[1].move_constructed); +} + +TEST(vector, LargeVectorMoveCallsNoConstructor) +{ + Vector<TypeConstructMock, 2> src(5); + Vector<TypeConstructMock, 2> dst(std::move(src)); + + EXPECT_TRUE(dst[0].default_constructed); + EXPECT_FALSE(dst[0].move_constructed); + EXPECT_FALSE(dst[0].copy_constructed); +} + +TEST(vector, Resize) +{ + std::string long_string = "012345678901234567890123456789"; + Vector<std::string> vec; + EXPECT_EQ(vec.size(), 0); + vec.resize(2); + EXPECT_EQ(vec.size(), 2); + EXPECT_EQ(vec[0], ""); + EXPECT_EQ(vec[1], ""); + vec.resize(5, long_string); + EXPECT_EQ(vec.size(), 5); + EXPECT_EQ(vec[0], ""); + EXPECT_EQ(vec[1], ""); + EXPECT_EQ(vec[2], long_string); + EXPECT_EQ(vec[3], long_string); + EXPECT_EQ(vec[4], long_string); + vec.resize(1); + EXPECT_EQ(vec.size(), 1); + EXPECT_EQ(vec[0], ""); +} + +TEST(vector, FirstIndexOf) +{ + Vector<int> vec = {2, 3, 5, 7, 5, 9}; + EXPECT_EQ(vec.first_index_of(2), 0); + EXPECT_EQ(vec.first_index_of(5), 2); + EXPECT_EQ(vec.first_index_of(9), 5); +} + +TEST(vector, FirstIndexTryOf) +{ + Vector<int> vec = {2, 3, 5, 7, 5, 9}; + EXPECT_EQ(vec.first_index_of_try(2), 0); + EXPECT_EQ(vec.first_index_of_try(4), -1); + EXPECT_EQ(vec.first_index_of_try(5), 2); + EXPECT_EQ(vec.first_index_of_try(9), 5); + EXPECT_EQ(vec.first_index_of_try(1), -1); +} + +TEST(vector, OveralignedValues) +{ + Vector<AlignedBuffer<1, 512>, 2> vec; + for (int i = 0; i < 100; i++) { + vec.append({}); + EXPECT_EQ((uintptr_t)&vec.last() % 512, 0); + } +} + +TEST(vector, ConstructVoidPointerVector) +{ + int a; + float b; + double c; + Vector<void *> vec = {&a, &b, &c}; + EXPECT_EQ(vec.size(), 3); +} + +TEST(vector, Fill) +{ + Vector<int> vec(5); + vec.fill(3); + EXPECT_EQ(vec.size(), 5u); + EXPECT_EQ(vec[0], 3); + EXPECT_EQ(vec[1], 3); + EXPECT_EQ(vec[2], 3); + EXPECT_EQ(vec[3], 3); + EXPECT_EQ(vec[4], 3); +} + +} // namespace blender::tests diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index cb2094d050f..888863dda06 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -102,28 +102,27 @@ void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp) if (bhead->code == ENDB) { break; } - else { - const short *sp = fd->filesdna->structs[bhead->SDNAnr]; - const char *name = fd->filesdna->types[sp[0]]; - char buf[4]; - - buf[0] = (bhead->code >> 24) & 0xFF; - buf[1] = (bhead->code >> 16) & 0xFF; - buf[2] = (bhead->code >> 8) & 0xFF; - buf[3] = (bhead->code >> 0) & 0xFF; - - buf[0] = buf[0] ? buf[0] : ' '; - buf[1] = buf[1] ? buf[1] : ' '; - buf[2] = buf[2] ? buf[2] : ' '; - buf[3] = buf[3] ? buf[3] : ' '; - - fprintf(fp, - "['%.4s', '%s', %d, %ld ],\n", - buf, - name, - bhead->nr, - (long int)(bhead->len + sizeof(BHead))); - } + + const short *sp = fd->filesdna->structs[bhead->SDNAnr]; + const char *name = fd->filesdna->types[sp[0]]; + char buf[4]; + + buf[0] = (bhead->code >> 24) & 0xFF; + buf[1] = (bhead->code >> 16) & 0xFF; + buf[2] = (bhead->code >> 8) & 0xFF; + buf[3] = (bhead->code >> 0) & 0xFF; + + buf[0] = buf[0] ? buf[0] : ' '; + buf[1] = buf[1] ? buf[1] : ' '; + buf[2] = buf[2] ? buf[2] : ' '; + buf[3] = buf[3] ? buf[3] : ' '; + + fprintf(fp, + "['%.4s', '%s', %d, %ld ],\n", + buf, + name, + bhead->nr, + (long int)(bhead->len + sizeof(BHead))); } fprintf(fp, "]\n"); } @@ -268,7 +267,7 @@ LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh) if (bhead->code == ENDB) { break; } - else if (BKE_idtype_idcode_is_valid(bhead->code)) { + if (BKE_idtype_idcode_is_valid(bhead->code)) { if (BKE_idtype_idcode_is_linkable(bhead->code)) { const char *str = BKE_idtype_idcode_to_name(bhead->code); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 134e23d36e8..dc2eda7686b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -373,7 +373,7 @@ static void oldnewmap_insert_or_replace(OldNewMap *onm, OldNew entry) onm->nentries++; break; } - else if (onm->entries[index].oldp == entry.oldp) { + if (onm->entries[index].oldp == entry.oldp) { onm->entries[index] = entry; break; } @@ -1112,9 +1112,8 @@ static bool read_file_dna(FileData *fd, const char **r_error_message) return true; } - else { - return false; - } + + return false; } else if (bhead->code == ENDB) { break; @@ -1156,7 +1155,7 @@ static int *read_file_thumbnail(FileData *fd) blend_thumb = data; break; } - else if (bhead->code != REND) { + if (bhead->code != REND) { /* Thumbnail is stored in TEST immediately after first REND... */ break; } @@ -1373,9 +1372,8 @@ static FileData *blo_filedata_from_file_descriptor(const char *filepath, errno ? strerror(errno) : TIP_("insufficient content")); return NULL; } - else { - BLI_lseek(file, 0, SEEK_SET); - } + + BLI_lseek(file, 0, SEEK_SET); /* Regular file. */ if (memcmp(header, "BLENDER", sizeof(header)) == 0) { @@ -1397,12 +1395,11 @@ static FileData *blo_filedata_from_file_descriptor(const char *filepath, errno ? strerror(errno) : TIP_("unknown error reading file")); return NULL; } - else { - /* 'seek_fn' is too slow for gzip, don't set it. */ - read_fn = fd_read_gzip_from_file; - /* Caller must close. */ - file = -1; - } + + /* 'seek_fn' is too slow for gzip, don't set it. */ + read_fn = fd_read_gzip_from_file; + /* Caller must close. */ + file = -1; } if (read_fn == NULL) { @@ -1487,7 +1484,7 @@ static int fd_read_gzip_from_memory(FileData *filedata, if (err == Z_STREAM_END) { return 0; } - else if (err != Z_OK) { + if (err != Z_OK) { printf("fd_read_gzip_from_memory: zlib error\n"); return 0; } @@ -1521,28 +1518,27 @@ FileData *blo_filedata_from_memory(const void *mem, int memsize, ReportList *rep BKE_report(reports, RPT_WARNING, (mem) ? TIP_("Unable to read") : TIP_("Unable to open")); return NULL; } - else { - FileData *fd = filedata_new(); - const char *cp = mem; - fd->buffer = mem; - fd->buffersize = memsize; + FileData *fd = filedata_new(); + const char *cp = mem; - /* test if gzip */ - if (cp[0] == 0x1f && cp[1] == 0x8b) { - if (0 == fd_read_gzip_from_memory_init(fd)) { - blo_filedata_free(fd); - return NULL; - } - } - else { - fd->read = fd_read_from_memory; + fd->buffer = mem; + fd->buffersize = memsize; + + /* test if gzip */ + if (cp[0] == 0x1f && cp[1] == 0x8b) { + if (0 == fd_read_gzip_from_memory_init(fd)) { + blo_filedata_free(fd); + return NULL; } + } + else { + fd->read = fd_read_from_memory; + } - fd->flags |= FD_FLAGS_NOT_MY_BUFFER; + fd->flags |= FD_FLAGS_NOT_MY_BUFFER; - return blo_decode_and_check(fd, reports); - } + return blo_decode_and_check(fd, reports); } FileData *blo_filedata_from_memfile(MemFile *memfile, @@ -1553,16 +1549,15 @@ FileData *blo_filedata_from_memfile(MemFile *memfile, BKE_report(reports, RPT_WARNING, "Unable to open blend <memory>"); return NULL; } - else { - FileData *fd = filedata_new(); - fd->memfile = memfile; - fd->undo_direction = params->undo_direction; - fd->read = fd_read_from_memfile; - fd->flags |= FD_FLAGS_NOT_MY_BUFFER; + FileData *fd = filedata_new(); + fd->memfile = memfile; + fd->undo_direction = params->undo_direction; - return blo_decode_and_check(fd, reports); - } + fd->read = fd_read_from_memfile; + fd->flags |= FD_FLAGS_NOT_MY_BUFFER; + + return blo_decode_and_check(fd, reports); } void blo_filedata_free(FileData *fd) @@ -1695,7 +1690,7 @@ bool BLO_library_path_explode(const char *path, char *r_dir, char **r_group, cha if (BLO_has_bfile_extension(r_dir) && BLI_is_file(r_dir)) { break; } - else if (STREQ(r_dir, BLO_EMBEDDED_STARTUP_BLEND)) { + if (STREQ(r_dir, BLO_EMBEDDED_STARTUP_BLEND)) { break; } @@ -4162,7 +4157,7 @@ static void direct_link_curve(BlendDataReader *reader, Curve *cu) direct_link_animdata(reader, cu->adt); /* Protect against integer overflow vulnerability. */ - CLAMP(cu->len_wchar, 0, INT_MAX - 4); + CLAMP(cu->len_char32, 0, INT_MAX - 4); BLO_read_pointer_array(reader, (void **)&cu->mat); @@ -5518,7 +5513,7 @@ static void direct_link_gpencil_modifiers(BlendDataReader *reader, ListBase *lb) if (gpmd->curve_intensity) { BKE_curvemapping_blend_read(reader, gpmd->curve_intensity); /* initialize the curve. Maybe this could be moved to modififer logic */ - BKE_curvemapping_initialize(gpmd->curve_intensity); + BKE_curvemapping_init(gpmd->curve_intensity); } } else if (md->type == eGpencilModifierType_Thick) { @@ -5527,7 +5522,7 @@ static void direct_link_gpencil_modifiers(BlendDataReader *reader, ListBase *lb) BLO_read_data_address(reader, &gpmd->curve_thickness); if (gpmd->curve_thickness) { BKE_curvemapping_blend_read(reader, gpmd->curve_thickness); - BKE_curvemapping_initialize(gpmd->curve_thickness); + BKE_curvemapping_init(gpmd->curve_thickness); } } else if (md->type == eGpencilModifierType_Tint) { @@ -5536,7 +5531,7 @@ static void direct_link_gpencil_modifiers(BlendDataReader *reader, ListBase *lb) BLO_read_data_address(reader, &gpmd->curve_intensity); if (gpmd->curve_intensity) { BKE_curvemapping_blend_read(reader, gpmd->curve_intensity); - BKE_curvemapping_initialize(gpmd->curve_intensity); + BKE_curvemapping_init(gpmd->curve_intensity); } } else if (md->type == eGpencilModifierType_Smooth) { @@ -5544,7 +5539,7 @@ static void direct_link_gpencil_modifiers(BlendDataReader *reader, ListBase *lb) BLO_read_data_address(reader, &gpmd->curve_intensity); if (gpmd->curve_intensity) { BKE_curvemapping_blend_read(reader, gpmd->curve_intensity); - BKE_curvemapping_initialize(gpmd->curve_intensity); + BKE_curvemapping_init(gpmd->curve_intensity); } } else if (md->type == eGpencilModifierType_Color) { @@ -5552,7 +5547,7 @@ static void direct_link_gpencil_modifiers(BlendDataReader *reader, ListBase *lb) BLO_read_data_address(reader, &gpmd->curve_intensity); if (gpmd->curve_intensity) { BKE_curvemapping_blend_read(reader, gpmd->curve_intensity); - BKE_curvemapping_initialize(gpmd->curve_intensity); + BKE_curvemapping_init(gpmd->curve_intensity); } } else if (md->type == eGpencilModifierType_Opacity) { @@ -5560,7 +5555,7 @@ static void direct_link_gpencil_modifiers(BlendDataReader *reader, ListBase *lb) BLO_read_data_address(reader, &gpmd->curve_intensity); if (gpmd->curve_intensity) { BKE_curvemapping_blend_read(reader, gpmd->curve_intensity); - BKE_curvemapping_initialize(gpmd->curve_intensity); + BKE_curvemapping_init(gpmd->curve_intensity); } } } @@ -8695,9 +8690,8 @@ static void direct_link_volume(BlendDataReader *reader, Volume *volume) static void lib_link_simulation(BlendLibReader *reader, Simulation *simulation) { - LISTBASE_FOREACH ( - PersistentDataHandleItem *, handle_item, &simulation->persistent_data_handles) { - BLO_read_id_address(reader, simulation->id.lib, &handle_item->id); + LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) { + BLO_read_id_address(reader, simulation->id.lib, &dependency->id); } } @@ -8716,7 +8710,7 @@ static void direct_link_simulation(BlendDataReader *reader, Simulation *simulati } } - BLO_read_list(reader, &simulation->persistent_data_handles); + BLO_read_list(reader, &simulation->dependencies); } /** \} */ @@ -9254,17 +9248,16 @@ static bool read_libblock_undo_restore( *r_id_old = id_old; return true; } - else if (id_old != NULL) { + if (id_old != NULL) { /* Local datablock was changed. Restore at the address of the old datablock. */ DEBUG_PRINTF("read to old existing address\n"); *r_id_old = id_old; return false; } - else { - /* Local datablock does not exist in the undo step, so read from scratch. */ - DEBUG_PRINTF("read at new address\n"); - return false; - } + + /* Local datablock does not exist in the undo step, so read from scratch. */ + DEBUG_PRINTF("read at new address\n"); + return false; } /* This routine reads a datablock and its direct data, and advances bhead to @@ -10035,7 +10028,7 @@ static int verg_bheadsort(const void *v1, const void *v2) if (x1->old > x2->old) { return 1; } - else if (x1->old < x2->old) { + if (x1->old < x2->old) { return -1; } return 0; @@ -11125,9 +11118,8 @@ static void expand_simulation(BlendExpander *expander, Simulation *simulation) if (simulation->adt) { expand_animdata(expander, simulation->adt); } - LISTBASE_FOREACH ( - PersistentDataHandleItem *, handle_item, &simulation->persistent_data_handles) { - BLO_expand(expander, handle_item->id); + LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) { + BLO_expand(expander, dependency->id); } } diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index 3ed59a0baa1..bef37bdd960 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -280,7 +280,7 @@ static void area_add_window_regions(ScrArea *area, SpaceLink *sl, ListBase *lb) region->v2d.keepzoom |= (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_KEEPASPECT); region->v2d.keeptot = V2D_KEEPTOT_STRICT; region->v2d.minzoom = region->v2d.maxzoom = 1.0f; - // region->v2d.flag |= V2D_IS_INITIALISED; + // region->v2d.flag |= V2D_IS_INIT; break; } case SPACE_GRAPH: { @@ -297,7 +297,7 @@ static void area_add_window_regions(ScrArea *area, SpaceLink *sl, ListBase *lb) region->v2d.max[0] = MAXFRAMEF; region->v2d.max[1] = FLT_MAX; - // region->v2d.flag |= V2D_IS_INITIALISED; + // region->v2d.flag |= V2D_IS_INIT; break; } case SPACE_NLA: { @@ -355,7 +355,7 @@ static void area_add_window_regions(ScrArea *area, SpaceLink *sl, ListBase *lb) region->v2d.scroll |= (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES); region->v2d.scroll |= (V2D_SCROLL_LEFT | V2D_SCROLL_VERTICAL_HANDLES); region->v2d.align = V2D_ALIGN_NO_NEG_Y; - region->v2d.flag |= V2D_IS_INITIALISED; + region->v2d.flag |= V2D_IS_INIT; break; } case SPACE_NODE: { @@ -635,6 +635,7 @@ static void do_versions_socket_default_value_259(bNodeSocket *sock) } } +/* NOLINTNEXTLINE: readability-function-size */ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -965,7 +966,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) bPoseChannel *pchan; for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - /* just need to initialise rotation axis properly... */ + /* Just need to initialize rotation axis properly. */ pchan->rotAxis[1] = 1.0f; } } diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c index b3bf8991c3e..3f24a7f14ca 100644 --- a/source/blender/blenloader/intern/versioning_260.c +++ b/source/blender/blenloader/intern/versioning_260.c @@ -658,6 +658,7 @@ static void do_versions_nodetree_customnodes(bNodeTree *ntree, int UNUSED(is_gro } } +/* NOLINTNEXTLINE: readability-function-size */ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) { if (bmain->versionfile < 260) { @@ -1205,7 +1206,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) if (region->regiontype == RGN_TYPE_PREVIEW) { if (region->alignment != RGN_ALIGN_NONE) { region->flag |= RGN_FLAG_HIDDEN; - region->v2d.flag &= ~V2D_IS_INITIALISED; + region->v2d.flag &= ~V2D_IS_INIT; region->alignment = RGN_ALIGN_NONE; hide = true; @@ -2520,7 +2521,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) for (cu = bmain->curves.first; cu; cu = cu->id.next) { if (cu->str) { - cu->len_wchar = BLI_strlen_utf8(cu->str); + cu->len_char32 = BLI_strlen_utf8(cu->str); } } } diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 521fc4b9b82..b19c6221391 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -242,7 +242,7 @@ static void do_version_action_editor_properties_region(ListBase *regionbase) /* already exists */ return; } - else if (region->regiontype == RGN_TYPE_WINDOW) { + if (region->regiontype == RGN_TYPE_WINDOW) { /* add new region here */ ARegion *arnew = MEM_callocN(sizeof(ARegion), "buttons for action"); @@ -377,9 +377,8 @@ static char *replace_bbone_easing_rnapath(char *old_path) MEM_freeN(old_path); return new_path; } - else { - return old_path; - } + + return old_path; } static void do_version_bbone_easing_fcurve_fix(ID *UNUSED(id), @@ -421,6 +420,7 @@ static void do_version_bbone_easing_fcurve_fix(ID *UNUSED(id), } } +/* NOLINTNEXTLINE: readability-function-size */ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) { if (!MAIN_VERSION_ATLEAST(bmain, 270, 0)) { @@ -1108,7 +1108,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) for (scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) { CurveMapping *curve_mapping = &scene->r.mblur_shutter_curve; BKE_curvemapping_set_defaults(curve_mapping, 1, 0.0f, 0.0f, 1.0f, 1.0f); - BKE_curvemapping_initialize(curve_mapping); + BKE_curvemapping_init(curve_mapping); BKE_curvemap_reset( curve_mapping->cm, &curve_mapping->clipr, CURVE_PRESET_MAX, CURVEMAP_SLOPE_POS_NEG); } diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 111ac728cc3..7add20431ad 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -190,7 +190,7 @@ static void do_version_workspaces_create_from_screens(Main *bmain) static void do_version_area_change_space_to_space_action(ScrArea *area, const Scene *scene) { SpaceType *stype = BKE_spacetype_from_id(SPACE_ACTION); - SpaceAction *saction = (SpaceAction *)stype->new (area, scene); + SpaceAction *saction = (SpaceAction *)stype->create(area, scene); ARegion *region_channels; /* Properly free current regions */ @@ -1792,6 +1792,7 @@ static void do_versions_seq_set_cache_defaults(Editing *ed) ed->recycle_max_cost = 10.0f; } +/* NOLINTNEXTLINE: readability-function-size */ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) { bool use_collection_compat_28 = true; @@ -1958,7 +1959,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) GP_Sculpt_Settings *gset = &scene->toolsettings->gp_sculpt; if ((gset) && (gset->cur_falloff == NULL)) { gset->cur_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); - BKE_curvemapping_initialize(gset->cur_falloff); + BKE_curvemapping_init(gset->cur_falloff); BKE_curvemap_reset(gset->cur_falloff->cm, &gset->cur_falloff->clipr, CURVE_PRESET_GAUSS, @@ -3371,7 +3372,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) GP_Sculpt_Settings *gset = &scene->toolsettings->gp_sculpt; if ((gset) && (gset->cur_primitive == NULL)) { gset->cur_primitive = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); - BKE_curvemapping_initialize(gset->cur_primitive); + BKE_curvemapping_init(gset->cur_primitive); BKE_curvemap_reset(gset->cur_primitive->cm, &gset->cur_primitive->clipr, CURVE_PRESET_BELL, @@ -4767,7 +4768,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (mmd->curve_intensity == NULL) { mmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); if (mmd->curve_intensity) { - BKE_curvemapping_initialize(mmd->curve_intensity); + BKE_curvemapping_init(mmd->curve_intensity); } } break; @@ -4778,7 +4779,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (mmd->curve_intensity == NULL) { mmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); if (mmd->curve_intensity) { - BKE_curvemapping_initialize(mmd->curve_intensity); + BKE_curvemapping_init(mmd->curve_intensity); } } break; @@ -4788,7 +4789,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (mmd->curve_intensity == NULL) { mmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); if (mmd->curve_intensity) { - BKE_curvemapping_initialize(mmd->curve_intensity); + BKE_curvemapping_init(mmd->curve_intensity); } } break; @@ -4798,7 +4799,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (mmd->curve_intensity == NULL) { mmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); if (mmd->curve_intensity) { - BKE_curvemapping_initialize(mmd->curve_intensity); + BKE_curvemapping_init(mmd->curve_intensity); } } break; @@ -4808,7 +4809,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (mmd->curve_intensity == NULL) { mmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); if (mmd->curve_intensity) { - BKE_curvemapping_initialize(mmd->curve_intensity); + BKE_curvemapping_init(mmd->curve_intensity); } } break; diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c index a96b82e2e91..12b5a297df5 100644 --- a/source/blender/blenloader/intern/versioning_290.c +++ b/source/blender/blenloader/intern/versioning_290.c @@ -22,9 +22,11 @@ #include "BLI_listbase.h" #include "BLI_math.h" +#include "BLI_string.h" #include "BLI_utildefines.h" #include "DNA_brush_types.h" +#include "DNA_cachefile_types.h" #include "DNA_constraint_types.h" #include "DNA_genfile.h" #include "DNA_gpencil_modifier_types.h" @@ -446,5 +448,39 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } + + /* Initialise additional velocity parameter for CacheFiles. */ + if (!DNA_struct_elem_find( + fd->filesdna, "MeshSeqCacheModifierData", "float", "velocity_scale")) { + for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) { + LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { + if (md->type == eModifierType_MeshSequenceCache) { + MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md; + mcmd->velocity_scale = 1.0f; + mcmd->vertex_velocities = NULL; + mcmd->num_vertices = 0; + } + } + } + } + + if (!DNA_struct_elem_find(fd->filesdna, "CacheFile", "char", "velocity_unit")) { + for (CacheFile *cache_file = bmain->cachefiles.first; cache_file != NULL; + cache_file = cache_file->id.next) { + BLI_strncpy(cache_file->velocity_name, ".velocities", sizeof(cache_file->velocity_name)); + cache_file->velocity_unit = CACHEFILE_VELOCITY_UNIT_SECOND; + } + } + + if (!DNA_struct_elem_find(fd->filesdna, "OceanModifierData", "int", "viewport_resolution")) { + for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) { + LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { + if (md->type == eModifierType_Ocean) { + OceanModifierData *omd = (OceanModifierData *)md; + omd->viewport_resolution = omd->resolution; + } + } + } + } } } diff --git a/source/blender/blenloader/intern/versioning_cycles.c b/source/blender/blenloader/intern/versioning_cycles.c index 46faddf6e5a..26329fca6fa 100644 --- a/source/blender/blenloader/intern/versioning_cycles.c +++ b/source/blender/blenloader/intern/versioning_cycles.c @@ -1447,7 +1447,7 @@ void do_versions_after_linking_cycles(Main *bmain) if (is_fstop) { continue; } - else if (aperture_size > 0.0f) { + if (aperture_size > 0.0f) { if (camera->type == CAM_ORTHO) { camera->dof.aperture_fstop = 1.0f / (2.0f * aperture_size); } diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c index 7f75c0100b8..ae6d3a58091 100644 --- a/source/blender/blenloader/intern/versioning_defaults.c +++ b/source/blender/blenloader/intern/versioning_defaults.c @@ -106,7 +106,7 @@ static void blo_update_defaults_screen(bScreen *screen, /* Some toolbars have been saved as initialized, * we don't want them to have odd zoom-level or scrolling set, see: T47047 */ if (ELEM(region->regiontype, RGN_TYPE_UI, RGN_TYPE_TOOLS, RGN_TYPE_TOOL_PROPS)) { - region->v2d.flag &= ~V2D_IS_INITIALISED; + region->v2d.flag &= ~V2D_IS_INIT; } } @@ -326,7 +326,7 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene) if (ts->gp_sculpt.cur_falloff == NULL) { ts->gp_sculpt.cur_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); CurveMapping *gp_falloff_curve = ts->gp_sculpt.cur_falloff; - BKE_curvemapping_initialize(gp_falloff_curve); + BKE_curvemapping_init(gp_falloff_curve); BKE_curvemap_reset(gp_falloff_curve->cm, &gp_falloff_curve->clipr, CURVE_PRESET_GAUSS, @@ -335,7 +335,7 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene) if (ts->gp_sculpt.cur_primitive == NULL) { ts->gp_sculpt.cur_primitive = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); CurveMapping *gp_primitive_curve = ts->gp_sculpt.cur_primitive; - BKE_curvemapping_initialize(gp_primitive_curve); + BKE_curvemapping_init(gp_primitive_curve); BKE_curvemap_reset(gp_primitive_curve->cm, &gp_primitive_curve->clipr, CURVE_PRESET_BELL, diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c index 44c7c35e47d..fa72e2a147d 100644 --- a/source/blender/blenloader/intern/versioning_legacy.c +++ b/source/blender/blenloader/intern/versioning_legacy.c @@ -493,6 +493,7 @@ void blo_do_version_old_trackto_to_constraints(Object *ob) ob->track = NULL; } +/* NOLINTNEXTLINE: readability-function-size */ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -2096,7 +2097,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) if (la->curfalloff == NULL) { la->curfalloff = BKE_curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f); - BKE_curvemapping_initialize(la->curfalloff); + BKE_curvemapping_init(la->curfalloff); } } } diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c index 50e3b375166..e2dc27d7e88 100644 --- a/source/blender/blenloader/intern/versioning_userdef.c +++ b/source/blender/blenloader/intern/versioning_userdef.c @@ -366,7 +366,7 @@ void BLO_version_defaults_userpref_blend(Main *bmain, UserDef *userdef) } if (!USER_VERSION_ATLEAST(250, 0)) { /* adjust grease-pencil distances */ - userdef->gp_manhattendist = 1; + userdef->gp_manhattandist = 1; userdef->gp_euclideandist = 2; /* adjust default interpolation for new IPO-curves */ diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 0d1c3f2c3e5..a393b4e07b7 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -240,9 +240,8 @@ static bool ww_open_none(WriteWrap *ww, const char *filepath) FILE_HANDLE(ww) = file; return true; } - else { - return false; - } + + return false; } static bool ww_close_none(WriteWrap *ww) { @@ -267,9 +266,8 @@ static bool ww_open_zlib(WriteWrap *ww, const char *filepath) FILE_HANDLE(ww) = file; return true; } - else { - return false; - } + + return false; } static bool ww_close_zlib(WriteWrap *ww) { @@ -2007,7 +2005,7 @@ static void write_curve(BlendWriter *writer, Curve *cu, const void *id_address) if (cu->vfont) { BLO_write_raw(writer, cu->len + 1, cu->str); - BLO_write_struct_array(writer, CharInfo, cu->len_wchar + 1, cu->strinfo); + BLO_write_struct_array(writer, CharInfo, cu->len_char32 + 1, cu->strinfo); BLO_write_struct_array(writer, TextBox, cu->totbox, cu->tb); } else { @@ -3867,7 +3865,7 @@ static void write_simulation(BlendWriter *writer, Simulation *simulation, const } } - BLO_write_struct_list(writer, PersistentDataHandleItem, &simulation->persistent_data_handles); + BLO_write_struct_list(writer, SimulationDependency, &simulation->dependencies); } } @@ -4052,8 +4050,9 @@ static bool write_file_handle(Main *mainvar, * avoid thumbnail detecting changes because of this. */ mywrite_flush(wd); - OverrideLibraryStorage *override_storage = - wd->use_memfile ? NULL : BKE_lib_override_library_operations_store_initialize(); + OverrideLibraryStorage *override_storage = wd->use_memfile ? + NULL : + BKE_lib_override_library_operations_store_init(); #define ID_BUFFER_STATIC_SIZE 8192 /* This outer loop allows to save first data-blocks from real mainvar, diff --git a/source/blender/blentranslation/intern/blt_translation.c b/source/blender/blentranslation/intern/blt_translation.c index 0ca068d4263..00118bc72e6 100644 --- a/source/blender/blentranslation/intern/blt_translation.c +++ b/source/blender/blentranslation/intern/blt_translation.c @@ -120,9 +120,9 @@ const char *BLT_translate_do(const char *msgctxt, const char *msgid) if (BLT_translate()) { return BLT_pgettext(msgctxt, msgid); } - else { - return msgid; - } + + return msgid; + #else (void)msgctxt; return msgid; @@ -135,9 +135,9 @@ const char *BLT_translate_do_iface(const char *msgctxt, const char *msgid) if (BLT_translate_iface()) { return BLT_pgettext(msgctxt, msgid); } - else { - return msgid; - } + + return msgid; + #else (void)msgctxt; return msgid; @@ -150,9 +150,9 @@ const char *BLT_translate_do_tooltip(const char *msgctxt, const char *msgid) if (BLT_translate_tooltips()) { return BLT_pgettext(msgctxt, msgid); } - else { - return msgid; - } + + return msgid; + #else (void)msgctxt; return msgid; @@ -165,9 +165,9 @@ const char *BLT_translate_do_new_dataname(const char *msgctxt, const char *msgid if (BLT_translate_new_dataname()) { return BLT_pgettext(msgctxt, msgid); } - else { - return msgid; - } + + return msgid; + #else (void)msgctxt; return msgid; diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index e8298f4dffc..256ef55ac59 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -295,7 +295,7 @@ static bool quad_co(const float v1[3], float r_uv[2]) { float projverts[5][3], n2[3]; - float origin[2] = {0.0f, 0.0f}; + const float origin[2] = {0.0f, 0.0f}; int i; /* project points into 2d along normal */ @@ -328,7 +328,7 @@ static bool quad_co(const float v1[3], return true; } -static void mdisp_axis_from_quad(float v1[3], +static void mdisp_axis_from_quad(const float v1[3], const float v2[3], float UNUSED(v3[3]), const float v4[3], diff --git a/source/blender/bmesh/intern/bmesh_query.c b/source/blender/bmesh/intern/bmesh_query.c index 80634618f6f..a9d1972bd7e 100644 --- a/source/blender/bmesh/intern/bmesh_query.c +++ b/source/blender/bmesh/intern/bmesh_query.c @@ -179,13 +179,12 @@ BMLoop *BM_loop_other_vert_loop_by_edge(BMLoop *l, BMEdge *e) if (l->e == e) { return l->next; } - else if (l->prev->e == e) { + if (l->prev->e == e) { return l->prev; } - else { - BLI_assert(0); - return NULL; - } + + BLI_assert(0); + return NULL; } /** diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 6c666183755..8b814240a42 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -45,6 +45,11 @@ #include "./intern/bmesh_private.h" +// #define BEVEL_DEBUG_TIME +#ifdef BEVEL_DEBUG_TIME +# include "PIL_time.h" +#endif + #define BEVEL_EPSILON_D 1e-6 #define BEVEL_EPSILON 1e-6f #define BEVEL_EPSILON_SQ 1e-12f @@ -917,7 +922,7 @@ static void math_layer_info_init(BevelParams *bp, BMesh *bm) * segment (and its continuation into vmesh) can usually arbitrarily be * the previous face or the next face. * Or, for the center polygon of a corner, all of the faces around - * the vertex are possible choices. + * the vertex are possibleface_component choices. * If we just choose randomly, the resulting UV maps or material * assignment can look ugly/inconsistent. * Allow for the case when arguments are null. @@ -1147,7 +1152,8 @@ static int edges_angle_kind(EdgeHalf *e1, EdgeHalf *e2, BMVert *v) /* co should be approximately on the plane between e1 and e2, which share common vert v and common * face f (which cannot be NULL). Is it between those edges, sweeping CCW? */ -static bool point_between_edges(float co[3], BMVert *v, BMFace *f, EdgeHalf *e1, EdgeHalf *e2) +static bool point_between_edges( + const float co[3], BMVert *v, BMFace *f, EdgeHalf *e1, EdgeHalf *e2) { BMVert *v1, *v2; float dir1[3], dir2[3], dirco[3], no[3]; @@ -1891,6 +1897,59 @@ static void get_profile_point(BevelParams *bp, const Profile *pro, int i, int ns } /** + * Helper for #calculate_profile that builds the 3D locations for the segments + * and the higher power of 2 segments. + */ +static void calculate_profile_segments(const Profile *profile, + const float map[4][4], + const bool use_map, + const bool reversed, + const int ns, + const double *xvals, + const double *yvals, + float *r_prof_co) +{ + /* Iterate over the vertices along the boundary arc. */ + for (int k = 0; k <= ns; k++) { + float co[3]; + if (k == 0) { + copy_v3_v3(co, profile->start); + } + else if (k == ns) { + copy_v3_v3(co, profile->end); + } + else { + if (use_map) { + const float p[3] = { + reversed ? (float)yvals[ns - k] : (float)xvals[k], + reversed ? (float)xvals[ns - k] : (float)yvals[k], + 0.0f, + }; + /* Do the 2D->3D transformation of the profile coordinates. */ + mul_v3_m4v3(co, map, p); + } + else { + interp_v3_v3v3(co, profile->start, profile->end, (float)k / (float)ns); + } + } + /* Finish the 2D->3D transformation by projecting onto the final profile plane. */ + float *prof_co_k = r_prof_co + 3 * k; + if (!is_zero_v3(profile->proj_dir)) { + float co2[3]; + add_v3_v3v3(co2, co, profile->proj_dir); + /* pro->plane_co and pro->plane_no are filled in #set_profile_params. */ + if (!isect_line_plane_v3(prof_co_k, co, co2, profile->plane_co, profile->plane_no)) { + /* Shouldn't happen. */ + copy_v3_v3(prof_co_k, co); + } + } + else { + copy_v3_v3(prof_co_k, co); + } + } +} + +/** * Calculate the actual coordinate values for bndv's profile. * This is only needed if bp->seg > 1. * Allocate the space for them if that hasn't been done already. @@ -1900,12 +1959,6 @@ static void get_profile_point(BevelParams *bp, const Profile *pro, int i, int ns */ static void calculate_profile(BevelParams *bp, BoundVert *bndv, bool reversed, bool miter) { - int i, k, ns; - const double *xvals, *yvals; - float co[3], co2[3], p[3], map[4][4], bottom_corner[3], top_corner[3]; - float *prof_co, *prof_co_k; - float r; - bool need_2, map_ok; Profile *pro = &bndv->profile; ProfileSpacing *pro_spacing = (miter) ? &bp->pro_spacing_miter : &bp->pro_spacing; @@ -1913,89 +1966,51 @@ static void calculate_profile(BevelParams *bp, BoundVert *bndv, bool reversed, b return; } - need_2 = bp->seg != bp->pro_spacing.seg_2; - if (!pro->prof_co) { - pro->prof_co = (float *)BLI_memarena_alloc(bp->mem_arena, - ((size_t)bp->seg + 1) * 3 * sizeof(float)); + bool need_2 = bp->seg != bp->pro_spacing.seg_2; + if (pro->prof_co == NULL) { + pro->prof_co = (float *)BLI_memarena_alloc(bp->mem_arena, sizeof(float) * 3 * (bp->seg + 1)); if (need_2) { pro->prof_co_2 = (float *)BLI_memarena_alloc( - bp->mem_arena, ((size_t)bp->pro_spacing.seg_2 + 1) * 3 * sizeof(float)); + bp->mem_arena, sizeof(float) * 3 * (bp->pro_spacing.seg_2 + 1)); } else { pro->prof_co_2 = pro->prof_co; } } - r = pro->super_r; - if (bp->profile_type == BEVEL_PROFILE_SUPERELLIPSE && r == PRO_LINE_R) { - map_ok = false; + + bool use_map; + float map[4][4]; + if (bp->profile_type == BEVEL_PROFILE_SUPERELLIPSE && pro->super_r == PRO_LINE_R) { + use_map = false; } else { - map_ok = make_unit_square_map(pro->start, pro->middle, pro->end, map); + use_map = make_unit_square_map(pro->start, pro->middle, pro->end, map); } - if (bp->vmesh_method == BEVEL_VMESH_CUTOFF && map_ok) { + if (bp->vmesh_method == BEVEL_VMESH_CUTOFF && use_map) { /* Calculate the "height" of the profile by putting the (0,0) and (1,1) corners of the * un-transformed profile through the 2D->3D map and calculating the distance between them. */ - zero_v3(p); - mul_v3_m4v3(bottom_corner, map, p); - p[0] = 1.0f; - p[1] = 1.0f; - mul_v3_m4v3(top_corner, map, p); + float bottom_corner[3] = {0.0f, 0.0f, 0.0f}; + mul_v3_m4v3(bottom_corner, map, bottom_corner); + float top_corner[3] = {1.0f, 1.0f, 0.0f}; + mul_v3_m4v3(top_corner, map, top_corner); + pro->height = len_v3v3(bottom_corner, top_corner); } - /* The first iteration is the nseg case, the second is the seg_2 case (if it's needed) .*/ - for (i = 0; i < 2; i++) { - if (i == 0) { - ns = bp->seg; - xvals = pro_spacing->xvals; - yvals = pro_spacing->yvals; - prof_co = pro->prof_co; - } - else { - if (!need_2) { - break; /* Shares coords with pro->prof_co. */ - } - ns = bp->pro_spacing.seg_2; - xvals = pro_spacing->xvals_2; - yvals = pro_spacing->yvals_2; - prof_co = pro->prof_co_2; - } - - /* Iterate over the vertices along the boundary arc. */ - for (k = 0; k <= ns; k++) { - if (k == 0) { - copy_v3_v3(co, pro->start); - } - else if (k == ns) { - copy_v3_v3(co, pro->end); - } - else { - if (map_ok) { - p[0] = reversed ? (float)yvals[ns - k] : (float)xvals[k]; - p[1] = reversed ? (float)xvals[ns - k] : (float)yvals[k]; - p[2] = 0.0f; - /* Do the 2D->3D transformation of the profile coordinates. */ - mul_v3_m4v3(co, map, p); - } - else { - interp_v3_v3v3(co, pro->start, pro->end, (float)k / (float)ns); - } - } - /* Finish the 2D->3D transformation by projecting onto the final profile plane. */ - prof_co_k = prof_co + 3 * k; /* Each coord takes up 3 spaces. */ - if (!is_zero_v3(pro->proj_dir)) { - add_v3_v3v3(co2, co, pro->proj_dir); - /* pro->plane_co and pro->plane_no are filled in "set_profile_params". */ - if (!isect_line_plane_v3(prof_co_k, co, co2, pro->plane_co, pro->plane_no)) { - /* Shouldn't happen. */ - copy_v3_v3(prof_co_k, co); - } - } - else { - copy_v3_v3(prof_co_k, co); - } - } + /* Calculate the 3D locations for the profile points */ + calculate_profile_segments( + pro, map, use_map, reversed, bp->seg, pro_spacing->xvals, pro_spacing->yvals, pro->prof_co); + /* Also calcualte for the is the seg_2 case if it's needed .*/ + if (need_2) { + calculate_profile_segments(pro, + map, + use_map, + reversed, + bp->pro_spacing.seg_2, + pro_spacing->xvals_2, + pro_spacing->yvals_2, + pro->prof_co_2); } } @@ -4843,7 +4858,7 @@ static void build_square_in_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv, VMesh /** * Copy whichever of \a a and \a b is closer to v into \a r. */ -static void closer_v3_v3v3v3(float r[3], float a[3], float b[3], float v[3]) +static void closer_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float v[3]) { if (len_squared_v3v3(a, v) <= len_squared_v3v3(b, v)) { copy_v3_v3(r, a); @@ -7143,68 +7158,64 @@ static float find_profile_fullness(BevelParams *bp) */ static void set_profile_spacing(BevelParams *bp, ProfileSpacing *pro_spacing, bool custom) { - int seg, seg_2; + int seg = bp->seg; - seg = bp->seg; - seg_2 = power_of_2_max_i(bp->seg); - if (seg > 1) { - /* Sample the seg_2 segments used for subdividing the vertex meshes. */ - if (seg_2 == 2) { - seg_2 = 4; - } - bp->pro_spacing.seg_2 = seg_2; - if (seg_2 == seg) { - pro_spacing->xvals_2 = pro_spacing->xvals; - pro_spacing->yvals_2 = pro_spacing->yvals; - } - else { - pro_spacing->xvals_2 = (double *)BLI_memarena_alloc(bp->mem_arena, - (size_t)(seg_2 + 1) * sizeof(double)); - pro_spacing->yvals_2 = (double *)BLI_memarena_alloc(bp->mem_arena, - (size_t)(seg_2 + 1) * sizeof(double)); - if (custom) { - /* Make sure the curve profile widget's sample table is full of the seg_2 samples. */ - BKE_curveprofile_initialize((CurveProfile *)bp->custom_profile, (short)seg_2); - - /* Copy segment locations into the profile spacing struct. */ - for (int i = 0; i < seg_2 + 1; i++) { - pro_spacing->xvals_2[i] = (double)bp->custom_profile->segments[i].y; - pro_spacing->yvals_2[i] = (double)bp->custom_profile->segments[i].x; - } - } - else { - find_even_superellipse_chords( - seg_2, bp->pro_super_r, pro_spacing->xvals_2, pro_spacing->yvals_2); - } - } + if (seg <= 1) { + /* Only 1 segment, we don't need any profile information. */ + pro_spacing->xvals = NULL; + pro_spacing->yvals = NULL; + pro_spacing->xvals_2 = NULL; + pro_spacing->yvals_2 = NULL; + pro_spacing->seg_2 = 0; + return; + } - /* Sample the input number of segments. */ - pro_spacing->xvals = (double *)BLI_memarena_alloc(bp->mem_arena, - (size_t)(seg + 1) * sizeof(double)); - pro_spacing->yvals = (double *)BLI_memarena_alloc(bp->mem_arena, - (size_t)(seg + 1) * sizeof(double)); + int seg_2 = max_ii(power_of_2_max_i(bp->seg), 4); + + /* Sample the seg_2 segments used during vertex mesh subdivision. */ + bp->pro_spacing.seg_2 = seg_2; + if (seg_2 == seg) { + pro_spacing->xvals_2 = pro_spacing->xvals; + pro_spacing->yvals_2 = pro_spacing->yvals; + } + else { + pro_spacing->xvals_2 = (double *)BLI_memarena_alloc(bp->mem_arena, + sizeof(double) * (seg_2 + 1)); + pro_spacing->yvals_2 = (double *)BLI_memarena_alloc(bp->mem_arena, + sizeof(double) * (seg_2 + 1)); if (custom) { - /* Make sure the curve profile's sample table is full. */ - if (bp->custom_profile->segments_len != seg || !bp->custom_profile->segments) { - BKE_curveprofile_initialize((CurveProfile *)bp->custom_profile, (short)seg); - } + /* Make sure the curve profile widget's sample table is full of the seg_2 samples. */ + BKE_curveprofile_init((CurveProfile *)bp->custom_profile, (short)seg_2); /* Copy segment locations into the profile spacing struct. */ - for (int i = 0; i < seg + 1; i++) { - pro_spacing->xvals[i] = (double)bp->custom_profile->segments[i].y; - pro_spacing->yvals[i] = (double)bp->custom_profile->segments[i].x; + for (int i = 0; i < seg_2 + 1; i++) { + pro_spacing->xvals_2[i] = (double)bp->custom_profile->segments[i].y; + pro_spacing->yvals_2[i] = (double)bp->custom_profile->segments[i].x; } } else { - find_even_superellipse_chords(seg, bp->pro_super_r, pro_spacing->xvals, pro_spacing->yvals); + find_even_superellipse_chords( + seg_2, bp->pro_super_r, pro_spacing->xvals_2, pro_spacing->yvals_2); } } - else { /* Only 1 segment, we don't need any profile information. */ - pro_spacing->xvals = NULL; - pro_spacing->yvals = NULL; - pro_spacing->xvals_2 = NULL; - pro_spacing->yvals_2 = NULL; - pro_spacing->seg_2 = 0; + + /* Sample the input number of segments. */ + pro_spacing->xvals = (double *)BLI_memarena_alloc(bp->mem_arena, sizeof(double) * (seg + 1)); + pro_spacing->yvals = (double *)BLI_memarena_alloc(bp->mem_arena, sizeof(double) * (seg + 1)); + if (custom) { + /* Make sure the curve profile's sample table is full. */ + if (bp->custom_profile->segments_len != seg || !bp->custom_profile->segments) { + BKE_curveprofile_init((CurveProfile *)bp->custom_profile, (short)seg); + } + + /* Copy segment locations into the profile spacing struct. */ + for (int i = 0; i < seg + 1; i++) { + pro_spacing->xvals[i] = (double)bp->custom_profile->segments[i].y; + pro_spacing->yvals[i] = (double)bp->custom_profile->segments[i].x; + } + } + else { + find_even_superellipse_chords(seg, bp->pro_super_r, pro_spacing->xvals, pro_spacing->yvals); } } @@ -7493,6 +7504,10 @@ void BM_mesh_bevel(BMesh *bm, bp.custom_profile = custom_profile; bp.vmesh_method = vmesh_method; +#ifdef BEVEL_DEBUG_TIME + double start_time = PIL_check_seconds_timer(); +#endif + /* Disable the miters with the cutoff vertex mesh method, the combination isn't useful anyway. */ if (bp.vmesh_method == BEVEL_VMESH_CUTOFF) { bp.miter_outer = BEVEL_MITER_SHARP; @@ -7661,4 +7676,8 @@ void BM_mesh_bevel(BMesh *bm, BLI_ghash_free(bp.face_hash, NULL, NULL); BLI_memarena_free(bp.mem_arena); } +#ifdef BEVEL_DEBUG_TIME + double end_time = PIL_check_seconds_timer(); + printf("BMESH BEVEL TIME = %.3f\n", end_time - start_time); +#endif } diff --git a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c index 3ed27ea580e..94a578fe1d7 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c +++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c @@ -171,7 +171,10 @@ static float bm_edge_calc_dissolve_error(const BMEdge *e, #ifdef USE_DEGENERATE_CHECK -static void mul_v2_m3v3_center(float r[2], float m[3][3], const float a[3], const float center[3]) +static void mul_v2_m3v3_center(float r[2], + const float m[3][3], + const float a[3], + const float center[3]) { BLI_assert(r != a); BLI_assert(r != center); diff --git a/source/blender/bmesh/tools/bmesh_intersect.c b/source/blender/bmesh/tools/bmesh_intersect.c index 6426fe9c687..371d8d59d6c 100644 --- a/source/blender/bmesh/tools/bmesh_intersect.c +++ b/source/blender/bmesh/tools/bmesh_intersect.c @@ -898,7 +898,7 @@ static int isect_bvhtree_point_v3(BVHTree *tree, const float **looptris, const f &z_buffer, }; BVHTreeRayHit hit = {0}; - float dir[3] = {1.0f, 0.0f, 0.0f}; + const float dir[3] = {1.0f, 0.0f, 0.0f}; /* Need to initialize hit even tho it's not used. * This is to make it so kd-tree believes we didn't intersect anything and diff --git a/source/blender/bmesh/tools/bmesh_intersect_edges.c b/source/blender/bmesh/tools/bmesh_intersect_edges.c index 52231033fd3..5e266fdac0e 100644 --- a/source/blender/bmesh/tools/bmesh_intersect_edges.c +++ b/source/blender/bmesh/tools/bmesh_intersect_edges.c @@ -455,7 +455,7 @@ static void bm_elemxelem_bvhtree_overlap(const BVHTree *tree1, int parallel_tasks_num = BLI_bvhtree_overlap_thread_num(tree1); for (int i = 0; i < parallel_tasks_num; i++) { if (pair_stack[i] == NULL) { - pair_stack[i] = BLI_stack_new(sizeof(struct EDBMSplitElem[2]), __func__); + pair_stack[i] = BLI_stack_new(sizeof(const struct EDBMSplitElem[2]), __func__); } } data->pair_stack = pair_stack; diff --git a/source/blender/compositor/intern/COM_CompositorContext.cpp b/source/blender/compositor/intern/COM_CompositorContext.cpp index e572fe7c99e..3d55fcba086 100644 --- a/source/blender/compositor/intern/COM_CompositorContext.cpp +++ b/source/blender/compositor/intern/COM_CompositorContext.cpp @@ -36,7 +36,6 @@ int CompositorContext::getFramenumber() const if (this->m_rd) { return this->m_rd->cfra; } - else { - return -1; /* this should never happen */ - } + + return -1; /* this should never happen */ } diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp index edfeb3a3a04..60676ee42b7 100644 --- a/source/blender/compositor/intern/COM_Converter.cpp +++ b/source/blender/compositor/intern/COM_Converter.cpp @@ -416,19 +416,19 @@ NodeOperation *Converter::convertDataType(NodeOperationOutput *from, NodeOperati if (fromDatatype == COM_DT_VALUE && toDatatype == COM_DT_COLOR) { return new ConvertValueToColorOperation(); } - else if (fromDatatype == COM_DT_VALUE && toDatatype == COM_DT_VECTOR) { + if (fromDatatype == COM_DT_VALUE && toDatatype == COM_DT_VECTOR) { return new ConvertValueToVectorOperation(); } - else if (fromDatatype == COM_DT_COLOR && toDatatype == COM_DT_VALUE) { + if (fromDatatype == COM_DT_COLOR && toDatatype == COM_DT_VALUE) { return new ConvertColorToValueOperation(); } - else if (fromDatatype == COM_DT_COLOR && toDatatype == COM_DT_VECTOR) { + if (fromDatatype == COM_DT_COLOR && toDatatype == COM_DT_VECTOR) { return new ConvertColorToVectorOperation(); } - else if (fromDatatype == COM_DT_VECTOR && toDatatype == COM_DT_VALUE) { + if (fromDatatype == COM_DT_VECTOR && toDatatype == COM_DT_VALUE) { return new ConvertVectorToValueOperation(); } - else if (fromDatatype == COM_DT_VECTOR && toDatatype == COM_DT_COLOR) { + if (fromDatatype == COM_DT_VECTOR && toDatatype == COM_DT_COLOR) { return new ConvertVectorToColorOperation(); } diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cpp b/source/blender/compositor/intern/COM_MemoryBuffer.cpp index b958314d1b4..f58d7a768cc 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.cpp +++ b/source/blender/compositor/intern/COM_MemoryBuffer.cpp @@ -136,10 +136,9 @@ float MemoryBuffer::getMaximumValue(rcti *rect) delete temp; return result; } - else { - BLI_assert(0); - return 0.0f; - } + + BLI_assert(0); + return 0.0f; } MemoryBuffer::~MemoryBuffer() diff --git a/source/blender/compositor/intern/COM_NodeOperation.cpp b/source/blender/compositor/intern/COM_NodeOperation.cpp index fa4b5a07c65..4e3c5d2df6c 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.cpp +++ b/source/blender/compositor/intern/COM_NodeOperation.cpp @@ -145,9 +145,8 @@ NodeOperation *NodeOperation::getInputOperation(unsigned int inputSocketIndex) if (input && input->isConnected()) { return &input->getLink()->getOperation(); } - else { - return NULL; - } + + return NULL; } void NodeOperation::getConnectedInputSockets(Inputs *sockets) @@ -168,30 +167,29 @@ bool NodeOperation::determineDependingAreaOfInterest(rcti *input, BLI_rcti_init(output, input->xmin, input->xmax, input->ymin, input->ymax); return false; } - else { - rcti tempOutput; - bool first = true; - for (int i = 0; i < getNumberOfInputSockets(); i++) { - NodeOperation *inputOperation = this->getInputOperation(i); - if (inputOperation && - inputOperation->determineDependingAreaOfInterest(input, readOperation, &tempOutput)) { - if (first) { - output->xmin = tempOutput.xmin; - output->ymin = tempOutput.ymin; - output->xmax = tempOutput.xmax; - output->ymax = tempOutput.ymax; - first = false; - } - else { - output->xmin = min(output->xmin, tempOutput.xmin); - output->ymin = min(output->ymin, tempOutput.ymin); - output->xmax = max(output->xmax, tempOutput.xmax); - output->ymax = max(output->ymax, tempOutput.ymax); - } + + rcti tempOutput; + bool first = true; + for (int i = 0; i < getNumberOfInputSockets(); i++) { + NodeOperation *inputOperation = this->getInputOperation(i); + if (inputOperation && + inputOperation->determineDependingAreaOfInterest(input, readOperation, &tempOutput)) { + if (first) { + output->xmin = tempOutput.xmin; + output->ymin = tempOutput.ymin; + output->xmax = tempOutput.xmax; + output->ymax = tempOutput.ymax; + first = false; + } + else { + output->xmin = min(output->xmin, tempOutput.xmin); + output->ymin = min(output->ymin, tempOutput.ymin); + output->xmax = max(output->xmax, tempOutput.xmax); + output->ymax = max(output->ymax, tempOutput.ymax); } } - return !first; } + return !first; } /***************** @@ -210,9 +208,8 @@ SocketReader *NodeOperationInput::getReader() if (isConnected()) { return &m_link->getOperation(); } - else { - return NULL; - } + + return NULL; } void NodeOperationInput::determineResolution(unsigned int resolution[2], diff --git a/source/blender/compositor/nodes/COM_TimeNode.cpp b/source/blender/compositor/nodes/COM_TimeNode.cpp index 9722ead0716..247e0d11df6 100644 --- a/source/blender/compositor/nodes/COM_TimeNode.cpp +++ b/source/blender/compositor/nodes/COM_TimeNode.cpp @@ -49,7 +49,7 @@ void TimeNode::convertToOperations(NodeConverter &converter, fac = (context.getFramenumber() - node->custom1) / (float)(node->custom2 - node->custom1); } - BKE_curvemapping_initialize((CurveMapping *)node->storage); + BKE_curvemapping_init((CurveMapping *)node->storage); fac = BKE_curvemapping_evaluateF((CurveMapping *)node->storage, 0, fac); operation->setValue(clamp_f(fac, 0.0f, 1.0f)); converter.addOperation(operation); diff --git a/source/blender/compositor/operations/COM_AntiAliasOperation.cpp b/source/blender/compositor/operations/COM_AntiAliasOperation.cpp index 85725cc1d37..2c762323104 100644 --- a/source/blender/compositor/operations/COM_AntiAliasOperation.cpp +++ b/source/blender/compositor/operations/COM_AntiAliasOperation.cpp @@ -105,9 +105,9 @@ static int extrapolate9(float *E0, } return 1; } - else { - return 0; - } + + return 0; + #undef PEQ #undef PCPY } diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp index 66043abd951..50f8eab5fbc 100644 --- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp @@ -39,9 +39,8 @@ float ConvertDepthToRadiusOperation::determineFocalDistance() this->m_cam_lens = camera->lens; return BKE_camera_object_dof_distance(this->m_cameraObject); } - else { - return 10.0f; - } + + return 10.0f; } void ConvertDepthToRadiusOperation::initExecution() diff --git a/source/blender/compositor/operations/COM_CurveBaseOperation.cpp b/source/blender/compositor/operations/COM_CurveBaseOperation.cpp index b18e77cf0e3..855f728f7bf 100644 --- a/source/blender/compositor/operations/COM_CurveBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_CurveBaseOperation.cpp @@ -35,7 +35,7 @@ CurveBaseOperation::~CurveBaseOperation() void CurveBaseOperation::initExecution() { - BKE_curvemapping_initialize(this->m_curveMapping); + BKE_curvemapping_init(this->m_curveMapping); } void CurveBaseOperation::deinitExecution() { diff --git a/source/blender/compositor/operations/COM_DenoiseOperation.cpp b/source/blender/compositor/operations/COM_DenoiseOperation.cpp index d9a59002caf..202e614c0c5 100644 --- a/source/blender/compositor/operations/COM_DenoiseOperation.cpp +++ b/source/blender/compositor/operations/COM_DenoiseOperation.cpp @@ -73,14 +73,13 @@ bool DenoiseOperation::determineDependingAreaOfInterest(rcti * /*input*/, if (isCached()) { return false; } - else { - rcti newInput; - newInput.xmax = this->getWidth(); - newInput.xmin = 0; - newInput.ymax = this->getHeight(); - newInput.ymin = 0; - return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); - } + + rcti newInput; + newInput.xmax = this->getWidth(); + newInput.xmin = 0; + newInput.ymax = this->getHeight(); + newInput.ymin = 0; + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } void DenoiseOperation::generateDenoise(float *data, diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.cpp b/source/blender/compositor/operations/COM_DisplaceOperation.cpp index b775bfdee4c..73790447216 100644 --- a/source/blender/compositor/operations/COM_DisplaceOperation.cpp +++ b/source/blender/compositor/operations/COM_DisplaceOperation.cpp @@ -74,13 +74,12 @@ bool DisplaceOperation::read_displacement( r_v = 0.0f; return false; } - else { - float col[4]; - m_inputVectorProgram->readSampled(col, x, y, COM_PS_BILINEAR); - r_u = origin[0] - col[0] * xscale; - r_v = origin[1] - col[1] * yscale; - return true; - } + + float col[4]; + m_inputVectorProgram->readSampled(col, x, y, COM_PS_BILINEAR); + r_u = origin[0] - col[0] * xscale; + r_v = origin[1] - col[1] * yscale; + return true; } void DisplaceOperation::pixelTransform(const float xy[2], float r_uv[2], float r_deriv[2][2]) diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp index 84f7fe2d225..675a402de6f 100644 --- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp +++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp @@ -1330,9 +1330,8 @@ bool DoubleEdgeMaskOperation::determineDependingAreaOfInterest(rcti * /*input*/, newInput.ymin = 0; return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } - else { - return false; - } + + return false; } void DoubleEdgeMaskOperation::initExecution() diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp index 7a6b69d12fa..0ccb959712f 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp @@ -47,18 +47,17 @@ bool FastGaussianBlurOperation::determineDependingAreaOfInterest( if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) { return true; } - else { - if (this->m_iirgaus) { - return false; - } - else { - newInput.xmin = 0; - newInput.ymin = 0; - newInput.xmax = this->getWidth(); - newInput.ymax = this->getHeight(); - } - return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); + + if (this->m_iirgaus) { + return false; } + + newInput.xmin = 0; + newInput.ymin = 0; + newInput.xmax = this->getWidth(); + newInput.ymax = this->getHeight(); + + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } void FastGaussianBlurOperation::initExecution() @@ -282,12 +281,12 @@ bool FastGaussianBlurValueOperation::determineDependingAreaOfInterest( if (this->m_iirgaus) { return false; } - else { - newInput.xmin = 0; - newInput.ymin = 0; - newInput.xmax = this->getWidth(); - newInput.ymax = this->getHeight(); - } + + newInput.xmin = 0; + newInput.ymin = 0; + newInput.xmax = this->getWidth(); + newInput.ymax = this->getHeight(); + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp index 43e571c4bb7..dd479da864c 100644 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp @@ -176,23 +176,22 @@ bool GaussianBokehBlurOperation::determineDependingAreaOfInterest( if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) { return true; } + + if (this->m_sizeavailable && this->m_gausstab != NULL) { + newInput.xmin = 0; + newInput.ymin = 0; + newInput.xmax = this->getWidth(); + newInput.ymax = this->getHeight(); + } else { - if (this->m_sizeavailable && this->m_gausstab != NULL) { - newInput.xmin = 0; - newInput.ymin = 0; - newInput.xmax = this->getWidth(); - newInput.ymax = this->getHeight(); - } - else { - int addx = this->m_radx; - int addy = this->m_rady; - newInput.xmax = input->xmax + addx; - newInput.xmin = input->xmin - addx; - newInput.ymax = input->ymax + addy; - newInput.ymin = input->ymin - addy; - } - return BlurBaseOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); + int addx = this->m_radx; + int addy = this->m_rady; + newInput.xmax = input->xmax + addx; + newInput.xmin = input->xmin - addx; + newInput.ymax = input->ymax + addy; + newInput.ymin = input->ymin - addy; } + return BlurBaseOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } // reference image @@ -351,13 +350,12 @@ bool GaussianBlurReferenceOperation::determineDependingAreaOfInterest( if (operation->determineDependingAreaOfInterest(input, readOperation, output)) { return true; } - else { - int addx = this->m_data.sizex + 2; - int addy = this->m_data.sizey + 2; - newInput.xmax = input->xmax + addx; - newInput.xmin = input->xmin - addx; - newInput.ymax = input->ymax + addy; - newInput.ymin = input->ymin - addy; - return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); - } + + int addx = this->m_data.sizex + 2; + int addy = this->m_data.sizey + 2; + newInput.xmax = input->xmax + addx; + newInput.xmin = input->xmin - addx; + newInput.ymax = input->ymax + addy; + newInput.ymin = input->ymin - addy; + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.cpp b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp index 593f1eaeefa..278e65a7dfd 100644 --- a/source/blender/compositor/operations/COM_GlareBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp @@ -58,12 +58,11 @@ bool GlareBaseOperation::determineDependingAreaOfInterest(rcti * /*input*/, if (isCached()) { return false; } - else { - rcti newInput; - newInput.xmax = this->getWidth(); - newInput.xmin = 0; - newInput.ymax = this->getHeight(); - newInput.ymin = 0; - return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); - } + + rcti newInput; + newInput.xmax = this->getWidth(); + newInput.xmin = 0; + newInput.ymax = this->getHeight(); + newInput.ymin = 0; + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp index 9f01cf5d63a..760b833d1e1 100644 --- a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp @@ -28,9 +28,8 @@ static float smoothMask(float x, float y) if ((t = 1.0f - sqrtf(x * x + y * y)) > 0.0f) { return t; } - else { - return 0.0f; - } + + return 0.0f; } void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings) diff --git a/source/blender/compositor/operations/COM_InpaintOperation.cpp b/source/blender/compositor/operations/COM_InpaintOperation.cpp index 0967984899d..0555ee24b9b 100644 --- a/source/blender/compositor/operations/COM_InpaintOperation.cpp +++ b/source/blender/compositor/operations/COM_InpaintOperation.cpp @@ -34,7 +34,7 @@ InpaintSimpleOperation::InpaintSimpleOperation() : NodeOperation() this->setComplex(true); this->m_inputImageProgram = NULL; this->m_pixelorder = NULL; - this->m_manhatten_distance = NULL; + this->m_manhattan_distance = NULL; this->m_cached_buffer = NULL; this->m_cached_buffer_ready = false; } @@ -43,7 +43,7 @@ void InpaintSimpleOperation::initExecution() this->m_inputImageProgram = this->getInputSocketReader(0); this->m_pixelorder = NULL; - this->m_manhatten_distance = NULL; + this->m_manhattan_distance = NULL; this->m_cached_buffer = NULL; this->m_cached_buffer_ready = false; @@ -85,7 +85,7 @@ int InpaintSimpleOperation::mdist(int x, int y) ASSERT_XY_RANGE(x, y); - return this->m_manhatten_distance[y * width + x]; + return this->m_manhattan_distance[y * width + x]; } bool InpaintSimpleOperation::next_pixel(int &x, int &y, int &curr, int iters) @@ -108,11 +108,11 @@ bool InpaintSimpleOperation::next_pixel(int &x, int &y, int &curr, int iters) return true; } -void InpaintSimpleOperation::calc_manhatten_distance() +void InpaintSimpleOperation::calc_manhattan_distance() { int width = this->getWidth(); int height = this->getHeight(); - short *m = this->m_manhatten_distance = (short *)MEM_mallocN(sizeof(short) * width * height, + short *m = this->m_manhattan_distance = (short *)MEM_mallocN(sizeof(short) * width * height, __func__); int *offsets; @@ -223,7 +223,7 @@ void *InpaintSimpleOperation::initializeTileData(rcti *rect) MemoryBuffer *buf = (MemoryBuffer *)this->m_inputImageProgram->initializeTileData(rect); this->m_cached_buffer = (float *)MEM_dupallocN(buf->getBuffer()); - this->calc_manhatten_distance(); + this->calc_manhattan_distance(); int curr = 0; int x, y; @@ -258,9 +258,9 @@ void InpaintSimpleOperation::deinitExecution() this->m_pixelorder = NULL; } - if (this->m_manhatten_distance) { - MEM_freeN(this->m_manhatten_distance); - this->m_manhatten_distance = NULL; + if (this->m_manhattan_distance) { + MEM_freeN(this->m_manhattan_distance); + this->m_manhattan_distance = NULL; } this->m_cached_buffer_ready = false; } @@ -272,14 +272,13 @@ bool InpaintSimpleOperation::determineDependingAreaOfInterest(rcti * /*input*/, if (this->m_cached_buffer_ready) { return false; } - else { - rcti newInput; - newInput.xmax = getWidth(); - newInput.xmin = 0; - newInput.ymax = getHeight(); - newInput.ymin = 0; + rcti newInput; - return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); - } + newInput.xmax = getWidth(); + newInput.xmin = 0; + newInput.ymax = getHeight(); + newInput.ymin = 0; + + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } diff --git a/source/blender/compositor/operations/COM_InpaintOperation.h b/source/blender/compositor/operations/COM_InpaintOperation.h index 12523d5f064..86f3393e1ea 100644 --- a/source/blender/compositor/operations/COM_InpaintOperation.h +++ b/source/blender/compositor/operations/COM_InpaintOperation.h @@ -34,7 +34,7 @@ class InpaintSimpleOperation : public NodeOperation { int *m_pixelorder; int m_area_size; - short *m_manhatten_distance; + short *m_manhattan_distance; public: InpaintSimpleOperation(); @@ -65,7 +65,7 @@ class InpaintSimpleOperation : public NodeOperation { rcti *output); private: - void calc_manhatten_distance(); + void calc_manhattan_distance(); void clamp_xy(int &x, int &y); float *get_pixel(int x, int y); int mdist(int x, int y); diff --git a/source/blender/compositor/operations/COM_MapUVOperation.cpp b/source/blender/compositor/operations/COM_MapUVOperation.cpp index de55c9fb4b8..9101b82202a 100644 --- a/source/blender/compositor/operations/COM_MapUVOperation.cpp +++ b/source/blender/compositor/operations/COM_MapUVOperation.cpp @@ -87,14 +87,13 @@ bool MapUVOperation::read_uv(float x, float y, float &r_u, float &r_v, float &r_ r_alpha = 0.0f; return false; } - else { - float vector[3]; - m_inputUVProgram->readSampled(vector, x, y, COM_PS_BILINEAR); - r_u = vector[0] * m_inputColorProgram->getWidth(); - r_v = vector[1] * m_inputColorProgram->getHeight(); - r_alpha = vector[2]; - return true; - } + + float vector[3]; + m_inputUVProgram->readSampled(vector, x, y, COM_PS_BILINEAR); + r_u = vector[0] * m_inputColorProgram->getWidth(); + r_v = vector[1] * m_inputColorProgram->getHeight(); + r_alpha = vector[2]; + return true; } void MapUVOperation::pixelTransform(const float xy[2], diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp index ee3779edcb4..374189a5c50 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp +++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp @@ -129,9 +129,8 @@ static float *init_buffer(unsigned int width, unsigned int height, DataType data int size = get_datatype_size(datatype); return (float *)MEM_callocN(width * height * size * sizeof(float), "OutputFile buffer"); } - else { - return NULL; - } + + return NULL; } static void write_buffer_rect(rcti *rect, diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp index 738c51fc719..b7731a34c91 100644 --- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp @@ -124,9 +124,8 @@ bool ScreenLensDistortionOperation::get_delta(float r_sq, distort_uv(uv, t, delta); return true; } - else { - return false; - } + + return false; } void ScreenLensDistortionOperation::accumulate(MemoryBuffer *buffer, diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp index 6f47e0e190b..4a7139537c1 100644 --- a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp +++ b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp @@ -172,7 +172,7 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator { return; } - /* initialise the iteration variables */ + /* Initialize the iteration variables. */ float *buffer = init_buffer_iterator( input, source, co, dist_min, dist_max, x, y, num, v, dv, falloff_factor); zero_v3(border); diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp index 56e0ab9b93f..0f81780bb00 100644 --- a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp @@ -115,9 +115,8 @@ bool VectorBlurOperation::determineDependingAreaOfInterest(rcti * /*input*/, newInput.ymin = 0; return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } - else { - return false; - } + + return false; } void VectorBlurOperation::generateVectorBlur(float *data, diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cpp b/source/blender/compositor/operations/COM_ViewerOperation.cpp index fc26d6219e1..3d5d50e1c7f 100644 --- a/source/blender/compositor/operations/COM_ViewerOperation.cpp +++ b/source/blender/compositor/operations/COM_ViewerOperation.cpp @@ -199,7 +199,6 @@ CompositorPriority ViewerOperation::getRenderPriority() const if (this->isActiveViewerOutput()) { return COM_PRIORITY_HIGH; } - else { - return COM_PRIORITY_LOW; - } + + return COM_PRIORITY_LOW; } diff --git a/source/blender/datatoc/datatoc_icon.c b/source/blender/datatoc/datatoc_icon.c index 80a335e22b7..4a9c5875c17 100644 --- a/source/blender/datatoc/datatoc_icon.c +++ b/source/blender/datatoc/datatoc_icon.c @@ -269,7 +269,7 @@ static bool icon_merge(const char *file_src, /* init once */ *r_canvas_w = head.canvas_w; *r_canvas_h = head.canvas_h; - *r_pixels_canvas = calloc(1, (head.canvas_w * head.canvas_h) * sizeof(unsigned char[4])); + *r_pixels_canvas = calloc(1, (head.canvas_w * head.canvas_h) * sizeof(const unsigned char[4])); } canvas_w = *r_canvas_w; diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt index 51fce738700..417aaa2c4c0 100644 --- a/source/blender/depsgraph/CMakeLists.txt +++ b/source/blender/depsgraph/CMakeLists.txt @@ -54,6 +54,11 @@ set(SRC intern/builder/deg_builder_remove_noop.cc intern/builder/deg_builder_rna.cc intern/builder/deg_builder_transitive.cc + intern/builder/pipeline.cc + intern/builder/pipeline_compositor.cc + intern/builder/pipeline_from_ids.cc + intern/builder/pipeline_render.cc + intern/builder/pipeline_view_layer.cc intern/debug/deg_debug.cc intern/debug/deg_debug_relations_graphviz.cc intern/debug/deg_debug_stats_gnuplot.cc @@ -110,6 +115,11 @@ set(SRC intern/builder/deg_builder_remove_noop.h intern/builder/deg_builder_rna.h intern/builder/deg_builder_transitive.h + intern/builder/pipeline.h + intern/builder/pipeline_compositor.h + intern/builder/pipeline_from_ids.h + intern/builder/pipeline_render.h + intern/builder/pipeline_view_layer.h intern/debug/deg_debug.h intern/debug/deg_time_average.h intern/eval/deg_eval.h diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index dcdcf0c05ca..e262c880421 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -1126,6 +1126,12 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene) if (object->type != OB_MESH) { continue; } + if (object->rigidbody_object == nullptr) { + continue; + } + if (object->rigidbody_object->type == RBO_TYPE_PASSIVE) { + continue; + } /* Create operation for flushing results. */ /* Object's transform component - where the rigidbody operation * lives. */ @@ -1466,6 +1472,18 @@ void DepsgraphNodeBuilder::build_light(Light *lamp) function_bind(BKE_light_eval, _1, lamp_cow)); } +void DepsgraphNodeBuilder::build_nodetree_socket(bNodeSocket *socket) +{ + build_idproperties(socket->prop); + + if (socket->type == SOCK_OBJECT) { + build_id((ID *)((bNodeSocketValueObject *)socket->default_value)->value); + } + else if (socket->type == SOCK_IMAGE) { + build_id((ID *)((bNodeSocketValueImage *)socket->default_value)->value); + } +} + void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree) { if (ntree == nullptr) { @@ -1494,10 +1512,10 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree) LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) { build_idproperties(bnode->prop); LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->inputs) { - build_idproperties(socket->prop); + build_nodetree_socket(socket); } LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->outputs) { - build_idproperties(socket->prop); + build_nodetree_socket(socket); } ID *id = bnode->id; @@ -1780,8 +1798,10 @@ void DepsgraphNodeBuilder::build_simulation(Simulation *simulation) return; } add_id_node(&simulation->id); + build_idproperties(simulation->id.properties); build_animdata(&simulation->id); build_parameters(&simulation->id); + build_nodetree(simulation->nodetree); Simulation *simulation_cow = get_cow_datablock(simulation); Scene *scene_cow = get_cow_datablock(scene_); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 256fa3450a6..40f42705a52 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -31,6 +31,7 @@ #include "DEG_depsgraph.h" +struct bNodeSocket; struct CacheFile; struct Camera; struct Collection; @@ -211,6 +212,7 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder { virtual void build_camera(Camera *camera); virtual void build_light(Light *lamp); virtual void build_nodetree(bNodeTree *ntree); + virtual void build_nodetree_socket(bNodeSocket *socket); virtual void build_material(Material *ma); virtual void build_materials(Material **materials, int num_materials); virtual void build_freestyle_lineset(FreestyleLineSet *fls); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index c5c509ee853..6d76829fa1d 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -254,9 +254,8 @@ TimeSourceNode *DepsgraphRelationBuilder::get_node(const TimeSourceKey &key) con /* XXX TODO */ return nullptr; } - else { - return graph_->time_source; - } + + return graph_->time_source; } ComponentNode *DepsgraphRelationBuilder::get_node(const ComponentKey &key) const @@ -353,16 +352,16 @@ Relation *DepsgraphRelationBuilder::add_time_relation(TimeSourceNode *timesrc, if (timesrc && node_to) { return graph_->add_new_relation(timesrc, node_to, description, flags); } - else { - DEG_DEBUG_PRINTF((::Depsgraph *)graph_, - BUILD, - "add_time_relation(%p = %s, %p = %s, %s) Failed\n", - timesrc, - (timesrc) ? timesrc->identifier().c_str() : "<None>", - node_to, - (node_to) ? node_to->identifier().c_str() : "<None>", - description); - } + + DEG_DEBUG_PRINTF((::Depsgraph *)graph_, + BUILD, + "add_time_relation(%p = %s, %p = %s, %s) Failed\n", + timesrc, + (timesrc) ? timesrc->identifier().c_str() : "<None>", + node_to, + (node_to) ? node_to->identifier().c_str() : "<None>", + description); + return nullptr; } @@ -374,16 +373,16 @@ Relation *DepsgraphRelationBuilder::add_operation_relation(OperationNode *node_f if (node_from && node_to) { return graph_->add_new_relation(node_from, node_to, description, flags); } - else { - DEG_DEBUG_PRINTF((::Depsgraph *)graph_, - BUILD, - "add_operation_relation(%p = %s, %p = %s, %s) Failed\n", - node_from, - (node_from) ? node_from->identifier().c_str() : "<None>", - node_to, - (node_to) ? node_to->identifier().c_str() : "<None>", - description); - } + + DEG_DEBUG_PRINTF((::Depsgraph *)graph_, + BUILD, + "add_operation_relation(%p = %s, %p = %s, %s) Failed\n", + node_from, + (node_from) ? node_from->identifier().c_str() : "<None>", + node_to, + (node_to) ? node_to->identifier().c_str() : "<None>", + description); + return nullptr; } @@ -1698,6 +1697,22 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) if (object->type != OB_MESH) { continue; } + if (object->rigidbody_object == nullptr) { + continue; + } + if (object->rigidbody_object->type == RBO_TYPE_PASSIVE) { + continue; + } + + if (object->parent != nullptr && object->parent->rigidbody_object != nullptr && + object->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND) { + /* If we are a child of a compound shape object, the transforms and sim evaluation will be + * handled by the parent compound shape object. Do not add any evaluation triggers + * for the child objects. + */ + continue; + } + OperationKey rb_transform_copy_key( &object->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY); /* Rigid body synchronization depends on the actual simulation. */ @@ -1747,13 +1762,18 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) /* final result of the constraint object's transform controls how * the constraint affects the physics sim for these objects. */ ComponentKey trans_key(&object->id, NodeType::TRANSFORM); - OperationKey ob1_key( - &rbc->ob1->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY); - OperationKey ob2_key( - &rbc->ob2->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY); - /* Constrained-objects sync depends on the constraint-holder. */ - add_relation(trans_key, ob1_key, "RigidBodyConstraint -> RBC.Object_1"); - add_relation(trans_key, ob2_key, "RigidBodyConstraint -> RBC.Object_2"); + if (rbc->ob1->rigidbody_object->type == RBO_TYPE_ACTIVE) { + OperationKey ob1_key( + &rbc->ob1->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY); + /* Constrained-objects sync depends on the constraint-holder. */ + add_relation(trans_key, ob1_key, "RigidBodyConstraint -> RBC.Object_1"); + } + if (rbc->ob2->rigidbody_object->type == RBO_TYPE_ACTIVE) { + OperationKey ob2_key( + &rbc->ob2->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY); + /* Constrained-objects sync depends on the constraint-holder. */ + add_relation(trans_key, ob2_key, "RigidBodyConstraint -> RBC.Object_2"); + } /* Ensure that sim depends on this constraint's transform. */ add_relation(trans_key, rb_simulate_key, "RigidBodyConstraint Transform -> RB Simulation"); } @@ -2276,6 +2296,24 @@ void DepsgraphRelationBuilder::build_light(Light *lamp) add_relation(lamp_parameters_key, shading_key, "Light Shading Parameters"); } +void DepsgraphRelationBuilder::build_nodetree_socket(bNodeSocket *socket) +{ + build_idproperties(socket->prop); + + if (socket->type == SOCK_OBJECT) { + Object *object = ((bNodeSocketValueObject *)socket->default_value)->value; + if (object != nullptr) { + build_object(object); + } + } + else if (socket->type == SOCK_IMAGE) { + Image *image = ((bNodeSocketValueImage *)socket->default_value)->value; + if (image != nullptr) { + build_image(image); + } + } +} + void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree) { if (ntree == nullptr) { @@ -2292,10 +2330,10 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree) LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) { build_idproperties(bnode->prop); LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->inputs) { - build_idproperties(socket->prop); + build_nodetree_socket(socket); } LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->outputs) { - build_idproperties(socket->prop); + build_nodetree_socket(socket); } ID *id = bnode->id; @@ -2602,13 +2640,39 @@ void DepsgraphRelationBuilder::build_simulation(Simulation *simulation) if (built_map_.checkIsBuiltAndTag(simulation)) { return; } + build_idproperties(simulation->id.properties); build_animdata(&simulation->id); build_parameters(&simulation->id); - OperationKey simulation_update_key( + build_nodetree(simulation->nodetree); + build_nested_nodetree(&simulation->id, simulation->nodetree); + + OperationKey simulation_eval_key( &simulation->id, NodeType::SIMULATION, OperationCode::SIMULATION_EVAL); TimeSourceKey time_src_key; - add_relation(time_src_key, simulation_update_key, "TimeSrc -> Simulation"); + add_relation(time_src_key, simulation_eval_key, "TimeSrc -> Simulation"); + + OperationKey nodetree_key( + &simulation->nodetree->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EXIT); + add_relation(nodetree_key, simulation_eval_key, "NodeTree -> Simulation", 0); + + LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) { + if (dependency->id == nullptr) { + continue; + } + build_id(dependency->id); + if (GS(dependency->id->name) == ID_OB) { + Object *object = (Object *)dependency->id; + if (dependency->flag & SIM_DEPENDS_ON_TRANSFORM) { + ComponentKey object_transform_key(&object->id, NodeType::TRANSFORM); + add_relation(object_transform_key, simulation_eval_key, "Object Transform -> Simulation"); + } + if (dependency->flag & SIM_DEPENDS_ON_GEOMETRY) { + ComponentKey object_geometry_key(&object->id, NodeType::GEOMETRY); + add_relation(object_geometry_key, simulation_eval_key, "Object Geometry -> Simulation"); + } + } + } } void DepsgraphRelationBuilder::build_scene_sequencer(Scene *scene) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index b4b0dc71f85..04f2a3f911d 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -46,6 +46,7 @@ #include "intern/node/deg_node_operation.h" struct Base; +struct bNodeSocket; struct CacheFile; struct Camera; struct Collection; @@ -275,6 +276,7 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder { virtual void build_camera(Camera *camera); virtual void build_light(Light *lamp); virtual void build_nodetree(bNodeTree *ntree); + virtual void build_nodetree_socket(bNodeSocket *socket); virtual void build_material(Material *ma); virtual void build_materials(Material **materials, int num_materials); virtual void build_freestyle_lineset(FreestyleLineSet *fls); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc index e3b667427a2..ec18b429c2e 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc @@ -190,7 +190,7 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, reinterpret_cast<const PropertyRNA *>(prop)); return node_identifier; } - else if (ptr->type == &RNA_PoseBone) { + if (ptr->type == &RNA_PoseBone) { const bPoseChannel *pchan = static_cast<const bPoseChannel *>(ptr->data); /* Bone - generally, we just want the bone component. */ node_identifier.type = NodeType::BONE; @@ -222,7 +222,7 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, } return node_identifier; } - else if (ptr->type == &RNA_Bone) { + if (ptr->type == &RNA_Bone) { /* Armature-level bone mapped to Armature Eval, and thus Pose Init. * Drivers have special code elsewhere that links them to the pose * bone components, instead of using this generic code. */ @@ -236,7 +236,7 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, } return node_identifier; } - else if (RNA_struct_is_a(ptr->type, &RNA_Constraint)) { + if (RNA_struct_is_a(ptr->type, &RNA_Constraint)) { const Object *object = reinterpret_cast<const Object *>(ptr->owner_id); const bConstraint *constraint = static_cast<const bConstraint *>(ptr->data); RNANodeQueryIDData *id_data = ensure_id_data(&object->id); @@ -256,7 +256,7 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, } return node_identifier; } - else if (ELEM(ptr->type, &RNA_ConstraintTarget, &RNA_ConstraintTargetBone)) { + if (ELEM(ptr->type, &RNA_ConstraintTarget, &RNA_ConstraintTargetBone)) { Object *object = reinterpret_cast<Object *>(ptr->owner_id); bConstraintTarget *tgt = (bConstraintTarget *)ptr->data; /* Check whether is object or bone constraint. */ @@ -315,17 +315,17 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, node_identifier.type = NodeType::TRANSFORM; return node_identifier; } - else if (contains(prop_identifier, "data")) { + if (contains(prop_identifier, "data")) { /* We access object.data, most likely a geometry. * Might be a bone tho. */ node_identifier.type = NodeType::GEOMETRY; return node_identifier; } - else if (STREQ(prop_identifier, "hide_viewport") || STREQ(prop_identifier, "hide_render")) { + if (STREQ(prop_identifier, "hide_viewport") || STREQ(prop_identifier, "hide_render")) { node_identifier.type = NodeType::OBJECT_FROM_LAYER; return node_identifier; } - else if (STREQ(prop_identifier, "dimensions")) { + if (STREQ(prop_identifier, "dimensions")) { node_identifier.type = NodeType::PARAMETERS; node_identifier.operation_code = OperationCode::DIMENSIONS; return node_identifier; diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.h b/source/blender/depsgraph/intern/builder/deg_builder_rna.h index c48c6489c47..d03903d508c 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_rna.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.h @@ -96,7 +96,7 @@ class RNANodeQuery { /* Check whether prop_identifier contains rna_path_component. * - * This checks more than a substring: + * This checks more than a sub-string: * * prop_identifier contains(prop_identifier, "location") * ------------------------ ------------------------------------- diff --git a/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc b/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc index bd6a364e08a..c5e020b3242 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc @@ -96,7 +96,7 @@ void deg_graph_transitive_reduction(Depsgraph *graph) * need modifying. */ continue; } - else if (rel->from->custom_flags & OP_REACHABLE) { + if (rel->from->custom_flags & OP_REACHABLE) { relations_to_remove.append(rel); } } diff --git a/source/blender/depsgraph/intern/builder/pipeline.cc b/source/blender/depsgraph/intern/builder/pipeline.cc new file mode 100644 index 00000000000..d6893ba11d8 --- /dev/null +++ b/source/blender/depsgraph/intern/builder/pipeline.cc @@ -0,0 +1,132 @@ +/* + * 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) 2020 Blender Foundation. + * All rights reserved. + */ + +#include "pipeline.h" + +#include "PIL_time.h" + +#include "BKE_global.h" + +#include "DNA_scene_types.h" + +#include "deg_builder_cycle.h" +#include "deg_builder_nodes.h" +#include "deg_builder_relations.h" +#include "deg_builder_transitive.h" + +namespace blender { +namespace deg { + +AbstractBuilderPipeline::AbstractBuilderPipeline(::Depsgraph *graph, + Main *bmain, + Scene *scene, + ViewLayer *view_layer) + : deg_graph_(reinterpret_cast<Depsgraph *>(graph)), + bmain_(bmain), + scene_(scene), + view_layer_(view_layer), + builder_cache_() +{ +} + +AbstractBuilderPipeline::~AbstractBuilderPipeline() +{ +} + +void AbstractBuilderPipeline::build() +{ + double start_time = 0.0; + if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) { + start_time = PIL_check_seconds_timer(); + } + + build_step_sanity_check(); + build_step_nodes(); + build_step_relations(); + build_step_finalize(); + + if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) { + printf("Depsgraph built in %f seconds.\n", PIL_check_seconds_timer() - start_time); + } +} + +void AbstractBuilderPipeline::build_step_sanity_check() +{ + BLI_assert(BLI_findindex(&scene_->view_layers, view_layer_) != -1); + BLI_assert(deg_graph_->scene == scene_); + BLI_assert(deg_graph_->view_layer == view_layer_); +} + +void AbstractBuilderPipeline::build_step_nodes() +{ + /* Generate all the nodes in the graph first */ + unique_ptr<DepsgraphNodeBuilder> node_builder = construct_node_builder(); + node_builder->begin_build(); + build_nodes(*node_builder); + node_builder->end_build(); +} + +void AbstractBuilderPipeline::build_step_relations() +{ + /* Hook up relationships between operations - to determine evaluation order. */ + unique_ptr<DepsgraphRelationBuilder> relation_builder = construct_relation_builder(); + relation_builder->begin_build(); + build_relations(*relation_builder); + relation_builder->build_copy_on_write_relations(); + relation_builder->build_driver_relations(); +} + +void AbstractBuilderPipeline::build_step_finalize() +{ + /* Detect and solve cycles. */ + deg_graph_detect_cycles(deg_graph_); + /* Simplify the graph by removing redundant relations (to optimize + * traversal later). */ + /* TODO: it would be useful to have an option to disable this in cases where + * it is causing trouble. */ + if (G.debug_value == 799) { + deg_graph_transitive_reduction(deg_graph_); + } + /* Store pointers to commonly used valuated datablocks. */ + deg_graph_->scene_cow = (Scene *)deg_graph_->get_cow_id(°_graph_->scene->id); + /* Flush visibility layer and re-schedule nodes for update. */ + deg_graph_build_finalize(bmain_, deg_graph_); + DEG_graph_on_visible_update(bmain_, reinterpret_cast<::Depsgraph *>(deg_graph_), false); +#if 0 + if (!DEG_debug_consistency_check(deg_graph_)) { + printf("Consistency validation failed, ABORTING!\n"); + abort(); + } +#endif + /* Relations are up to date. */ + deg_graph_->need_update = false; +} + +unique_ptr<DepsgraphNodeBuilder> AbstractBuilderPipeline::construct_node_builder() +{ + return std::make_unique<DepsgraphNodeBuilder>(bmain_, deg_graph_, &builder_cache_); +} + +unique_ptr<DepsgraphRelationBuilder> AbstractBuilderPipeline::construct_relation_builder() +{ + return std::make_unique<DepsgraphRelationBuilder>(bmain_, deg_graph_, &builder_cache_); +} + +} // namespace deg +} // namespace blender diff --git a/source/blender/depsgraph/intern/builder/pipeline.h b/source/blender/depsgraph/intern/builder/pipeline.h new file mode 100644 index 00000000000..2c9c78bb2cb --- /dev/null +++ b/source/blender/depsgraph/intern/builder/pipeline.h @@ -0,0 +1,77 @@ +/* + * 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) 2020 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup depsgraph + */ + +#pragma once + +#include "deg_builder_cache.h" + +#include "intern/depsgraph_type.h" + +struct Main; +struct Scene; +struct ViewLayer; +struct Depsgraph; + +namespace blender { +namespace deg { + +struct Depsgraph; +class DepsgraphNodeBuilder; +class DepsgraphRelationBuilder; + +/* Base class for Depsgraph Builder pipelines. + * + * Basically it runs through the following steps: + * - sanity check + * - build nodes + * - build relations + * - finalize + */ +class AbstractBuilderPipeline { + public: + AbstractBuilderPipeline(::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer); + virtual ~AbstractBuilderPipeline(); + + void build(); + + protected: + Depsgraph *deg_graph_; + Main *bmain_; + Scene *scene_; + ViewLayer *view_layer_; + DepsgraphBuilderCache builder_cache_; + + virtual unique_ptr<DepsgraphNodeBuilder> construct_node_builder(); + virtual unique_ptr<DepsgraphRelationBuilder> construct_relation_builder(); + + virtual void build_step_sanity_check(); + void build_step_nodes(); + void build_step_relations(); + void build_step_finalize(); + + virtual void build_nodes(DepsgraphNodeBuilder &node_builder) = 0; + virtual void build_relations(DepsgraphRelationBuilder &relation_builder) = 0; +}; + +} // namespace deg +} // namespace blender diff --git a/source/blender/depsgraph/intern/builder/pipeline_compositor.cc b/source/blender/depsgraph/intern/builder/pipeline_compositor.cc new file mode 100644 index 00000000000..3e56f17fc7e --- /dev/null +++ b/source/blender/depsgraph/intern/builder/pipeline_compositor.cc @@ -0,0 +1,49 @@ +/* + * 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) 2020 Blender Foundation. + * All rights reserved. + */ + +#include "pipeline_compositor.h" + +#include "intern/builder/deg_builder_nodes.h" +#include "intern/builder/deg_builder_relations.h" +#include "intern/depsgraph.h" + +namespace blender { +namespace deg { + +CompositorBuilderPipeline::CompositorBuilderPipeline( + ::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer, bNodeTree *nodetree) + : AbstractBuilderPipeline(graph, bmain, scene, view_layer), nodetree_(nodetree) +{ + deg_graph_->is_render_pipeline_depsgraph = true; +} + +void CompositorBuilderPipeline::build_nodes(DepsgraphNodeBuilder &node_builder) +{ + node_builder.build_scene_render(scene_, view_layer_); + node_builder.build_nodetree(nodetree_); +} + +void CompositorBuilderPipeline::build_relations(DepsgraphRelationBuilder &relation_builder) +{ + relation_builder.build_scene_render(scene_, view_layer_); + relation_builder.build_nodetree(nodetree_); +} + +} // namespace deg +} // namespace blender diff --git a/source/blender/depsgraph/intern/builder/pipeline_compositor.h b/source/blender/depsgraph/intern/builder/pipeline_compositor.h new file mode 100644 index 00000000000..892ece7c2a4 --- /dev/null +++ b/source/blender/depsgraph/intern/builder/pipeline_compositor.h @@ -0,0 +1,47 @@ +/* + * 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) 2020 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup depsgraph + */ + +#pragma once + +#include "pipeline.h" + +struct bNodeTree; + +namespace blender { +namespace deg { + +class CompositorBuilderPipeline : public AbstractBuilderPipeline { + public: + CompositorBuilderPipeline( + ::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer, bNodeTree *nodetree); + + protected: + virtual void build_nodes(DepsgraphNodeBuilder &node_builder) override; + virtual void build_relations(DepsgraphRelationBuilder &relation_builder) override; + + private: + bNodeTree *nodetree_; +}; + +} // namespace deg +} // namespace blender diff --git a/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc b/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc new file mode 100644 index 00000000000..e44f554f197 --- /dev/null +++ b/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc @@ -0,0 +1,154 @@ +/* + * 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) 2020 Blender Foundation. + * All rights reserved. + */ + +#include "pipeline_from_ids.h" + +#include "DNA_layer_types.h" + +#include "intern/builder/deg_builder_nodes.h" +#include "intern/builder/deg_builder_relations.h" +#include "intern/depsgraph.h" + +namespace blender { +namespace deg { + +namespace { + +class DepsgraphFromIDsFilter { + public: + DepsgraphFromIDsFilter(ID **ids, const int num_ids) + { + for (int i = 0; i < num_ids; ++i) { + ids_.add(ids[i]); + } + } + + bool contains(ID *id) + { + return ids_.contains(id); + } + + protected: + Set<ID *> ids_; +}; + +class DepsgraphFromIDsNodeBuilder : public DepsgraphNodeBuilder { + public: + DepsgraphFromIDsNodeBuilder( + Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache, ID **ids, const int num_ids) + : DepsgraphNodeBuilder(bmain, graph, cache), filter_(ids, num_ids) + { + } + + virtual bool need_pull_base_into_graph(Base *base) override + { + if (!filter_.contains(&base->object->id)) { + return false; + } + return DepsgraphNodeBuilder::need_pull_base_into_graph(base); + } + + virtual void build_object_proxy_group(Object *object, bool is_visible) override + { + if (object->proxy_group == nullptr) { + return; + } + if (!filter_.contains(&object->proxy_group->id)) { + return; + } + DepsgraphNodeBuilder::build_object_proxy_group(object, is_visible); + } + + protected: + DepsgraphFromIDsFilter filter_; +}; + +class DepsgraphFromIDsRelationBuilder : public DepsgraphRelationBuilder { + public: + DepsgraphFromIDsRelationBuilder( + Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache, ID **ids, const int num_ids) + : DepsgraphRelationBuilder(bmain, graph, cache), filter_(ids, num_ids) + { + } + + virtual bool need_pull_base_into_graph(Base *base) override + { + if (!filter_.contains(&base->object->id)) { + return false; + } + return DepsgraphRelationBuilder::need_pull_base_into_graph(base); + } + + virtual void build_object_proxy_group(Object *object) override + { + if (object->proxy_group == nullptr) { + return; + } + if (!filter_.contains(&object->proxy_group->id)) { + return; + } + DepsgraphRelationBuilder::build_object_proxy_group(object); + } + + protected: + DepsgraphFromIDsFilter filter_; +}; + +} // namespace + +FromIDsBuilderPipeline::FromIDsBuilderPipeline(::Depsgraph *graph, + Main *bmain, + Scene *scene, + ViewLayer *view_layer, + ID **ids, + const int num_ids) + : AbstractBuilderPipeline(graph, bmain, scene, view_layer), ids_(ids), num_ids_(num_ids) +{ +} + +unique_ptr<DepsgraphNodeBuilder> FromIDsBuilderPipeline::construct_node_builder() +{ + return std::make_unique<DepsgraphFromIDsNodeBuilder>( + bmain_, deg_graph_, &builder_cache_, ids_, num_ids_); +} + +unique_ptr<DepsgraphRelationBuilder> FromIDsBuilderPipeline::construct_relation_builder() +{ + return std::make_unique<DepsgraphFromIDsRelationBuilder>( + bmain_, deg_graph_, &builder_cache_, ids_, num_ids_); +} + +void FromIDsBuilderPipeline::build_nodes(DepsgraphNodeBuilder &node_builder) +{ + node_builder.build_view_layer(scene_, view_layer_, DEG_ID_LINKED_DIRECTLY); + for (int i = 0; i < num_ids_; ++i) { + node_builder.build_id(ids_[i]); + } +} + +void FromIDsBuilderPipeline::build_relations(DepsgraphRelationBuilder &relation_builder) +{ + relation_builder.build_view_layer(scene_, view_layer_, DEG_ID_LINKED_DIRECTLY); + for (int i = 0; i < num_ids_; ++i) { + relation_builder.build_id(ids_[i]); + } +} + +} // namespace deg +} // namespace blender diff --git a/source/blender/depsgraph/intern/builder/pipeline_from_ids.h b/source/blender/depsgraph/intern/builder/pipeline_from_ids.h new file mode 100644 index 00000000000..4a507f2c728 --- /dev/null +++ b/source/blender/depsgraph/intern/builder/pipeline_from_ids.h @@ -0,0 +1,62 @@ +/* + * 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) 2020 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup depsgraph + */ + +#pragma once + +#include "pipeline.h" + +namespace blender { +namespace deg { + +/* Optimized builders for dependency graph built from a given set of IDs. + * + * General notes: + * + * - We pull in all bases if their objects are in the set of IDs. This allows to have proper + * visibility and other flags assigned to the objects. + * All other bases (the ones which points to object which is outside of the set of IDs) are + * completely ignored. + * + * - Proxy groups pointing to objects which are outside of the IDs set are also ignored. + * This way we avoid high-poly character body pulled into the dependency graph when it's coming + * from a library into an animation file and the dependency graph constructed for a proxy rig. */ + +class FromIDsBuilderPipeline : public AbstractBuilderPipeline { + public: + FromIDsBuilderPipeline( + ::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer, ID **ids, int num_ids); + + protected: + virtual unique_ptr<DepsgraphNodeBuilder> construct_node_builder() override; + virtual unique_ptr<DepsgraphRelationBuilder> construct_relation_builder() override; + + virtual void build_nodes(DepsgraphNodeBuilder &node_builder) override; + virtual void build_relations(DepsgraphRelationBuilder &relation_builder) override; + + private: + ID **ids_; + const int num_ids_; +}; + +} // namespace deg +} // namespace blender diff --git a/source/blender/depsgraph/intern/builder/pipeline_render.cc b/source/blender/depsgraph/intern/builder/pipeline_render.cc new file mode 100644 index 00000000000..50a37d0d3e4 --- /dev/null +++ b/source/blender/depsgraph/intern/builder/pipeline_render.cc @@ -0,0 +1,49 @@ +/* + * 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) 2020 Blender Foundation. + * All rights reserved. + */ + +#include "pipeline_render.h" + +#include "intern/builder/deg_builder_nodes.h" +#include "intern/builder/deg_builder_relations.h" +#include "intern/depsgraph.h" + +namespace blender { +namespace deg { + +RenderBuilderPipeline::RenderBuilderPipeline(::Depsgraph *graph, + Main *bmain, + Scene *scene, + ViewLayer *view_layer) + : AbstractBuilderPipeline(graph, bmain, scene, view_layer) +{ + deg_graph_->is_render_pipeline_depsgraph = true; +} + +void RenderBuilderPipeline::build_nodes(DepsgraphNodeBuilder &node_builder) +{ + node_builder.build_scene_render(scene_, view_layer_); +} + +void RenderBuilderPipeline::build_relations(DepsgraphRelationBuilder &relation_builder) +{ + relation_builder.build_scene_render(scene_, view_layer_); +} + +} // namespace deg +} // namespace blender diff --git a/source/blender/depsgraph/intern/builder/pipeline_render.h b/source/blender/depsgraph/intern/builder/pipeline_render.h new file mode 100644 index 00000000000..df7f9e0de68 --- /dev/null +++ b/source/blender/depsgraph/intern/builder/pipeline_render.h @@ -0,0 +1,41 @@ +/* + * 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) 2020 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup depsgraph + */ + +#pragma once + +#include "pipeline.h" + +namespace blender { +namespace deg { + +class RenderBuilderPipeline : public AbstractBuilderPipeline { + public: + RenderBuilderPipeline(::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer); + + protected: + virtual void build_nodes(DepsgraphNodeBuilder &node_builder) override; + virtual void build_relations(DepsgraphRelationBuilder &relation_builder) override; +}; + +} // namespace deg +} // namespace blender diff --git a/source/blender/depsgraph/intern/builder/pipeline_view_layer.cc b/source/blender/depsgraph/intern/builder/pipeline_view_layer.cc new file mode 100644 index 00000000000..3223f17f349 --- /dev/null +++ b/source/blender/depsgraph/intern/builder/pipeline_view_layer.cc @@ -0,0 +1,48 @@ +/* + * 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) 2020 Blender Foundation. + * All rights reserved. + */ + +#include "pipeline_view_layer.h" + +#include "intern/builder/deg_builder_nodes.h" +#include "intern/builder/deg_builder_relations.h" +#include "intern/depsgraph.h" + +namespace blender { +namespace deg { + +ViewLayerBuilderPipeline::ViewLayerBuilderPipeline(::Depsgraph *graph, + Main *bmain, + Scene *scene, + ViewLayer *view_layer) + : AbstractBuilderPipeline(graph, bmain, scene, view_layer) +{ +} + +void ViewLayerBuilderPipeline::build_nodes(DepsgraphNodeBuilder &node_builder) +{ + node_builder.build_view_layer(scene_, view_layer_, DEG_ID_LINKED_DIRECTLY); +} + +void ViewLayerBuilderPipeline::build_relations(DepsgraphRelationBuilder &relation_builder) +{ + relation_builder.build_view_layer(scene_, view_layer_, DEG_ID_LINKED_DIRECTLY); +} + +} // namespace deg +} // namespace blender diff --git a/source/blender/depsgraph/intern/builder/pipeline_view_layer.h b/source/blender/depsgraph/intern/builder/pipeline_view_layer.h new file mode 100644 index 00000000000..fbd7b98acad --- /dev/null +++ b/source/blender/depsgraph/intern/builder/pipeline_view_layer.h @@ -0,0 +1,41 @@ +/* + * 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) 2020 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup depsgraph + */ + +#pragma once + +#include "pipeline.h" + +namespace blender { +namespace deg { + +class ViewLayerBuilderPipeline : public AbstractBuilderPipeline { + public: + ViewLayerBuilderPipeline(::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer); + + protected: + virtual void build_nodes(DepsgraphNodeBuilder &node_builder) override; + virtual void build_relations(DepsgraphRelationBuilder &relation_builder) override; +}; + +} // namespace deg +} // namespace blender 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 458baf4fb1e..d0356f44022 100644 --- a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc +++ b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc @@ -25,6 +25,7 @@ #include <cstdarg> +#include "BLI_dot_export.hh" #include "BLI_utildefines.h" #include "DNA_listBase.h" @@ -41,6 +42,7 @@ #include "intern/node/deg_node_time.h" namespace deg = blender::deg; +namespace dot = blender::dot; /* ****************** */ /* Graphviz Debugging */ @@ -48,8 +50,6 @@ namespace deg = blender::deg; namespace blender { namespace deg { -#define NL "\r\n" - /* Only one should be enabled, defines whether graphviz nodes * get colored by individual types or classes. */ @@ -158,47 +158,43 @@ static int deg_debug_node_color_index(const Node *node) #endif } -struct DebugContext { - FILE *file; +struct DotExportContext { bool show_tags; + dot::DirectedGraph &digraph; + Map<const Node *, dot::Node *> nodes_map; + Map<const Node *, dot::Cluster *> clusters_map; }; -static void deg_debug_fprintf(const DebugContext &ctx, const char *fmt, ...) - ATTR_PRINTF_FORMAT(2, 3); -static void deg_debug_fprintf(const DebugContext &ctx, const char *fmt, ...) +static void deg_debug_graphviz_legend_color(const char *name, + const char *color, + std::stringstream &ss) { - va_list args; - va_start(args, fmt); - vfprintf(ctx.file, fmt, args); - va_end(args); -} -static void deg_debug_graphviz_legend_color(const DebugContext &ctx, - const char *name, - const char *color) -{ - deg_debug_fprintf(ctx, "<TR>"); - deg_debug_fprintf(ctx, "<TD>%s</TD>", name); - deg_debug_fprintf(ctx, "<TD BGCOLOR=\"%s\"></TD>", color); - deg_debug_fprintf(ctx, "</TR>" NL); + ss << "<TR>"; + ss << "<TD>" << name << "</TD>"; + ss << "<TD BGCOLOR=\"" << color << "\"></TD>"; + ss << "</TR>"; } -static void deg_debug_graphviz_legend(const DebugContext &ctx) +static void deg_debug_graphviz_legend(DotExportContext &ctx) { - deg_debug_fprintf(ctx, "{" NL); - deg_debug_fprintf(ctx, "rank = sink;" NL); - deg_debug_fprintf(ctx, "Legend [shape=none, margin=0, label=<" NL); - deg_debug_fprintf( - ctx, " <TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"4\">" NL); - deg_debug_fprintf(ctx, "<TR><TD COLSPAN=\"2\"><B>Legend</B></TD></TR>" NL); + dot::Node &legend_node = ctx.digraph.new_node(""); + legend_node.attributes.set("rank", "sink"); + legend_node.attributes.set("shape", "none"); + legend_node.attributes.set("margin", 0); + + std::stringstream ss; + ss << "<"; + ss << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"4\">"; + ss << "<TR><TD COLSPAN=\"2\"><B>Legend</B></TD></TR>"; #ifdef COLOR_SCHEME_NODE_CLASS const char **colors = deg_debug_colors_light; - deg_debug_graphviz_legend_color(ctx, "Operation", colors[4]); - deg_debug_graphviz_legend_color(ctx, "Component", colors[1]); - deg_debug_graphviz_legend_color(ctx, "ID Node", colors[5]); - deg_debug_graphviz_legend_color(ctx, "NOOP", colors[8]); - deg_debug_graphviz_legend_color(ctx, "Pinned OP", colors[7]); + deg_debug_graphviz_legend_color("Operation", colors[4], ss); + deg_debug_graphviz_legend_color("Component", colors[1], ss); + deg_debug_graphviz_legend_color("ID Node", colors[5], ss); + deg_debug_graphviz_legend_color("NOOP", colors[8], ss); + deg_debug_graphviz_legend_color("Pinned OP", colors[7], ss); #endif #ifdef COLOR_SCHEME_NODE_TYPE @@ -206,18 +202,19 @@ static void deg_debug_graphviz_legend(const DebugContext &ctx) for (pair = deg_debug_node_type_color_map; (*pair)[0] >= 0; pair++) { DepsNodeFactory *nti = type_get_factory((NodeType)(*pair)[0]); deg_debug_graphviz_legend_color( - ctx, nti->tname().c_str(), deg_debug_colors_light[(*pair)[1] % deg_debug_max_colors]); + ctx, nti->tname().c_str(), deg_debug_colors_light[(*pair)[1] % deg_debug_max_colors], ss); } #endif - deg_debug_fprintf(ctx, "</TABLE>" NL); - deg_debug_fprintf(ctx, ">" NL); - deg_debug_fprintf(ctx, ",fontname=\"%s\"", deg_debug_graphviz_fontname); - deg_debug_fprintf(ctx, "];" NL); - deg_debug_fprintf(ctx, "}" NL); + ss << "</TABLE>"; + ss << ">"; + legend_node.attributes.set("label", ss.str()); + legend_node.attributes.set("fontname", deg_debug_graphviz_fontname); } -static void deg_debug_graphviz_node_color(const DebugContext &ctx, const Node *node) +static void deg_debug_graphviz_node_color(DotExportContext &ctx, + const Node *node, + dot::Attributes &dot_attributes) { const char *color_default = "black"; const char *color_modified = "orangered4"; @@ -234,10 +231,12 @@ static void deg_debug_graphviz_node_color(const DebugContext &ctx, const Node *n } } } - deg_debug_fprintf(ctx, "\"%s\"", color); + dot_attributes.set("color", color); } -static void deg_debug_graphviz_node_penwidth(const DebugContext &ctx, const Node *node) +static void deg_debug_graphviz_node_penwidth(DotExportContext &ctx, + const Node *node, + dot::Attributes &dot_attributes) { float penwidth_default = 1.0f; float penwidth_modified = 4.0f; @@ -254,20 +253,20 @@ static void deg_debug_graphviz_node_penwidth(const DebugContext &ctx, const Node } } } - deg_debug_fprintf(ctx, "\"%f\"", penwidth); + dot_attributes.set("penwidth", penwidth); } -static void deg_debug_graphviz_node_fillcolor(const DebugContext &ctx, const Node *node) +static void deg_debug_graphviz_node_fillcolor(const Node *node, dot::Attributes &dot_attributes) { const char *defaultcolor = "gainsboro"; int color_index = deg_debug_node_color_index(node); const char *fillcolor = color_index < 0 ? defaultcolor : deg_debug_colors_light[color_index % deg_debug_max_colors]; - deg_debug_fprintf(ctx, "\"%s\"", fillcolor); + dot_attributes.set("fillcolor", fillcolor); } -static void deg_debug_graphviz_relation_color(const DebugContext &ctx, const Relation *rel) +static void deg_debug_graphviz_relation_color(const Relation *rel, dot::DirectedEdge &edge) { const char *color_default = "black"; const char *color_cyclic = "red4"; /* The color of crime scene. */ @@ -279,10 +278,10 @@ static void deg_debug_graphviz_relation_color(const DebugContext &ctx, const Rel else if (rel->flag & RELATION_FLAG_GODMODE) { color = color_godmode; } - deg_debug_fprintf(ctx, "%s", color); + edge.attributes.set("color", color); } -static void deg_debug_graphviz_relation_style(const DebugContext &ctx, const Relation *rel) +static void deg_debug_graphviz_relation_style(const Relation *rel, dot::DirectedEdge &edge) { const char *style_default = "solid"; const char *style_no_flush = "dashed"; @@ -294,10 +293,10 @@ static void deg_debug_graphviz_relation_style(const DebugContext &ctx, const Rel if (rel->flag & RELATION_FLAG_FLUSH_USER_EDIT_ONLY) { style = style_flush_user_only; } - deg_debug_fprintf(ctx, "%s", style); + edge.attributes.set("style", style); } -static void deg_debug_graphviz_relation_arrowhead(const DebugContext &ctx, const Relation *rel) +static void deg_debug_graphviz_relation_arrowhead(const Relation *rel, dot::DirectedEdge &edge) { const char *shape_default = "normal"; const char *shape_no_cow = "box"; @@ -311,12 +310,14 @@ static void deg_debug_graphviz_relation_arrowhead(const DebugContext &ctx, const shape = shape_no_cow; } } - deg_debug_fprintf(ctx, "%s", shape); + edge.attributes.set("arrowhead", shape); } -static void deg_debug_graphviz_node_style(const DebugContext &ctx, const Node *node) +static void deg_debug_graphviz_node_style(DotExportContext &ctx, + const Node *node, + dot::Attributes &dot_attributes) { - const char *base_style = "filled"; /* default style */ + StringRef base_style = "filled"; /* default style */ if (ctx.show_tags) { if (node->get_class() == NodeClass::OPERATION) { OperationNode *op_node = (OperationNode *)node; @@ -327,95 +328,78 @@ static void deg_debug_graphviz_node_style(const DebugContext &ctx, const Node *n } switch (node->get_class()) { case NodeClass::GENERIC: - deg_debug_fprintf(ctx, "\"%s\"", base_style); + dot_attributes.set("style", base_style); break; case NodeClass::COMPONENT: - deg_debug_fprintf(ctx, "\"%s\"", base_style); + dot_attributes.set("style", base_style); break; case NodeClass::OPERATION: - deg_debug_fprintf(ctx, "\"%s,rounded\"", base_style); + dot_attributes.set("style", base_style + ",rounded"); break; } } -static void deg_debug_graphviz_node_single(const DebugContext &ctx, const Node *node) +static void deg_debug_graphviz_node_single(DotExportContext &ctx, + const Node *node, + dot::Cluster *parent_cluster) { - const char *shape = "box"; string name = node->identifier(); - deg_debug_fprintf(ctx, "// %s\n", name.c_str()); - deg_debug_fprintf(ctx, "\"node_%p\"", node); - deg_debug_fprintf(ctx, "["); - // deg_debug_fprintf(ctx, "label=<<B>%s</B>>", name); - deg_debug_fprintf(ctx, "label=<%s>", name.c_str()); - deg_debug_fprintf(ctx, ",fontname=\"%s\"", deg_debug_graphviz_fontname); - deg_debug_fprintf(ctx, ",fontsize=%f", deg_debug_graphviz_node_label_size); - deg_debug_fprintf(ctx, ",shape=%s", shape); - deg_debug_fprintf(ctx, ",style="); - deg_debug_graphviz_node_style(ctx, node); - deg_debug_fprintf(ctx, ",color="); - deg_debug_graphviz_node_color(ctx, node); - deg_debug_fprintf(ctx, ",fillcolor="); - deg_debug_graphviz_node_fillcolor(ctx, node); - deg_debug_fprintf(ctx, ",penwidth="); - deg_debug_graphviz_node_penwidth(ctx, node); - deg_debug_fprintf(ctx, "];" NL); - deg_debug_fprintf(ctx, NL); + + dot::Node &dot_node = ctx.digraph.new_node(name); + ctx.nodes_map.add_new(node, &dot_node); + dot_node.set_parent_cluster(parent_cluster); + dot_node.attributes.set("fontname", deg_debug_graphviz_fontname); + dot_node.attributes.set("frontsize", deg_debug_graphviz_node_label_size); + dot_node.attributes.set("shape", "box"); + + deg_debug_graphviz_node_style(ctx, node, dot_node.attributes); + deg_debug_graphviz_node_color(ctx, node, dot_node.attributes); + deg_debug_graphviz_node_fillcolor(node, dot_node.attributes); + deg_debug_graphviz_node_penwidth(ctx, node, dot_node.attributes); } -static void deg_debug_graphviz_node_cluster_begin(const DebugContext &ctx, const Node *node) +static dot::Cluster °_debug_graphviz_node_cluster_create(DotExportContext &ctx, + const Node *node, + dot::Cluster *parent_cluster) { string name = node->identifier(); - deg_debug_fprintf(ctx, "// %s\n", name.c_str()); - deg_debug_fprintf(ctx, "subgraph \"cluster_%p\" {" NL, node); - // deg_debug_fprintf(ctx, "label=<<B>%s</B>>;" NL, name); - deg_debug_fprintf(ctx, "label=<%s>;" NL, name.c_str()); - deg_debug_fprintf(ctx, "fontname=\"%s\";" NL, deg_debug_graphviz_fontname); - deg_debug_fprintf(ctx, "fontsize=%f;" NL, deg_debug_graphviz_node_label_size); - deg_debug_fprintf(ctx, "margin=\"%d\";" NL, 16); - deg_debug_fprintf(ctx, "style="); - deg_debug_graphviz_node_style(ctx, node); - deg_debug_fprintf(ctx, ";" NL); - deg_debug_fprintf(ctx, "color="); - deg_debug_graphviz_node_color(ctx, node); - deg_debug_fprintf(ctx, ";" NL); - deg_debug_fprintf(ctx, "fillcolor="); - deg_debug_graphviz_node_fillcolor(ctx, node); - deg_debug_fprintf(ctx, ";" NL); - deg_debug_fprintf(ctx, "penwidth="); - deg_debug_graphviz_node_penwidth(ctx, node); - deg_debug_fprintf(ctx, ";" NL); + dot::Cluster &cluster = ctx.digraph.new_cluster(name); + cluster.set_parent_cluster(parent_cluster); + cluster.attributes.set("fontname", deg_debug_graphviz_fontname); + cluster.attributes.set("fontsize", deg_debug_graphviz_node_label_size); + cluster.attributes.set("margin", 16); + deg_debug_graphviz_node_style(ctx, node, cluster.attributes); + deg_debug_graphviz_node_color(ctx, node, cluster.attributes); + deg_debug_graphviz_node_fillcolor(node, cluster.attributes); + deg_debug_graphviz_node_penwidth(ctx, node, cluster.attributes); /* dummy node, so we can add edges between clusters */ - deg_debug_fprintf(ctx, "\"node_%p\"", node); - deg_debug_fprintf(ctx, "["); - deg_debug_fprintf(ctx, "shape=%s", "point"); - deg_debug_fprintf(ctx, ",style=%s", "invis"); - deg_debug_fprintf(ctx, "];" NL); - deg_debug_fprintf(ctx, NL); + dot::Node &dot_node = ctx.digraph.new_node(""); + dot_node.attributes.set("shape", "point"); + dot_node.attributes.set("style", "invis"); + dot_node.set_parent_cluster(&cluster); + ctx.nodes_map.add_new(node, &dot_node); + ctx.clusters_map.add_new(node, &cluster); + return cluster; } -static void deg_debug_graphviz_node_cluster_end(const DebugContext &ctx) -{ - deg_debug_fprintf(ctx, "}" NL); - deg_debug_fprintf(ctx, NL); -} +static void deg_debug_graphviz_graph_nodes(DotExportContext &ctx, const Depsgraph *graph); +static void deg_debug_graphviz_graph_relations(DotExportContext &ctx, const Depsgraph *graph); -static void deg_debug_graphviz_graph_nodes(const DebugContext &ctx, const Depsgraph *graph); -static void deg_debug_graphviz_graph_relations(const DebugContext &ctx, const Depsgraph *graph); - -static void deg_debug_graphviz_node(const DebugContext &ctx, const Node *node) +static void deg_debug_graphviz_node(DotExportContext &ctx, + const Node *node, + dot::Cluster *parent_cluster) { switch (node->type) { case NodeType::ID_REF: { const IDNode *id_node = (const IDNode *)node; if (id_node->components.is_empty()) { - deg_debug_graphviz_node_single(ctx, node); + deg_debug_graphviz_node_single(ctx, node, parent_cluster); } else { - deg_debug_graphviz_node_cluster_begin(ctx, node); + dot::Cluster &cluster = deg_debug_graphviz_node_cluster_create(ctx, node, parent_cluster); for (const ComponentNode *comp : id_node->components.values()) { - deg_debug_graphviz_node(ctx, comp); + deg_debug_graphviz_node(ctx, comp, &cluster); } - deg_debug_graphviz_node_cluster_end(ctx); } break; } @@ -445,127 +429,72 @@ static void deg_debug_graphviz_node(const DebugContext &ctx, const Node *node) case NodeType::GENERIC_DATABLOCK: case NodeType::SIMULATION: { ComponentNode *comp_node = (ComponentNode *)node; - if (!comp_node->operations.is_empty()) { - deg_debug_graphviz_node_cluster_begin(ctx, node); - for (Node *op_node : comp_node->operations) { - deg_debug_graphviz_node(ctx, op_node); - } - deg_debug_graphviz_node_cluster_end(ctx); + if (comp_node->operations.is_empty()) { + deg_debug_graphviz_node_single(ctx, node, parent_cluster); } else { - deg_debug_graphviz_node_single(ctx, node); + dot::Cluster &cluster = deg_debug_graphviz_node_cluster_create(ctx, node, parent_cluster); + for (Node *op_node : comp_node->operations) { + deg_debug_graphviz_node(ctx, op_node, &cluster); + } } break; } case NodeType::UNDEFINED: case NodeType::TIMESOURCE: case NodeType::OPERATION: - deg_debug_graphviz_node_single(ctx, node); + deg_debug_graphviz_node_single(ctx, node, parent_cluster); break; case NodeType::NUM_TYPES: break; } } -static bool deg_debug_graphviz_is_cluster(const Node *node) -{ - switch (node->type) { - case NodeType::ID_REF: { - const IDNode *id_node = (const IDNode *)node; - return !id_node->components.is_empty(); - } - case NodeType::PARAMETERS: - case NodeType::ANIMATION: - case NodeType::TRANSFORM: - case NodeType::PROXY: - case NodeType::GEOMETRY: - case NodeType::SEQUENCER: - case NodeType::EVAL_POSE: - case NodeType::BONE: { - ComponentNode *comp_node = (ComponentNode *)node; - return !comp_node->operations.is_empty(); - } - default: - return false; - } -} - -static bool deg_debug_graphviz_is_owner(const Node *node, const Node *other) -{ - switch (node->get_class()) { - case NodeClass::COMPONENT: { - ComponentNode *comp_node = (ComponentNode *)node; - if (comp_node->owner == other) { - return true; - } - break; - } - case NodeClass::OPERATION: { - OperationNode *op_node = (OperationNode *)node; - if (op_node->owner == other) { - return true; - } - else if (op_node->owner->owner == other) { - return true; - } - break; - } - default: - break; - } - return false; -} - -static void deg_debug_graphviz_node_relations(const DebugContext &ctx, const Node *node) +static void deg_debug_graphviz_node_relations(DotExportContext &ctx, const Node *node) { for (Relation *rel : node->inlinks) { float penwidth = 2.0f; - const Node *tail = rel->to; /* same as node */ - const Node *head = rel->from; - deg_debug_fprintf( - ctx, "// %s -> %s\n", head->identifier().c_str(), tail->identifier().c_str()); - deg_debug_fprintf(ctx, "\"node_%p\"", head); - deg_debug_fprintf(ctx, " -> "); - deg_debug_fprintf(ctx, "\"node_%p\"", tail); + const Node *head = rel->to; /* same as node */ + const Node *tail = rel->from; + dot::Node &dot_tail = *ctx.nodes_map.lookup(tail); + dot::Node &dot_head = *ctx.nodes_map.lookup(head); + + dot::DirectedEdge &edge = ctx.digraph.new_edge(dot_tail, dot_head); - 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, ",color="); - deg_debug_graphviz_relation_color(ctx, rel); - deg_debug_fprintf(ctx, ",style="); - deg_debug_graphviz_relation_style(ctx, rel); - deg_debug_fprintf(ctx, ",arrowhead="); - deg_debug_graphviz_relation_arrowhead(ctx, rel); - deg_debug_fprintf(ctx, ",penwidth=\"%f\"", penwidth); + edge.attributes.set("id", rel->name); + deg_debug_graphviz_relation_color(rel, edge); + deg_debug_graphviz_relation_style(rel, edge); + deg_debug_graphviz_relation_arrowhead(rel, edge); + edge.attributes.set("penwidth", penwidth); + /* NOTE: edge from node to own cluster is not possible and gives graphviz * warning, avoid this here by just linking directly to the invisible * placeholder node. */ - if (deg_debug_graphviz_is_cluster(tail) && !deg_debug_graphviz_is_owner(head, tail)) { - deg_debug_fprintf(ctx, ",ltail=\"cluster_%p\"", tail); + dot::Cluster *tail_cluster = ctx.clusters_map.lookup_default(tail, nullptr); + if (tail_cluster != nullptr && tail_cluster->contains(dot_head)) { + edge.attributes.set("ltail", tail_cluster->name()); } - if (deg_debug_graphviz_is_cluster(head) && !deg_debug_graphviz_is_owner(tail, head)) { - deg_debug_fprintf(ctx, ",lhead=\"cluster_%p\"", head); + dot::Cluster *head_cluster = ctx.clusters_map.lookup_default(head, nullptr); + if (head_cluster != nullptr && head_cluster->contains(dot_tail)) { + edge.attributes.set("lhead", head_cluster->name()); } - deg_debug_fprintf(ctx, "];" NL); - deg_debug_fprintf(ctx, NL); } } -static void deg_debug_graphviz_graph_nodes(const DebugContext &ctx, const Depsgraph *graph) +static void deg_debug_graphviz_graph_nodes(DotExportContext &ctx, const Depsgraph *graph) { for (Node *node : graph->id_nodes) { - deg_debug_graphviz_node(ctx, node); + deg_debug_graphviz_node(ctx, node, nullptr); } TimeSourceNode *time_source = graph->find_time_source(); if (time_source != nullptr) { - deg_debug_graphviz_node(ctx, time_source); + deg_debug_graphviz_node(ctx, time_source, nullptr); } } -static void deg_debug_graphviz_graph_relations(const DebugContext &ctx, const Depsgraph *graph) +static void deg_debug_graphviz_graph_relations(DotExportContext &ctx, const Depsgraph *graph) { for (IDNode *id_node : graph->id_nodes) { for (ComponentNode *comp_node : id_node->components.values()) { @@ -592,27 +521,23 @@ void DEG_debug_relations_graphviz(const Depsgraph *graph, FILE *f, const char *l const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph); - deg::DebugContext ctx; - ctx.file = f; - - deg::deg_debug_fprintf(ctx, "digraph depgraph {" NL); - deg::deg_debug_fprintf(ctx, "rankdir=LR;" NL); - deg::deg_debug_fprintf(ctx, "graph ["); - deg::deg_debug_fprintf(ctx, "compound=true"); - deg::deg_debug_fprintf(ctx, ",labelloc=\"t\""); - deg::deg_debug_fprintf(ctx, ",fontsize=%f", deg::deg_debug_graphviz_graph_label_size); - deg::deg_debug_fprintf(ctx, ",fontname=\"%s\"", deg::deg_debug_graphviz_fontname); - deg::deg_debug_fprintf(ctx, ",label=\"%s\"", label); - deg::deg_debug_fprintf(ctx, ",splines=ortho"); - deg::deg_debug_fprintf(ctx, ",overlap=scalexy"); // XXX: only when using neato - deg::deg_debug_fprintf(ctx, "];" NL); + dot::DirectedGraph digraph; + deg::DotExportContext ctx{false, digraph}; + + digraph.set_rankdir(dot::Attr_rankdir::LeftToRight); + digraph.attributes.set("compound", "true"); + digraph.attributes.set("labelloc", "t"); + digraph.attributes.set("fontsize", deg::deg_debug_graphviz_graph_label_size); + digraph.attributes.set("fontname", deg::deg_debug_graphviz_fontname); + digraph.attributes.set("label", label); + digraph.attributes.set("splines", "ortho"); + digraph.attributes.set("overlap", "scalexy"); deg::deg_debug_graphviz_graph_nodes(ctx, deg_graph); deg::deg_debug_graphviz_graph_relations(ctx, deg_graph); deg::deg_debug_graphviz_legend(ctx); - deg::deg_debug_fprintf(ctx, "}" NL); + std::string dot_string = digraph.to_dot_string(); + fprintf(f, "%s", dot_string.c_str()); } - -#undef NL diff --git a/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc b/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc index 515b53297b9..16bdc2d6115 100644 --- a/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc +++ b/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc @@ -83,7 +83,7 @@ string gnuplotify_id_code(const string &name) string gnuplotify_name(const string &name) { - string result = ""; + string result; const int length = name.length(); for (int i = 0; i < length; i++) { const char ch = name[i]; diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index c11d051e663..fb933cb38f3 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -43,12 +43,11 @@ #include "DEG_depsgraph_build.h" #include "DEG_depsgraph_debug.h" -#include "builder/deg_builder.h" -#include "builder/deg_builder_cache.h" -#include "builder/deg_builder_cycle.h" -#include "builder/deg_builder_nodes.h" #include "builder/deg_builder_relations.h" -#include "builder/deg_builder_transitive.h" +#include "builder/pipeline_compositor.h" +#include "builder/pipeline_from_ids.h" +#include "builder/pipeline_render.h" +#include "builder/pipeline_view_layer.h" #include "intern/debug/deg_debug.h" @@ -209,65 +208,14 @@ struct Depsgraph *DEG_get_graph_from_handle(struct DepsNodeHandle *node_handle) /* ******************** */ /* Graph Building API's */ -static void graph_build_finalize_common(deg::Depsgraph *deg_graph, Main *bmain) -{ - /* Detect and solve cycles. */ - deg::deg_graph_detect_cycles(deg_graph); - /* Simplify the graph by removing redundant relations (to optimize - * traversal later). */ - /* TODO: it would be useful to have an option to disable this in cases where - * it is causing trouble. */ - if (G.debug_value == 799) { - deg::deg_graph_transitive_reduction(deg_graph); - } - /* Store pointers to commonly used valuated datablocks. */ - deg_graph->scene_cow = (Scene *)deg_graph->get_cow_id(°_graph->scene->id); - /* Flush visibility layer and re-schedule nodes for update. */ - deg::deg_graph_build_finalize(bmain, deg_graph); - DEG_graph_on_visible_update(bmain, reinterpret_cast<::Depsgraph *>(deg_graph), false); -#if 0 - if (!DEG_debug_consistency_check(deg_graph)) { - printf("Consistency validation failed, ABORTING!\n"); - abort(); - } -#endif - /* Relations are up to date. */ - deg_graph->need_update = false; -} - /* Build depsgraph for the given scene layer, and dump results in given graph container. */ void DEG_graph_build_from_view_layer(Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer) { - double start_time = 0.0; - if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) { - start_time = PIL_check_seconds_timer(); - } - deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph); - /* Perform sanity checks. */ - BLI_assert(BLI_findindex(&scene->view_layers, view_layer) != -1); - BLI_assert(deg_graph->scene == scene); - BLI_assert(deg_graph->view_layer == view_layer); - deg::DepsgraphBuilderCache builder_cache; - /* Generate all the nodes in the graph first */ - deg::DepsgraphNodeBuilder node_builder(bmain, deg_graph, &builder_cache); - node_builder.begin_build(); - node_builder.build_view_layer(scene, view_layer, deg::DEG_ID_LINKED_DIRECTLY); - node_builder.end_build(); - /* Hook up relationships between operations - to determine evaluation order. */ - deg::DepsgraphRelationBuilder relation_builder(bmain, deg_graph, &builder_cache); - relation_builder.begin_build(); - relation_builder.build_view_layer(scene, view_layer, deg::DEG_ID_LINKED_DIRECTLY); - relation_builder.build_copy_on_write_relations(); - relation_builder.build_driver_relations(); - /* Finalize building. */ - graph_build_finalize_common(deg_graph, bmain); - /* Finish statistics. */ - if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) { - printf("Depsgraph built in %f seconds.\n", PIL_check_seconds_timer() - start_time); - } + deg::ViewLayerBuilderPipeline builder(graph, bmain, scene, view_layer); + builder.build(); } void DEG_graph_build_for_render_pipeline(Depsgraph *graph, @@ -275,170 +223,17 @@ void DEG_graph_build_for_render_pipeline(Depsgraph *graph, Scene *scene, ViewLayer *view_layer) { - double start_time = 0.0; - if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) { - start_time = PIL_check_seconds_timer(); - } - deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph); - /* Perform sanity checks. */ - BLI_assert(deg_graph->scene == scene); - deg_graph->is_render_pipeline_depsgraph = true; - deg::DepsgraphBuilderCache builder_cache; - /* Generate all the nodes in the graph first */ - deg::DepsgraphNodeBuilder node_builder(bmain, deg_graph, &builder_cache); - node_builder.begin_build(); - node_builder.build_scene_render(scene, view_layer); - node_builder.end_build(); - /* Hook up relationships between operations - to determine evaluation - * order. */ - deg::DepsgraphRelationBuilder relation_builder(bmain, deg_graph, &builder_cache); - relation_builder.begin_build(); - relation_builder.build_scene_render(scene, view_layer); - relation_builder.build_copy_on_write_relations(); - relation_builder.build_driver_relations(); - /* Finalize building. */ - graph_build_finalize_common(deg_graph, bmain); - /* Finish statistics. */ - if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) { - printf("Depsgraph built in %f seconds.\n", PIL_check_seconds_timer() - start_time); - } + deg::RenderBuilderPipeline builder(graph, bmain, scene, view_layer); + builder.build(); } void DEG_graph_build_for_compositor_preview( Depsgraph *graph, Main *bmain, Scene *scene, struct ViewLayer *view_layer, bNodeTree *nodetree) { - double start_time = 0.0; - if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) { - start_time = PIL_check_seconds_timer(); - } - deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph); - /* Perform sanity checks. */ - BLI_assert(deg_graph->scene == scene); - deg_graph->is_render_pipeline_depsgraph = true; - deg::DepsgraphBuilderCache builder_cache; - /* Generate all the nodes in the graph first */ - deg::DepsgraphNodeBuilder node_builder(bmain, deg_graph, &builder_cache); - node_builder.begin_build(); - node_builder.build_scene_render(scene, view_layer); - node_builder.build_nodetree(nodetree); - node_builder.end_build(); - /* Hook up relationships between operations - to determine evaluation - * order. */ - deg::DepsgraphRelationBuilder relation_builder(bmain, deg_graph, &builder_cache); - relation_builder.begin_build(); - relation_builder.build_scene_render(scene, view_layer); - relation_builder.build_nodetree(nodetree); - relation_builder.build_copy_on_write_relations(); - relation_builder.build_driver_relations(); - /* Finalize building. */ - graph_build_finalize_common(deg_graph, bmain); - /* Finish statistics. */ - if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) { - printf("Depsgraph built in %f seconds.\n", PIL_check_seconds_timer() - start_time); - } + deg::CompositorBuilderPipeline builder(graph, bmain, scene, view_layer, nodetree); + builder.build(); } -/* Optimized builders for dependency graph built from a given set of IDs. - * - * General notes: - * - * - We pull in all bases if their objects are in the set of IDs. This allows to have proper - * visibility and other flags assigned to the objects. - * All other bases (the ones which points to object which is outside of the set of IDs) are - * completely ignored. - * - * - Proxy groups pointing to objects which are outside of the IDs set are also ignored. - * This way we avoid high-poly character body pulled into the dependency graph when it's coming - * from a library into an animation file and the dependency graph constructed for a proxy rig. */ - -namespace blender { -namespace deg { -namespace { - -class DepsgraphFromIDsFilter { - public: - DepsgraphFromIDsFilter(ID **ids, const int num_ids) - { - for (int i = 0; i < num_ids; ++i) { - ids_.add(ids[i]); - } - } - - bool contains(ID *id) - { - return ids_.contains(id); - } - - protected: - Set<ID *> ids_; -}; - -class DepsgraphFromIDsNodeBuilder : public DepsgraphNodeBuilder { - public: - DepsgraphFromIDsNodeBuilder( - Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache, ID **ids, const int num_ids) - : DepsgraphNodeBuilder(bmain, graph, cache), filter_(ids, num_ids) - { - } - - virtual bool need_pull_base_into_graph(Base *base) override - { - if (!filter_.contains(&base->object->id)) { - return false; - } - return DepsgraphNodeBuilder::need_pull_base_into_graph(base); - } - - virtual void build_object_proxy_group(Object *object, bool is_visible) override - { - if (object->proxy_group == nullptr) { - return; - } - if (!filter_.contains(&object->proxy_group->id)) { - return; - } - DepsgraphNodeBuilder::build_object_proxy_group(object, is_visible); - } - - protected: - DepsgraphFromIDsFilter filter_; -}; - -class DepsgraphFromIDsRelationBuilder : public DepsgraphRelationBuilder { - public: - DepsgraphFromIDsRelationBuilder( - Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache, ID **ids, const int num_ids) - : DepsgraphRelationBuilder(bmain, graph, cache), filter_(ids, num_ids) - { - } - - virtual bool need_pull_base_into_graph(Base *base) override - { - if (!filter_.contains(&base->object->id)) { - return false; - } - return DepsgraphRelationBuilder::need_pull_base_into_graph(base); - } - - virtual void build_object_proxy_group(Object *object) override - { - if (object->proxy_group == nullptr) { - return; - } - if (!filter_.contains(&object->proxy_group->id)) { - return; - } - DepsgraphRelationBuilder::build_object_proxy_group(object); - } - - protected: - DepsgraphFromIDsFilter filter_; -}; - -} // namespace -} // namespace deg -} // namespace blender - void DEG_graph_build_from_ids(Depsgraph *graph, Main *bmain, Scene *scene, @@ -446,40 +241,8 @@ void DEG_graph_build_from_ids(Depsgraph *graph, ID **ids, const int num_ids) { - double start_time = 0.0; - if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) { - start_time = PIL_check_seconds_timer(); - } - deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph); - /* Perform sanity checks. */ - BLI_assert(BLI_findindex(&scene->view_layers, view_layer) != -1); - BLI_assert(deg_graph->scene == scene); - BLI_assert(deg_graph->view_layer == view_layer); - deg::DepsgraphBuilderCache builder_cache; - /* Generate all the nodes in the graph first */ - deg::DepsgraphFromIDsNodeBuilder node_builder(bmain, deg_graph, &builder_cache, ids, num_ids); - node_builder.begin_build(); - node_builder.build_view_layer(scene, view_layer, deg::DEG_ID_LINKED_DIRECTLY); - for (int i = 0; i < num_ids; ++i) { - node_builder.build_id(ids[i]); - } - node_builder.end_build(); - /* Hook up relationships between operations - to determine evaluation order. */ - deg::DepsgraphFromIDsRelationBuilder relation_builder( - bmain, deg_graph, &builder_cache, ids, num_ids); - relation_builder.begin_build(); - relation_builder.build_view_layer(scene, view_layer, deg::DEG_ID_LINKED_DIRECTLY); - for (int i = 0; i < num_ids; ++i) { - relation_builder.build_id(ids[i]); - } - relation_builder.build_copy_on_write_relations(); - relation_builder.build_driver_relations(); - /* Finalize building. */ - graph_build_finalize_common(deg_graph, bmain); - /* Finish statistics. */ - if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) { - printf("Depsgraph built in %f seconds.\n", PIL_check_seconds_timer() - start_time); - } + deg::FromIDsBuilderPipeline builder(graph, bmain, scene, view_layer, ids, num_ids); + builder.build(); } /* Tag graph relations for update. */ diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc index 814f467e3d5..048c0125f53 100644 --- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc +++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc @@ -282,15 +282,14 @@ void DEG_iterator_objects_next(BLI_Iterator *iter) if (deg_objects_dupli_iterator_next(iter)) { return; } - else { - verify_id_properties_freed(data); - free_object_duplilist(data->dupli_list); - data->dupli_parent = nullptr; - data->dupli_list = nullptr; - data->dupli_object_next = nullptr; - data->dupli_object_current = nullptr; - deg_invalidate_iterator_work_data(data); - } + + verify_id_properties_freed(data); + free_object_duplilist(data->dupli_list); + data->dupli_parent = nullptr; + data->dupli_list = nullptr; + data->dupli_object_next = nullptr; + data->dupli_object_current = nullptr; + deg_invalidate_iterator_work_data(data); } ++data->id_node_index; @@ -324,7 +323,7 @@ static void DEG_iterator_ids_step(BLI_Iterator *iter, deg::IDNode *id_node, bool iter->skip = true; return; } - else if (only_updated && !(id_cow->recalc & ID_RECALC_ALL)) { + if (only_updated && !(id_cow->recalc & ID_RECALC_ALL)) { bNodeTree *ntree = ntreeFromID(id_cow); /* Nodetree is considered part of the datablock. */ diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index 848275eb899..4a2d47f9379 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -48,11 +48,8 @@ #include "BKE_idtype.h" #include "BKE_node.h" #include "BKE_scene.h" -#include "BKE_workspace.h" - -#define new new_ #include "BKE_screen.h" -#undef new +#include "BKE_workspace.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_debug.h" @@ -375,7 +372,7 @@ void graph_id_tag_update_single_flag(Main *bmain, } return; } - else if (tag == ID_RECALC_TIME) { + if (tag == ID_RECALC_TIME) { if (graph != nullptr) { graph->need_update_time = true; } @@ -432,7 +429,7 @@ string stringify_update_bitfield(int flag) if (flag == 0) { return "LEGACY_0"; } - string result = ""; + string result; int current_flag = flag; /* Special cases to avoid ALL flags form being split into * individual bits. */ @@ -786,6 +783,7 @@ void DEG_graph_id_type_tag(Depsgraph *depsgraph, short id_type) DEG_graph_id_type_tag(depsgraph, ID_LA); DEG_graph_id_type_tag(depsgraph, ID_WO); DEG_graph_id_type_tag(depsgraph, ID_SCE); + DEG_graph_id_type_tag(depsgraph, ID_SIM); } const int id_type_index = BKE_idtype_idcode_to_index(id_type); deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph); diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index 6ca30a67f1f..1ede2cf914a 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -353,9 +353,8 @@ static TaskPool *deg_evaluate_task_pool_create(DepsgraphEvalState *state) if (G.debug & G_DEBUG_DEPSGRAPH_NO_THREADS) { return BLI_task_pool_create_no_threads(state); } - else { - return BLI_task_pool_create_suspended(state, TASK_PRIORITY_HIGH); - } + + return BLI_task_pool_create_suspended(state, TASK_PRIORITY_HIGH); } /** 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 c1e1ed3036d..d76f5991dac 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 @@ -120,6 +120,7 @@ union NestedIDHackTempStorage { Scene scene; Tex tex; World world; + Simulation simulation; }; /* Set nested owned ID pointers to nullptr. */ @@ -137,6 +138,7 @@ void nested_id_hack_discard_pointers(ID *id_cow) SPECIAL_CASE(ID_MA, Material, nodetree) SPECIAL_CASE(ID_TE, Tex, nodetree) SPECIAL_CASE(ID_WO, World, nodetree) + SPECIAL_CASE(ID_SIM, Simulation, nodetree) SPECIAL_CASE(ID_CU, Curve, key) SPECIAL_CASE(ID_LT, Lattice, key) @@ -185,6 +187,7 @@ const ID *nested_id_hack_get_discarded_pointers(NestedIDHackTempStorage *storage SPECIAL_CASE(ID_MA, Material, nodetree, material) SPECIAL_CASE(ID_TE, Tex, nodetree, tex) SPECIAL_CASE(ID_WO, World, nodetree, world) + SPECIAL_CASE(ID_SIM, Simulation, nodetree, simulation) SPECIAL_CASE(ID_CU, Curve, key, curve) SPECIAL_CASE(ID_LT, Lattice, key, lattice) @@ -224,6 +227,7 @@ void nested_id_hack_restore_pointers(const ID *old_id, ID *new_id) SPECIAL_CASE(ID_SCE, Scene, nodetree) SPECIAL_CASE(ID_TE, Tex, nodetree) SPECIAL_CASE(ID_WO, World, nodetree) + SPECIAL_CASE(ID_SIM, Simulation, nodetree) SPECIAL_CASE(ID_CU, Curve, key) SPECIAL_CASE(ID_LT, Lattice, key) @@ -261,6 +265,7 @@ void ntree_hack_remap_pointers(const Depsgraph *depsgraph, ID *id_cow) SPECIAL_CASE(ID_SCE, Scene, nodetree, bNodeTree) SPECIAL_CASE(ID_TE, Tex, nodetree, bNodeTree) SPECIAL_CASE(ID_WO, World, nodetree, bNodeTree) + SPECIAL_CASE(ID_SIM, Simulation, nodetree, bNodeTree) SPECIAL_CASE(ID_CU, Curve, key, Key) SPECIAL_CASE(ID_LT, Lattice, key, Key) @@ -343,7 +348,7 @@ ViewLayer *get_original_view_layer(const Depsgraph *depsgraph, const IDNode *id_ if (id_node->linked_state == DEG_ID_LINKED_DIRECTLY) { return depsgraph->view_layer; } - else if (id_node->linked_state == DEG_ID_LINKED_VIA_SET) { + if (id_node->linked_state == DEG_ID_LINKED_VIA_SET) { Scene *scene_orig = reinterpret_cast<Scene *>(id_node->id_orig); return BKE_view_layer_default_render(scene_orig); } @@ -377,7 +382,7 @@ void scene_remove_unused_view_layers(const Depsgraph *depsgraph, } return; } - else if (id_node->linked_state == DEG_ID_LINKED_INDIRECTLY) { + if (id_node->linked_state == DEG_ID_LINKED_INDIRECTLY) { /* Indirectly linked scenes means it's not an input scene and not a set scene, and is pulled * via some driver. Such scenes should not have view layers after copy. */ view_layer_input = nullptr; diff --git a/source/blender/depsgraph/intern/node/deg_node.cc b/source/blender/depsgraph/intern/node/deg_node.cc index 9e386f13888..b10e66336dc 100644 --- a/source/blender/depsgraph/intern/node/deg_node.cc +++ b/source/blender/depsgraph/intern/node/deg_node.cc @@ -317,12 +317,11 @@ NodeClass Node::get_class() const if (type == NodeType::OPERATION) { return NodeClass::OPERATION; } - else if (type < NodeType::PARAMETERS) { + if (type < NodeType::PARAMETERS) { return NodeClass::GENERIC; } - else { - return NodeClass::COMPONENT; - } + + return NodeClass::COMPONENT; } /******************************************************************************* diff --git a/source/blender/depsgraph/intern/node/deg_node_component.cc b/source/blender/depsgraph/intern/node/deg_node_component.cc index cd82b7be050..2767513d6df 100644 --- a/source/blender/depsgraph/intern/node/deg_node_component.cc +++ b/source/blender/depsgraph/intern/node/deg_node_component.cc @@ -251,7 +251,7 @@ OperationNode *ComponentNode::get_entry_operation() if (entry_operation) { return entry_operation; } - else if (operations_map != nullptr && operations_map->size() == 1) { + if (operations_map != nullptr && operations_map->size() == 1) { OperationNode *op_node = nullptr; /* TODO(sergey): This is somewhat slow. */ for (OperationNode *tmp : operations_map->values()) { @@ -261,7 +261,7 @@ OperationNode *ComponentNode::get_entry_operation() entry_operation = op_node; return op_node; } - else if (operations.size() == 1) { + if (operations.size() == 1) { return operations[0]; } return nullptr; @@ -272,7 +272,7 @@ OperationNode *ComponentNode::get_exit_operation() if (exit_operation) { return exit_operation; } - else if (operations_map != nullptr && operations_map->size() == 1) { + if (operations_map != nullptr && operations_map->size() == 1) { OperationNode *op_node = nullptr; /* TODO(sergey): This is somewhat slow. */ for (OperationNode *tmp : operations_map->values()) { @@ -282,7 +282,7 @@ OperationNode *ComponentNode::get_exit_operation() exit_operation = op_node; return op_node; } - else if (operations.size() == 1) { + if (operations.size() == 1) { return operations[0]; } return nullptr; diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index cfcd4e0c65a..f85b03dc517 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -64,6 +64,7 @@ set(SRC intern/draw_color_management.c intern/draw_common.c intern/draw_debug.c + intern/draw_fluid.c intern/draw_hair.c intern/draw_instance_data.c intern/draw_manager.c @@ -186,10 +187,10 @@ set(LIB ) data_to_c_simple(engines/eevee/shaders/ambient_occlusion_lib.glsl SRC) -data_to_c_simple(engines/eevee/shaders/default_frag.glsl SRC) -data_to_c_simple(engines/eevee/shaders/default_world_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/background_vert.glsl SRC) +data_to_c_simple(engines/eevee/shaders/closure_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/common_uniforms_lib.glsl SRC) +data_to_c_simple(engines/eevee/shaders/common_utiltex_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/lights_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/lightprobe_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl SRC) @@ -204,8 +205,8 @@ data_to_c_simple(engines/eevee/shaders/lightprobe_grid_display_vert.glsl SRC) data_to_c_simple(engines/eevee/shaders/lightprobe_grid_fill_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/lightprobe_planar_display_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/lightprobe_planar_display_vert.glsl SRC) -data_to_c_simple(engines/eevee/shaders/lit_surface_frag.glsl SRC) -data_to_c_simple(engines/eevee/shaders/lit_surface_vert.glsl SRC) +data_to_c_simple(engines/eevee/shaders/lookdev_world_frag.glsl SRC) +data_to_c_simple(engines/eevee/shaders/closure_lit_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_bloom_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_dof_vert.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_dof_frag.glsl SRC) @@ -229,7 +230,6 @@ data_to_c_simple(engines/eevee/shaders/object_motion_vert.glsl SRC) data_to_c_simple(engines/eevee/shaders/prepass_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/prepass_vert.glsl SRC) data_to_c_simple(engines/eevee/shaders/shadow_accum_frag.glsl SRC) - data_to_c_simple(engines/eevee/shaders/shadow_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/shadow_vert.glsl SRC) data_to_c_simple(engines/eevee/shaders/bsdf_lut_frag.glsl SRC) @@ -240,9 +240,14 @@ data_to_c_simple(engines/eevee/shaders/octahedron_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/cubemap_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/bsdf_sampling_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/raytrace_lib.glsl SRC) +data_to_c_simple(engines/eevee/shaders/renderpass_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/renderpass_postprocess_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/ltc_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/ssr_lib.glsl SRC) +data_to_c_simple(engines/eevee/shaders/surface_frag.glsl SRC) +data_to_c_simple(engines/eevee/shaders/surface_geom.glsl SRC) +data_to_c_simple(engines/eevee/shaders/surface_lib.glsl SRC) +data_to_c_simple(engines/eevee/shaders/surface_vert.glsl SRC) data_to_c_simple(engines/eevee/shaders/update_noise_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/volumetric_accum_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/volumetric_lib.glsl SRC) @@ -288,6 +293,8 @@ data_to_c_simple(intern/shaders/common_globals_lib.glsl SRC) data_to_c_simple(intern/shaders/common_pointcloud_lib.glsl SRC) data_to_c_simple(intern/shaders/common_hair_lib.glsl SRC) data_to_c_simple(intern/shaders/common_hair_refine_vert.glsl SRC) +data_to_c_simple(intern/shaders/common_math_lib.glsl SRC) +data_to_c_simple(intern/shaders/common_math_geom_lib.glsl SRC) data_to_c_simple(intern/shaders/common_view_lib.glsl SRC) data_to_c_simple(intern/shaders/common_fxaa_lib.glsl SRC) data_to_c_simple(intern/shaders/common_smaa_lib.glsl SRC) @@ -397,6 +404,13 @@ data_to_c_simple(engines/overlay/shaders/xray_fade_frag.glsl SRC) list(APPEND INC ) +if(WITH_MOD_FLUID) + list(APPEND INC + ../../../intern/mantaflow/extern + ) + add_definitions(-DWITH_FLUID) +endif() + if(WITH_FREESTYLE) add_definitions(-DWITH_FREESTYLE) endif() 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 4a3cc36ddef..1d8082538a8 100644 --- a/source/blender/draw/engines/eevee/eevee_depth_of_field.c +++ b/source/blender/draw/engines/eevee/eevee_depth_of_field.c @@ -54,24 +54,30 @@ extern char datatoc_common_view_lib_glsl[]; static void eevee_create_shader_depth_of_field(const bool use_alpha) { - char *frag = BLI_string_joinN(datatoc_common_view_lib_glsl, datatoc_effect_dof_frag_glsl); - e_data.dof_downsample_sh[use_alpha] = DRW_shader_create_fullscreen( - frag, + DRWShaderLibrary *lib = EEVEE_shader_lib_get(); + + e_data.dof_downsample_sh[use_alpha] = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_dof_frag_glsl, + lib, use_alpha ? "#define USE_ALPHA_DOF\n" "#define STEP_DOWNSAMPLE\n" : "#define STEP_DOWNSAMPLE\n"); - e_data.dof_scatter_sh[use_alpha] = DRW_shader_create(datatoc_effect_dof_vert_glsl, - NULL, - frag, - use_alpha ? "#define USE_ALPHA_DOF\n" - "#define STEP_SCATTER\n" : - "#define STEP_SCATTER\n"); - e_data.dof_resolve_sh[use_alpha] = DRW_shader_create_fullscreen(frag, - use_alpha ? - "#define USE_ALPHA_DOF\n" - "#define STEP_RESOLVE\n" : - "#define STEP_RESOLVE\n"); - MEM_freeN(frag); + + e_data.dof_scatter_sh[use_alpha] = DRW_shader_create_with_shaderlib( + datatoc_effect_dof_vert_glsl, + NULL, + datatoc_effect_dof_frag_glsl, + lib, + use_alpha ? "#define USE_ALPHA_DOF\n" + "#define STEP_SCATTER\n" : + "#define STEP_SCATTER\n"); + + e_data.dof_resolve_sh[use_alpha] = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_dof_frag_glsl, + lib, + use_alpha ? "#define USE_ALPHA_DOF\n" + "#define STEP_RESOLVE\n" : + "#define STEP_RESOLVE\n"); } int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata), @@ -255,7 +261,7 @@ void EEVEE_depth_of_field_draw(EEVEE_Data *vedata) /* Depth Of Field */ if ((effects->enabled_effects & EFFECT_DOF) != 0) { - float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; /* Downsample */ GPU_framebuffer_bind(fbl->dof_down_fb); diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c index f6e74c6822c..365ba0afaac 100644 --- a/source/blender/draw/engines/eevee/eevee_effects.c +++ b/source/blender/draw/engines/eevee/eevee_effects.c @@ -138,7 +138,7 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); const float *viewport_size = DRW_viewport_size_get(); - int size_fs[2] = {(int)viewport_size[0], (int)viewport_size[1]}; + const int size_fs[2] = {(int)viewport_size[0], (int)viewport_size[1]}; /* Shaders */ if (!e_data.downsample_sh) { diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index a142648d08d..72f008ea66a 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -32,6 +32,8 @@ #include "DNA_world_types.h" +#include "IMB_imbuf.h" + #include "eevee_private.h" #include "eevee_engine.h" /* own include */ @@ -215,10 +217,10 @@ static void eevee_draw_scene(void *vedata) } while (loop_len--) { - float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; float clear_depth = 1.0f; uint clear_stencil = 0x0; - uint primes[3] = {2, 3, 7}; + const uint primes[3] = {2, 3, 7}; double offset[3] = {0.0, 0.0, 0.0}; double r[3]; diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c index 19325729114..6d2577d5b78 100644 --- a/source/blender/draw/engines/eevee/eevee_lightcache.c +++ b/source/blender/draw/engines/eevee/eevee_lightcache.c @@ -863,7 +863,7 @@ static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lb /* HACK: set txl->color but unset it before Draw Manager frees it. */ txl->color = lbake->rt_color; - int viewport_size[2] = { + const int viewport_size[2] = { GPU_texture_width(txl->color), GPU_texture_height(txl->color), }; @@ -1021,9 +1021,8 @@ static void compute_cell_id(EEVEE_LightGrid *egrid, if (visited_cells == cell_idx) { return; } - else { - visited_cells++; - } + + visited_cells++; } } } @@ -1032,7 +1031,7 @@ static void compute_cell_id(EEVEE_LightGrid *egrid, BLI_assert(0); } -static void grid_loc_to_world_loc(EEVEE_LightGrid *egrid, int local_cell[3], float r_pos[3]) +static void grid_loc_to_world_loc(EEVEE_LightGrid *egrid, const int local_cell[3], float r_pos[3]) { copy_v3_v3(r_pos, egrid->corner); madd_v3_v3fl(r_pos, egrid->increment_x, local_cell[0]); diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index a2f7686619f..0f4a9dc79b6 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -335,38 +335,28 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat { DRW_PASS_CREATE(psl->probe_background, DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL); - struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); DRWShadingGroup *grp = NULL; + EEVEE_lookdev_cache_init(vedata, sldata, psl->probe_background, pinfo, &grp); - Scene *scene = draw_ctx->scene; - World *wo = scene->world; - - /* LookDev */ - EEVEE_lookdev_cache_init(vedata, sldata, &grp, psl->probe_background, wo, pinfo); + if (grp == NULL) { + Scene *scene = draw_ctx->scene; + World *world = (scene->world) ? scene->world : EEVEE_world_default_get(); - if (!grp && wo) { - struct GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, NULL, wo, VAR_WORLD_PROBE); + const int options = VAR_WORLD_BACKGROUND | VAR_WORLD_PROBE; + struct GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, NULL, world, options); grp = DRW_shgroup_material_create(gpumat, psl->probe_background); DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f); - /* TODO (fclem): remove those (need to clean the GLSL files). */ - DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); - DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); - DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); - DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); - DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo); - DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo); - DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); - DRW_shgroup_call(grp, geom, NULL); } - /* Fallback if shader fails or if not using nodetree. */ - if (grp == NULL) { - grp = DRW_shgroup_create(EEVEE_shaders_probe_default_sh_get(), psl->probe_background); - DRW_shgroup_uniform_vec3(grp, "color", G_draw.block.colorBackground, 1); - DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f); - DRW_shgroup_call(grp, geom, NULL); - } + DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); + DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); + DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); + DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); + DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo); + DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo); + DRW_shgroup_uniform_block_ref(grp, "renderpass_block", &stl->g_data->renderpass_ubo); + DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL); } if (DRW_state_draw_support()) { @@ -1122,7 +1112,7 @@ void EEVEE_lightbake_filter_diffuse(EEVEE_ViewLayerData *sldata, #if defined(IRRADIANCE_SH_L2) int size[2] = {3, 3}; #elif defined(IRRADIANCE_HL2) - int size[2] = {3, 2}; + const int size[2] = {3, 2}; pinfo->samples_len = 1024.0f; #endif diff --git a/source/blender/draw/engines/eevee/eevee_lookdev.c b/source/blender/draw/engines/eevee/eevee_lookdev.c index b044213e029..f79d90500bd 100644 --- a/source/blender/draw/engines/eevee/eevee_lookdev.c +++ b/source/blender/draw/engines/eevee/eevee_lookdev.c @@ -97,10 +97,9 @@ static void eevee_lookdev_hdri_preview_init(EEVEE_Data *vedata, EEVEE_ViewLayerD void EEVEE_lookdev_cache_init(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, - DRWShadingGroup **r_grp, DRWPass *pass, - World *UNUSED(world), - EEVEE_LightProbesInfo *pinfo) + EEVEE_LightProbesInfo *pinfo, + DRWShadingGroup **r_shgrp) { EEVEE_StorageList *stl = vedata->stl; EEVEE_TextureList *txl = vedata->txl; @@ -153,89 +152,88 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata, const View3DShading *shading = &v3d->shading; StudioLight *sl = BKE_studiolight_find(shading->lookdev_light, STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE); - if (sl && (sl->flag & STUDIOLIGHT_TYPE_WORLD)) { - GPUShader *shader = probe_render ? EEVEE_shaders_default_studiolight_sh_get() : - EEVEE_shaders_background_studiolight_sh_get(); + if (sl == NULL || (sl->flag & STUDIOLIGHT_TYPE_WORLD) == 0) { + return; + } + + GPUShader *shader = probe_render ? EEVEE_shaders_studiolight_probe_sh_get() : + EEVEE_shaders_studiolight_background_sh_get(); - const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); - int cube_res = scene_eval->eevee.gi_cubemap_resolution; + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); + int cube_res = scene_eval->eevee.gi_cubemap_resolution; - /* If one of the component is missing we start from scratch. */ - if ((stl->lookdev_grid_data == NULL) || (stl->lookdev_cube_data == NULL) || - (txl->lookdev_grid_tx == NULL) || (txl->lookdev_cube_tx == NULL) || - (g_data->light_cache && g_data->light_cache->ref_res != cube_res)) { - eevee_lookdev_lightcache_delete(vedata); - } + /* If one of the component is missing we start from scratch. */ + if ((stl->lookdev_grid_data == NULL) || (stl->lookdev_cube_data == NULL) || + (txl->lookdev_grid_tx == NULL) || (txl->lookdev_cube_tx == NULL) || + (g_data->light_cache && g_data->light_cache->ref_res != cube_res)) { + eevee_lookdev_lightcache_delete(vedata); + } - if (stl->lookdev_lightcache == NULL) { + if (stl->lookdev_lightcache == NULL) { #if defined(IRRADIANCE_SH_L2) - int grid_res = 4; + int grid_res = 4; #elif defined(IRRADIANCE_HL2) - int grid_res = 4; + int grid_res = 4; #endif - stl->lookdev_lightcache = EEVEE_lightcache_create( - 1, 1, cube_res, 8, (int[3]){grid_res, grid_res, 1}); - - /* XXX: Fix memleak. TODO find out why. */ - MEM_SAFE_FREE(stl->lookdev_cube_mips); - - /* We do this to use a special light cache for lookdev. - * This light-cache needs to be per viewport. But we need to - * have correct freeing when the viewport is closed. So we - * need to reference all textures to the txl and the memblocks - * to the stl. */ - stl->lookdev_grid_data = stl->lookdev_lightcache->grid_data; - stl->lookdev_cube_data = stl->lookdev_lightcache->cube_data; - stl->lookdev_cube_mips = stl->lookdev_lightcache->cube_mips; - txl->lookdev_grid_tx = stl->lookdev_lightcache->grid_tx.tex; - txl->lookdev_cube_tx = stl->lookdev_lightcache->cube_tx.tex; - } - - g_data->light_cache = stl->lookdev_lightcache; - - DRWShadingGroup *grp = *r_grp = DRW_shgroup_create(shader, pass); - axis_angle_to_mat3_single(g_data->studiolight_matrix, 'Z', shading->studiolight_rot_z); - DRW_shgroup_uniform_mat3(grp, "StudioLightMatrix", g_data->studiolight_matrix); - - if (probe_render) { - DRW_shgroup_uniform_float_copy( - grp, "studioLightIntensity", shading->studiolight_intensity); - BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE); - DRW_shgroup_uniform_texture(grp, "image", sl->equirect_radiance_gputexture); - /* Do not fadeout when doing probe rendering, only when drawing the background */ - DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f); - } - else { - float background_alpha = g_data->background_alpha * shading->studiolight_background; - float studiolight_blur = powf(shading->studiolight_blur, 2.5f); - DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", background_alpha); - DRW_shgroup_uniform_float_copy(grp, "studioLightBlur", studiolight_blur); - DRW_shgroup_uniform_texture(grp, "probeCubes", txl->lookdev_cube_tx); - DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); - DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); - DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); - DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); - DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); - } - - DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL); - - /* Do we need to recalc the lightprobes? */ - if (g_data->studiolight_index != sl->index || - g_data->studiolight_rot_z != shading->studiolight_rot_z || - g_data->studiolight_intensity != shading->studiolight_intensity || - g_data->studiolight_cubemap_res != scene->eevee.gi_cubemap_resolution || - g_data->studiolight_glossy_clamp != scene->eevee.gi_glossy_clamp || - g_data->studiolight_filter_quality != scene->eevee.gi_filter_quality) { - stl->lookdev_lightcache->flag |= LIGHTCACHE_UPDATE_WORLD; - g_data->studiolight_index = sl->index; - g_data->studiolight_rot_z = shading->studiolight_rot_z; - g_data->studiolight_intensity = shading->studiolight_intensity; - g_data->studiolight_cubemap_res = scene->eevee.gi_cubemap_resolution; - g_data->studiolight_glossy_clamp = scene->eevee.gi_glossy_clamp; - g_data->studiolight_filter_quality = scene->eevee.gi_filter_quality; - } + stl->lookdev_lightcache = EEVEE_lightcache_create( + 1, 1, cube_res, 8, (int[3]){grid_res, grid_res, 1}); + + /* XXX: Fix memleak. TODO find out why. */ + MEM_SAFE_FREE(stl->lookdev_cube_mips); + + /* We do this to use a special light cache for lookdev. + * This light-cache needs to be per viewport. But we need to + * have correct freeing when the viewport is closed. So we + * need to reference all textures to the txl and the memblocks + * to the stl. */ + stl->lookdev_grid_data = stl->lookdev_lightcache->grid_data; + stl->lookdev_cube_data = stl->lookdev_lightcache->cube_data; + stl->lookdev_cube_mips = stl->lookdev_lightcache->cube_mips; + txl->lookdev_grid_tx = stl->lookdev_lightcache->grid_tx.tex; + txl->lookdev_cube_tx = stl->lookdev_lightcache->cube_tx.tex; + } + + g_data->light_cache = stl->lookdev_lightcache; + + DRWShadingGroup *grp = DRW_shgroup_create(shader, pass); + axis_angle_to_mat3_single(g_data->studiolight_matrix, 'Z', shading->studiolight_rot_z); + DRW_shgroup_uniform_mat3(grp, "StudioLightMatrix", g_data->studiolight_matrix); + + if (probe_render) { + /* Avoid artifact with equirectangular mapping. */ + eGPUSamplerState state = (GPU_SAMPLER_FILTER | GPU_SAMPLER_REPEAT_S); + DRW_shgroup_uniform_float_copy(grp, "studioLightIntensity", shading->studiolight_intensity); + BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE); + DRW_shgroup_uniform_texture_ex(grp, "studioLight", sl->equirect_radiance_gputexture, state); + /* Do not fadeout when doing probe rendering, only when drawing the background */ + DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f); + } + else { + float background_alpha = g_data->background_alpha * shading->studiolight_background; + float studiolight_blur = powf(shading->studiolight_blur, 2.5f); + DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", background_alpha); + DRW_shgroup_uniform_float_copy(grp, "studioLightBlur", studiolight_blur); + DRW_shgroup_uniform_texture(grp, "probeCubes", txl->lookdev_cube_tx); + } + + /* Common UBOs are setup latter. */ + *r_shgrp = grp; + + /* Do we need to recalc the lightprobes? */ + if (g_data->studiolight_index != sl->index || + g_data->studiolight_rot_z != shading->studiolight_rot_z || + g_data->studiolight_intensity != shading->studiolight_intensity || + g_data->studiolight_cubemap_res != scene->eevee.gi_cubemap_resolution || + g_data->studiolight_glossy_clamp != scene->eevee.gi_glossy_clamp || + g_data->studiolight_filter_quality != scene->eevee.gi_filter_quality) { + stl->lookdev_lightcache->flag |= LIGHTCACHE_UPDATE_WORLD; + g_data->studiolight_index = sl->index; + g_data->studiolight_rot_z = shading->studiolight_rot_z; + g_data->studiolight_intensity = shading->studiolight_intensity; + g_data->studiolight_cubemap_res = scene->eevee.gi_cubemap_resolution; + g_data->studiolight_glossy_clamp = scene->eevee.gi_glossy_clamp; + g_data->studiolight_filter_quality = scene->eevee.gi_filter_quality; } } } @@ -247,7 +245,7 @@ static void eevee_lookdev_apply_taa(const EEVEE_EffectsInfo *effects, if (DRW_state_is_image_render() || ((effects->enabled_effects & EFFECT_TAA) != 0)) { double ht_point[2]; double ht_offset[2] = {0.0, 0.0}; - uint ht_primes[2] = {2, 3}; + const uint ht_primes[2] = {2, 3}; float ofs[2]; BLI_halton_2d(ht_primes, ht_offset, effects->taa_current_sample, ht_point); diff --git a/source/blender/draw/engines/eevee/eevee_lut_gen.c b/source/blender/draw/engines/eevee/eevee_lut_gen.c index 6cee05bf015..9b07a6908c3 100644 --- a/source/blender/draw/engines/eevee/eevee_lut_gen.c +++ b/source/blender/draw/engines/eevee/eevee_lut_gen.c @@ -31,6 +31,8 @@ #include "BLI_rand.h" #include "BLI_string_utils.h" +#include "eevee_private.h" + extern char datatoc_bsdf_lut_frag_glsl[]; extern char datatoc_btdf_lut_frag_glsl[]; extern char datatoc_bsdf_common_lib_glsl[]; @@ -45,15 +47,13 @@ static struct GPUTexture *create_ggx_lut_texture(int UNUSED(w), int UNUSED(h)) static float samples_len = 8192.0f; static float inv_samples_len = 1.0f / 8192.0f; - char *lib_str = BLI_string_joinN(datatoc_bsdf_common_lib_glsl, datatoc_bsdf_sampling_lib_glsl); + DRWShaderLibrary *lib = EEVEE_shader_lib_get(); - struct GPUShader *sh = DRW_shader_create_with_lib(datatoc_lightprobe_vert_glsl, - datatoc_lightprobe_geom_glsl, - datatoc_bsdf_lut_frag_glsl, - lib_str, - "#define HAMMERSLEY_SIZE 8192\n" - "#define BRDF_LUT_SIZE 64\n" - "#define NOISE_SIZE 64\n"); + struct GPUShader *sh = DRW_shader_create_with_shaderlib(datatoc_lightprobe_vert_glsl, + datatoc_lightprobe_geom_glsl, + datatoc_bsdf_lut_frag_glsl, + lib, + "#define HAMMERSLEY_SIZE 8192\n"); DRWPass *pass = DRW_pass_create("LightProbe Filtering", DRW_STATE_WRITE_COLOR); DRWShadingGroup *grp = DRW_shgroup_create(sh, pass); @@ -105,16 +105,10 @@ static struct GPUTexture *create_ggx_refraction_lut_texture(int w, int h) static float a2 = 0.0f; static float inv_samples_len = 1.0f / 8192.0f; - char *frag_str = BLI_string_joinN( - datatoc_bsdf_common_lib_glsl, datatoc_bsdf_sampling_lib_glsl, datatoc_btdf_lut_frag_glsl); - - struct GPUShader *sh = DRW_shader_create_fullscreen(frag_str, - "#define HAMMERSLEY_SIZE 8192\n" - "#define BRDF_LUT_SIZE 64\n" - "#define NOISE_SIZE 64\n" - "#define LUT_SIZE 64\n"); + DRWShaderLibrary *lib = EEVEE_shader_lib_get(); - MEM_freeN(frag_str); + struct GPUShader *sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_btdf_lut_frag_glsl, lib, "#define HAMMERSLEY_SIZE 8192\n"); DRWPass *pass = DRW_pass_create("LightProbe Filtering", DRW_STATE_WRITE_COLOR); DRWShadingGroup *grp = DRW_shgroup_create(sh, pass); @@ -194,4 +188,4 @@ static struct GPUTexture *create_ggx_refraction_lut_texture(int w, int h) MEM_freeN(data); return tex; -}
\ No newline at end of file +} diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 143945b637a..fb07208be47 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -56,37 +56,6 @@ static struct { float noise_offsets[3]; } e_data = {NULL}; /* Engine data */ -extern char datatoc_lights_lib_glsl[]; -extern char datatoc_lightprobe_lib_glsl[]; -extern char datatoc_ambient_occlusion_lib_glsl[]; -extern char datatoc_prepass_frag_glsl[]; -extern char datatoc_prepass_vert_glsl[]; -extern char datatoc_default_frag_glsl[]; -extern char datatoc_default_world_frag_glsl[]; -extern char datatoc_ltc_lib_glsl[]; -extern char datatoc_bsdf_common_lib_glsl[]; -extern char datatoc_bsdf_sampling_lib_glsl[]; -extern char datatoc_common_uniforms_lib_glsl[]; -extern char datatoc_common_hair_lib_glsl[]; -extern char datatoc_common_view_lib_glsl[]; -extern char datatoc_irradiance_lib_glsl[]; -extern char datatoc_octahedron_lib_glsl[]; -extern char datatoc_cubemap_lib_glsl[]; -extern char datatoc_lit_surface_frag_glsl[]; -extern char datatoc_lit_surface_vert_glsl[]; -extern char datatoc_raytrace_lib_glsl[]; -extern char datatoc_ssr_lib_glsl[]; -extern char datatoc_shadow_vert_glsl[]; -extern char datatoc_lightprobe_geom_glsl[]; -extern char datatoc_lightprobe_vert_glsl[]; -extern char datatoc_background_vert_glsl[]; -extern char datatoc_update_noise_frag_glsl[]; -extern char datatoc_volumetric_vert_glsl[]; -extern char datatoc_volumetric_geom_glsl[]; -extern char datatoc_volumetric_frag_glsl[]; -extern char datatoc_volumetric_lib_glsl[]; -extern char datatoc_gpu_shader_uniform_color_frag_glsl[]; - typedef struct EeveeMaterialCache { struct DRWShadingGroup *depth_grp; struct DRWShadingGroup *shading_grp; @@ -238,46 +207,6 @@ void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const d DRW_draw_pass(psl->update_noise_pass); } -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_Data *vedata, EEVEE_StorageList *stl, @@ -305,15 +234,6 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, } { - /* Update view_vecs */ - float invproj[4][4], winmat[4][4]; - DRW_view_winmat_get(NULL, winmat, false); - DRW_view_winmat_get(NULL, invproj, true); - - EEVEE_update_viewvecs(invproj, winmat, sldata->common_data.view_vecs); - } - - { /* Update noise Framebuffer. */ GPU_framebuffer_ensure_config( &fbl->update_noise_fb, @@ -391,39 +311,28 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) { DRW_PASS_CREATE(psl->background_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL); - struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); DRWShadingGroup *grp = NULL; + EEVEE_lookdev_cache_init(vedata, sldata, psl->background_ps, NULL, &grp); - Scene *scene = draw_ctx->scene; - World *wo = scene->world; - - EEVEE_lookdev_cache_init(vedata, sldata, &grp, psl->background_ps, wo, NULL); + if (grp == NULL) { + Scene *scene = draw_ctx->scene; + World *world = (scene->world) ? scene->world : EEVEE_world_default_get(); - if (!grp && wo) { - struct GPUMaterial *gpumat = EEVEE_material_get( - vedata, scene, NULL, wo, VAR_WORLD_BACKGROUND); + const int options = VAR_WORLD_BACKGROUND; + struct GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, NULL, world, options); grp = DRW_shgroup_material_create(gpumat, psl->background_ps); DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1); - /* TODO (fclem): remove those (need to clean the GLSL files). */ - DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); - DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); - DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); - DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); - DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo); - DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo); - DRW_shgroup_uniform_block_ref(grp, "renderpass_block", &stl->g_data->renderpass_ubo); - DRW_shgroup_call(grp, geom, NULL); } - /* Fallback if shader fails or if not using nodetree. */ - if (grp == NULL) { - GPUShader *sh = EEVEE_shaders_default_background_sh_get(); - grp = DRW_shgroup_create(sh, psl->background_ps); - DRW_shgroup_uniform_vec3(grp, "color", G_draw.block.colorBackground, 1); - DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1); - DRW_shgroup_call(grp, geom, NULL); - } + DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); + DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); + DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); + DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); + DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo); + DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo); + DRW_shgroup_uniform_block_ref(grp, "renderpass_block", &stl->g_data->renderpass_ubo); + DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL); } #define EEVEE_PASS_CREATE(pass, state) \ @@ -574,9 +483,8 @@ static EeveeMaterialCache material_opaque(EEVEE_Data *vedata, if (BLI_ghash_ensure_p(pd->material_hash, key, (void ***)&emc_p)) { return **emc_p; } - else { - *emc_p = emc = BLI_memblock_alloc(sldata->material_cache); - } + + *emc_p = emc = BLI_memblock_alloc(sldata->material_cache); material_shadow(vedata, sldata, ma, is_hair, emc); @@ -999,7 +907,7 @@ static void material_renderpass_init(EEVEE_FramebufferList *fbl, DRW_texture_ensure_fullscreen_2d(output_tx, format, 0); /* Clear texture. */ if (do_clear) { - float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; /* TODO(fclem) replace by GPU_texture_clear once it is fast. */ GPU_framebuffer_texture_attach(fbl->material_accum_fb, *output_tx, 0, 0); GPU_framebuffer_bind(fbl->material_accum_fb); diff --git a/source/blender/draw/engines/eevee/eevee_mist.c b/source/blender/draw/engines/eevee/eevee_mist.c index 1cedd334d67..cfac6cc4d62 100644 --- a/source/blender/draw/engines/eevee/eevee_mist.c +++ b/source/blender/draw/engines/eevee/eevee_mist.c @@ -53,17 +53,13 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) EEVEE_PrivateData *g_data = stl->g_data; Scene *scene = draw_ctx->scene; - float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const 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_view_lib_glsl, - datatoc_common_uniforms_lib_glsl, - datatoc_bsdf_common_lib_glsl, - datatoc_effect_mist_frag_glsl); + DRWShaderLibrary *lib = EEVEE_shader_lib_get(); - e_data.mist_sh = DRW_shader_create_fullscreen(frag_str, "#define FIRST_PASS\n"); - - MEM_freeN(frag_str); + e_data.mist_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_mist_frag_glsl, lib, "#define FIRST_PASS\n"); } /* Create FrameBuffer. */ @@ -98,11 +94,11 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) } } else { - float near = -sldata->common_data.view_vecs[0][2]; - float range = sldata->common_data.view_vecs[1][2]; + float near = DRW_view_near_distance_get(NULL); + float far = DRW_view_far_distance_get(NULL); /* Fallback */ g_data->mist_start = near; - g_data->mist_inv_dist = 1.0f / fabsf(range); + g_data->mist_inv_dist = 1.0f / fabsf(far - near); g_data->mist_falloff = 1.0f; } diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c index 400b309de07..2a315927015 100644 --- a/source/blender/draw/engines/eevee/eevee_motion_blur.c +++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c @@ -69,27 +69,23 @@ extern char datatoc_common_view_lib_glsl[]; static void eevee_create_shader_motion_blur(void) { - e_data.motion_blur_sh = DRW_shader_create_fullscreen( - datatoc_effect_motion_blur_frag_glsl, - "#define EEVEE_VELOCITY_TILE_SIZE " STRINGIFY(EEVEE_VELOCITY_TILE_SIZE) "\n"); - e_data.motion_blur_object_sh = DRW_shader_create_with_lib(datatoc_object_motion_vert_glsl, - NULL, - datatoc_object_motion_frag_glsl, - datatoc_common_view_lib_glsl, - NULL); - e_data.velocity_tiles_sh = DRW_shader_create_fullscreen( - datatoc_effect_velocity_tile_frag_glsl, - "#define TILE_GATHER\n" - "#define EEVEE_VELOCITY_TILE_SIZE " STRINGIFY(EEVEE_VELOCITY_TILE_SIZE) "\n"); +#define TILE_SIZE_STR "#define EEVEE_VELOCITY_TILE_SIZE " STRINGIFY(EEVEE_VELOCITY_TILE_SIZE) "\n" + DRWShaderLibrary *lib = EEVEE_shader_lib_get(); + e_data.motion_blur_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_motion_blur_frag_glsl, lib, TILE_SIZE_STR); + e_data.motion_blur_object_sh = DRW_shader_create_with_shaderlib( + datatoc_object_motion_vert_glsl, NULL, datatoc_object_motion_frag_glsl, lib, NULL); + + e_data.motion_blur_hair_sh = DRW_shader_create_with_shaderlib(datatoc_object_motion_vert_glsl, + NULL, + datatoc_object_motion_frag_glsl, + lib, + "#define HAIR\n"); + + e_data.velocity_tiles_sh = DRW_shader_create_fullscreen(datatoc_effect_velocity_tile_frag_glsl, + "#define TILE_GATHER\n" TILE_SIZE_STR); e_data.velocity_tiles_expand_sh = DRW_shader_create_fullscreen( - datatoc_effect_velocity_tile_frag_glsl, - "#define TILE_EXPANSION\n" - "#define EEVEE_VELOCITY_TILE_SIZE " STRINGIFY(EEVEE_VELOCITY_TILE_SIZE) "\n"); - - char *vert = BLI_string_joinN(datatoc_common_hair_lib_glsl, datatoc_object_motion_vert_glsl); - e_data.motion_blur_hair_sh = DRW_shader_create_with_lib( - vert, NULL, datatoc_object_motion_frag_glsl, datatoc_common_view_lib_glsl, "#define HAIR\n"); - MEM_freeN(vert); + datatoc_effect_velocity_tile_frag_glsl, "#define TILE_EXPANSION\n" TILE_SIZE_STR); } int EEVEE_motion_blur_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) @@ -121,8 +117,10 @@ int EEVEE_motion_blur_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *veda } const float *fs_size = DRW_viewport_size_get(); - int tx_size[2] = {1 + ((int)fs_size[0] / EEVEE_VELOCITY_TILE_SIZE), - 1 + ((int)fs_size[1] / EEVEE_VELOCITY_TILE_SIZE)}; + const int tx_size[2] = { + 1 + ((int)fs_size[0] / EEVEE_VELOCITY_TILE_SIZE), + 1 + ((int)fs_size[1] / EEVEE_VELOCITY_TILE_SIZE), + }; effects->velocity_tiles_x_tx = DRW_texture_pool_query_2d( tx_size[0], fs_size[1], GPU_RGBA16, &draw_engine_eevee_type); @@ -177,8 +175,10 @@ void EEVEE_motion_blur_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat if ((effects->enabled_effects & EFFECT_MOTION_BLUR) != 0) { const float *fs_size = DRW_viewport_size_get(); - int tx_size[2] = {GPU_texture_width(effects->velocity_tiles_tx), - GPU_texture_height(effects->velocity_tiles_tx)}; + const int tx_size[2] = { + GPU_texture_width(effects->velocity_tiles_tx), + GPU_texture_height(effects->velocity_tiles_tx), + }; eevee_motion_blur_sync_camera(vedata); @@ -484,16 +484,15 @@ void EEVEE_motion_blur_cache_finish(EEVEE_Data *vedata) GPU_VERTBUF_DISCARD_SAFE(mb_geom->vbo[MB_NEXT]); break; } + + /* Modify the batch to include the previous & next position. */ + if (i == MB_PREV) { + GPU_batch_vertbuf_add_ex(batch, vbo, true); + mb_geom->vbo[i] = NULL; + } else { - /* Modify the batch to include the previous & next position. */ - if (i == MB_PREV) { - GPU_batch_vertbuf_add_ex(batch, vbo, true); - mb_geom->vbo[i] = NULL; - } - else { - /* This VBO can be reuse by next time step. Don't pass ownership. */ - GPU_batch_vertbuf_add_ex(batch, vbo, false); - } + /* This VBO can be reuse by next time step. Don't pass ownership. */ + GPU_batch_vertbuf_add_ex(batch, vbo, false); } } } diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c index a075210967c..9aae801197f 100644 --- a/source/blender/draw/engines/eevee/eevee_occlusion.c +++ b/source/blender/draw/engines/eevee/eevee_occlusion.c @@ -53,17 +53,14 @@ extern char datatoc_effect_gtao_frag_glsl[]; static void eevee_create_shader_occlusion(void) { - char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_common_uniforms_lib_glsl, - datatoc_bsdf_common_lib_glsl, - datatoc_ambient_occlusion_lib_glsl, - datatoc_effect_gtao_frag_glsl); - - e_data.gtao_sh = DRW_shader_create_fullscreen(frag_str, NULL); - e_data.gtao_layer_sh = DRW_shader_create_fullscreen(frag_str, "#define LAYERED_DEPTH\n"); - e_data.gtao_debug_sh = DRW_shader_create_fullscreen(frag_str, "#define DEBUG_AO\n"); - - MEM_freeN(frag_str); + DRWShaderLibrary *lib = EEVEE_shader_lib_get(); + + e_data.gtao_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_gtao_frag_glsl, lib, NULL); + e_data.gtao_layer_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_gtao_frag_glsl, lib, "#define LAYERED_DEPTH\n"); + e_data.gtao_debug_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_gtao_frag_glsl, lib, "#define DEBUG_AO\n"); } int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) @@ -77,7 +74,7 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); if (!e_data.dummy_horizon_tx) { - float pixel[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float pixel[4] = {0.0f, 0.0f, 0.0f, 0.0f}; e_data.dummy_horizon_tx = DRW_texture_create_2d(1, 1, GPU_RGBA8, DRW_TEX_WRAP, pixel); } @@ -146,7 +143,7 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata const eGPUTextureFormat texture_format = (tot_samples > 128) ? GPU_R32F : GPU_R16F; DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; /* Should be enough precision for many samples. */ DRW_texture_ensure_fullscreen_2d(&txl->ao_accum, texture_format, 0); diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 829d26ef876..34cd22ad13c 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -164,7 +164,7 @@ enum { VAR_MAT_MESH = (1 << 0), VAR_MAT_VOLUME = (1 << 1), VAR_MAT_HAIR = (1 << 2), - VAR_MAT_PROBE = (1 << 3), + /* VAR_MAT_PROBE = (1 << 3), UNUSED */ VAR_MAT_BLEND = (1 << 4), VAR_MAT_LOOKDEV = (1 << 5), VAR_MAT_HOLDOUT = (1 << 6), @@ -748,7 +748,6 @@ typedef struct EEVEE_EffectsInfo { * - sizeof(bool) == sizeof(int) in GLSL so use int in C */ typedef struct EEVEE_CommonUniformBuffer { float prev_persmat[4][4]; /* mat4 */ - float view_vecs[2][4]; /* vec4[2] */ float mip_ratio[10][4]; /* vec2[10] */ /* Ambient Occlusion */ /* -- 16 byte aligned -- */ @@ -1006,7 +1005,6 @@ void EEVEE_object_hair_cache_populate(EEVEE_Data *vedata, void EEVEE_materials_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_materials_free(void); void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const double offsets[3]); -void EEVEE_update_viewvecs(float invproj[4][4], float winmat[4][4], float (*r_viewvecs)[4]); void EEVEE_material_renderpasses_init(EEVEE_Data *vedata); void EEVEE_material_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples); void EEVEE_material_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); @@ -1062,15 +1060,14 @@ void EEVEE_random_rotation_m4(int sample_ofs, float scale, float r_mat[4][4]); /* eevee_shaders.c */ void EEVEE_shaders_lightprobe_shaders_init(void); void EEVEE_shaders_material_shaders_init(void); +struct DRWShaderLibrary *EEVEE_shader_lib_get(void); struct GPUShader *EEVEE_shaders_probe_filter_glossy_sh_get(void); -struct GPUShader *EEVEE_shaders_probe_default_sh_get(void); struct GPUShader *EEVEE_shaders_probe_filter_diffuse_sh_get(void); struct GPUShader *EEVEE_shaders_probe_filter_visibility_sh_get(void); struct GPUShader *EEVEE_shaders_probe_grid_fill_sh_get(void); struct GPUShader *EEVEE_shaders_probe_planar_downsample_sh_get(void); -struct GPUShader *EEVEE_shaders_default_studiolight_sh_get(void); -struct GPUShader *EEVEE_shaders_default_background_sh_get(void); -struct GPUShader *EEVEE_shaders_background_studiolight_sh_get(void); +struct GPUShader *EEVEE_shaders_studiolight_probe_sh_get(void); +struct GPUShader *EEVEE_shaders_studiolight_background_sh_get(void); struct GPUShader *EEVEE_shaders_probe_cube_display_sh_get(void); struct GPUShader *EEVEE_shaders_probe_grid_display_sh_get(void); struct GPUShader *EEVEE_shaders_probe_planar_display_sh_get(void); @@ -1082,6 +1079,7 @@ struct bNodeTree *EEVEE_shader_default_world_nodetree(World *wo); Material *EEVEE_material_default_diffuse_get(void); Material *EEVEE_material_default_glossy_get(void); Material *EEVEE_material_default_error_get(void); +World *EEVEE_world_default_get(void); struct GPUMaterial *EEVEE_material_default_get(struct Scene *scene, Material *ma, int options); struct GPUMaterial *EEVEE_material_get( EEVEE_Data *vedata, struct Scene *scene, Material *ma, World *wo, int options); @@ -1308,10 +1306,9 @@ void EEVEE_render_update_passes(struct RenderEngine *engine, /** eevee_lookdev.c */ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, - DRWShadingGroup **grp, DRWPass *pass, - struct World *world, - EEVEE_LightProbesInfo *pinfo); + EEVEE_LightProbesInfo *pinfo, + DRWShadingGroup **r_shgrp); void EEVEE_lookdev_draw(EEVEE_Data *vedata); /** eevee_engine.c */ diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c index b6b8833b1da..62698bc5da3 100644 --- a/source/blender/draw/engines/eevee/eevee_render.c +++ b/source/blender/draw/engines/eevee/eevee_render.c @@ -93,8 +93,10 @@ bool EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph * copy_v4_fl4(camtexcofac, 1.0f, 1.0f, 0.0f, 0.0f); } - int final_res[2] = {size_orig[0] + g_data->overscan_pixels * 2.0f, - size_orig[1] + g_data->overscan_pixels * 2.0f}; + const int final_res[2] = { + size_orig[0] + g_data->overscan_pixels * 2.0f, + size_orig[1] + g_data->overscan_pixels * 2.0f, + }; int max_dim = max_ii(final_res[0], final_res[1]); if (max_dim > GPU_max_texture_size()) { @@ -523,10 +525,10 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl } while (render_samples < tot_sample && !RE_engine_test_break(engine)) { - float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; float clear_depth = 1.0f; uint clear_stencil = 0x00; - uint primes[3] = {2, 3, 7}; + const uint primes[3] = {2, 3, 7}; double offset[3] = {0.0, 0.0, 0.0}; double r[3]; diff --git a/source/blender/draw/engines/eevee/eevee_renderpasses.c b/source/blender/draw/engines/eevee/eevee_renderpasses.c index be771d7cf42..089d8b7a287 100644 --- a/source/blender/draw/engines/eevee/eevee_renderpasses.c +++ b/source/blender/draw/engines/eevee/eevee_renderpasses.c @@ -199,12 +199,10 @@ void EEVEE_renderpasses_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ve EEVEE_RENDERPASSES_WITH_POST_PROCESSING) > 0; if (needs_post_processing) { if (e_data.postprocess_sh == NULL) { - char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_common_uniforms_lib_glsl, - datatoc_bsdf_common_lib_glsl, - datatoc_renderpass_postprocess_frag_glsl); - e_data.postprocess_sh = DRW_shader_create_fullscreen(frag_str, NULL); - MEM_freeN(frag_str); + DRWShaderLibrary *lib = EEVEE_shader_lib_get(); + + e_data.postprocess_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_renderpass_postprocess_frag_glsl, lib, NULL); } DRW_PASS_CREATE(psl->renderpass_pass, DRW_STATE_WRITE_COLOR); diff --git a/source/blender/draw/engines/eevee/eevee_sampling.c b/source/blender/draw/engines/eevee/eevee_sampling.c index 5e951928c5a..253dae79902 100644 --- a/source/blender/draw/engines/eevee/eevee_sampling.c +++ b/source/blender/draw/engines/eevee/eevee_sampling.c @@ -34,7 +34,7 @@ void EEVEE_sample_ball(int sample_ofs, float radius, float rsample[3]) { double ht_point[3]; double ht_offset[3] = {0.0, 0.0, 0.0}; - uint ht_primes[3] = {2, 3, 7}; + const uint ht_primes[3] = {2, 3, 7}; BLI_halton_3d(ht_primes, ht_offset, sample_ofs, ht_point); @@ -65,7 +65,7 @@ void EEVEE_sample_rectangle(int sample_ofs, { double ht_point[2]; double ht_offset[2] = {0.0, 0.0}; - uint ht_primes[2] = {2, 3}; + const uint ht_primes[2] = {2, 3}; BLI_halton_2d(ht_primes, ht_offset, sample_ofs, ht_point); @@ -91,7 +91,7 @@ void EEVEE_sample_ellipse(int sample_ofs, { double ht_point[2]; double ht_offset[2] = {0.0, 0.0}; - uint ht_primes[2] = {2, 3}; + const uint ht_primes[2] = {2, 3}; BLI_halton_2d(ht_primes, ht_offset, sample_ofs, ht_point); @@ -114,7 +114,7 @@ void EEVEE_random_rotation_m4(int sample_ofs, float scale, float r_mat[4][4]) { double ht_point[3]; double ht_offset[3] = {0.0, 0.0, 0.0}; - uint ht_primes[3] = {2, 3, 5}; + const uint ht_primes[3] = {2, 3, 5}; BLI_halton_3d(ht_primes, ht_offset, sample_ofs, ht_point); diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c index 32d758dba4b..88029c2e940 100644 --- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c +++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c @@ -48,30 +48,12 @@ static struct { struct GPUTexture *depth_src; } e_data = {{NULL}}; /* Engine data */ -extern char datatoc_ambient_occlusion_lib_glsl[]; -extern char datatoc_common_view_lib_glsl[]; -extern char datatoc_common_uniforms_lib_glsl[]; -extern char datatoc_bsdf_common_lib_glsl[]; -extern char datatoc_bsdf_sampling_lib_glsl[]; -extern char datatoc_octahedron_lib_glsl[]; -extern char datatoc_cubemap_lib_glsl[]; extern char datatoc_effect_ssr_frag_glsl[]; -extern char datatoc_lightprobe_lib_glsl[]; -extern char datatoc_raytrace_lib_glsl[]; static struct GPUShader *eevee_effects_screen_raytrace_shader_get(int options) { if (e_data.ssr_sh[options] == NULL) { - char *ssr_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_common_uniforms_lib_glsl, - datatoc_bsdf_common_lib_glsl, - datatoc_bsdf_sampling_lib_glsl, - datatoc_ambient_occlusion_lib_glsl, - datatoc_octahedron_lib_glsl, - datatoc_cubemap_lib_glsl, - datatoc_lightprobe_lib_glsl, - datatoc_raytrace_lib_glsl, - datatoc_effect_ssr_frag_glsl); + DRWShaderLibrary *lib = EEVEE_shader_lib_get(); DynStr *ds_defines = BLI_dynstr_new(); BLI_dynstr_append(ds_defines, SHADER_DEFINES); @@ -91,9 +73,9 @@ static struct GPUShader *eevee_effects_screen_raytrace_shader_get(int options) char *ssr_define_str = BLI_dynstr_get_cstring(ds_defines); BLI_dynstr_free(ds_defines); - e_data.ssr_sh[options] = DRW_shader_create_fullscreen(ssr_shader_str, ssr_define_str); + e_data.ssr_sh[options] = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_ssr_frag_glsl, lib, ssr_define_str); - MEM_freeN(ssr_shader_str); MEM_freeN(ssr_define_str); } @@ -156,7 +138,7 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) const int divisor = (effects->reflection_trace_full) ? 1 : 2; int tracing_res[2] = {(int)viewport_size[0] / divisor, (int)viewport_size[1] / divisor}; - int size_fs[2] = {(int)viewport_size[0], (int)viewport_size[1]}; + const int size_fs[2] = {(int)viewport_size[0], (int)viewport_size[1]}; const bool high_qual_input = true; /* TODO dither low quality input */ const eGPUTextureFormat format = (high_qual_input) ? GPU_RGBA16F : GPU_RGBA8; @@ -348,7 +330,7 @@ void EEVEE_reflection_output_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_StorageList *stl = vedata->stl; EEVEE_EffectsInfo *effects = stl->effects; - float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; /* Create FrameBuffer. */ const eGPUTextureFormat texture_format = (tot_samples > 256) ? GPU_RGBA32F : GPU_RGBA16F; diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c index 09e74c84948..5f125d395d3 100644 --- a/source/blender/draw/engines/eevee/eevee_shaders.c +++ b/source/blender/draw/engines/eevee/eevee_shaders.c @@ -28,6 +28,8 @@ #include "BLI_dynstr.h" #include "BLI_string_utils.h" +#include "DNA_world_types.h" + #include "MEM_guardedalloc.h" #include "GPU_material.h" @@ -40,19 +42,17 @@ static const char *filter_defines = "#define HAMMERSLEY_SIZE " STRINGIFY(HAMMERSLEY_SIZE) "\n" #if defined(IRRADIANCE_SH_L2) - "#define IRRADIANCE_SH_L2\n" -#elif defined(IRRADIANCE_CUBEMAP) - "#define IRRADIANCE_CUBEMAP\n" + "#define IRRADIANCE_SH_L2\n"; #elif defined(IRRADIANCE_HL2) - "#define IRRADIANCE_HL2\n" + "#define IRRADIANCE_HL2\n"; #endif - "#define NOISE_SIZE 64\n"; static struct { + /* Lookdev */ + struct GPUShader *studiolight_probe_sh; + struct GPUShader *studiolight_background_sh; + /* Probes */ - struct GPUShader *probe_default_sh; - struct GPUShader *probe_default_studiolight_sh; - struct GPUShader *probe_background_studiolight_sh; struct GPUShader *probe_grid_display_sh; struct GPUShader *probe_cube_display_sh; struct GPUShader *probe_planar_display_sh; @@ -70,17 +70,16 @@ static struct { struct GPUShader *taa_resolve_reproject_sh; /* General purpose Shaders. */ - struct GPUShader *default_background; + struct GPUShader *lookdev_background; struct GPUShader *update_noise_sh; /* Shader strings */ - char *frag_shader_lib; - char *vert_shader_str; - char *vert_shadow_shader_str; - char *vert_background_shader_str; - char *vert_volume_shader_str; - char *geom_volume_shader_str; - char *volume_shader_lib; + char *closure_lit_lib; + char *surface_lit_frag; + char *surface_prepass_frag; + char *surface_geom_barycentric; + + DRWShaderLibrary *lib; /* LookDev Materials */ Material *glossy_mat; @@ -88,6 +87,8 @@ static struct { Material *error_mat; + World *default_world; + /* Default Material */ struct { bNodeTree *ntree; @@ -103,16 +104,39 @@ static struct { } world; } e_data = {NULL}; /* Engine data */ -extern char datatoc_bsdf_common_lib_glsl[]; -extern char datatoc_bsdf_sampling_lib_glsl[]; -extern char datatoc_common_uniforms_lib_glsl[]; +extern char datatoc_common_hair_lib_glsl[]; +extern char datatoc_common_math_lib_glsl[]; +extern char datatoc_common_math_geom_lib_glsl[]; extern char datatoc_common_view_lib_glsl[]; +extern char datatoc_gpu_shader_common_obinfos_lib_glsl[]; extern char datatoc_ambient_occlusion_lib_glsl[]; extern char datatoc_background_vert_glsl[]; -extern char datatoc_common_hair_lib_glsl[]; +extern char datatoc_bsdf_common_lib_glsl[]; +extern char datatoc_bsdf_lut_frag_glsl[]; +extern char datatoc_bsdf_sampling_lib_glsl[]; +extern char datatoc_btdf_lut_frag_glsl[]; +extern char datatoc_closure_lib_glsl[]; +extern char datatoc_common_uniforms_lib_glsl[]; +extern char datatoc_common_utiltex_lib_glsl[]; extern char datatoc_cubemap_lib_glsl[]; -extern char datatoc_default_world_frag_glsl[]; +extern char datatoc_default_frag_glsl[]; +extern char datatoc_lookdev_world_frag_glsl[]; +extern char datatoc_effect_bloom_frag_glsl[]; +extern char datatoc_effect_dof_frag_glsl[]; +extern char datatoc_effect_dof_vert_glsl[]; +extern char datatoc_effect_downsample_cube_frag_glsl[]; +extern char datatoc_effect_downsample_frag_glsl[]; +extern char datatoc_effect_gtao_frag_glsl[]; +extern char datatoc_effect_minmaxz_frag_glsl[]; +extern char datatoc_effect_mist_frag_glsl[]; +extern char datatoc_effect_motion_blur_frag_glsl[]; +extern char datatoc_effect_ssr_frag_glsl[]; +extern char datatoc_effect_subsurface_frag_glsl[]; +extern char datatoc_effect_temporal_aa_glsl[]; +extern char datatoc_effect_translucency_frag_glsl[]; +extern char datatoc_effect_velocity_resolve_frag_glsl[]; +extern char datatoc_effect_velocity_tile_frag_glsl[]; extern char datatoc_irradiance_lib_glsl[]; extern char datatoc_lightprobe_cube_display_frag_glsl[]; extern char datatoc_lightprobe_cube_display_vert_glsl[]; @@ -131,72 +155,111 @@ extern char datatoc_lightprobe_planar_downsample_geom_glsl[]; extern char datatoc_lightprobe_planar_downsample_vert_glsl[]; extern char datatoc_lightprobe_vert_glsl[]; extern char datatoc_lights_lib_glsl[]; -extern char datatoc_lit_surface_frag_glsl[]; -extern char datatoc_lit_surface_vert_glsl[]; +extern char datatoc_closure_lit_lib_glsl[]; extern char datatoc_ltc_lib_glsl[]; +extern char datatoc_object_motion_frag_glsl[]; +extern char datatoc_object_motion_vert_glsl[]; extern char datatoc_octahedron_lib_glsl[]; extern char datatoc_prepass_frag_glsl[]; +extern char datatoc_prepass_vert_glsl[]; extern char datatoc_raytrace_lib_glsl[]; +extern char datatoc_renderpass_lib_glsl[]; +extern char datatoc_renderpass_postprocess_frag_glsl[]; +extern char datatoc_shadow_accum_frag_glsl[]; +extern char datatoc_shadow_frag_glsl[]; extern char datatoc_shadow_vert_glsl[]; extern char datatoc_ssr_lib_glsl[]; +extern char datatoc_surface_frag_glsl[]; +extern char datatoc_surface_geom_glsl[]; +extern char datatoc_surface_lib_glsl[]; +extern char datatoc_surface_vert_glsl[]; extern char datatoc_update_noise_frag_glsl[]; +extern char datatoc_volumetric_accum_frag_glsl[]; extern char datatoc_volumetric_frag_glsl[]; extern char datatoc_volumetric_geom_glsl[]; +extern char datatoc_volumetric_integration_frag_glsl[]; extern char datatoc_volumetric_lib_glsl[]; +extern char datatoc_volumetric_resolve_frag_glsl[]; +extern char datatoc_volumetric_scatter_frag_glsl[]; extern char datatoc_volumetric_vert_glsl[]; -/* Velocity Resolve */ -extern char datatoc_effect_velocity_resolve_frag_glsl[]; - -/* Temporal Sampling */ -extern char datatoc_effect_temporal_aa_glsl[]; - /* *********** FUNCTIONS *********** */ +static void eevee_shader_library_ensure(void) +{ + if (e_data.lib == NULL) { + e_data.lib = DRW_shader_library_create(); + /* NOTE: Theses needs to be ordered by dependencies. */ + DRW_SHADER_LIB_ADD(e_data.lib, common_math_lib); + DRW_SHADER_LIB_ADD(e_data.lib, common_math_geom_lib); + DRW_SHADER_LIB_ADD(e_data.lib, common_hair_lib); + DRW_SHADER_LIB_ADD(e_data.lib, common_view_lib); + DRW_SHADER_LIB_ADD(e_data.lib, common_uniforms_lib); + DRW_SHADER_LIB_ADD(e_data.lib, gpu_shader_common_obinfos_lib); + DRW_SHADER_LIB_ADD(e_data.lib, renderpass_lib); + DRW_SHADER_LIB_ADD(e_data.lib, bsdf_common_lib); + DRW_SHADER_LIB_ADD(e_data.lib, common_utiltex_lib); + DRW_SHADER_LIB_ADD(e_data.lib, bsdf_sampling_lib); + DRW_SHADER_LIB_ADD(e_data.lib, cubemap_lib); + DRW_SHADER_LIB_ADD(e_data.lib, raytrace_lib); + DRW_SHADER_LIB_ADD(e_data.lib, ambient_occlusion_lib); + DRW_SHADER_LIB_ADD(e_data.lib, octahedron_lib); + DRW_SHADER_LIB_ADD(e_data.lib, irradiance_lib); + DRW_SHADER_LIB_ADD(e_data.lib, lightprobe_lib); + DRW_SHADER_LIB_ADD(e_data.lib, ltc_lib); + DRW_SHADER_LIB_ADD(e_data.lib, lights_lib); + DRW_SHADER_LIB_ADD(e_data.lib, surface_lib); + DRW_SHADER_LIB_ADD(e_data.lib, volumetric_lib); + DRW_SHADER_LIB_ADD(e_data.lib, closure_lib); + DRW_SHADER_LIB_ADD(e_data.lib, ssr_lib); + + /* Add one for each Closure */ + e_data.closure_lit_lib = BLI_string_joinN(datatoc_closure_lit_lib_glsl, + datatoc_closure_lit_lib_glsl, + datatoc_closure_lit_lib_glsl, + datatoc_closure_lit_lib_glsl, + datatoc_closure_lit_lib_glsl, + datatoc_closure_lit_lib_glsl, + datatoc_closure_lit_lib_glsl, + datatoc_closure_lit_lib_glsl, + datatoc_closure_lit_lib_glsl, + datatoc_closure_lit_lib_glsl, + datatoc_closure_lit_lib_glsl); + + DRW_shader_library_add_file(e_data.lib, e_data.closure_lit_lib, "closure_lit_lib.glsl"); + + e_data.surface_lit_frag = DRW_shader_library_create_shader_string(e_data.lib, + datatoc_surface_frag_glsl); + + e_data.surface_prepass_frag = DRW_shader_library_create_shader_string( + e_data.lib, datatoc_prepass_frag_glsl); + + e_data.surface_geom_barycentric = DRW_shader_library_create_shader_string( + e_data.lib, datatoc_surface_geom_glsl); + } +} + void EEVEE_shaders_lightprobe_shaders_init(void) { BLI_assert(e_data.probe_filter_glossy_sh == NULL); - char *shader_str = NULL; - - shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_common_uniforms_lib_glsl, - datatoc_bsdf_common_lib_glsl, - datatoc_bsdf_sampling_lib_glsl, - datatoc_lightprobe_filter_glossy_frag_glsl); - - e_data.probe_filter_glossy_sh = DRW_shader_create( - datatoc_lightprobe_vert_glsl, datatoc_lightprobe_geom_glsl, shader_str, filter_defines); - - e_data.probe_default_sh = DRW_shader_create_with_lib(datatoc_background_vert_glsl, - NULL, - datatoc_default_world_frag_glsl, - datatoc_common_view_lib_glsl, - NULL); - MEM_freeN(shader_str); + eevee_shader_library_ensure(); - shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_common_uniforms_lib_glsl, - datatoc_bsdf_common_lib_glsl, - datatoc_bsdf_sampling_lib_glsl, - datatoc_lightprobe_filter_diffuse_frag_glsl); + e_data.probe_filter_glossy_sh = DRW_shader_create_with_shaderlib( + datatoc_lightprobe_vert_glsl, + datatoc_lightprobe_geom_glsl, + datatoc_lightprobe_filter_glossy_frag_glsl, + e_data.lib, + filter_defines); - e_data.probe_filter_diffuse_sh = DRW_shader_create_fullscreen(shader_str, filter_defines); + e_data.probe_filter_diffuse_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_lightprobe_filter_diffuse_frag_glsl, e_data.lib, filter_defines); - MEM_freeN(shader_str); + e_data.probe_filter_visibility_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_lightprobe_filter_visibility_frag_glsl, e_data.lib, filter_defines); - shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_common_uniforms_lib_glsl, - datatoc_bsdf_common_lib_glsl, - datatoc_bsdf_sampling_lib_glsl, - datatoc_lightprobe_filter_visibility_frag_glsl); - - e_data.probe_filter_visibility_sh = DRW_shader_create_fullscreen(shader_str, filter_defines); - - MEM_freeN(shader_str); - - e_data.probe_grid_fill_sh = DRW_shader_create_fullscreen(datatoc_lightprobe_grid_fill_frag_glsl, - filter_defines); + e_data.probe_grid_fill_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_lightprobe_grid_fill_frag_glsl, e_data.lib, filter_defines); e_data.probe_planar_downsample_sh = DRW_shader_create( datatoc_lightprobe_planar_downsample_vert_glsl, @@ -207,70 +270,18 @@ void EEVEE_shaders_lightprobe_shaders_init(void) void EEVEE_shaders_material_shaders_init(void) { - e_data.frag_shader_lib = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_common_uniforms_lib_glsl, - datatoc_bsdf_common_lib_glsl, - datatoc_bsdf_sampling_lib_glsl, - datatoc_ambient_occlusion_lib_glsl, - datatoc_raytrace_lib_glsl, - datatoc_ssr_lib_glsl, - datatoc_octahedron_lib_glsl, - datatoc_cubemap_lib_glsl, - datatoc_irradiance_lib_glsl, - datatoc_lightprobe_lib_glsl, - datatoc_ltc_lib_glsl, - datatoc_lights_lib_glsl, - /* Add one for each Closure */ - datatoc_lit_surface_frag_glsl, - datatoc_lit_surface_frag_glsl, - datatoc_lit_surface_frag_glsl, - datatoc_lit_surface_frag_glsl, - datatoc_lit_surface_frag_glsl, - datatoc_lit_surface_frag_glsl, - datatoc_lit_surface_frag_glsl, - datatoc_lit_surface_frag_glsl, - datatoc_lit_surface_frag_glsl, - datatoc_lit_surface_frag_glsl, - datatoc_lit_surface_frag_glsl, - datatoc_volumetric_lib_glsl); - - e_data.volume_shader_lib = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_common_uniforms_lib_glsl, - datatoc_bsdf_common_lib_glsl, - datatoc_ambient_occlusion_lib_glsl, - datatoc_octahedron_lib_glsl, - datatoc_cubemap_lib_glsl, - datatoc_irradiance_lib_glsl, - datatoc_lightprobe_lib_glsl, - datatoc_ltc_lib_glsl, - datatoc_lights_lib_glsl, - datatoc_volumetric_lib_glsl, - datatoc_volumetric_frag_glsl); - - e_data.vert_shader_str = BLI_string_joinN( - datatoc_common_view_lib_glsl, datatoc_common_hair_lib_glsl, datatoc_lit_surface_vert_glsl); - - e_data.vert_shadow_shader_str = BLI_string_joinN( - datatoc_common_view_lib_glsl, datatoc_common_hair_lib_glsl, datatoc_shadow_vert_glsl); - - e_data.vert_background_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_background_vert_glsl); - - e_data.vert_volume_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_volumetric_vert_glsl); - - e_data.geom_volume_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_volumetric_geom_glsl); + eevee_shader_library_ensure(); } -GPUShader *EEVEE_shaders_probe_filter_glossy_sh_get(void) +DRWShaderLibrary *EEVEE_shader_lib_get(void) { - return e_data.probe_filter_glossy_sh; + eevee_shader_library_ensure(); + return e_data.lib; } -GPUShader *EEVEE_shaders_probe_default_sh_get(void) +GPUShader *EEVEE_shaders_probe_filter_glossy_sh_get(void) { - return e_data.probe_default_sh; + return e_data.probe_filter_glossy_sh; } GPUShader *EEVEE_shaders_probe_filter_diffuse_sh_get(void) @@ -293,59 +304,40 @@ GPUShader *EEVEE_shaders_probe_planar_downsample_sh_get(void) return e_data.probe_planar_downsample_sh; } -GPUShader *EEVEE_shaders_default_studiolight_sh_get(void) +GPUShader *EEVEE_shaders_studiolight_probe_sh_get(void) { - if (e_data.probe_default_studiolight_sh == NULL) { - e_data.probe_default_studiolight_sh = DRW_shader_create_with_lib( - datatoc_background_vert_glsl, - NULL, - datatoc_default_world_frag_glsl, - datatoc_common_view_lib_glsl, - "#define LOOKDEV\n"); - } - return e_data.probe_default_studiolight_sh; + if (e_data.studiolight_probe_sh == NULL) { + e_data.studiolight_probe_sh = DRW_shader_create_with_shaderlib(datatoc_background_vert_glsl, + NULL, + datatoc_lookdev_world_frag_glsl, + e_data.lib, + SHADER_DEFINES); + } + return e_data.studiolight_probe_sh; } -GPUShader *EEVEE_shaders_background_studiolight_sh_get(void) +GPUShader *EEVEE_shaders_studiolight_background_sh_get(void) { - if (e_data.probe_background_studiolight_sh == NULL) { - char *frag_str = BLI_string_joinN(datatoc_octahedron_lib_glsl, - datatoc_cubemap_lib_glsl, - datatoc_common_uniforms_lib_glsl, - datatoc_bsdf_common_lib_glsl, - datatoc_lightprobe_lib_glsl, - datatoc_default_world_frag_glsl); - - e_data.probe_background_studiolight_sh = DRW_shader_create_with_lib( + if (e_data.studiolight_background_sh == NULL) { + e_data.studiolight_background_sh = DRW_shader_create_with_shaderlib( datatoc_background_vert_glsl, NULL, - frag_str, - datatoc_common_view_lib_glsl, + datatoc_lookdev_world_frag_glsl, + e_data.lib, "#define LOOKDEV_BG\n" SHADER_DEFINES); - - MEM_freeN(frag_str); } - return e_data.probe_background_studiolight_sh; + return e_data.studiolight_background_sh; } GPUShader *EEVEE_shaders_probe_cube_display_sh_get(void) { if (e_data.probe_cube_display_sh == NULL) { - char *shader_str = BLI_string_joinN(datatoc_octahedron_lib_glsl, - datatoc_cubemap_lib_glsl, - datatoc_common_view_lib_glsl, - datatoc_common_uniforms_lib_glsl, - datatoc_bsdf_common_lib_glsl, - datatoc_lightprobe_lib_glsl, - datatoc_lightprobe_cube_display_frag_glsl); - - char *vert_str = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_lightprobe_cube_display_vert_glsl); - - e_data.probe_cube_display_sh = DRW_shader_create(vert_str, NULL, shader_str, SHADER_DEFINES); - - MEM_freeN(vert_str); - MEM_freeN(shader_str); + e_data.probe_cube_display_sh = DRW_shader_create_with_shaderlib( + datatoc_lightprobe_cube_display_vert_glsl, + NULL, + datatoc_lightprobe_cube_display_frag_glsl, + e_data.lib, + SHADER_DEFINES); } return e_data.probe_cube_display_sh; } @@ -353,22 +345,12 @@ GPUShader *EEVEE_shaders_probe_cube_display_sh_get(void) GPUShader *EEVEE_shaders_probe_grid_display_sh_get(void) { if (e_data.probe_grid_display_sh == NULL) { - char *shader_str = BLI_string_joinN(datatoc_octahedron_lib_glsl, - datatoc_cubemap_lib_glsl, - datatoc_common_view_lib_glsl, - datatoc_common_uniforms_lib_glsl, - datatoc_bsdf_common_lib_glsl, - datatoc_irradiance_lib_glsl, - datatoc_lightprobe_lib_glsl, - datatoc_lightprobe_grid_display_frag_glsl); - - char *vert_str = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_lightprobe_grid_display_vert_glsl); - - e_data.probe_grid_display_sh = DRW_shader_create(vert_str, NULL, shader_str, filter_defines); - - MEM_freeN(vert_str); - MEM_freeN(shader_str); + e_data.probe_grid_display_sh = DRW_shader_create_with_shaderlib( + datatoc_lightprobe_grid_display_vert_glsl, + NULL, + datatoc_lightprobe_grid_display_frag_glsl, + e_data.lib, + filter_defines); } return e_data.probe_grid_display_sh; } @@ -376,16 +358,12 @@ GPUShader *EEVEE_shaders_probe_grid_display_sh_get(void) GPUShader *EEVEE_shaders_probe_planar_display_sh_get(void) { if (e_data.probe_planar_display_sh == NULL) { - char *vert_str = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_lightprobe_planar_display_vert_glsl); - - char *shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_lightprobe_planar_display_frag_glsl); - - e_data.probe_planar_display_sh = DRW_shader_create(vert_str, NULL, shader_str, NULL); - - MEM_freeN(vert_str); - MEM_freeN(shader_str); + e_data.probe_planar_display_sh = DRW_shader_create_with_shaderlib( + datatoc_lightprobe_planar_display_vert_glsl, + NULL, + datatoc_lightprobe_planar_display_frag_glsl, + e_data.lib, + NULL); } return e_data.probe_planar_display_sh; } @@ -393,34 +371,17 @@ GPUShader *EEVEE_shaders_probe_planar_display_sh_get(void) GPUShader *EEVEE_shaders_velocity_resolve_sh_get(void) { if (e_data.velocity_resolve_sh == NULL) { - char *frag_str = BLI_string_joinN(datatoc_common_uniforms_lib_glsl, - datatoc_common_view_lib_glsl, - datatoc_bsdf_common_lib_glsl, - datatoc_effect_velocity_resolve_frag_glsl); - - e_data.velocity_resolve_sh = DRW_shader_create_fullscreen(frag_str, NULL); - - MEM_freeN(frag_str); + e_data.velocity_resolve_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_velocity_resolve_frag_glsl, e_data.lib, NULL); } return e_data.velocity_resolve_sh; } -GPUShader *EEVEE_shaders_default_background_sh_get(void) -{ - if (e_data.default_background == NULL) { - e_data.default_background = DRW_shader_create_with_lib(datatoc_background_vert_glsl, - NULL, - datatoc_default_world_frag_glsl, - datatoc_common_view_lib_glsl, - NULL); - } - return e_data.default_background; -} - GPUShader *EEVEE_shaders_update_noise_sh_get(void) { if (e_data.update_noise_sh == NULL) { - e_data.update_noise_sh = DRW_shader_create_fullscreen(datatoc_update_noise_frag_glsl, NULL); + e_data.update_noise_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_update_noise_frag_glsl, e_data.lib, NULL); } return e_data.update_noise_sh; } @@ -437,13 +398,8 @@ GPUShader *EEVEE_shaders_taa_resolve_sh_get(EEVEE_EffectsFlag enabled_effects) sh = &e_data.taa_resolve_sh; } if (*sh == NULL) { - char *frag_str = BLI_string_joinN(datatoc_common_uniforms_lib_glsl, - datatoc_common_view_lib_glsl, - datatoc_bsdf_common_lib_glsl, - datatoc_effect_temporal_aa_glsl); - - *sh = DRW_shader_create_fullscreen(frag_str, define); - MEM_freeN(frag_str); + *sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_temporal_aa_glsl, e_data.lib, define); } return *sh; @@ -583,6 +539,18 @@ struct bNodeTree *EEVEE_shader_default_world_nodetree(World *wo) return e_data.world.ntree; } +World *EEVEE_world_default_get(void) +{ + if (e_data.default_world == NULL) { + e_data.default_world = BKE_id_new_nomain(ID_WO, "EEVEEE default world"); + copy_v3_fl(&e_data.default_world->horr, 0.0f); + e_data.default_world->use_nodes = 0; + e_data.default_world->nodetree = NULL; + BLI_listbase_clear(&e_data.default_world->gpumaterial); + } + return e_data.default_world; +} + static char *eevee_get_defines(int options) { char *str = NULL; @@ -605,7 +573,7 @@ static char *eevee_get_defines(int options) if ((options & VAR_MAT_HAIR) != 0) { BLI_dynstr_append(ds, "#define HAIR_SHADER\n"); } - if ((options & (VAR_MAT_PROBE | VAR_WORLD_PROBE)) != 0) { + if ((options & VAR_WORLD_PROBE) != 0) { BLI_dynstr_append(ds, "#define PROBE_CAPTURE\n"); } if ((options & VAR_MAT_HASH) != 0) { @@ -635,13 +603,13 @@ static char *eevee_get_vert(int options) char *str = NULL; if ((options & VAR_MAT_VOLUME) != 0) { - str = BLI_strdup(e_data.vert_volume_shader_str); + str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_volumetric_vert_glsl); } else if ((options & (VAR_WORLD_PROBE | VAR_WORLD_BACKGROUND)) != 0) { - str = BLI_strdup(e_data.vert_background_shader_str); + str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_background_vert_glsl); } else { - str = BLI_strdup(e_data.vert_shader_str); + str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_surface_vert_glsl); } return str; @@ -652,7 +620,7 @@ static char *eevee_get_geom(int options) char *str = NULL; if ((options & VAR_MAT_VOLUME) != 0) { - str = BLI_strdup(e_data.geom_volume_shader_str); + str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_volumetric_geom_glsl); } return str; @@ -663,18 +631,36 @@ static char *eevee_get_frag(int options) char *str = NULL; if ((options & VAR_MAT_VOLUME) != 0) { - str = BLI_strdup(e_data.volume_shader_lib); + str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_volumetric_frag_glsl); } else if ((options & VAR_MAT_DEPTH) != 0) { - str = BLI_string_joinN(e_data.frag_shader_lib, datatoc_prepass_frag_glsl); + str = BLI_strdup(e_data.surface_prepass_frag); } else { - str = BLI_strdup(e_data.frag_shader_lib); + str = BLI_strdup(e_data.surface_lit_frag); } return str; } +static void eevee_material_post_eval(GPUMaterial *mat, + int options, + const char **UNUSED(vert_code), + const char **geom_code, + const char **UNUSED(frag_lib), + const char **UNUSED(defines)) +{ + const bool is_hair = (options & VAR_MAT_HAIR) != 0; + const bool is_mesh = (options & VAR_MAT_MESH) != 0; + + /* Force geometry usage if GPU_BARYCENTRIC_DIST or GPU_BARYCENTRIC_TEXCO are used. + * Note: GPU_BARYCENTRIC_TEXCO only requires it if the shader is not drawing hairs. */ + if (!is_hair && is_mesh && GPU_material_flag_get(mat, GPU_MATFLAG_BARYCENTRIC) && + *geom_code == NULL) { + *geom_code = e_data.surface_geom_barycentric; + } +} + static struct GPUMaterial *eevee_material_get_ex( struct Scene *scene, Material *ma, World *wo, int options, bool deferred) { @@ -702,14 +688,16 @@ static struct GPUMaterial *eevee_material_get_ex( char *frag = eevee_get_frag(options); if (ma) { + GPUMaterialEvalCallbackFn cbfn = &eevee_material_post_eval; + bNodeTree *ntree = !is_default ? ma->nodetree : EEVEE_shader_default_surface_nodetree(ma); mat = DRW_shader_create_from_material( - scene, ma, ntree, engine, options, is_volume, vert, geom, frag, defines, deferred); + scene, ma, ntree, engine, options, is_volume, vert, geom, frag, defines, deferred, cbfn); } else { bNodeTree *ntree = !is_default ? wo->nodetree : EEVEE_shader_default_world_nodetree(wo); mat = DRW_shader_create_from_world( - scene, wo, ntree, engine, options, is_volume, vert, geom, frag, defines, deferred); + scene, wo, ntree, engine, options, is_volume, vert, geom, frag, defines, deferred, NULL); } MEM_SAFE_FREE(defines); @@ -764,30 +752,31 @@ struct GPUMaterial *EEVEE_material_get( void EEVEE_shaders_free(void) { - MEM_SAFE_FREE(e_data.frag_shader_lib); - MEM_SAFE_FREE(e_data.vert_shader_str); - MEM_SAFE_FREE(e_data.vert_shadow_shader_str); - MEM_SAFE_FREE(e_data.vert_background_shader_str); - MEM_SAFE_FREE(e_data.vert_volume_shader_str); - MEM_SAFE_FREE(e_data.geom_volume_shader_str); - MEM_SAFE_FREE(e_data.volume_shader_lib); - DRW_SHADER_FREE_SAFE(e_data.default_background); + MEM_SAFE_FREE(e_data.closure_lit_lib); + MEM_SAFE_FREE(e_data.surface_prepass_frag); + MEM_SAFE_FREE(e_data.surface_lit_frag); + MEM_SAFE_FREE(e_data.surface_geom_barycentric); + DRW_SHADER_FREE_SAFE(e_data.lookdev_background); DRW_SHADER_FREE_SAFE(e_data.update_noise_sh); - 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); DRW_SHADER_FREE_SAFE(e_data.probe_filter_visibility_sh); DRW_SHADER_FREE_SAFE(e_data.probe_grid_fill_sh); DRW_SHADER_FREE_SAFE(e_data.probe_planar_downsample_sh); - DRW_SHADER_FREE_SAFE(e_data.probe_default_studiolight_sh); - DRW_SHADER_FREE_SAFE(e_data.probe_background_studiolight_sh); + DRW_SHADER_FREE_SAFE(e_data.studiolight_probe_sh); + DRW_SHADER_FREE_SAFE(e_data.studiolight_background_sh); DRW_SHADER_FREE_SAFE(e_data.probe_grid_display_sh); DRW_SHADER_FREE_SAFE(e_data.probe_cube_display_sh); DRW_SHADER_FREE_SAFE(e_data.probe_planar_display_sh); DRW_SHADER_FREE_SAFE(e_data.velocity_resolve_sh); DRW_SHADER_FREE_SAFE(e_data.taa_resolve_sh); DRW_SHADER_FREE_SAFE(e_data.taa_resolve_reproject_sh); + DRW_SHADER_LIB_FREE_SAFE(e_data.lib); + if (e_data.default_world) { + BKE_id_free(NULL, e_data.default_world); + e_data.default_world = NULL; + } if (e_data.glossy_mat) { BKE_id_free(NULL, e_data.glossy_mat); e_data.glossy_mat = NULL; diff --git a/source/blender/draw/engines/eevee/eevee_shadows.c b/source/blender/draw/engines/eevee/eevee_shadows.c index 8c50b26b45f..71a4da9fcab 100644 --- a/source/blender/draw/engines/eevee/eevee_shadows.c +++ b/source/blender/draw/engines/eevee/eevee_shadows.c @@ -42,11 +42,6 @@ static struct { extern char datatoc_shadow_vert_glsl[]; extern char datatoc_shadow_frag_glsl[]; extern char datatoc_shadow_accum_frag_glsl[]; -extern char datatoc_common_view_lib_glsl[]; -extern char datatoc_common_uniforms_lib_glsl[]; -extern char datatoc_bsdf_common_lib_glsl[]; -extern char datatoc_lights_lib_glsl[]; -extern char datatoc_raytrace_lib_glsl[]; void eevee_contact_shadow_setup(const Light *la, EEVEE_Shadow *evsh) { @@ -65,23 +60,13 @@ void EEVEE_shadows_init(EEVEE_ViewLayerData *sldata) const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); if (!e_data.shadow_sh) { - e_data.shadow_sh = DRW_shader_create_with_lib(datatoc_shadow_vert_glsl, - NULL, - datatoc_shadow_frag_glsl, - datatoc_common_view_lib_glsl, - NULL); - } + DRWShaderLibrary *lib = EEVEE_shader_lib_get(); - if (!e_data.shadow_accum_sh) { - char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_common_uniforms_lib_glsl, - datatoc_bsdf_common_lib_glsl, - datatoc_raytrace_lib_glsl, - datatoc_lights_lib_glsl, - datatoc_shadow_accum_frag_glsl); + e_data.shadow_sh = DRW_shader_create_with_shaderlib( + datatoc_shadow_vert_glsl, NULL, datatoc_shadow_frag_glsl, lib, NULL); - e_data.shadow_accum_sh = DRW_shader_create_fullscreen(frag_str, SHADER_DEFINES); - MEM_freeN(frag_str); + e_data.shadow_accum_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_shadow_accum_frag_glsl, lib, SHADER_DEFINES); } if (!sldata->lights) { @@ -400,7 +385,7 @@ void EEVEE_shadow_output_init(EEVEE_ViewLayerData *sldata, EEVEE_EffectsInfo *effects = stl->effects; DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; /* Create FrameBuffer. */ const eGPUTextureFormat texture_format = GPU_R32F; diff --git a/source/blender/draw/engines/eevee/eevee_shadows_cascade.c b/source/blender/draw/engines/eevee/eevee_shadows_cascade.c index 1fd8d818b33..246bc18b71a 100644 --- a/source/blender/draw/engines/eevee/eevee_shadows_cascade.c +++ b/source/blender/draw/engines/eevee/eevee_shadows_cascade.c @@ -139,7 +139,7 @@ static void eevee_shadow_cascade_setup(EEVEE_LightsInfo *linfo, float jitter_ofs[2]; double ht_point[2]; double ht_offset[2] = {0.0, 0.0}; - uint ht_primes[2] = {2, 3}; + const uint ht_primes[2] = {2, 3}; BLI_halton_2d(ht_primes, ht_offset, sample_ofs, ht_point); diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c index ef4588f4aca..74fb7ac99b7 100644 --- a/source/blender/draw/engines/eevee/eevee_subsurface.c +++ b/source/blender/draw/engines/eevee/eevee_subsurface.c @@ -38,41 +38,19 @@ static struct { struct GPUShader *sss_sh[3]; } e_data = {{NULL}}; /* Engine data */ -extern char datatoc_common_view_lib_glsl[]; -extern char datatoc_common_uniforms_lib_glsl[]; -extern char datatoc_lights_lib_glsl[]; -extern char datatoc_raytrace_lib_glsl[]; -extern char datatoc_octahedron_lib_glsl[]; -extern char datatoc_cubemap_lib_glsl[]; -extern char datatoc_bsdf_sampling_lib_glsl[]; -extern char datatoc_bsdf_common_lib_glsl[]; extern char datatoc_effect_subsurface_frag_glsl[]; extern char datatoc_effect_translucency_frag_glsl[]; static void eevee_create_shader_subsurface(void) { - char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_common_uniforms_lib_glsl, - datatoc_effect_subsurface_frag_glsl); - - /* TODO(fclem) remove some of these dependencies. */ - char *frag_translucent_str = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_common_uniforms_lib_glsl, - datatoc_bsdf_common_lib_glsl, - datatoc_bsdf_sampling_lib_glsl, - datatoc_raytrace_lib_glsl, - datatoc_octahedron_lib_glsl, - datatoc_cubemap_lib_glsl, - datatoc_lights_lib_glsl, - datatoc_effect_translucency_frag_glsl); - - e_data.sss_sh[0] = DRW_shader_create_fullscreen(frag_str, "#define FIRST_PASS\n"); - 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_translucent_str, - "#define EEVEE_TRANSLUCENCY\n" SHADER_DEFINES); - - MEM_freeN(frag_translucent_str); - MEM_freeN(frag_str); + DRWShaderLibrary *lib = EEVEE_shader_lib_get(); + + e_data.sss_sh[0] = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_subsurface_frag_glsl, lib, "#define FIRST_PASS\n"); + e_data.sss_sh[1] = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_subsurface_frag_glsl, lib, "#define SECOND_PASS\n"); + e_data.sss_sh[2] = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_translucency_frag_glsl, lib, "#define EEVEE_TRANSLUCENCY\n" SHADER_DEFINES); } void EEVEE_subsurface_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *UNUSED(vedata)) @@ -188,7 +166,7 @@ void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata), * pass in look dev mode active. `texture_created` will make sure that newly created textures * are cleared. */ if (effects->taa_current_sample == 1 || texture_created) { - float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; GPU_framebuffer_bind(fbl->sss_accum_fb); GPU_framebuffer_clear_color(fbl->sss_accum_fb, clear); } @@ -304,7 +282,7 @@ void EEVEE_subsurface_data_render(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat EEVEE_EffectsInfo *effects = stl->effects; if ((effects->enabled_effects & EFFECT_SSS) != 0) { - float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; /* Clear sss_data texture only... can this be done in a more clever way? */ GPU_framebuffer_bind(fbl->sss_clear_fb); GPU_framebuffer_clear_color(fbl->sss_clear_fb, clear); @@ -342,7 +320,7 @@ void EEVEE_subsurface_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) EEVEE_EffectsInfo *effects = stl->effects; if ((effects->enabled_effects & EFFECT_SSS) != 0) { - float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; DRW_stats_group_start("SSS"); diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c index e184a80d2f6..12b50030435 100644 --- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c +++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c @@ -171,7 +171,7 @@ void EEVEE_temporal_sampling_update_matrices(EEVEE_Data *vedata) double ht_point[2]; double ht_offset[2] = {0.0, 0.0}; - uint ht_primes[2] = {2, 3}; + const uint ht_primes[2] = {2, 3}; BLI_halton_2d(ht_primes, ht_offset, effects->taa_current_sample - 1, ht_point); diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c index 300022e97a9..e1e65c29b4f 100644 --- a/source/blender/draw/engines/eevee/eevee_volumes.c +++ b/source/blender/draw/engines/eevee/eevee_volumes.c @@ -44,16 +44,12 @@ #include "DEG_depsgraph_query.h" -#include "GPU_draw.h" #include "GPU_extensions.h" #include "GPU_material.h" #include "GPU_texture.h" #include "eevee_private.h" static struct { - char *volumetric_common_lib; - char *volumetric_common_lights_lib; - struct GPUShader *volumetric_clear_sh; struct GPUShader *scatter_sh; struct GPUShader *scatter_with_lights_sh; @@ -97,57 +93,48 @@ extern char datatoc_common_fullscreen_vert_glsl[]; static void eevee_create_shader_volumes(void) { - e_data.volumetric_common_lib = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_common_uniforms_lib_glsl, - datatoc_bsdf_common_lib_glsl, - datatoc_volumetric_lib_glsl); - - e_data.volumetric_common_lights_lib = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_common_uniforms_lib_glsl, - datatoc_bsdf_common_lib_glsl, - datatoc_octahedron_lib_glsl, - datatoc_cubemap_lib_glsl, - datatoc_irradiance_lib_glsl, - datatoc_lights_lib_glsl, - datatoc_volumetric_lib_glsl); - - e_data.volumetric_clear_sh = DRW_shader_create_with_lib(datatoc_volumetric_vert_glsl, - datatoc_volumetric_geom_glsl, - datatoc_volumetric_frag_glsl, - e_data.volumetric_common_lib, - "#define VOLUMETRICS\n" - "#define CLEAR\n"); - e_data.scatter_sh = DRW_shader_create_with_lib(datatoc_volumetric_vert_glsl, - datatoc_volumetric_geom_glsl, - datatoc_volumetric_scatter_frag_glsl, - e_data.volumetric_common_lights_lib, - SHADER_DEFINES - "#define VOLUMETRICS\n" - "#define VOLUME_SHADOW\n"); - e_data.scatter_with_lights_sh = DRW_shader_create_with_lib(datatoc_volumetric_vert_glsl, - datatoc_volumetric_geom_glsl, - datatoc_volumetric_scatter_frag_glsl, - e_data.volumetric_common_lights_lib, - SHADER_DEFINES - "#define VOLUMETRICS\n" - "#define VOLUME_LIGHTING\n" - "#define VOLUME_SHADOW\n"); - e_data.volumetric_integration_sh = DRW_shader_create_with_lib( + DRWShaderLibrary *lib = EEVEE_shader_lib_get(); + + e_data.volumetric_clear_sh = DRW_shader_create_with_shaderlib(datatoc_volumetric_vert_glsl, + datatoc_volumetric_geom_glsl, + datatoc_volumetric_frag_glsl, + lib, + SHADER_DEFINES + "#define VOLUMETRICS\n" + "#define CLEAR\n"); + + e_data.scatter_sh = DRW_shader_create_with_shaderlib(datatoc_volumetric_vert_glsl, + datatoc_volumetric_geom_glsl, + datatoc_volumetric_scatter_frag_glsl, + lib, + SHADER_DEFINES + "#define VOLUMETRICS\n" + "#define VOLUME_SHADOW\n"); + + e_data.scatter_with_lights_sh = DRW_shader_create_with_shaderlib( + datatoc_volumetric_vert_glsl, + datatoc_volumetric_geom_glsl, + datatoc_volumetric_scatter_frag_glsl, + lib, + SHADER_DEFINES + "#define VOLUMETRICS\n" + "#define VOLUME_LIGHTING\n" + "#define VOLUME_SHADOW\n"); + + e_data.volumetric_integration_sh = DRW_shader_create_with_shaderlib( datatoc_volumetric_vert_glsl, datatoc_volumetric_geom_glsl, datatoc_volumetric_integration_frag_glsl, - e_data.volumetric_common_lib, + lib, USE_VOLUME_OPTI ? "#extension GL_ARB_shader_image_load_store: enable\n" "#extension GL_ARB_shading_language_420pack: enable\n" - "#define USE_VOLUME_OPTI\n" : - NULL); - e_data.volumetric_resolve_sh = DRW_shader_create_with_lib(datatoc_common_fullscreen_vert_glsl, - NULL, - datatoc_volumetric_resolve_frag_glsl, - e_data.volumetric_common_lib, - NULL); - e_data.volumetric_accum_sh = DRW_shader_create_fullscreen(datatoc_volumetric_accum_frag_glsl, - NULL); + "#define USE_VOLUME_OPTI\n" SHADER_DEFINES : + SHADER_DEFINES); + + e_data.volumetric_resolve_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_volumetric_resolve_frag_glsl, lib, SHADER_DEFINES); + e_data.volumetric_accum_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_volumetric_accum_frag_glsl, lib, SHADER_DEFINES); const float density[4] = {1.0f, 1.0f, 1.0f, 1.0f}; e_data.dummy_density = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, density); @@ -162,7 +149,7 @@ void EEVEE_volumes_set_jitter(EEVEE_ViewLayerData *sldata, uint current_sample) double ht_point[3]; double ht_offset[3] = {0.0, 0.0}; - uint ht_primes[3] = {3, 7, 2}; + const uint ht_primes[3] = {3, 7, 2}; BLI_halton_3d(ht_primes, ht_offset, current_sample, ht_point); @@ -259,17 +246,11 @@ void EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) common_data->vol_shadow_steps = 0; } - /* Update view_vecs */ - float invproj[4][4], winmat[4][4]; - DRW_view_winmat_get(NULL, winmat, false); - DRW_view_winmat_get(NULL, invproj, true); - EEVEE_update_viewvecs(invproj, winmat, sldata->common_data.view_vecs); - if (DRW_view_is_persp_get(NULL)) { float sample_distribution = scene_eval->eevee.volumetric_sample_distribution; sample_distribution = 4.0f * (max_ff(1.0f - sample_distribution, 1e-2f)); - const float clip_start = common_data->view_vecs[0][2]; + const float clip_start = DRW_view_near_distance_get(NULL); /* Negate */ float near = integration_start = min_ff(-integration_start, clip_start - 1e-4f); float far = integration_end = min_ff(-integration_end, near - 1e-4f); @@ -280,8 +261,8 @@ void EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) common_data->vol_depth_param[2] = sample_distribution; } else { - const float clip_start = common_data->view_vecs[0][2]; - const float clip_end = clip_start + common_data->view_vecs[1][2]; + const float clip_start = DRW_view_near_distance_get(NULL); + const float clip_end = DRW_view_far_distance_get(NULL); integration_start = min_ff(integration_end, clip_start); integration_end = max_ff(-integration_end, clip_end); @@ -298,8 +279,8 @@ void EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) common_data->vol_use_lights = (scene_eval->eevee.flag & SCE_EEVEE_VOLUMETRIC_LIGHTS) != 0; if (!e_data.dummy_scatter) { - float scatter[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - float transmit[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + const float scatter[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float transmit[4] = {1.0f, 1.0f, 1.0f, 1.0f}; e_data.dummy_scatter = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, scatter); e_data.dummy_transmit = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, transmit); } @@ -504,12 +485,7 @@ static bool eevee_volume_object_mesh_init(Scene *scene, #endif if (fds->fluid && (fds->type == FLUID_DOMAIN_TYPE_GAS) /* && show_smoke */) { - if (!(fds->flags & FLUID_DOMAIN_USE_NOISE)) { - GPU_create_smoke(fmd, 0); - } - else if (fds->flags & FLUID_DOMAIN_USE_NOISE) { - GPU_create_smoke(fmd, 1); - } + DRW_smoke_ensure(fmd, fds->flags & FLUID_DOMAIN_USE_NOISE); BLI_addtail(&e_data.smoke_domains, BLI_genericNodeN(fmd)); } @@ -841,16 +817,13 @@ void EEVEE_volumes_free_smoke_textures(void) /* Free Smoke Textures after rendering */ LISTBASE_FOREACH (LinkData *, link, &e_data.smoke_domains) { FluidModifierData *fmd = (FluidModifierData *)link->data; - GPU_free_smoke(fmd); + DRW_smoke_free(fmd); } BLI_freelistN(&e_data.smoke_domains); } void EEVEE_volumes_free(void) { - MEM_SAFE_FREE(e_data.volumetric_common_lib); - MEM_SAFE_FREE(e_data.volumetric_common_lights_lib); - DRW_TEXTURE_FREE_SAFE(e_data.dummy_scatter); DRW_TEXTURE_FREE_SAFE(e_data.dummy_transmit); @@ -879,7 +852,7 @@ void EEVEE_volumes_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, EEVEE_PassList *psl = vedata->psl; EEVEE_EffectsInfo *effects = stl->effects; - float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; /* Create FrameBuffer. */ diff --git a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl index 57b16418696..2f6f8327f58 100644 --- a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl @@ -1,4 +1,7 @@ +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(raytrace_lib.glsl) + /* Based on Practical Realtime Strategies for Accurate Indirect Occlusion * http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pdf * http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pptx @@ -24,12 +27,6 @@ #define MAX_SEARCH_ITER 32 #define MAX_LOD 6.0 -#ifndef UTIL_TEX -# define UTIL_TEX -uniform sampler2DArray utilTex; -# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0) -#endif /* UTIL_TEX */ - uniform sampler2D horizonBuffer; /* aoSettings flags */ @@ -243,6 +240,11 @@ float gtao_multibounce(float visibility, vec3 albedo) return max(x, ((x * a + b) * x + c) * x); } +float specular_occlusion(float NV, float AO, float roughness) +{ + return saturate(pow(NV + AO, roughness) - 1.0 + AO); +} + /* Use the right occlusion */ float occlusion_compute(vec3 N, vec3 vpos, float user_occlusion, vec4 rand, out vec3 bent_normal) { diff --git a/source/blender/draw/engines/eevee/shaders/background_vert.glsl b/source/blender/draw/engines/eevee/shaders/background_vert.glsl index aff8e0857f6..ab5d9a7ebe4 100644 --- a/source/blender/draw/engines/eevee/shaders/background_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/background_vert.glsl @@ -1,17 +1,17 @@ -in vec2 pos; +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(surface_lib.glsl) -out vec3 viewPosition; +in vec2 pos; -#ifndef VOLUMETRICS -/* necessary for compilation*/ -out vec3 worldPosition; -out vec3 worldNormal; -out vec3 viewNormal; -#endif +RESOURCE_ID_VARYING void main() { + GPU_INTEL_VERTEX_SHADER_WORKAROUND + + PASS_RESOURCE_ID + gl_Position = vec4(pos, 1.0, 1.0); viewPosition = vec3(pos, -1.0); @@ -22,6 +22,6 @@ void main() #endif #ifdef USE_ATTR - pass_attr(viewPosition); + pass_attr(viewPosition, NormalMatrix, ModelMatrixInverse); #endif } 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 a8b8566edec..deedde64194 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl @@ -1,487 +1,7 @@ -#define M_PI 3.14159265358979323846 /* pi */ -#define M_2PI 6.28318530717958647692 /* 2*pi */ -#define M_PI_2 1.57079632679489661923 /* pi/2 */ -#define M_1_PI 0.318309886183790671538 /* 1/pi */ -#define M_1_2PI 0.159154943091895335768 /* 1/(2*pi) */ -#define M_1_PI2 0.101321183642337771443 /* 1/(pi^2) */ -#define FLT_MAX 3.402823e+38 +#pragma BLENDER_REQUIRE(common_math_lib.glsl) -#define LUT_SIZE 64 - -/* Buffers */ -uniform sampler2D colorBuffer; -uniform sampler2D depthBuffer; -uniform sampler2D maxzBuffer; -uniform sampler2D minzBuffer; -uniform sampler2DArray planarDepth; - -#define cameraForward ViewMatrixInverse[2].xyz -#define cameraPos ViewMatrixInverse[3].xyz -#define cameraVec \ - ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward) -#define viewCameraVec \ - ((ProjectionMatrix[3][3] == 0.0) ? normalize(-viewPosition) : vec3(0.0, 0.0, 1.0)) - -/* ------- Structures -------- */ - -/* ------ Lights ----- */ -struct LightData { - vec4 position_influence; /* w : InfluenceRadius (inversed and squared) */ - vec4 color_spec; /* w : Spec Intensity */ - vec4 spotdata_radius_shadow; /* x : spot size, y : spot blend, z : radius, w: shadow id */ - vec4 rightvec_sizex; /* xyz: Normalized up vector, w: area size X or spot scale X */ - vec4 upvec_sizey; /* xyz: Normalized right vector, w: area size Y or spot scale Y */ - vec4 forwardvec_type; /* xyz: Normalized forward vector, w: Light Type */ -}; - -/* convenience aliases */ -#define l_color color_spec.rgb -#define l_spec color_spec.a -#define l_position position_influence.xyz -#define l_influence position_influence.w -#define l_sizex rightvec_sizex.w -#define l_sizey upvec_sizey.w -#define l_right rightvec_sizex.xyz -#define l_up upvec_sizey.xyz -#define l_forward forwardvec_type.xyz -#define l_type forwardvec_type.w -#define l_spot_size spotdata_radius_shadow.x -#define l_spot_blend spotdata_radius_shadow.y -#define l_radius spotdata_radius_shadow.z -#define l_shadowid spotdata_radius_shadow.w - -/* ------ Shadows ----- */ -#ifndef MAX_CASCADE_NUM -# define MAX_CASCADE_NUM 4 -#endif - -struct ShadowData { - vec4 near_far_bias_id; - vec4 contact_shadow_data; -}; - -struct ShadowCubeData { - mat4 shadowmat; - vec4 position; -}; - -struct ShadowCascadeData { - mat4 shadowmat[MAX_CASCADE_NUM]; - vec4 split_start_distances; - vec4 split_end_distances; - vec4 shadow_vec_id; -}; - -/* convenience aliases */ -#define sh_near near_far_bias_id.x -#define sh_far near_far_bias_id.y -#define sh_bias near_far_bias_id.z -#define sh_data_index near_far_bias_id.w -#define sh_contact_dist contact_shadow_data.x -#define sh_contact_offset contact_shadow_data.y -#define sh_contact_spread contact_shadow_data.z -#define sh_contact_thickness contact_shadow_data.w -#define sh_shadow_vec shadow_vec_id.xyz -#define sh_tex_index shadow_vec_id.w - -/* ------ Render Passes ----- */ -layout(std140) uniform renderpass_block -{ - bool renderPassDiffuse; - bool renderPassDiffuseLight; - bool renderPassGlossy; - bool renderPassGlossyLight; - bool renderPassEmit; - bool renderPassSSSColor; - bool renderPassEnvironment; -}; - -vec3 render_pass_diffuse_mask(vec3 diffuse_color, vec3 diffuse_light) -{ - return renderPassDiffuse ? (renderPassDiffuseLight ? diffuse_light : diffuse_color) : vec3(0.0); -} - -vec3 render_pass_sss_mask(vec3 sss_color) -{ - return renderPassSSSColor ? sss_color : vec3(0.0); -} - -vec3 render_pass_glossy_mask(vec3 specular_color, vec3 specular_light) -{ - return renderPassGlossy ? (renderPassGlossyLight ? specular_light : specular_color) : vec3(0.0); -} - -vec3 render_pass_emission_mask(vec3 emission_light) -{ - return renderPassEmit ? emission_light : vec3(0.0); -} - -/* ------- Convenience functions --------- */ - -vec3 mul(mat3 m, vec3 v) -{ - return m * v; -} -mat3 mul(mat3 m1, mat3 m2) -{ - return m1 * m2; -} -vec3 transform_direction(mat4 m, vec3 v) -{ - return mat3(m) * v; -} -vec3 transform_point(mat4 m, vec3 v) -{ - return (m * vec4(v, 1.0)).xyz; -} -vec3 project_point(mat4 m, vec3 v) -{ - vec4 tmp = m * vec4(v, 1.0); - return tmp.xyz / tmp.w; -} - -#define min3(a, b, c) min(a, min(b, c)) -#define min4(a, b, c, d) min(a, min3(b, c, d)) -#define min5(a, b, c, d, e) min(a, min4(b, c, d, e)) -#define min6(a, b, c, d, e, f) min(a, min5(b, c, d, e, f)) -#define min7(a, b, c, d, e, f, g) min(a, min6(b, c, d, e, f, g)) -#define min8(a, b, c, d, e, f, g, h) min(a, min7(b, c, d, e, f, g, h)) -#define min9(a, b, c, d, e, f, g, h, i) min(a, min8(b, c, d, e, f, g, h, i)) - -#define max3(a, b, c) max(a, max(b, c)) -#define max4(a, b, c, d) max(a, max3(b, c, d)) -#define max5(a, b, c, d, e) max(a, max4(b, c, d, e)) -#define max6(a, b, c, d, e, f) max(a, max5(b, c, d, e, f)) -#define max7(a, b, c, d, e, f, g) max(a, max6(b, c, d, e, f, g)) -#define max8(a, b, c, d, e, f, g, h) max(a, max7(b, c, d, e, f, g, h)) -#define max9(a, b, c, d, e, f, g, h, i) max(a, max8(b, c, d, e, f, g, h, i)) - -#define avg3(a, b, c) (a + b + c) * (1.0 / 3.0) -#define avg4(a, b, c, d) (a + b + c + d) * (1.0 / 4.0) -#define avg5(a, b, c, d, e) (a + b + c + d + e) * (1.0 / 5.0) -#define avg6(a, b, c, d, e, f) (a + b + c + d + e + f) * (1.0 / 6.0) -#define avg7(a, b, c, d, e, f, g) (a + b + c + d + e + f + g) * (1.0 / 7.0) -#define avg8(a, b, c, d, e, f, g, h) (a + b + c + d + e + f + g + h) * (1.0 / 8.0) -#define avg9(a, b, c, d, e, f, g, h, i) (a + b + c + d + e + f + g + h + i) * (1.0 / 9.0) - -float min_v2(vec2 v) -{ - return min(v.x, v.y); -} -float min_v3(vec3 v) -{ - return min(v.x, min(v.y, v.z)); -} -float min_v4(vec4 v) -{ - return min(min(v.x, v.y), min(v.z, v.w)); -} -float max_v2(vec2 v) -{ - return max(v.x, v.y); -} -float max_v3(vec3 v) -{ - return max(v.x, max(v.y, v.z)); -} -float max_v4(vec4 v) -{ - return max(max(v.x, v.y), max(v.z, v.w)); -} - -float sum(vec2 v) -{ - return dot(vec2(1.0), v); -} -float sum(vec3 v) -{ - return dot(vec3(1.0), v); -} -float sum(vec4 v) -{ - return dot(vec4(1.0), v); -} - -float avg(vec2 v) -{ - return dot(vec2(1.0 / 2.0), v); -} -float avg(vec3 v) -{ - return dot(vec3(1.0 / 3.0), v); -} -float avg(vec4 v) -{ - return dot(vec4(1.0 / 4.0), v); -} - -float saturate(float a) -{ - return clamp(a, 0.0, 1.0); -} -vec2 saturate(vec2 a) -{ - return clamp(a, 0.0, 1.0); -} -vec3 saturate(vec3 a) -{ - return clamp(a, 0.0, 1.0); -} -vec4 saturate(vec4 a) -{ - return clamp(a, 0.0, 1.0); -} - -float distance_squared(vec2 a, vec2 b) -{ - a -= b; - return dot(a, a); -} -float distance_squared(vec3 a, vec3 b) -{ - a -= b; - return dot(a, a); -} -float len_squared(vec3 a) -{ - return dot(a, a); -} - -float inverse_distance(vec3 V) -{ - return max(1 / length(V), 1e-8); -} - -vec2 mip_ratio_interp(float mip) -{ - float low_mip = floor(mip); - return mix(mipRatio[int(low_mip)], mipRatio[int(low_mip + 1.0)], mip - low_mip); -} - -/* ------- RNG ------- */ - -float wang_hash_noise(uint s) -{ - s = (s ^ 61u) ^ (s >> 16u); - s *= 9u; - s = s ^ (s >> 4u); - s *= 0x27d4eb2du; - s = s ^ (s >> 15u); - - return fract(float(s) / 4294967296.0); -} - -/* ------- Fast Math ------- */ - -/* [Drobot2014a] Low Level Optimizations for GCN */ -float fast_sqrt(float v) -{ - return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1)); -} - -vec2 fast_sqrt(vec2 v) -{ - return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1)); -} - -/* [Eberly2014] GPGPU Programming for Games and Science */ -float fast_acos(float v) -{ - float res = -0.156583 * abs(v) + M_PI_2; - res *= fast_sqrt(1.0 - abs(v)); - return (v >= 0) ? res : M_PI - res; -} - -vec2 fast_acos(vec2 v) -{ - vec2 res = -0.156583 * abs(v) + M_PI_2; - res *= fast_sqrt(1.0 - abs(v)); - v.x = (v.x >= 0) ? res.x : M_PI - res.x; - v.y = (v.y >= 0) ? res.y : M_PI - res.y; - return v; -} - -float point_plane_projection_dist(vec3 lineorigin, vec3 planeorigin, vec3 planenormal) -{ - return dot(planenormal, planeorigin - lineorigin); -} - -float line_plane_intersect_dist(vec3 lineorigin, - vec3 linedirection, - vec3 planeorigin, - vec3 planenormal) -{ - return dot(planenormal, planeorigin - lineorigin) / dot(planenormal, linedirection); -} - -float line_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec4 plane) -{ - vec3 plane_co = plane.xyz * (-plane.w / len_squared(plane.xyz)); - vec3 h = lineorigin - plane_co; - return -dot(plane.xyz, h) / dot(plane.xyz, linedirection); -} - -vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal) -{ - float dist = line_plane_intersect_dist(lineorigin, linedirection, planeorigin, planenormal); - return lineorigin + linedirection * dist; -} - -vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec4 plane) -{ - float dist = line_plane_intersect_dist(lineorigin, linedirection, plane); - return lineorigin + linedirection * dist; -} - -float line_aligned_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin) -{ - /* aligned plane normal */ - vec3 L = planeorigin - lineorigin; - float diskdist = length(L); - vec3 planenormal = -normalize(L); - return -diskdist / dot(planenormal, linedirection); -} - -vec3 line_aligned_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin) -{ - float dist = line_aligned_plane_intersect_dist(lineorigin, linedirection, planeorigin); - if (dist < 0) { - /* if intersection is behind we fake the intersection to be - * really far and (hopefully) not inside the radius of interest */ - dist = 1e16; - } - return lineorigin + linedirection * dist; -} - -float line_unit_sphere_intersect_dist(vec3 lineorigin, vec3 linedirection) -{ - float a = dot(linedirection, linedirection); - float b = dot(linedirection, lineorigin); - float c = dot(lineorigin, lineorigin) - 1; - - float dist = 1e15; - float determinant = b * b - a * c; - if (determinant >= 0) { - dist = (sqrt(determinant) - b) / a; - } - - return dist; -} - -float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection) -{ - /* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ - */ - vec3 firstplane = (vec3(1.0) - lineorigin) / linedirection; - vec3 secondplane = (vec3(-1.0) - lineorigin) / linedirection; - vec3 furthestplane = max(firstplane, secondplane); - - return min_v3(furthestplane); -} - -/* Return texture coordinates to sample Surface LUT */ -vec2 lut_coords(float cosTheta, float roughness) -{ - float theta = acos(cosTheta); - vec2 coords = vec2(roughness, theta / M_PI_2); - - /* scale and bias coordinates, for correct filtered lookup */ - return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE; -} - -vec2 lut_coords_ltc(float cosTheta, float roughness) -{ - vec2 coords = vec2(roughness, sqrt(1.0 - cosTheta)); - - /* scale and bias coordinates, for correct filtered lookup */ - return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE; -} - -/* -- Tangent Space conversion -- */ -vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B) -{ - return T * vector.x + B * vector.y + N * vector.z; -} - -vec3 world_to_tangent(vec3 vector, vec3 N, vec3 T, vec3 B) -{ - return vec3(dot(T, vector), dot(B, vector), dot(N, vector)); -} - -void make_orthonormal_basis(vec3 N, out vec3 T, out vec3 B) -{ - vec3 UpVector = abs(N.z) < 0.99999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); - T = normalize(cross(UpVector, N)); - B = cross(N, T); -} - -/* ---- Opengl Depth conversion ---- */ - -float linear_depth(bool is_persp, float z, float zf, float zn) -{ - if (is_persp) { - return (zn * zf) / (z * (zn - zf) + zf); - } - else { - return (z * 2.0 - 1.0) * zf; - } -} - -float buffer_depth(bool is_persp, float z, float zf, float zn) -{ - if (is_persp) { - return (zf * (zn - z)) / (z * (zn - zf)); - } - else { - return (z / (zf * 2.0)) + 0.5; - } -} - -float get_view_z_from_depth(float depth) -{ - if (ProjectionMatrix[3][3] == 0.0) { - float d = 2.0 * depth - 1.0; - return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]); - } - else { - return viewVecs[0].z + depth * viewVecs[1].z; - } -} - -float get_depth_from_view_z(float z) -{ - if (ProjectionMatrix[3][3] == 0.0) { - float d = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2]; - return d * 0.5 + 0.5; - } - else { - return (z - viewVecs[0].z) / viewVecs[1].z; - } -} - -vec2 get_uvs_from_view(vec3 view) -{ - vec3 ndc = project_point(ProjectionMatrix, view); - return ndc.xy * 0.5 + 0.5; -} - -vec3 get_view_space_from_depth(vec2 uvcoords, float depth) -{ - if (ProjectionMatrix[3][3] == 0.0) { - 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; - } -} - -vec3 get_world_space_from_depth(vec2 uvcoords, float depth) -{ - return (ViewMatrixInverse * vec4(get_view_space_from_depth(uvcoords, depth), 1.0)).xyz; -} - -vec3 get_specular_reflection_dominant_dir(vec3 N, vec3 V, float roughness) +vec3 specular_dominant_dir(vec3 N, vec3 V, float roughness) { vec3 R = -reflect(V, N); float smoothness = 1.0 - roughness; @@ -489,13 +9,6 @@ vec3 get_specular_reflection_dominant_dir(vec3 N, vec3 V, float roughness) return normalize(mix(N, R, fac)); } -float specular_occlusion(float NV, float AO, float roughness) -{ - return saturate(pow(NV + AO, roughness) - 1.0 + AO); -} - -/* --- Refraction utils --- */ - float ior_from_f0(float f0) { float f = sqrt(f0); @@ -508,7 +21,7 @@ float f0_from_ior(float eta) return A * A; } -vec3 get_specular_refraction_dominant_dir(vec3 N, vec3 V, float roughness, float ior) +vec3 refraction_dominant_dir(vec3 N, vec3 V, float roughness, float ior) { /* TODO: This a bad approximation. Better approximation should fit * the refracted vector and roughness into the best prefiltered reflection @@ -527,128 +40,6 @@ vec3 get_specular_refraction_dominant_dir(vec3 N, vec3 V, float roughness, float return R; } -float get_btdf_lut(sampler2DArray btdf_lut_tex, float NV, float roughness, float ior) -{ - const vec3 lut_scale_bias_texel_size = vec3((LUT_SIZE - 1.0), 0.5, 1.5) / LUT_SIZE; - - vec3 coords; - /* Try to compensate for the low resolution and interpolation error. */ - coords.x = (ior > 1.0) ? (0.9 + lut_scale_bias_texel_size.z) + - (0.1 - lut_scale_bias_texel_size.z) * f0_from_ior(ior) : - (0.9 + lut_scale_bias_texel_size.z) * ior * ior; - coords.y = 1.0 - saturate(NV); - coords.xy *= lut_scale_bias_texel_size.x; - coords.xy += lut_scale_bias_texel_size.y; - - const float lut_lvl_ofs = 4.0; /* First texture lvl of roughness. */ - const float lut_lvl_scale = 16.0; /* How many lvl of roughness in the lut. */ - - float mip = roughness * lut_lvl_scale; - float mip_floor = floor(mip); - - coords.z = lut_lvl_ofs + mip_floor + 1.0; - float btdf_high = textureLod(btdf_lut_tex, coords, 0.0).r; - - coords.z -= 1.0; - float btdf_low = textureLod(btdf_lut_tex, coords, 0.0).r; - - float btdf = (ior == 1.0) ? 1.0 : mix(btdf_low, btdf_high, mip - coords.z); - - return btdf; -} - -/* ---- Encode / Decode Normal buffer data ---- */ -/* From http://aras-p.info/texts/CompactNormalStorage.html - * 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; -} - -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; -} - -/* ---- RGBM (shared multiplier) encoding ---- */ -/* From http://iwasbeingirony.blogspot.fr/2010/06/difference-between-rgbm-and-rgbd.html */ - -/* Higher RGBM_MAX_RANGE gives imprecision issues in low intensity. */ -#define RGBM_MAX_RANGE 512.0 - -vec4 rgbm_encode(vec3 rgb) -{ - float maxRGB = max_v3(rgb); - float M = maxRGB / RGBM_MAX_RANGE; - M = ceil(M * 255.0) / 255.0; - return vec4(rgb / (M * RGBM_MAX_RANGE), M); -} - -vec3 rgbm_decode(vec4 data) -{ - return data.rgb * (data.a * RGBM_MAX_RANGE); -} - -/* ---- RGBE (shared exponent) encoding ---- */ -vec4 rgbe_encode(vec3 rgb) -{ - float maxRGB = max_v3(rgb); - float fexp = ceil(log2(maxRGB)); - return vec4(rgb / exp2(fexp), (fexp + 128.0) / 255.0); -} - -vec3 rgbe_decode(vec4 data) -{ - float fexp = data.a * 255.0 - 128.0; - return data.rgb * exp2(fexp); -} - -#if 1 -# define irradiance_encode rgbe_encode -# define irradiance_decode rgbe_decode -#else /* No ecoding (when using floating point format) */ -# define irradiance_encode(X) (X).rgbb -# define irradiance_decode(X) (X).rgb -#endif - -/* Irradiance Visibility Encoding */ -#if 1 -vec4 visibility_encode(vec2 accum, float range) -{ - accum /= range; - - vec4 data; - data.x = fract(accum.x); - data.y = floor(accum.x) / 255.0; - data.z = fract(accum.y); - data.w = floor(accum.y) / 255.0; - - return data; -} - -vec2 visibility_decode(vec4 data, float range) -{ - return (data.xz + data.yw * 255.0) * range; -} -#else /* No ecoding (when using floating point format) */ -vec4 visibility_encode(vec2 accum, float range) -{ - return accum.xyxy; -} - -vec2 visibility_decode(vec4 data, float range) -{ - return data.xy; -} -#endif - /* Fresnel monochromatic, perfect mirror */ float F_eta(float eta, float cos_theta) { @@ -766,265 +157,3 @@ float cone_cosine(float r) /* Jimenez 2016 in Practical Realtime Strategies for Accurate Indirect Occlusion*/ return exp2(-3.32193 * r * r); } - -/* --------- Closure ---------- */ - -#ifdef VOLUMETRICS - -struct Closure { - vec3 absorption; - vec3 scatter; - vec3 emission; - float anisotropy; -}; - -Closure nodetree_exec(void); /* Prototype */ - -# define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), vec3(0.0), 0.0) - -Closure closure_mix(Closure cl1, Closure cl2, float fac) -{ - Closure cl; - cl.absorption = mix(cl1.absorption, cl2.absorption, fac); - cl.scatter = mix(cl1.scatter, cl2.scatter, fac); - cl.emission = mix(cl1.emission, cl2.emission, fac); - cl.anisotropy = mix(cl1.anisotropy, cl2.anisotropy, fac); - return cl; -} - -Closure closure_add(Closure cl1, Closure cl2) -{ - Closure cl; - cl.absorption = cl1.absorption + cl2.absorption; - cl.scatter = cl1.scatter + cl2.scatter; - cl.emission = cl1.emission + cl2.emission; - cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */ - return cl; -} - -Closure closure_emission(vec3 rgb) -{ - Closure cl = CLOSURE_DEFAULT; - cl.emission = rgb; - return cl; -} - -#else /* VOLUMETRICS */ - -struct Closure { - vec3 radiance; - vec3 transmittance; - float holdout; -# ifdef USE_SSS - vec3 sss_irradiance; - vec3 sss_albedo; - float sss_radius; -# endif - vec4 ssr_data; - vec2 ssr_normal; - int flag; -}; - -Closure nodetree_exec(void); /* Prototype */ - -# define FLAG_TEST(flag, val) (((flag) & (val)) != 0) - -# define CLOSURE_SSR_FLAG 1 -# define CLOSURE_SSS_FLAG 2 -# define CLOSURE_HOLDOUT_FLAG 4 - -# ifdef USE_SSS -# define CLOSURE_DEFAULT \ - Closure(vec3(0.0), vec3(0.0), 0.0, vec3(0.0), vec3(0.0), 0.0, vec4(0.0), vec2(0.0), 0) -# else -# define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), 0.0, vec4(0.0), vec2(0.0), 0) -# endif - -uniform int outputSsrId = 1; -uniform int outputSssId = 1; - -void closure_load_ssr_data( - vec3 ssr_spec, float roughness, vec3 N, vec3 viewVec, int ssr_id, inout Closure cl) -{ - /* Still encode to avoid artifacts in the SSR pass. */ - vec3 vN = normalize(mat3(ViewMatrix) * N); - cl.ssr_normal = normal_encode(vN, viewVec); - - if (ssr_id == outputSsrId) { - cl.ssr_data = vec4(ssr_spec, roughness); - cl.flag |= CLOSURE_SSR_FLAG; - } -} - -void closure_load_sss_data( - float radius, vec3 sss_irradiance, vec3 sss_albedo, int sss_id, inout Closure cl) -{ -# ifdef USE_SSS - if (sss_id == outputSssId) { - cl.sss_irradiance = sss_irradiance; - cl.sss_radius = radius; - cl.sss_albedo = sss_albedo; - cl.flag |= CLOSURE_SSS_FLAG; - cl.radiance += render_pass_diffuse_mask(sss_albedo, vec3(0)); - } - else -# endif - { - cl.radiance += render_pass_diffuse_mask(sss_albedo, sss_irradiance * sss_albedo); - } -} - -Closure closure_mix(Closure cl1, Closure cl2, float fac) -{ - Closure cl; - cl.holdout = mix(cl1.holdout, cl2.holdout, fac); - - if (FLAG_TEST(cl1.flag, CLOSURE_HOLDOUT_FLAG)) { - fac = 1.0; - } - else if (FLAG_TEST(cl2.flag, CLOSURE_HOLDOUT_FLAG)) { - fac = 0.0; - } - - cl.transmittance = mix(cl1.transmittance, cl2.transmittance, fac); - cl.radiance = mix(cl1.radiance, cl2.radiance, fac); - cl.flag = cl1.flag | cl2.flag; - cl.ssr_data = mix(cl1.ssr_data, cl2.ssr_data, fac); - bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG); - /* When mixing SSR don't blend roughness and normals but only specular (ssr_data.xyz).*/ - cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w; - cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal; - -# ifdef USE_SSS - cl.sss_albedo = mix(cl1.sss_albedo, cl2.sss_albedo, fac); - bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG); - /* It also does not make sense to mix SSS radius or irradiance. */ - cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius; - cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance; -# endif - return cl; -} - -Closure closure_add(Closure cl1, Closure cl2) -{ - Closure cl; - cl.transmittance = cl1.transmittance + cl2.transmittance; - cl.radiance = cl1.radiance + cl2.radiance; - cl.holdout = cl1.holdout + cl2.holdout; - cl.flag = cl1.flag | cl2.flag; - cl.ssr_data = cl1.ssr_data + cl2.ssr_data; - bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG); - /* When mixing SSR don't blend roughness and normals.*/ - cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w; - cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal; - -# ifdef USE_SSS - cl.sss_albedo = cl1.sss_albedo + cl2.sss_albedo; - bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG); - /* It also does not make sense to mix SSS radius or irradiance. */ - cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius; - cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance; -# endif - return cl; -} - -Closure closure_emission(vec3 rgb) -{ - Closure cl = CLOSURE_DEFAULT; - cl.radiance = rgb; - return cl; -} - -/* Breaking this across multiple lines causes issues for some older GLSL compilers. */ -/* clang-format off */ -# if defined(MESH_SHADER) && !defined(DEPTH_SHADER) -/* clang-format on */ -# ifndef USE_ALPHA_BLEND -layout(location = 0) out vec4 outRadiance; -layout(location = 1) out vec2 ssrNormals; -layout(location = 2) out vec4 ssrData; -# ifdef USE_SSS -layout(location = 3) out vec3 sssIrradiance; -layout(location = 4) out float sssRadius; -layout(location = 5) out vec3 sssAlbedo; -# endif -# else /* USE_ALPHA_BLEND */ -/* Use dual source blending to be able to make a whole range of effects. */ -layout(location = 0, index = 0) out vec4 outRadiance; -layout(location = 0, index = 1) out vec4 outTransmittance; -# endif /* USE_ALPHA_BLEND */ - -# if defined(USE_ALPHA_BLEND) -/* Prototype because this file is included before volumetric_lib.glsl */ -void volumetric_resolve(vec2 frag_uvs, - float frag_depth, - out vec3 transmittance, - out vec3 scattering); -# endif - -# define NODETREE_EXEC -void main() -{ - Closure cl = nodetree_exec(); - - float holdout = saturate(1.0 - cl.holdout); - float transmit = saturate(avg(cl.transmittance)); - float alpha = 1.0 - transmit; - -# ifdef USE_ALPHA_BLEND - vec2 uvs = gl_FragCoord.xy * volCoordScale.zw; - vec3 vol_transmit, vol_scatter; - volumetric_resolve(uvs, gl_FragCoord.z, vol_transmit, vol_scatter); - - /* Removes part of the volume scattering that have - * already been added to the destination pixels. - * Since we do that using the blending pipeline we need to account for material transmittance. */ - vol_scatter -= vol_scatter * cl.transmittance; - - cl.radiance = cl.radiance * holdout * vol_transmit + vol_scatter; - outRadiance = vec4(cl.radiance, alpha * holdout); - outTransmittance = vec4(cl.transmittance, transmit) * holdout; -# else - outRadiance = vec4(cl.radiance, holdout); - ssrNormals = cl.ssr_normal; - ssrData = cl.ssr_data; -# ifdef USE_SSS - sssIrradiance = cl.sss_irradiance; - sssRadius = cl.sss_radius; - sssAlbedo = cl.sss_albedo; -# endif -# endif - - /* For Probe capture */ -# ifdef USE_SSS - float fac = float(!sssToggle); - - /* TODO(fclem) we shouldn't need this. - * Just disable USE_SSS when USE_REFRACTION is enabled. */ -# ifdef USE_REFRACTION - /* SSRefraction pass is done after the SSS pass. - * In order to not loose the diffuse light totally we - * need to merge the SSS radiance to the main radiance. */ - fac = 1.0; -# endif - - outRadiance.rgb += cl.sss_irradiance.rgb * cl.sss_albedo.rgb * fac; -# endif - -# ifdef LOOKDEV - gl_FragDepth = 0.0; -# endif - -# ifndef USE_ALPHA_BLEND - float alpha_div = 1.0 / max(1e-8, alpha); - outRadiance.rgb *= alpha_div; - ssrData.rgb *= alpha_div; -# ifdef USE_SSS - sssAlbedo.rgb *= alpha_div; -# endif -# endif -} - -# endif /* MESH_SHADER */ - -#endif /* VOLUMETRICS */ diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl index f05b3396428..2b2da884fde 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl @@ -1,3 +1,4 @@ +#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl) out vec4 FragColor; @@ -5,8 +6,8 @@ void main() { vec3 N, T, B, V; - float NV = (1.0 - (clamp(gl_FragCoord.y / BRDF_LUT_SIZE, 1e-4, 0.9999))); - float sqrtRoughness = clamp(gl_FragCoord.x / BRDF_LUT_SIZE, 1e-4, 0.9999); + float NV = (1.0 - (clamp(gl_FragCoord.y / b, 1e-4, 0.9999))); + float sqrtRoughness = clamp(gl_FragCoord.x / LUT_SIZE, 1e-4, 0.9999); float a = sqrtRoughness * sqrtRoughness; float a2 = a * a; diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl index 5f2b719095e..066ea58e2bf 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl @@ -1,6 +1,7 @@ +#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl) + uniform sampler1D texHammersley; -uniform sampler2D texJitter; uniform float sampleCount; uniform float invSampleCount; @@ -8,8 +9,7 @@ vec2 jitternoise = vec2(0.0); #ifndef UTIL_TEX # define UTIL_TEX -uniform sampler2DArray utilTex; -# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0) + #endif /* UTIL_TEX */ void setup_noise(void) @@ -17,6 +17,11 @@ void setup_noise(void) jitternoise = texelfetch_noise_tex(gl_FragCoord.xy).rg; /* Global variable */ } +vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B) +{ + return T * vector.x + B * vector.y + N * vector.z; +} + #ifdef HAMMERSLEY_SIZE vec3 hammersley_3d(float i, float invsamplenbr) { diff --git a/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl b/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl index 1389a9763c0..d815d9d4e6b 100644 --- a/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl @@ -1,3 +1,4 @@ +#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl) uniform float a2; @@ -7,8 +8,8 @@ void main() { vec3 N, T, B, V; - float x = gl_FragCoord.x / BRDF_LUT_SIZE; - float y = gl_FragCoord.y / BRDF_LUT_SIZE; + float x = gl_FragCoord.x / LUT_SIZE; + float y = gl_FragCoord.y / LUT_SIZE; /* There is little variation if ior > 1.0 so we * maximize LUT precision for ior < 1.0 */ x = x * 1.1; diff --git a/source/blender/draw/engines/eevee/shaders/closure_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_lib.glsl new file mode 100644 index 00000000000..e572245ace9 --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/closure_lib.glsl @@ -0,0 +1,181 @@ + +#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) +#pragma BLENDER_REQUIRE(renderpass_lib.glsl) + +#ifndef VOLUMETRICS + +uniform int outputSsrId = 1; +uniform int outputSssId = 1; + +#endif + +struct Closure { +#ifdef VOLUMETRICS + vec3 absorption; + vec3 scatter; + vec3 emission; + float anisotropy; + +#else /* SURFACE */ + vec3 radiance; + vec3 transmittance; + float holdout; + vec4 ssr_data; + vec2 ssr_normal; + int flag; +# ifdef USE_SSS + vec3 sss_irradiance; + vec3 sss_albedo; + float sss_radius; +# endif + +#endif +}; + +/* Prototype */ +Closure nodetree_exec(void); + +/* clang-format off */ +/* Avoid multiline defines. */ +#ifdef VOLUMETRICS +# define CLOSURE_DEFAULT Closure(vec3(0), vec3(0), vec3(0), 0.0) +#elif !defined(USE_SSS) +# define CLOSURE_DEFAULT Closure(vec3(0), vec3(0), 0.0, vec4(0), vec2(0), 0) +#else +# define CLOSURE_DEFAULT Closure(vec3(0), vec3(0), 0.0, vec4(0), vec2(0), 0, vec3(0), vec3(0), 0.0) +#endif +/* clang-format on */ + +#define FLAG_TEST(flag, val) (((flag) & (val)) != 0) + +#define CLOSURE_SSR_FLAG 1 +#define CLOSURE_SSS_FLAG 2 +#define CLOSURE_HOLDOUT_FLAG 4 + +#ifdef VOLUMETRICS +Closure closure_mix(Closure cl1, Closure cl2, float fac) +{ + Closure cl; + cl.absorption = mix(cl1.absorption, cl2.absorption, fac); + cl.scatter = mix(cl1.scatter, cl2.scatter, fac); + cl.emission = mix(cl1.emission, cl2.emission, fac); + cl.anisotropy = mix(cl1.anisotropy, cl2.anisotropy, fac); + return cl; +} + +Closure closure_add(Closure cl1, Closure cl2) +{ + Closure cl; + cl.absorption = cl1.absorption + cl2.absorption; + cl.scatter = cl1.scatter + cl2.scatter; + cl.emission = cl1.emission + cl2.emission; + cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */ + return cl; +} + +Closure closure_emission(vec3 rgb) +{ + Closure cl = CLOSURE_DEFAULT; + cl.emission = rgb; + return cl; +} + +#else /* SURFACE */ + +Closure closure_mix(Closure cl1, Closure cl2, float fac) +{ + Closure cl; + cl.holdout = mix(cl1.holdout, cl2.holdout, fac); + + if (FLAG_TEST(cl1.flag, CLOSURE_HOLDOUT_FLAG)) { + fac = 1.0; + } + else if (FLAG_TEST(cl2.flag, CLOSURE_HOLDOUT_FLAG)) { + fac = 0.0; + } + + cl.transmittance = mix(cl1.transmittance, cl2.transmittance, fac); + cl.radiance = mix(cl1.radiance, cl2.radiance, fac); + cl.flag = cl1.flag | cl2.flag; + cl.ssr_data = mix(cl1.ssr_data, cl2.ssr_data, fac); + bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG); + /* When mixing SSR don't blend roughness and normals but only specular (ssr_data.xyz).*/ + cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w; + cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal; + +# ifdef USE_SSS + cl.sss_albedo = mix(cl1.sss_albedo, cl2.sss_albedo, fac); + bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG); + /* It also does not make sense to mix SSS radius or irradiance. */ + cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius; + cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance; +# endif + return cl; +} + +Closure closure_add(Closure cl1, Closure cl2) +{ + Closure cl; + cl.transmittance = cl1.transmittance + cl2.transmittance; + cl.radiance = cl1.radiance + cl2.radiance; + cl.holdout = cl1.holdout + cl2.holdout; + cl.flag = cl1.flag | cl2.flag; + cl.ssr_data = cl1.ssr_data + cl2.ssr_data; + bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG); + /* When mixing SSR don't blend roughness and normals.*/ + cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w; + cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal; + +# ifdef USE_SSS + cl.sss_albedo = cl1.sss_albedo + cl2.sss_albedo; + bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG); + /* It also does not make sense to mix SSS radius or irradiance. */ + cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius; + cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance; +# endif + return cl; +} + +Closure closure_emission(vec3 rgb) +{ + Closure cl = CLOSURE_DEFAULT; + cl.radiance = rgb; + return cl; +} + +#endif + +#ifndef VOLUMETRICS + +void closure_load_ssr_data( + vec3 ssr_spec, float roughness, vec3 N, vec3 viewVec, int ssr_id, inout Closure cl) +{ + /* Still encode to avoid artifacts in the SSR pass. */ + vec3 vN = normalize(mat3(ViewMatrix) * N); + cl.ssr_normal = normal_encode(vN, viewVec); + + if (ssr_id == outputSsrId) { + cl.ssr_data = vec4(ssr_spec, roughness); + cl.flag |= CLOSURE_SSR_FLAG; + } +} + +void closure_load_sss_data( + float radius, vec3 sss_irradiance, vec3 sss_albedo, int sss_id, inout Closure cl) +{ +# ifdef USE_SSS + if (sss_id == outputSssId) { + cl.sss_irradiance = sss_irradiance; + cl.sss_radius = radius; + cl.sss_albedo = sss_albedo; + cl.flag |= CLOSURE_SSS_FLAG; + cl.radiance += render_pass_diffuse_mask(sss_albedo, vec3(0)); + } + else +# endif + { + cl.radiance += render_pass_diffuse_mask(sss_albedo, sss_irradiance * sss_albedo); + } +} + +#endif diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/closure_lit_lib.glsl index bc7879763c3..bf33caf9854 100644 --- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_lit_lib.glsl @@ -1,32 +1,8 @@ -#ifndef LIT_SURFACE_UNIFORM -# define LIT_SURFACE_UNIFORM - -uniform float refractionDepth; - -# ifndef UTIL_TEX -# define UTIL_TEX -uniform sampler2DArray utilTex; -# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0) -# endif /* UTIL_TEX */ - -in vec3 worldPosition; -in vec3 viewPosition; - -in vec3 worldNormal; -in vec3 viewNormal; - -# ifdef HAIR_SHADER -in vec3 hairTangent; /* world space */ -in float hairThickTime; -in float hairThickness; -in float hairTime; -flat in int hairStrandID; - -uniform int hairThicknessRes = 1; -# endif - -#endif /* LIT_SURFACE_UNIFORM */ +#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl) +#pragma BLENDER_REQUIRE(lightprobe_lib.glsl) +#pragma BLENDER_REQUIRE(ambient_occlusion_lib.glsl) +#pragma BLENDER_REQUIRE(ssr_lib.glsl) /** * AUTO CONFIG @@ -209,7 +185,7 @@ void CLOSURE_NAME(vec3 N vec3 V = cameraVec; - vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0); + vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); /* ---------------------------------------------------------------- */ /* -------------------- SCENE LIGHTS LIGHTING --------------------- */ @@ -328,11 +304,11 @@ void CLOSURE_NAME(vec3 N # endif # ifdef CLOSURE_GLOSSY - vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughnessSquared); + vec3 spec_dir = specular_dominant_dir(N, V, roughnessSquared); # endif # ifdef CLOSURE_CLEARCOAT - vec3 C_spec_dir = get_specular_reflection_dominant_dir(C_N, V, C_roughnessSquared); + vec3 C_spec_dir = specular_dominant_dir(C_N, V, C_roughnessSquared); # endif # ifdef CLOSURE_REFRACTION @@ -345,7 +321,7 @@ void CLOSURE_NAME(vec3 N line_plane_intersect( worldPosition, refr_V, worldPosition - N * refractionDepth, N) : worldPosition; - vec3 refr_dir = get_specular_refraction_dominant_dir(N, refr_V, roughness, final_ior); + vec3 refr_dir = refraction_dominant_dir(N, refr_V, roughness, final_ior); # endif # ifdef CLOSURE_REFRACTION @@ -485,7 +461,7 @@ void CLOSURE_NAME(vec3 N # endif # ifdef CLOSURE_REFRACTION - float btdf = get_btdf_lut(utilTex, NV, roughness, ior); + float btdf = get_btdf_lut(NV, roughness, ior); out_refr += refr_accum.rgb * btdf; # endif diff --git a/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl b/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl index 759b4098b37..a6c9eebaff2 100644 --- a/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl @@ -2,7 +2,6 @@ layout(std140) uniform common_block { mat4 pastViewProjectionMatrix; - vec4 viewVecs[2]; vec2 mipRatio[10]; /* To correct mip level texel misalignment */ /* Ambient Occlusion */ vec4 aoParameters[2]; @@ -70,3 +69,9 @@ layout(std140) uniform common_block #define ssrQuality ssrParameters.x #define ssrThickness ssrParameters.y #define ssrPixelSize ssrParameters.zw + +vec2 mip_ratio_interp(float mip) +{ + float low_mip = floor(mip); + return mix(mipRatio[int(low_mip)], mipRatio[int(low_mip + 1.0)], mip - low_mip); +} diff --git a/source/blender/draw/engines/eevee/shaders/common_utiltex_lib.glsl b/source/blender/draw/engines/eevee/shaders/common_utiltex_lib.glsl new file mode 100644 index 00000000000..95a585f0d9c --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/common_utiltex_lib.glsl @@ -0,0 +1,65 @@ + +#pragma BLENDER_REQUIRE(bsdf_common_lib.glsl) + +/* ---------------------------------------------------------------------- */ +/** \name Utiltex + * + * Utiltex is a sampler2DArray that stores a number of useful small utilitary textures and lookup + * tables. + * \{ */ + +uniform sampler2DArray utilTex; + +#define LUT_SIZE 64 + +#define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0) + +/* Return texture coordinates to sample Surface LUT */ +vec2 lut_coords(float cosTheta, float roughness) +{ + float theta = acos(cosTheta); + vec2 coords = vec2(roughness, theta / M_PI_2); + + /* scale and bias coordinates, for correct filtered lookup */ + return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE; +} + +vec2 lut_coords_ltc(float cosTheta, float roughness) +{ + vec2 coords = vec2(roughness, sqrt(1.0 - cosTheta)); + + /* scale and bias coordinates, for correct filtered lookup */ + return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE; +} + +float get_btdf_lut(float NV, float roughness, float ior) +{ + const vec3 lut_scale_bias_texel_size = vec3((LUT_SIZE - 1.0), 0.5, 1.5) / LUT_SIZE; + + vec3 coords; + /* Try to compensate for the low resolution and interpolation error. */ + coords.x = (ior > 1.0) ? (0.9 + lut_scale_bias_texel_size.z) + + (0.1 - lut_scale_bias_texel_size.z) * f0_from_ior(ior) : + (0.9 + lut_scale_bias_texel_size.z) * ior * ior; + coords.y = 1.0 - saturate(NV); + coords.xy *= lut_scale_bias_texel_size.x; + coords.xy += lut_scale_bias_texel_size.y; + + const float lut_lvl_ofs = 4.0; /* First texture lvl of roughness. */ + const float lut_lvl_scale = 16.0; /* How many lvl of roughness in the lut. */ + + float mip = roughness * lut_lvl_scale; + float mip_floor = floor(mip); + + coords.z = lut_lvl_ofs + mip_floor + 1.0; + float btdf_high = textureLod(utilTex, coords, 0.0).r; + + coords.z -= 1.0; + float btdf_low = textureLod(utilTex, coords, 0.0).r; + + float btdf = (ior == 1.0) ? 1.0 : mix(btdf_low, btdf_high, mip - coords.z); + + return btdf; +} + +/** \} */ diff --git a/source/blender/draw/engines/eevee/shaders/default_frag.glsl b/source/blender/draw/engines/eevee/shaders/default_frag.glsl deleted file mode 100644 index 1014b25033a..00000000000 --- a/source/blender/draw/engines/eevee/shaders/default_frag.glsl +++ /dev/null @@ -1,51 +0,0 @@ - -uniform vec3 basecol; -uniform float metallic; -uniform float specular; -uniform float roughness; - -Closure nodetree_exec(void) -{ -#ifdef HAIR_SHADER - vec3 B = normalize(cross(worldNormal, hairTangent)); - float cos_theta; - if (hairThicknessRes == 1) { - vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0); - /* Random cosine normal distribution on the hair surface. */ - cos_theta = rand.x * 2.0 - 1.0; - } - else { - /* Shade as a cylinder. */ - cos_theta = hairThickTime / hairThickness; - } - float sin_theta = sqrt(max(0.0, 1.0f - cos_theta * cos_theta)); - vec3 N = normalize(worldNormal * sin_theta + B * cos_theta); - vec3 vN = mat3(ViewMatrix) * N; -#else - vec3 N = normalize(gl_FrontFacing ? worldNormal : -worldNormal); - vec3 vN = normalize(gl_FrontFacing ? viewNormal : -viewNormal); -#endif - - vec3 dielectric = vec3(0.034) * specular * 2.0; - vec3 albedo = mix(basecol, vec3(0.0), metallic); - vec3 f0 = mix(dielectric, basecol, metallic); - vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic); - vec3 out_diff, out_spec, ssr_spec; - eevee_closure_default(N, albedo, f0, f90, 1, roughness, 1.0, true, out_diff, out_spec, ssr_spec); - - Closure cl = CLOSURE_DEFAULT; - cl.radiance = render_pass_glossy_mask(vec3(1.0), out_spec) + - render_pass_diffuse_mask(albedo, out_diff * albedo); - closure_load_ssr_data(ssr_spec, roughness, N, viewCameraVec, 1, cl); - -#ifdef LOOKDEV - gl_FragDepth = 0.0; -#endif - -#ifdef HOLDOUT - cl = CLOSURE_DEFAULT; - cl.holdout = 1.0; -#endif - - return cl; -} diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl index d56890769a7..9c1ca17f87c 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl @@ -1,4 +1,8 @@ + +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_lib.glsl) + uniform sampler2D colorBuffer; uniform sampler2D depthBuffer; @@ -18,9 +22,6 @@ uniform vec4 bokehParams[2]; uniform vec2 nearFar; /* Near & far view depths values */ -#define M_PI 3.1415926535897932384626433832795 -#define M_2PI 6.2831853071795864769252868 - /* -------------- Utils ------------- */ /* divide by sensor size to get the normalized size */ @@ -34,11 +35,6 @@ uniform vec2 nearFar; /* Near & far view depths values */ #define weighted_sum(a, b, c, d, e) \ (a * e.x + b * e.y + c * e.z + d * e.w) / max(1e-6, dot(e, vec4(1.0))); -float max_v4(vec4 v) -{ - return max(max(v.x, v.y), max(v.z, v.w)); -} - vec4 safe_color(vec4 c) { /* Clamp to avoid black square artifacts if a pixel goes NaN. */ diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl index d83b410125a..6e35d4a54ae 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl @@ -1,4 +1,6 @@ +#pragma BLENDER_REQUIRE(common_math_lib.glsl) + uniform vec4 bokehParams[2]; #define bokeh_rotation bokehParams[0].x @@ -15,8 +17,6 @@ flat out float smoothFac; flat out ivec2 edge; out vec2 particlecoord; -#define M_PI 3.1415926535897932384626433832795 - /* Scatter pass, calculate a triangle covering the CoC. */ void main() { 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 eea0ce0aae2..47fe21928b3 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl @@ -1,14 +1,34 @@ + +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) +#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl) +#pragma BLENDER_REQUIRE(ambient_occlusion_lib.glsl) + /** * This shader only compute maximum horizon angles for each directions. * The final integration is done at the resolve stage with the shading normal. */ -uniform float rotationOffset; - out vec4 FragColor; -#ifdef DEBUG_AO uniform sampler2D normalBuffer; +#ifdef LAYERED_DEPTH +uniform sampler2DArray depthBufferLayered; +uniform int layer; +# define gtao_depthBuffer depthBufferLayered +# define gtao_textureLod(a, b, c) textureLod(a, vec3(b, layer), c) + +#else +uniform sampler2D depthBuffer; +# define gtao_depthBuffer depthBuffer +# define gtao_textureLod(a, b, c) textureLod(a, b, c) + +#endif + +uniform float rotationOffset; + +#ifdef DEBUG_AO void main() { @@ -34,18 +54,6 @@ void main() #else -# ifdef LAYERED_DEPTH -uniform sampler2DArray depthBufferLayered; -uniform int layer; -# define gtao_depthBuffer depthBufferLayered -# define gtao_textureLod(a, b, c) textureLod(a, vec3(b, layer), c) - -# else -# define gtao_depthBuffer depthBuffer -# define gtao_textureLod(a, b, c) textureLod(a, b, c) - -# endif - void main() { vec2 uvs = saturate(gl_FragCoord.xy / vec2(textureSize(gtao_depthBuffer, 0).xy)); diff --git a/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl index edee55a07e0..7331f92ba6d 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl @@ -1,5 +1,10 @@ + +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(common_view_lib.glsl) + /* Convert depth to Mist factor */ uniform vec3 mistSettings; +uniform sampler2D depthBuffer; #define mistStart mistSettings.x #define mistInvDistance mistSettings.y diff --git a/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl index fbf507a2e40..3501a4448c5 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl @@ -1,4 +1,6 @@ +#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl) + /* * Based on: * A Fast and Stable Feature-Aware Motion Blur Filter @@ -15,11 +17,6 @@ uniform sampler2D tileMaxBuffer; #define KERNEL 8 -/* TODO(fclem) deduplicate this code. */ -uniform sampler2DArray utilTex; -#define LUT_SIZE 64 -#define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0) - uniform float depthScale; uniform ivec2 tileBufferSize; uniform vec2 viewportSize; diff --git a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl index 598cc3e5183..f8dccb7511a 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl @@ -1,4 +1,11 @@ +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) +#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl) +#pragma BLENDER_REQUIRE(raytrace_lib.glsl) +#pragma BLENDER_REQUIRE(lightprobe_lib.glsl) +#pragma BLENDER_REQUIRE(ssr_lib.glsl) + /* Based on Stochastic Screen Space Reflections * https://www.ea.com/frostbite/news/stochastic-screen-space-reflections */ @@ -131,7 +138,7 @@ void main() return; } - vec4 rand = texelFetch(utilTex, ivec3(halfres_texel % LUT_SIZE, 2), 0); + vec4 rand = texelfetch_noise_tex(halfres_texel); /* Gives *perfect* reflection for very small roughness */ if (roughness < 0.04) { 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 e9da49c9eb9..2a53a4f119f 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl @@ -1,4 +1,9 @@ +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl) +#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl) + /* Based on Separable SSS. by Jorge Jimenez and Diego Gutierrez */ #define MAX_SSS_SAMPLES 65 @@ -14,36 +19,16 @@ uniform sampler2D sssIrradiance; uniform sampler2D sssRadius; uniform sampler2D sssAlbedo; -#ifndef UTIL_TEX -# define UTIL_TEX -uniform sampler2DArray utilTex; -# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0) -#endif /* UTIL_TEX */ - layout(location = 0) out vec4 sssRadiance; -float get_view_z_from_depth(float depth) -{ - if (ProjectionMatrix[3][3] == 0.0) { - float d = 2.0 * depth - 1.0; - return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]); - } - else { - return viewVecs[0].z + depth * viewVecs[1].z; - } -} - -#define LUT_SIZE 64 -#define M_PI_2 1.5707963267948966 /* pi/2 */ -#define M_2PI 6.2831853071795865 /* 2*pi */ - void main(void) { vec2 pixel_size = 1.0 / vec2(textureSize(depthBuffer, 0).xy); /* TODO precompute */ vec2 uvs = gl_FragCoord.xy * pixel_size; vec3 sss_irradiance = texture(sssIrradiance, uvs).rgb; float sss_radius = texture(sssRadius, uvs).r; - float depth_view = get_view_z_from_depth(texture(depthBuffer, uvs).r); + float depth = texture(depthBuffer, uvs).r; + float depth_view = get_view_z_from_depth(depth); float rand = texelfetch_noise_tex(gl_FragCoord.xy).r; #ifdef FIRST_PASS diff --git a/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl b/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl index b44645174bd..28947e971d2 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl @@ -1,5 +1,11 @@ +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(common_view_lib.glsl) + +uniform sampler2D colorBuffer; +uniform sampler2D depthBuffer; uniform sampler2D colorHistoryBuffer; + uniform mat4 prevViewProjectionMatrix; out vec4 FragColor; diff --git a/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl index 6531ceb8dbe..c85eff92e37 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl @@ -1,11 +1,16 @@ +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) +#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl) +#pragma BLENDER_REQUIRE(lights_lib.glsl) + in vec4 uvcoordsvar; out vec4 FragColor; +uniform sampler2D depthBuffer; uniform sampler1D sssTexProfile; uniform sampler2D sssRadius; - uniform sampler2DArray sssShadowCubes; uniform sampler2DArray sssShadowCascades; @@ -27,12 +32,6 @@ vec3 sss_profile(float s) return texture(sssTexProfile, saturate(s) * SSS_LUT_SCALE + SSS_LUT_BIAS).rgb; } -#ifndef UTIL_TEX -# define UTIL_TEX -uniform sampler2DArray utilTex; -# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0) -#endif /* UTIL_TEX */ - float light_translucent_power_with_falloff(LightData ld, vec3 N, vec4 l_vector) { float power, falloff; diff --git a/source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl index d927fd78d30..145939cefb2 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl @@ -1,4 +1,8 @@ +#pragma BLENDER_REQUIRE(common_math_lib.glsl) + +uniform sampler2D depthBuffer; + uniform mat4 prevViewProjMatrix; uniform mat4 currViewProjMatrixInv; uniform mat4 nextViewProjMatrix; diff --git a/source/blender/draw/engines/eevee/shaders/effect_velocity_tile_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_velocity_tile_frag.glsl index 0eb598521af..f52acaf6f7f 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_velocity_tile_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_velocity_tile_frag.glsl @@ -148,4 +148,4 @@ void main() tileMaxVelocity = encode_velocity(max_motion); } -#endif
\ No newline at end of file +#endif diff --git a/source/blender/draw/engines/eevee/shaders/irradiance_lib.glsl b/source/blender/draw/engines/eevee/shaders/irradiance_lib.glsl index 64ea87001f4..2274bf8b950 100644 --- a/source/blender/draw/engines/eevee/shaders/irradiance_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/irradiance_lib.glsl @@ -1,18 +1,71 @@ -uniform sampler2DArray irradianceGrid; +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl) +#pragma BLENDER_REQUIRE(octahedron_lib.glsl) #define IRRADIANCE_LIB +/* ---------------------------------------------------------------------- */ +/** \name Structure + * \{ */ + #if defined(IRRADIANCE_SH_L2) struct IrradianceData { vec3 shcoefs[9]; }; + #else /* defined(IRRADIANCE_HL2) */ struct IrradianceData { vec3 cubesides[3]; }; + #endif +/** \} */ + +/* ---------------------------------------------------------------------- */ +/** \name Resources + * \{ */ + +uniform sampler2DArray irradianceGrid; + +/** \} */ + +/* ---------------------------------------------------------------------- */ +/** \name Functions + * \{ */ + +vec4 irradiance_encode(vec3 rgb) +{ + float maxRGB = max_v3(rgb); + float fexp = ceil(log2(maxRGB)); + return vec4(rgb / exp2(fexp), (fexp + 128.0) / 255.0); +} + +vec3 irradiance_decode(vec4 data) +{ + float fexp = data.a * 255.0 - 128.0; + return data.rgb * exp2(fexp); +} + +vec4 visibility_encode(vec2 accum, float range) +{ + accum /= range; + + vec4 data; + data.x = fract(accum.x); + data.y = floor(accum.x) / 255.0; + data.z = fract(accum.y); + data.w = floor(accum.y) / 255.0; + + return data; +} + +vec2 visibility_decode(vec4 data, float range) +{ + return (data.xz + data.yw * 255.0) * range; +} + IrradianceData load_irradiance_cell(int cell, vec3 N) { /* Keep in sync with diffuse_filter_probe() */ @@ -155,3 +208,5 @@ vec3 irradiance_from_cell_get(int cell, vec3 ir_dir) IrradianceData ir_data = load_irradiance_cell(cell, ir_dir); return compute_irradiance(ir_dir, ir_data); } + +/** \} */ diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl index 96fe94fc41e..b0da4274a13 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl @@ -1,4 +1,7 @@ +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(lightprobe_lib.glsl) + flat in int pid; in vec2 quadCoord; diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl index db780714091..d06ad553ca4 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl @@ -1,4 +1,6 @@ +#pragma BLENDER_REQUIRE(common_view_lib.glsl) + /* XXX TODO fix code duplication */ struct CubeData { vec4 position_type; diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl index b485511318b..bf45169ebaa 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl @@ -1,4 +1,8 @@ +#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) +#pragma BLENDER_REQUIRE(irradiance_lib.glsl) + uniform samplerCube probeHdr; uniform int probeSize; uniform float lodFactor; diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl index 00eb3c7e200..ccb77427ed2 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl @@ -1,4 +1,7 @@ +#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) + uniform samplerCube probeHdr; uniform float roughnessSquared; uniform float texelSize; diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl index 5d8af21032a..8d7c58a93d5 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl @@ -1,4 +1,8 @@ +#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) +#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl) +#pragma BLENDER_REQUIRE(irradiance_lib.glsl) + uniform samplerCube probeDepth; uniform int outputSize; uniform float lodFactor; diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl index f8bc1703c66..009ccf6535e 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl @@ -40,9 +40,6 @@ void main() for (int v = 0; v < 3; v++) { gl_Position = vPos[v]; worldPosition = x_axis[fFace] * vPos[v].x + y_axis[fFace] * vPos[v].y + maj_axes[fFace]; -#ifdef USE_ATTR - pass_attr(v); -#endif EmitVertex(); } diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_frag.glsl index f9bcc718a1e..dc5ec1e40f5 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_frag.glsl @@ -1,3 +1,5 @@ +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(irradiance_lib.glsl) flat in int cellOffset; in vec2 quadCoord; diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl index 4e500db827e..6fefe1319bd 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl @@ -1,4 +1,6 @@ +#pragma BLENDER_REQUIRE(common_view_lib.glsl) + uniform float sphere_size; uniform int offset; uniform ivec3 grid_resolution; diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl index 6c6db88139b..a2e25b83532 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl @@ -1,3 +1,12 @@ + +#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl) +#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl) +#pragma BLENDER_REQUIRE(cubemap_lib.glsl) +#pragma BLENDER_REQUIRE(ambient_occlusion_lib.glsl) +#pragma BLENDER_REQUIRE(irradiance_lib.glsl) + /* ----------- Uniforms --------- */ uniform sampler2DArray probePlanars; @@ -73,12 +82,6 @@ struct GridData { # define MAX_PLANAR 1 #endif -#ifndef UTIL_TEX -# define UTIL_TEX -uniform sampler2DArray utilTex; -# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0) -#endif /* UTIL_TEX */ - layout(std140) uniform probe_block { CubeData probes_data[MAX_PROBE]; @@ -218,7 +221,7 @@ void fallback_cubemap(vec3 N, inout vec4 spec_accum) { /* Specular probes */ - vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughnessSquared); + vec3 spec_dir = specular_dominant_dir(N, V, roughnessSquared); #ifdef SSR_AO vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); @@ -246,7 +249,6 @@ void fallback_cubemap(vec3 N, } } -#ifdef IRRADIANCE_LIB vec3 probe_evaluate_grid(GridData gd, vec3 W, vec3 N, vec3 localpos) { localpos = localpos * 0.5 + 0.5; @@ -308,5 +310,3 @@ vec3 probe_evaluate_world_diff(vec3 N) { return irradiance_from_cell_get(0, N); } - -#endif /* IRRADIANCE_LIB */ diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl index 2807488db6c..0a53abcb04a 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl @@ -1,4 +1,6 @@ +#pragma BLENDER_REQUIRE(common_view_lib.glsl) + uniform sampler2DArray probePlanars; in vec3 worldPosition; diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl index 65506e5c7b1..6759c060259 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl @@ -1,4 +1,6 @@ +#pragma BLENDER_REQUIRE(common_view_lib.glsl) + in vec3 pos; in int probe_id; diff --git a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl index 3b9d0a8f2bc..949e4d8f04f 100644 --- a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl @@ -1,8 +1,76 @@ -uniform sampler2DArrayShadow shadowCubeTexture; -uniform sampler2DArrayShadow shadowCascadeTexture; +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) +#pragma BLENDER_REQUIRE(raytrace_lib.glsl) +#pragma BLENDER_REQUIRE(ltc_lib.glsl) + +#ifndef MAX_CASCADE_NUM +# define MAX_CASCADE_NUM 4 +#endif + +/* ---------------------------------------------------------------------- */ +/** \name Structure + * \{ */ + +struct LightData { + vec4 position_influence; /* w : InfluenceRadius (inversed and squared) */ + vec4 color_spec; /* w : Spec Intensity */ + vec4 spotdata_radius_shadow; /* x : spot size, y : spot blend, z : radius, w: shadow id */ + vec4 rightvec_sizex; /* xyz: Normalized up vector, w: area size X or spot scale X */ + vec4 upvec_sizey; /* xyz: Normalized right vector, w: area size Y or spot scale Y */ + vec4 forwardvec_type; /* xyz: Normalized forward vector, w: Light Type */ +}; + +/* convenience aliases */ +#define l_color color_spec.rgb +#define l_spec color_spec.a +#define l_position position_influence.xyz +#define l_influence position_influence.w +#define l_sizex rightvec_sizex.w +#define l_sizey upvec_sizey.w +#define l_right rightvec_sizex.xyz +#define l_up upvec_sizey.xyz +#define l_forward forwardvec_type.xyz +#define l_type forwardvec_type.w +#define l_spot_size spotdata_radius_shadow.x +#define l_spot_blend spotdata_radius_shadow.y +#define l_radius spotdata_radius_shadow.z +#define l_shadowid spotdata_radius_shadow.w + +struct ShadowData { + vec4 near_far_bias_id; + vec4 contact_shadow_data; +}; + +struct ShadowCubeData { + mat4 shadowmat; + vec4 position; +}; + +struct ShadowCascadeData { + mat4 shadowmat[MAX_CASCADE_NUM]; + vec4 split_start_distances; + vec4 split_end_distances; + vec4 shadow_vec_id; +}; + +/* convenience aliases */ +#define sh_near near_far_bias_id.x +#define sh_far near_far_bias_id.y +#define sh_bias near_far_bias_id.z +#define sh_data_index near_far_bias_id.w +#define sh_contact_dist contact_shadow_data.x +#define sh_contact_offset contact_shadow_data.y +#define sh_contact_spread contact_shadow_data.z +#define sh_contact_thickness contact_shadow_data.w +#define sh_shadow_vec shadow_vec_id.xyz +#define sh_tex_index shadow_vec_id.w + +/** \} */ -#define LAMPS_LIB +/* ---------------------------------------------------------------------- */ +/** \name Resources + * \{ */ layout(std140) uniform shadow_block { @@ -16,6 +84,15 @@ layout(std140) uniform light_block LightData lights_data[MAX_LIGHT]; }; +uniform sampler2DArrayShadow shadowCubeTexture; +uniform sampler2DArrayShadow shadowCascadeTexture; + +/** \} */ + +/* ---------------------------------------------------------------------- */ +/** \name Shadow Functions + * \{ */ + /* type */ #define POINT 0.0 #define SUN 1.0 @@ -133,9 +210,11 @@ float sample_cascade_shadow(int shadow_id, vec3 W) #undef scube #undef scsmd -/* ----------------------------------------------------------- */ -/* --------------------- Light Functions --------------------- */ -/* ----------------------------------------------------------- */ +/** \} */ + +/* ---------------------------------------------------------------------- */ +/** \name Light Functions + * \{ */ /* From Frostbite PBR Course * Distance based attenuation @@ -258,7 +337,6 @@ float light_visibility(LightData ld, l_atten); } -#ifdef USE_LTC float light_diffuse(LightData ld, vec3 N, vec3 V, vec4 l_vector) { if (ld.l_type == AREA_RECT) { @@ -321,4 +399,5 @@ float light_specular(LightData ld, vec4 ltc_mat, vec3 N, vec3 V, vec4 l_vector) return ltc_evaluate_disk(N, V, ltc_matrix(ltc_mat), points); } } -#endif + +/** \} */ diff --git a/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl b/source/blender/draw/engines/eevee/shaders/lookdev_world_frag.glsl index 8c876cf582c..9077b414026 100644 --- a/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lookdev_world_frag.glsl @@ -1,20 +1,17 @@ -uniform float backgroundAlpha; -uniform vec3 color; - -out vec4 FragColor; +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(lightprobe_lib.glsl) +#pragma BLENDER_REQUIRE(surface_lib.glsl) -#if defined(LOOKDEV_BG) || defined(LOOKDEV) +uniform sampler2D studioLight; +uniform float backgroundAlpha; uniform mat3 StudioLightMatrix; -uniform sampler2D image; uniform float studioLightIntensity = 1.0; uniform float studioLightBlur = 0.0; -in vec3 viewPosition; -# ifndef M_PI -# define M_PI 3.14159265358979323846 -# endif +out vec4 FragColor; vec3 background_transform_to_world(vec3 viewvec) { @@ -35,36 +32,20 @@ vec4 node_tex_environment_equirectangular(vec3 co, sampler2D ima) vec3 nco = normalize(co); float u = -atan(nco.y, nco.x) / (2.0 * M_PI) + 0.5; float v = atan(nco.z, hypot(nco.x, nco.y)) / M_PI + 0.5; - - /* Fix pole bleeding */ - float width = float(textureSize(ima, 0).x); - float texel_width = 1.0 / width; - v = clamp(v, texel_width, 1.0 - texel_width); - - /* Fix u = 0 seam */ - /* This is caused by texture filtering, since uv don't have smooth derivatives - * at u = 0 or 2PI, hardware filtering is using the smallest mipmap for certain - * texels. So we force the highest mipmap and don't do anisotropic filtering. */ return textureLod(ima, vec2(u, v), 0.0); } -#endif void main() { - vec3 background_color; + vec3 worldvec = background_transform_to_world(viewPosition); + vec3 background_color; #if defined(LOOKDEV_BG) - vec3 worldvec = background_transform_to_world(viewPosition); background_color = probe_evaluate_world_spec(worldvec, studioLightBlur).rgb; - background_color *= studioLightIntensity; - -#elif defined(LOOKDEV) - vec3 worldvec = background_transform_to_world(viewPosition); - background_color = node_tex_environment_equirectangular(StudioLightMatrix * worldvec, image).rgb; - background_color *= studioLightIntensity; - #else - background_color = color; + worldvec = StudioLightMatrix * worldvec; + background_color = node_tex_environment_equirectangular(worldvec, studioLight).rgb; + background_color *= studioLightIntensity; #endif FragColor = vec4(clamp(background_color, vec3(0.0), vec3(1e10)), 1.0) * backgroundAlpha; diff --git a/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl b/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl index dbfc7ad5a71..2750d42a74a 100644 --- a/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl @@ -8,12 +8,6 @@ #define USE_LTC -#ifndef UTIL_TEX -# define UTIL_TEX -uniform sampler2DArray utilTex; -# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0) -#endif /* UTIL_TEX */ - /* Diffuse *clipped* sphere integral. */ float diffuse_sphere_integral(float avg_dir_z, float form_factor) { diff --git a/source/blender/draw/engines/eevee/shaders/object_motion_vert.glsl b/source/blender/draw/engines/eevee/shaders/object_motion_vert.glsl index 95cd69ba310..ef96bcbaedb 100644 --- a/source/blender/draw/engines/eevee/shaders/object_motion_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/object_motion_vert.glsl @@ -1,4 +1,7 @@ +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(common_hair_lib.glsl) + uniform mat4 currModelMatrix; uniform mat4 prevModelMatrix; uniform mat4 nextModelMatrix; @@ -19,6 +22,8 @@ out vec3 nextWorldPos; void main() { + GPU_INTEL_VERTEX_SHADER_WORKAROUND + #ifdef HAIR bool is_persp = (ProjectionMatrix[3][3] == 0.0); float time, thick_time, thickness; diff --git a/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl b/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl index 9acd8f998f6..34999076f9c 100644 --- a/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl @@ -1,4 +1,14 @@ +/* Required by some nodes. */ +#pragma BLENDER_REQUIRE(common_hair_lib.glsl) +#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl) + +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl) +#pragma BLENDER_REQUIRE(closure_lib.glsl) +#pragma BLENDER_REQUIRE(closure_lit_lib.glsl) +#pragma BLENDER_REQUIRE(surface_lib.glsl) + #ifdef USE_ALPHA_HASH /* From the paper "Hashed Alpha Testing" by Chris Wyman and Morgan McGuire */ @@ -56,8 +66,6 @@ float hashed_alpha_threshold(vec3 co) #endif -#define NODETREE_EXEC - void main() { #if defined(USE_ALPHA_HASH) @@ -66,11 +74,9 @@ void main() float opacity = saturate(1.0 - avg(cl.transmittance)); -# if defined(USE_ALPHA_HASH) /* Hashed Alpha Testing */ if (opacity < hashed_alpha_threshold(worldPosition)) { discard; } -# endif #endif } diff --git a/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl b/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl index 2c7e0aca3fb..f650e2eeb8c 100644 --- a/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl @@ -1,16 +1,14 @@ +#pragma BLENDER_REQUIRE(common_hair_lib.glsl) +#pragma BLENDER_REQUIRE(common_view_lib.glsl) + #ifndef HAIR_SHADER in vec3 pos; #endif void main() { -#ifdef GPU_INTEL - /* Due to some shader compiler bug, we somewhat - * need to access gl_VertexID to make it work. even - * if it's actually dead code. */ - gl_Position.x = float(gl_VertexID); -#endif + GPU_INTEL_VERTEX_SHADER_WORKAROUND #ifdef HAIR_SHADER float time, thick_time, thickness; @@ -34,5 +32,4 @@ void main() #ifdef CLIP_PLANES gl_ClipDistance[0] = dot(vec4(worldPosition.xyz, 1.0), clipPlanes[0]); #endif - /* TODO motion vectors */ } diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl index f88cfdf3787..39db39f8756 100644 --- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl @@ -1,3 +1,11 @@ + +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl) + +uniform sampler2D maxzBuffer; +uniform sampler2DArray planarDepth; + #define MAX_STEP 256 float sample_depth(vec2 uv, int index, float lod) diff --git a/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl b/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl new file mode 100644 index 00000000000..36cf3cecf40 --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl @@ -0,0 +1,43 @@ + +/* ---------------------------------------------------------------------- */ +/** \name Resources + * \{ */ + +layout(std140) uniform renderpass_block +{ + bool renderPassDiffuse; + bool renderPassDiffuseLight; + bool renderPassGlossy; + bool renderPassGlossyLight; + bool renderPassEmit; + bool renderPassSSSColor; + bool renderPassEnvironment; +}; + +/** \} */ + +/* ---------------------------------------------------------------------- */ +/** \name Functions + * \{ */ + +vec3 render_pass_diffuse_mask(vec3 diffuse_color, vec3 diffuse_light) +{ + return renderPassDiffuse ? (renderPassDiffuseLight ? diffuse_light : diffuse_color) : vec3(0.0); +} + +vec3 render_pass_sss_mask(vec3 sss_color) +{ + return renderPassSSSColor ? sss_color : vec3(0.0); +} + +vec3 render_pass_glossy_mask(vec3 specular_color, vec3 specular_light) +{ + return renderPassGlossy ? (renderPassGlossyLight ? specular_light : specular_color) : vec3(0.0); +} + +vec3 render_pass_emission_mask(vec3 emission_light) +{ + return renderPassEmit ? emission_light : vec3(0.0); +} + +/** \} */ diff --git a/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl index 361963d5ac3..89a411bc7cb 100644 --- a/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl @@ -1,3 +1,7 @@ + +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) + #define PASS_POST_UNDEFINED 0 #define PASS_POST_ACCUMULATED_COLOR 1 #define PASS_POST_ACCUMULATED_LIGHT 2 @@ -9,6 +13,8 @@ uniform int postProcessType; uniform int currentSample; + +uniform sampler2D depthBuffer; uniform sampler2D inputBuffer; uniform sampler2D inputSecondLightBuffer; uniform sampler2D inputColorBuffer; diff --git a/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl index 860ec9e1727..e0b9d4a60db 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl @@ -1,11 +1,11 @@ -out vec4 fragColor; +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl) +#pragma BLENDER_REQUIRE(lights_lib.glsl) + +uniform sampler2D depthBuffer; -#ifndef UTIL_TEX -# define UTIL_TEX -uniform sampler2DArray utilTex; -# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0) -#endif /* UTIL_TEX */ +out vec4 fragColor; void main() { diff --git a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl index c42f905cf7e..0e342938396 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl @@ -1,39 +1,23 @@ +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(common_hair_lib.glsl) +#pragma BLENDER_REQUIRE(surface_lib.glsl) + in vec3 pos; in vec3 nor; -#ifdef MESH_SHADER -out vec3 worldPosition; -out vec3 viewPosition; -out vec3 worldNormal; -out vec3 viewNormal; -#endif - -#ifdef HAIR_SHADER -out vec3 hairTangent; -out float hairThickTime; -out float hairThickness; -out float hairTime; -flat out int hairStrandID; -#endif - void main() { -#ifdef GPU_INTEL - /* Due to some shader compiler bug, we somewhat - * need to access gl_VertexID to make it work. even - * if it's actually dead code. */ - gl_Position.x = float(gl_VertexID); -#endif + GPU_INTEL_VERTEX_SHADER_WORKAROUND #ifdef HAIR_SHADER hairStrandID = hair_get_strand_id(); - vec3 world_pos, binor; + vec3 pos, binor; hair_get_pos_tan_binor_time((ProjectionMatrix[3][3] == 0.0), ModelMatrixInverse, ViewMatrixInverse[3].xyz, ViewMatrixInverse[2].xyz, - world_pos, + pos, hairTangent, binor, hairTime, @@ -41,6 +25,7 @@ void main() hairThickTime); worldNormal = cross(hairTangent, binor); + vec3 world_pos = pos; #else vec3 world_pos = point_object_to_world(pos); #endif @@ -57,7 +42,10 @@ void main() /* No need to normalize since this is just a rotation. */ viewNormal = normal_world_to_view(worldNormal); # ifdef USE_ATTR - pass_attr(pos); +# ifdef HAIR_SHADER + pos = hair_get_strand_pos(); +# endif + pass_attr(pos, NormalMatrix, ModelMatrixInverse); # endif #endif } diff --git a/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl index 0591b247541..29495e98355 100644 --- a/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl @@ -1,3 +1,10 @@ + +#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) +#pragma BLENDER_REQUIRE(bsdf_common_lib.glsl) +#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl) +#pragma BLENDER_REQUIRE(raytrace_lib.glsl) +#pragma BLENDER_REQUIRE(surface_lib.glsl) + /* ------------ Refraction ------------ */ #define BTDF_BIAS 0.85 diff --git a/source/blender/draw/engines/eevee/shaders/surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/surface_frag.glsl new file mode 100644 index 00000000000..e746acfdfa3 --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/surface_frag.glsl @@ -0,0 +1,89 @@ + +/* Required by some nodes. */ +#pragma BLENDER_REQUIRE(common_hair_lib.glsl) +#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl) + +#pragma BLENDER_REQUIRE(closure_lib.glsl) +#pragma BLENDER_REQUIRE(closure_lit_lib.glsl) +#pragma BLENDER_REQUIRE(surface_lib.glsl) +#pragma BLENDER_REQUIRE(volumetric_lib.glsl) + +#ifdef USE_ALPHA_BLEND +/* Use dual source blending to be able to make a whole range of effects. */ +layout(location = 0, index = 0) out vec4 outRadiance; +layout(location = 0, index = 1) out vec4 outTransmittance; + +#else /* OPAQUE */ +layout(location = 0) out vec4 outRadiance; +layout(location = 1) out vec2 ssrNormals; +layout(location = 2) out vec4 ssrData; +# ifdef USE_SSS +layout(location = 3) out vec3 sssIrradiance; +layout(location = 4) out float sssRadius; +layout(location = 5) out vec3 sssAlbedo; +# endif + +#endif + +void main() +{ + Closure cl = nodetree_exec(); + + float holdout = saturate(1.0 - cl.holdout); + float transmit = saturate(avg(cl.transmittance)); + float alpha = 1.0 - transmit; + +#ifdef USE_ALPHA_BLEND + vec2 uvs = gl_FragCoord.xy * volCoordScale.zw; + vec3 vol_transmit, vol_scatter; + volumetric_resolve(uvs, gl_FragCoord.z, vol_transmit, vol_scatter); + + /* Removes part of the volume scattering that have + * already been added to the destination pixels. + * Since we do that using the blending pipeline we need to account for material transmittance. */ + vol_scatter -= vol_scatter * cl.transmittance; + + cl.radiance = cl.radiance * holdout * vol_transmit + vol_scatter; + outRadiance = vec4(cl.radiance, alpha * holdout); + outTransmittance = vec4(cl.transmittance, transmit) * holdout; +#else + outRadiance = vec4(cl.radiance, holdout); + ssrNormals = cl.ssr_normal; + ssrData = cl.ssr_data; +# ifdef USE_SSS + sssIrradiance = cl.sss_irradiance; + sssRadius = cl.sss_radius; + sssAlbedo = cl.sss_albedo; +# endif +#endif + + /* For Probe capture */ +#ifdef USE_SSS + float fac = float(!sssToggle); + + /* TODO(fclem) we shouldn't need this. + * Just disable USE_SSS when USE_REFRACTION is enabled. */ +# ifdef USE_REFRACTION + /* SSRefraction pass is done after the SSS pass. + * In order to not loose the diffuse light totally we + * need to merge the SSS radiance to the main radiance. */ + fac = 1.0; +# endif + + outRadiance.rgb += cl.sss_irradiance.rgb * cl.sss_albedo.rgb * fac; +#endif + +#ifndef USE_ALPHA_BLEND + float alpha_div = 1.0 / max(1e-8, alpha); + outRadiance.rgb *= alpha_div; + ssrData.rgb *= alpha_div; +# ifdef USE_SSS + sssAlbedo.rgb *= alpha_div; +# endif +#endif + +#ifdef LOOKDEV + /* Lookdev spheres are rendered in front. */ + gl_FragDepth = 0.0; +#endif +} diff --git a/source/blender/draw/engines/eevee/shaders/surface_geom.glsl b/source/blender/draw/engines/eevee/shaders/surface_geom.glsl new file mode 100644 index 00000000000..ad437dca79a --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/surface_geom.glsl @@ -0,0 +1,46 @@ + +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(surface_lib.glsl) + +layout(triangles) in; +layout(triangle_strip, max_vertices = 3) out; + +RESOURCE_ID_VARYING + +/* Only used to compute barycentric coordinates. */ + +void main() +{ +#ifdef DO_BARYCENTRIC_DISTANCES + dataAttrOut.barycentricDist = calc_barycentric_distances( + dataIn[0].worldPosition, dataIn[1].worldPosition, dataIn[2].worldPosition); +#endif + + PASS_RESOURCE_ID + +#ifdef USE_ATTR + pass_attr(0); +#endif + PASS_SURFACE_INTERFACE(0); + gl_Position = gl_in[0].gl_Position; + gl_ClipDistance[0] = gl_in[0].gl_ClipDistance[0]; + EmitVertex(); + +#ifdef USE_ATTR + pass_attr(1); +#endif + PASS_SURFACE_INTERFACE(1); + gl_Position = gl_in[1].gl_Position; + gl_ClipDistance[0] = gl_in[1].gl_ClipDistance[0]; + EmitVertex(); + +#ifdef USE_ATTR + pass_attr(2); +#endif + PASS_SURFACE_INTERFACE(2); + gl_Position = gl_in[2].gl_Position; + gl_ClipDistance[0] = gl_in[2].gl_ClipDistance[0]; + EmitVertex(); + + EndPrimitive(); +} diff --git a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl new file mode 100644 index 00000000000..b93a3a23eff --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl @@ -0,0 +1,43 @@ +/** This describe the entire interface of the shader. */ + +/* Samplers */ +uniform sampler2D colorBuffer; +uniform sampler2D depthBuffer; + +/* Uniforms */ +uniform float refractionDepth; + +#define SURFACE_INTERFACE \ + vec3 worldPosition; \ + vec3 viewPosition; \ + vec3 worldNormal; \ + vec3 viewNormal; + +#ifdef GPU_GEOMETRY_SHADER +in ShaderStageInterface{SURFACE_INTERFACE} dataIn[]; + +out ShaderStageInterface{SURFACE_INTERFACE} dataOut; + +# define PASS_SURFACE_INTERFACE(vert) \ + dataOut.worldPosition = dataIn[vert].worldPosition; \ + dataOut.viewPosition = dataIn[vert].viewPosition; \ + dataOut.worldNormal = dataIn[vert].worldNormal; \ + dataOut.viewNormal = dataIn[vert].viewNormal; + +#else + +IN_OUT ShaderStageInterface{SURFACE_INTERFACE}; + +#endif + +#ifdef HAIR_SHADER +IN_OUT ShaderHairInterface +{ + /* world space */ + vec3 hairTangent; + float hairThickTime; + float hairThickness; + float hairTime; + flat int hairStrandID; +}; +#endif diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl b/source/blender/draw/engines/eevee/shaders/surface_vert.glsl index 1b94fc2bee1..0ad1393dd70 100644 --- a/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/surface_vert.glsl @@ -1,32 +1,20 @@ +#pragma BLENDER_REQUIRE(common_hair_lib.glsl) +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(surface_lib.glsl) + #ifndef HAIR_SHADER in vec3 pos; in vec3 nor; #endif -#ifdef MESH_SHADER -out vec3 worldPosition; -out vec3 viewPosition; -out vec3 worldNormal; -out vec3 viewNormal; -#endif - -#ifdef HAIR_SHADER -out vec3 hairTangent; -out float hairThickTime; -out float hairThickness; -out float hairTime; -flat out int hairStrandID; -#endif +RESOURCE_ID_VARYING void main() { -#ifdef GPU_INTEL - /* Due to some shader compiler bug, we somewhat - * need to access gl_VertexID to make it work. even - * if it's actually dead code. */ - gl_Position.x = float(gl_VertexID); -#endif + GPU_INTEL_VERTEX_SHADER_WORKAROUND + + PASS_RESOURCE_ID #ifdef HAIR_SHADER hairStrandID = hair_get_strand_id(); @@ -63,7 +51,10 @@ void main() /* No need to normalize since this is just a rotation. */ viewNormal = normal_world_to_view(worldNormal); # ifdef USE_ATTR - pass_attr(pos); +# ifdef HAIR_SHADER + pos = hair_get_strand_pos(); +# endif + pass_attr(pos, NormalMatrix, ModelMatrixInverse); # endif #endif } diff --git a/source/blender/draw/engines/eevee/shaders/update_noise_frag.glsl b/source/blender/draw/engines/eevee/shaders/update_noise_frag.glsl index 02ad2170f06..0c01c46c2ba 100644 --- a/source/blender/draw/engines/eevee/shaders/update_noise_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/update_noise_frag.glsl @@ -1,11 +1,11 @@ +#pragma BLENDER_REQUIRE(common_math_lib.glsl) + uniform sampler2D blueNoise; uniform vec3 offsets; out vec4 FragColor; -#define M_2PI 6.28318530717958647692 - void main(void) { vec3 blue_noise = texelFetch(blueNoise, ivec2(gl_FragCoord.xy), 0).xyz; diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl index 312fc07054a..bac69ab0355 100644 --- a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl @@ -1,9 +1,10 @@ +#pragma BLENDER_REQUIRE(volumetric_lib.glsl) +#pragma BLENDER_REQUIRE(closure_lib.glsl) + /* Based on Frosbite Unified Volumetric. * https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */ -#define NODETREE_EXEC - #ifdef MESH_SHADER uniform vec3 volumeOrcoLoc; uniform vec3 volumeOrcoSize; diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_geom.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_geom.glsl index 96b891c929f..30cda401284 100644 --- a/source/blender/draw/engines/eevee/shaders/volumetric_geom.glsl +++ b/source/blender/draw/engines/eevee/shaders/volumetric_geom.glsl @@ -1,4 +1,6 @@ +#pragma BLENDER_REQUIRE(common_view_lib.glsl) + #ifdef MESH_SHADER /* TODO tight slices */ layout(triangles) in; @@ -12,12 +14,16 @@ in vec4 vPos[]; flat out int slice; +RESOURCE_ID_VARYING + #ifdef MESH_SHADER /* TODO tight slices */ void main() { gl_Layer = slice = int(vPos[0].z); + PASS_RESOURCE_ID + # ifdef USE_ATTR pass_attr(0); # endif @@ -48,6 +54,8 @@ void main() { gl_Layer = slice = int(vPos[0].z); + PASS_RESOURCE_ID + # ifdef USE_ATTR pass_attr(0); # endif diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl index c3c442e7b69..f4276bd61bd 100644 --- a/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl @@ -1,4 +1,6 @@ +#pragma BLENDER_REQUIRE(volumetric_lib.glsl) + /* Based on Frosbite Unified Volumetric. * https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */ @@ -11,9 +13,11 @@ uniform sampler3D volumeExtinction; #ifdef USE_VOLUME_OPTI uniform layout(binding = 0, r11f_g11f_b10f) writeonly restrict image3D finalScattering_img; uniform layout(binding = 1, r11f_g11f_b10f) writeonly restrict image3D finalTransmittance_img; + vec3 finalScattering; vec3 finalTransmittance; #else + flat in int slice; layout(location = 0) out vec3 finalScattering; diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl index 40eb3da42d1..9b852a57ec4 100644 --- a/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl @@ -1,4 +1,8 @@ +#pragma BLENDER_REQUIRE(lights_lib.glsl) +#pragma BLENDER_REQUIRE(lightprobe_lib.glsl) +#pragma BLENDER_REQUIRE(irradiance_lib.glsl) + /* Based on Frosbite Unified Volumetric. * https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */ @@ -58,7 +62,6 @@ float phase_function(vec3 v, vec3 l, float g) return (1 - sqr_g) / max(1e-8, 4.0 * M_PI * pow(1 + sqr_g - 2 * g * cos_theta, 3.0 / 2.0)); } -#ifdef LAMPS_LIB vec3 light_volume(LightData ld, vec4 l_vector) { float power; @@ -95,7 +98,7 @@ vec3 light_volume(LightData ld, vec4 l_vector) return tint * lum; } -# define VOLUMETRIC_SHADOW_MAX_STEP 32.0 +#define VOLUMETRIC_SHADOW_MAX_STEP 32.0 vec3 participating_media_extinction(vec3 wpos, sampler3D volume_extinction) { @@ -109,7 +112,7 @@ vec3 participating_media_extinction(vec3 wpos, sampler3D volume_extinction) vec3 light_volume_shadow(LightData ld, vec3 ray_wpos, vec4 l_vector, sampler3D volume_extinction) { -# if defined(VOLUME_SHADOW) +#if defined(VOLUME_SHADOW) /* Heterogeneous volume shadows */ float dd = l_vector.w / volShadowSteps; vec3 L = l_vector.xyz * l_vector.w; @@ -120,27 +123,24 @@ vec3 light_volume_shadow(LightData ld, vec3 ray_wpos, vec4 l_vector, sampler3D v shadow *= exp(-s_extinction * dd); } return shadow; -# else +#else return vec3(1.0); -# endif /* VOLUME_SHADOW */ +#endif /* VOLUME_SHADOW */ } -#endif -#ifdef IRRADIANCE_LIB vec3 irradiance_volumetric(vec3 wpos) { -# ifdef IRRADIANCE_HL2 +#ifdef IRRADIANCE_HL2 IrradianceData ir_data = load_irradiance_cell(0, vec3(1.0)); vec3 irradiance = ir_data.cubesides[0] + ir_data.cubesides[1] + ir_data.cubesides[2]; ir_data = load_irradiance_cell(0, vec3(-1.0)); irradiance += ir_data.cubesides[0] + ir_data.cubesides[1] + ir_data.cubesides[2]; irradiance *= 0.16666666; /* 1/6 */ return irradiance; -# else +#else return vec3(0.0); -# endif -} #endif +} uniform sampler3D inScattering; uniform sampler3D inTransmittance; diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_resolve_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_resolve_frag.glsl index 1ff7e848c40..6ab21587c9a 100644 --- a/source/blender/draw/engines/eevee/shaders/volumetric_resolve_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/volumetric_resolve_frag.glsl @@ -1,4 +1,6 @@ +#pragma BLENDER_REQUIRE(volumetric_lib.glsl) + /* Based on Frosbite Unified Volumetric. * https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */ diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl index 9621fa1cc0d..806f1b5b205 100644 --- a/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl @@ -1,4 +1,6 @@ +#pragma BLENDER_REQUIRE(volumetric_lib.glsl) + /* Based on Frosbite Unified Volumetric. * https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */ diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_vert.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_vert.glsl index b96360febb0..b70747ecec3 100644 --- a/source/blender/draw/engines/eevee/shaders/volumetric_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/volumetric_vert.glsl @@ -1,6 +1,10 @@ +#pragma BLENDER_REQUIRE(common_view_lib.glsl) + out vec4 vPos; +RESOURCE_ID_VARYING + void main() { /* Generate Triangle : less memory fetches from a VBO */ @@ -25,7 +29,9 @@ void main() vPos.z = float(t_id); vPos.w = 1.0; + PASS_RESOURCE_ID + #ifdef USE_ATTR - pass_attr(vec3(0.0)); + pass_attr(vec3(0.0), mat3(1), mat4(1)); #endif } diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c index 3ef20dbe9ec..36d295d1dde 100644 --- a/source/blender/draw/engines/external/external_engine.c +++ b/source/blender/draw/engines/external/external_engine.c @@ -268,7 +268,7 @@ static void external_draw_scene(void *vedata) * OpenGL render is used for quick preview (thumbnails or sequencer preview) * where using the rendering engine to preview doesn't make so much sense. */ if (draw_ctx->evil_C) { - float clear_col[4] = {0, 0, 0, 0}; + const float clear_col[4] = {0, 0, 0, 0}; /* This is to keep compatibility with external engine. */ /* TODO(fclem) remove it eventually. */ GPU_framebuffer_bind(dfbl->default_fb); diff --git a/source/blender/draw/engines/gpencil/gpencil_antialiasing.c b/source/blender/draw/engines/gpencil/gpencil_antialiasing.c index 8955240c549..b9600ad8caf 100644 --- a/source/blender/draw/engines/gpencil/gpencil_antialiasing.c +++ b/source/blender/draw/engines/gpencil/gpencil_antialiasing.c @@ -36,7 +36,7 @@ void GPENCIL_antialiasing_init(struct GPENCIL_Data *vedata) const float *size = DRW_viewport_size_get(); const float *sizeinv = DRW_viewport_invert_size_get(); - float metrics[4] = {sizeinv[0], sizeinv[1], size[0], size[1]}; + const float metrics[4] = {sizeinv[0], sizeinv[1], size[0], size[1]}; if (pd->simplify_antialias) { /* No AA fallback. */ diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c index 8a4134ec8ea..363794e1be3 100644 --- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c +++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c @@ -132,12 +132,11 @@ static int gpencil_tobject_dist_sort(const void *a, const void *b) if (ob_a->camera_z > ob_b->camera_z) { return 1; } - else if (ob_a->camera_z < ob_b->camera_z) { + if (ob_a->camera_z < ob_b->camera_z) { return -1; } - else { - return 0; - } + + return 0; } void gpencil_object_cache_sort(GPENCIL_PrivateData *pd) @@ -193,7 +192,7 @@ static float gpencil_layer_final_opacity_get(const GPENCIL_PrivateData *pd, if (is_obact && is_fade) { return gpl->opacity * pd->fade_layer_opacity; } - else if (!is_obact && (pd->fade_gp_object_opacity > -1.0f)) { + if (!is_obact && (pd->fade_gp_object_opacity > -1.0f)) { return gpl->opacity * pd->fade_gp_object_opacity; } } @@ -246,7 +245,7 @@ static void gpencil_layer_random_color_get(const Object *ob, uint ob_hash = BLI_ghashutil_strhash_p_murmur(ob->id.name); uint gpl_hash = BLI_ghashutil_strhash_p_murmur(gpl->info); float hue = BLI_hash_int_01(ob_hash * gpl_hash); - float hsv[3] = {hue, hsv_saturation, hsv_value}; + const float hsv[3] = {hue, hsv_saturation, hsv_value}; hsv_to_rgb_v(hsv, r_color); } diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_data.c b/source/blender/draw/engines/gpencil/gpencil_draw_data.c index 6e6b35e19ca..51152475a06 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_data.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_data.c @@ -63,7 +63,7 @@ static struct GPUTexture *gpencil_image_texture_get(Image *image, bool *r_alpha_ ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock); if (ibuf != NULL && ibuf->rect != NULL) { - gpu_tex = GPU_texture_from_blender(image, &iuser, ibuf, GL_TEXTURE_2D); + gpu_tex = BKE_image_get_gpu_texture(image, &iuser, ibuf); *r_alpha_premult = (image->alpha_mode == IMA_ALPHA_PREMUL); } BKE_image_release_ibuf(image, ibuf, lock); @@ -359,12 +359,11 @@ static float light_power_get(const Light *la) if (la->type == LA_AREA) { return 1.0f / (4.0f * M_PI); } - else if (la->type == LA_SPOT || la->type == LA_LOCAL) { + if (la->type == LA_SPOT || la->type == LA_LOCAL) { return 1.0f / (4.0f * M_PI * M_PI); } - else { - return 1.0f / M_PI; - } + + return 1.0f / M_PI; } void gpencil_light_pool_populate(GPENCIL_LightPool *lightpool, Object *ob) diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index dbad226099e..746920e38c6 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -71,7 +71,7 @@ void GPENCIL_engine_init(void *ved) } if (txl->dummy_texture == NULL) { - float pixels[1][4] = {{1.0f, 0.0f, 1.0f, 1.0f}}; + const float pixels[1][4] = {{1.0f, 0.0f, 1.0f, 1.0f}}; txl->dummy_texture = DRW_texture_create_2d(1, 1, GPU_RGBA8, DRW_TEX_WRAP, (float *)pixels); } @@ -766,7 +766,7 @@ static void gpencil_draw_mask(GPENCIL_Data *vedata, GPENCIL_tObject *ob, GPENCIL { GPENCIL_PassList *psl = vedata->psl; GPENCIL_FramebufferList *fbl = vedata->fbl; - float clear_col[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + const float clear_col[4] = {1.0f, 1.0f, 1.0f, 1.0f}; float clear_depth = ob->is_drawmode3d ? 1.0f : 0.0f; bool inverted = false; /* OPTI(fclem) we could optimize by only clearing if the new mask_bits does not contain all @@ -813,7 +813,7 @@ static void GPENCIL_draw_object(GPENCIL_Data *vedata, GPENCIL_tObject *ob) GPENCIL_PassList *psl = vedata->psl; GPENCIL_PrivateData *pd = vedata->stl->pd; GPENCIL_FramebufferList *fbl = vedata->fbl; - float clear_cols[2][4] = {{0.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}; + const float clear_cols[2][4] = {{0.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}; DRW_stats_group_start("GPencil Object"); diff --git a/source/blender/draw/engines/gpencil/gpencil_render.c b/source/blender/draw/engines/gpencil/gpencil_render.c index 4748858a6a8..df52b65aa78 100644 --- a/source/blender/draw/engines/gpencil/gpencil_render.c +++ b/source/blender/draw/engines/gpencil/gpencil_render.c @@ -129,7 +129,7 @@ void GPENCIL_render_init(GPENCIL_Data *vedata, /* To avoid unpredictable result, clear buffers that have not be initialized. */ GPU_framebuffer_bind(fbl->render_fb); if (do_clear_col) { - float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; GPU_framebuffer_clear_color(fbl->render_fb, clear_col); } if (do_clear_z) { @@ -143,9 +143,11 @@ void GPENCIL_render_init(GPENCIL_Data *vedata, int w = BLI_rcti_size_x(rect); int h = BLI_rcti_size_y(rect); if (pix_col) { + GPU_texture_bind(txl->render_color_tx, 0); GPU_texture_update_sub(txl->render_color_tx, GPU_DATA_FLOAT, pix_col, x, y, 0, w, h, 0); } if (pix_z) { + GPU_texture_bind(txl->render_depth_tx, 0); GPU_texture_update_sub(txl->render_depth_tx, GPU_DATA_FLOAT, pix_z, x, y, 0, w, h, 0); } } diff --git a/source/blender/draw/engines/overlay/overlay_antialiasing.c b/source/blender/draw/engines/overlay/overlay_antialiasing.c index a32242d6292..9e95e860d0a 100644 --- a/source/blender/draw/engines/overlay/overlay_antialiasing.c +++ b/source/blender/draw/engines/overlay/overlay_antialiasing.c @@ -69,7 +69,7 @@ void OVERLAY_antialiasing_init(OVERLAY_Data *vedata) /* Small texture which will have very small impact on rendertime. */ if (txl->dummy_depth_tx == NULL) { - float pixel[1] = {1.0f}; + const float pixel[1] = {1.0f}; txl->dummy_depth_tx = DRW_texture_create_2d(1, 1, GPU_DEPTH_COMPONENT24, 0, pixel); } @@ -202,7 +202,7 @@ void OVERLAY_antialiasing_start(OVERLAY_Data *vedata) OVERLAY_PrivateData *pd = vedata->stl->pd; if (pd->antialiasing.enabled) { - float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; GPU_framebuffer_bind(fbl->overlay_line_fb); GPU_framebuffer_clear_color(fbl->overlay_line_fb, clear_col); } diff --git a/source/blender/draw/engines/overlay/overlay_armature.c b/source/blender/draw/engines/overlay/overlay_armature.c index 960e5e424f2..49b8257e0c6 100644 --- a/source/blender/draw/engines/overlay/overlay_armature.c +++ b/source/blender/draw/engines/overlay/overlay_armature.c @@ -601,7 +601,7 @@ static void drw_shgroup_bone_custom_empty(ArmatureDrawContext *ctx, const float color[4], Object *custom) { - float final_color[4] = {color[0], color[1], color[2], 1.0f}; + const float final_color[4] = {color[0], color[1], color[2], 1.0f}; float mat[4][4]; mul_m4_m4m4(mat, ctx->ob->obmat, bone_mat); @@ -924,12 +924,11 @@ static float get_bone_wire_thickness(const ArmatureDrawContext *ctx, int bonefla if (ctx->const_color) { return ctx->const_wire; } - else if (boneflag & (BONE_DRAW_ACTIVE | BONE_SELECTED)) { + if (boneflag & (BONE_DRAW_ACTIVE | BONE_SELECTED)) { return 2.0f; } - else { - return 1.0f; - } + + return 1.0f; } static const float *get_bone_wire_color(const ArmatureDrawContext *ctx, @@ -1079,7 +1078,7 @@ static void edbo_compute_bbone_child(bArmature *arm) } /* A version of BKE_pchan_bbone_spline_setup() for previewing editmode curve settings. */ -static void ebone_spline_preview(EditBone *ebone, float result_array[MAX_BBONE_SUBDIV][4][4]) +static void ebone_spline_preview(EditBone *ebone, const float result_array[MAX_BBONE_SUBDIV][4][4]) { BBoneSplineParameters param; EditBone *prev, *next; @@ -2219,13 +2218,13 @@ static bool POSE_is_driven_by_active_armature(Object *ob) } return is_active; } - else { - Object *ob_mesh_deform = BKE_modifiers_is_deformed_by_meshdeform(ob); - if (ob_mesh_deform) { - /* Recursive. */ - return POSE_is_driven_by_active_armature(ob_mesh_deform); - } + + Object *ob_mesh_deform = BKE_modifiers_is_deformed_by_meshdeform(ob); + if (ob_mesh_deform) { + /* Recursive. */ + return POSE_is_driven_by_active_armature(ob_mesh_deform); } + return false; } diff --git a/source/blender/draw/engines/overlay/overlay_edit_text.c b/source/blender/draw/engines/overlay/overlay_edit_text.c index 6ddd0e6d9be..fd68b319f02 100644 --- a/source/blender/draw/engines/overlay/overlay_edit_text.c +++ b/source/blender/draw/engines/overlay/overlay_edit_text.c @@ -74,7 +74,7 @@ void OVERLAY_edit_text_cache_init(OVERLAY_Data *vedata) /* Use 2D quad corners to create a matrix that set * a [-1..1] quad at the right position. */ -static void v2_quad_corners_to_mat4(float corners[4][2], float r_mat[4][4]) +static void v2_quad_corners_to_mat4(const float corners[4][2], float r_mat[4][4]) { unit_m4(r_mat); sub_v2_v2v2(r_mat[0], corners[1], corners[0]); diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c index bc96a03da31..1312408498a 100644 --- a/source/blender/draw/engines/overlay/overlay_engine.c +++ b/source/blender/draw/engines/overlay/overlay_engine.c @@ -440,7 +440,7 @@ static void OVERLAY_draw_scene(void *vedata) DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); if (DRW_state_is_fbo()) { - float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; GPU_framebuffer_bind(dfbl->overlay_only_fb); GPU_framebuffer_clear_color(dfbl->overlay_only_fb, clear_col); } diff --git a/source/blender/draw/engines/overlay/overlay_extra.c b/source/blender/draw/engines/overlay/overlay_extra.c index 0b4d0fcdc11..ce678c7d03f 100644 --- a/source/blender/draw/engines/overlay/overlay_extra.c +++ b/source/blender/draw/engines/overlay/overlay_extra.c @@ -53,8 +53,6 @@ #include "ED_view3d.h" -#include "GPU_draw.h" - #include "overlay_private.h" #include "draw_common.h" @@ -279,7 +277,7 @@ void OVERLAY_extra_wire(OVERLAY_ExtraCallBuffers *cb, const float color[4]) { float draw_mat[4][4]; - float col[4] = {UNPACK3(color), 0.0f /* No stipples. */}; + const float col[4] = {UNPACK3(color), 0.0f /* No stipples. */}; pack_v4_in_mat4(draw_mat, mat, col); DRW_shgroup_call_obmat(cb->extra_wire, geom, draw_mat); } @@ -681,8 +679,8 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob) DRW_buffer_add_entry(cb->light_spot, color, &instdata); if ((la->mode & LA_SHOW_CONE) && !DRW_state_is_select()) { - float color_inside[4] = {0.0f, 0.0f, 0.0f, 0.5f}; - float color_outside[4] = {1.0f, 1.0f, 1.0f, 0.3f}; + const float color_inside[4] = {0.0f, 0.0f, 0.0f, 0.5f}; + const float color_outside[4] = {1.0f, 1.0f, 1.0f, 0.3f}; DRW_buffer_add_entry(cb->light_spot_cone_front, color_inside, &instdata); DRW_buffer_add_entry(cb->light_spot_cone_back, color_outside, &instdata); } @@ -1020,9 +1018,8 @@ static float camera_offaxis_shiftx_get(Scene *scene, const float width = instdata->corner_x * 2.0f; return delta_shiftx * width; } - else { - return 0.0; - } + + return 0.0; } /** * Draw the stereo 3d support elements (cameras, plane, volume). @@ -1339,7 +1336,7 @@ static void OVERLAY_relationship_lines(OVERLAY_ExtraCallBuffers *cb, else { const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon); - if ((cti && cti->get_constraint_targets) && (curcon->ui_expand_flag && (1 << 0))) { + if ((cti && cti->get_constraint_targets) && (curcon->ui_expand_flag & (1 << 0))) { ListBase targets = {NULL, NULL}; bConstraintTarget *ct; @@ -1422,7 +1419,7 @@ static void OVERLAY_volume_extra(OVERLAY_ExtraCallBuffers *cb, line_count /= fds->res[axis]; } - GPU_create_smoke_velocity(fmd); + DRW_smoke_ensure_velocity(fmd); GPUShader *sh = OVERLAY_shader_volume_velocity(use_needle); DRWShadingGroup *grp = DRW_shgroup_create(sh, data->psl->extra_ps[0]); @@ -1452,7 +1449,7 @@ static void OVERLAY_volume_free_smoke_textures(OVERLAY_Data *data) LinkData *link; while ((link = BLI_pophead(&data->stl->pd->smoke_domains))) { FluidModifierData *fmd = (FluidModifierData *)link->data; - GPU_free_smoke_velocity(fmd); + DRW_smoke_free_velocity(fmd); MEM_freeN(link); } } @@ -1542,7 +1539,7 @@ void OVERLAY_extra_cache_populate(OVERLAY_Data *vedata, Object *ob) } /* Helpers for when we're transforming origins. */ if (draw_xform) { - float color_xform[4] = {0.15f, 0.15f, 0.15f, 0.7f}; + const float color_xform[4] = {0.15f, 0.15f, 0.15f, 0.7f}; DRW_buffer_add_entry(cb->origin_xform, color_xform, ob->obmat); } /* don't show object extras in set's */ diff --git a/source/blender/draw/engines/overlay/overlay_image.c b/source/blender/draw/engines/overlay/overlay_image.c index 67132a9e0ed..08cddf4e185 100644 --- a/source/blender/draw/engines/overlay/overlay_image.c +++ b/source/blender/draw/engines/overlay/overlay_image.c @@ -109,13 +109,12 @@ static eStereoViews camera_background_images_stereo_eye(const Scene *scene, cons if ((scene->r.scemode & R_MULTIVIEW) == 0) { return STEREO_LEFT_ID; } - else if (v3d->stereo3d_camera != STEREO_3D_ID) { + if (v3d->stereo3d_camera != STEREO_3D_ID) { /* show only left or right camera */ return v3d->stereo3d_camera; } - else { - return v3d->multiview_eye; - } + + return v3d->multiview_eye; } static void camera_background_images_stereo_setup(const Scene *scene, @@ -162,9 +161,8 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp /* Frame is out of range, dont show. */ return NULL; } - else { - camera_background_images_stereo_setup(scene, draw_ctx->v3d, image, iuser); - } + + camera_background_images_stereo_setup(scene, draw_ctx->v3d, image, iuser); iuser->scene = draw_ctx->scene; ImBuf *ibuf = BKE_image_acquire_ibuf(image, iuser, &lock); @@ -175,7 +173,7 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp } width = ibuf->x; height = ibuf->y; - tex = GPU_texture_from_blender(image, iuser, ibuf, GL_TEXTURE_2D); + tex = BKE_image_get_gpu_texture(image, iuser, ibuf); BKE_image_release_ibuf(image, ibuf, lock); iuser->scene = NULL; @@ -203,7 +201,7 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp } BKE_movieclip_user_set_frame(&bgpic->cuser, ctime); - tex = GPU_texture_from_movieclip(clip, &bgpic->cuser, GL_TEXTURE_2D); + tex = BKE_movieclip_get_gpu_texture(clip, &bgpic->cuser); if (tex == NULL) { return NULL; } @@ -232,7 +230,7 @@ static void OVERLAY_image_free_movieclips_textures(OVERLAY_Data *data) LinkData *link; while ((link = BLI_pophead(&data->stl->pd->bg_movie_clips))) { MovieClip *clip = (MovieClip *)link->data; - GPU_free_texture_movieclip(clip); + BKE_movieclip_free_gputexture(clip); MEM_freeN(link); } } @@ -342,7 +340,7 @@ void OVERLAY_image_camera_cache_populate(OVERLAY_Data *vedata, Object *ob) mul_m4_m4m4(mat, modelmat, mat); const bool is_foreground = (bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) != 0; - float color_premult_alpha[4] = {1.0f, 1.0f, 1.0f, bgpic->alpha}; + const float color_premult_alpha[4] = {1.0f, 1.0f, 1.0f, bgpic->alpha}; DRWPass *pass = is_foreground ? psl->image_foreground_ps : psl->image_background_ps; @@ -383,7 +381,7 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob) if (ima != NULL) { ImageUser iuser = *ob->iuser; camera_background_images_stereo_setup(draw_ctx->scene, draw_ctx->v3d, ima, &iuser); - tex = GPU_texture_from_blender(ima, &iuser, NULL, GL_TEXTURE_2D); + tex = BKE_image_get_gpu_texture(ima, &iuser, NULL); if (tex) { size[0] = GPU_texture_orig_width(tex); size[1] = GPU_texture_orig_height(tex); diff --git a/source/blender/draw/engines/overlay/overlay_motion_path.c b/source/blender/draw/engines/overlay/overlay_motion_path.c index 168f6f8a17f..0e5a52702fe 100644 --- a/source/blender/draw/engines/overlay/overlay_motion_path.c +++ b/source/blender/draw/engines/overlay/overlay_motion_path.c @@ -149,7 +149,7 @@ static void motion_path_cache(OVERLAY_Data *vedata, /* Draw curve-line of path. */ if (show_lines) { - int motion_path_settings[4] = {cfra, sfra, efra, mpath->start_frame}; + const int motion_path_settings[4] = {cfra, sfra, efra, mpath->start_frame}; DRWShadingGroup *grp = DRW_shgroup_create_sub(pd->motion_path_lines_grp); DRW_shgroup_uniform_ivec4_copy(grp, "mpathLineSettings", motion_path_settings); DRW_shgroup_uniform_int_copy(grp, "lineThickness", mpath->line_thickness); @@ -162,7 +162,7 @@ static void motion_path_cache(OVERLAY_Data *vedata, /* Draw points. */ { int pt_size = max_ii(mpath->line_thickness - 1, 1); - int motion_path_settings[4] = {pt_size, cfra, mpath->start_frame, stepsize}; + const int motion_path_settings[4] = {pt_size, cfra, mpath->start_frame, stepsize}; DRWShadingGroup *grp = DRW_shgroup_create_sub(pd->motion_path_points_grp); DRW_shgroup_uniform_ivec4_copy(grp, "mpathPointSettings", motion_path_settings); DRW_shgroup_uniform_bool_copy(grp, "showKeyFrames", show_keyframes); diff --git a/source/blender/draw/engines/overlay/overlay_outline.c b/source/blender/draw/engines/overlay/overlay_outline.c index 214322c4adc..e904066248f 100644 --- a/source/blender/draw/engines/overlay/overlay_outline.c +++ b/source/blender/draw/engines/overlay/overlay_outline.c @@ -342,7 +342,7 @@ void OVERLAY_outline_draw(OVERLAY_Data *vedata) { OVERLAY_FramebufferList *fbl = vedata->fbl; OVERLAY_PassList *psl = vedata->psl; - float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f}; bool do_outlines = psl->outlines_prepass_ps != NULL && !DRW_pass_is_empty(psl->outlines_prepass_ps); diff --git a/source/blender/draw/engines/overlay/overlay_paint.c b/source/blender/draw/engines/overlay/overlay_paint.c index e94cc820568..f0a1e77cf05 100644 --- a/source/blender/draw/engines/overlay/overlay_paint.c +++ b/source/blender/draw/engines/overlay/overlay_paint.c @@ -22,6 +22,8 @@ #include "DRW_render.h" +#include "BKE_image.h" + #include "DNA_mesh_types.h" #include "DEG_depsgraph_query.h" @@ -34,7 +36,7 @@ static bool paint_object_is_rendered_transparent(View3D *v3d, Object *ob) if (v3d->shading.type == OB_WIRE) { return true; } - else if (v3d->shading.type == OB_SOLID) { + if (v3d->shading.type == OB_SOLID) { if (v3d->shading.flag & V3D_SHADING_XRAY) { return true; } @@ -42,8 +44,8 @@ static bool paint_object_is_rendered_transparent(View3D *v3d, Object *ob) if (ob && v3d->shading.color_type == V3D_SHADING_OBJECT_COLOR) { return ob->color[3] < 1.0f; } - else if (ob && ob->type == OB_MESH && ob->data && - v3d->shading.color_type == V3D_SHADING_MATERIAL_COLOR) { + if (ob && ob->type == OB_MESH && ob->data && + v3d->shading.color_type == V3D_SHADING_MATERIAL_COLOR) { Mesh *me = ob->data; for (int i = 0; i < me->totcol; i++) { Material *mat = me->mat[i]; @@ -136,7 +138,7 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata) state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ALPHA; DRW_PASS_CREATE(psl->paint_color_ps, state | pd->clipping_state); - GPUTexture *tex = GPU_texture_from_blender(imapaint->stencil, NULL, NULL, GL_TEXTURE_2D); + GPUTexture *tex = BKE_image_get_gpu_texture(imapaint->stencil, NULL, NULL); const bool mask_premult = (imapaint->stencil->alpha_mode == IMA_ALPHA_PREMUL); const bool mask_inverted = (imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) != 0; diff --git a/source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl b/source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl index 0d01f67c6ea..2989e07691f 100644 --- a/source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl @@ -1,4 +1,6 @@ +#pragma BLENDER_REQUIRE(common_math_lib.glsl) + uniform sampler2D colorTex; uniform sampler2D depthTex; uniform sampler2D lineTex; diff --git a/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl b/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl index 380708795e9..0925901a9c9 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl @@ -14,19 +14,6 @@ layout(depth_greater) out float gl_FragDepth; layout(location = 0) out vec4 fragColor; layout(location = 1) out vec4 lineOutput; -#define cameraPos ViewMatrixInverse[3].xyz - -float get_depth_from_view_z(float z) -{ - if (ProjectionMatrix[3][3] == 0.0) { - z = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2]; - } - else { - z = z * ProjectionMatrix[2][2] / (1.0 - ProjectionMatrix[3][2]); - } - return z * 0.5 + 0.5; -} - void main() { const float sphere_radius = 0.05; diff --git a/source/blender/draw/engines/overlay/shaders/grid_frag.glsl b/source/blender/draw/engines/overlay/shaders/grid_frag.glsl index 317e9fe0447..d0b68df0625 100644 --- a/source/blender/draw/engines/overlay/shaders/grid_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/grid_frag.glsl @@ -14,8 +14,6 @@ uniform float meshSize; uniform float lineKernel = 0.0; uniform sampler2D depthBuffer; -#define cameraPos (ViewMatrixInverse[3].xyz) - uniform int gridFlag; #define STEPS_LEN 8 diff --git a/source/blender/draw/engines/overlay/shaders/grid_vert.glsl b/source/blender/draw/engines/overlay/shaders/grid_vert.glsl index 496bb011c74..dd0e771ad93 100644 --- a/source/blender/draw/engines/overlay/shaders/grid_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/grid_vert.glsl @@ -7,8 +7,6 @@ uniform float meshSize; uniform int gridFlag; -#define cameraPos (ViewMatrixInverse[3].xyz) - #define PLANE_XY (1 << 4) #define PLANE_XZ (1 << 5) #define PLANE_YZ (1 << 6) diff --git a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl index 722dbdd0b5e..d0d52c8485b 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl @@ -28,7 +28,7 @@ void cavity_compute(vec2 screenco, return; } - vec3 position = view_position_from_depth(screenco, depth, ViewVecs, ProjectionMatrix); + vec3 position = get_view_space_from_depth(screenco, depth); vec3 normal = workbench_normal_decode(texture(normalBuffer, screenco)); vec2 jitter_co = (screenco * world_data.viewport_size.xy) * world_data.cavity_jitter_scale; @@ -68,7 +68,7 @@ void cavity_compute(vec2 screenco, bool is_background = (s_depth == 1.0); /* This trick provide good edge effect even if no neighbor is found. */ s_depth = (is_background) ? depth : s_depth; - vec3 s_pos = view_position_from_depth(uvcoords, s_depth, ViewVecs, ProjectionMatrix); + vec3 s_pos = get_view_space_from_depth(uvcoords, s_depth); if (is_background) { s_pos.z -= world_data.cavity_distance; diff --git a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl index c529f23265b..eb61edca6c7 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl @@ -67,31 +67,3 @@ void workbench_float_pair_decode(float data, out float v1, out float v2) v1 = float(idata & v1_mask) * (1.0 / float(v1_mask)); v2 = float(idata >> int(ROUGHNESS_BITS)) * (1.0 / float(v2_mask)); } - -vec3 view_vector_from_screen_uv(vec2 uv, vec4 viewvecs[2], mat4 proj_mat) -{ - if (proj_mat[3][3] == 0.0) { - return normalize(vec3(viewvecs[0].xy + uv * viewvecs[1].xy, 1.0)); - } - else { - return vec3(0.0, 0.0, 1.0); - } -} - -vec3 view_position_from_depth(vec2 uvcoords, float depth, vec4 viewvecs[2], mat4 proj_mat) -{ - if (proj_mat[3][3] == 0.0) { - /* Perspective */ - float d = 2.0 * depth - 1.0; - - float zview = -proj_mat[3][2] / (d + proj_mat[2][2]); - - return zview * vec3(viewvecs[0].xy + uvcoords * viewvecs[1].xy, 1.0); - } - else { - /* Orthographic */ - vec3 offset = vec3(uvcoords, depth); - - return viewvecs[0].xyz + offset * viewvecs[1].xyz; - } -} diff --git a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl index f3a238fd112..6e10a656fc1 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl @@ -14,7 +14,7 @@ out vec4 fragColor; void main() { /* Normal and Incident vector are in viewspace. Lighting is evaluated in viewspace. */ - vec3 I = view_vector_from_screen_uv(uvcoordsvar.st, ViewVecs, ProjectionMatrix); + vec3 I = get_view_vector_from_screen_uv(uvcoordsvar.st); vec3 N = workbench_normal_decode(texture(normalBuffer, uvcoordsvar.st)); vec4 mat_data = texture(materialBuffer, uvcoordsvar.st); diff --git a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl index 51007a9f246..71816f6ff6e 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl @@ -1,3 +1,6 @@ + +#pragma BLENDER_REQUIRE(common_math_lib.glsl) + /** * Separable Hexagonal Bokeh Blur by Colin Barré-Brisebois * https://colinbarrebrisebois.com/2017/04/18/hexagonal-bokeh-blur-revisited-part-1-basic-3-pass-version/ @@ -21,13 +24,6 @@ uniform sampler2D noiseTex; #define dof_distance dofParams.y #define dof_invsensorsize dofParams.z -#define M_PI 3.1415926535897932 /* pi */ - -float max_v4(vec4 v) -{ - return max(max(v.x, v.y), max(v.z, v.w)); -} - #define weighted_sum(a, b, c, d, e, e_sum) \ ((a)*e.x + (b)*e.y + (c)*e.z + (d)*e.w) / max(1e-6, e_sum); diff --git a/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl index ba8eeff1001..fd4d00d96dd 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl @@ -57,7 +57,7 @@ void main() { /* Normal and Incident vector are in viewspace. Lighting is evaluated in viewspace. */ vec2 uv_viewport = gl_FragCoord.xy * world_data.viewport_size_inv; - vec3 I = view_vector_from_screen_uv(uv_viewport, ViewVecs, ProjectionMatrix); + vec3 I = get_view_vector_from_screen_uv(uv_viewport); vec3 N = normalize(normal_interp); vec3 color = color_interp; diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl index 6ab652cbf36..aa938d80fa3 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl @@ -1,4 +1,5 @@ +#pragma BLENDER_REQUIRE(common_math_lib.glsl) #pragma BLENDER_REQUIRE(common_view_lib.glsl) #pragma BLENDER_REQUIRE(gpu_shader_common_obinfos_lib.glsl) #pragma BLENDER_REQUIRE(workbench_data_lib.glsl) @@ -33,11 +34,6 @@ float phase_function_isotropic() return 1.0 / (4.0 * M_PI); } -float max_v3(vec3 v) -{ - return max(v.x, max(v.y, v.z)); -} - float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection) { /* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ @@ -194,8 +190,8 @@ void main() float depth = texelFetch(depthBuffer, ivec2(gl_FragCoord.xy), 0).r; float depth_end = min(depth, gl_FragCoord.z); - vec3 vs_ray_end = view_position_from_depth(screen_uv, depth_end, ViewVecs, ProjectionMatrix); - vec3 vs_ray_ori = view_position_from_depth(screen_uv, 0.0, ViewVecs, ProjectionMatrix); + vec3 vs_ray_end = get_view_space_from_depth(screen_uv, depth_end); + vec3 vs_ray_ori = get_view_space_from_depth(screen_uv, 0.0); vec3 vs_ray_dir = (is_persp) ? (vs_ray_end - vs_ray_ori) : vec3(0.0, 0.0, -1.0); vs_ray_dir /= abs(vs_ray_dir.z); diff --git a/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c index 0e896c4b7bb..47a03073839 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c +++ b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c @@ -112,17 +112,15 @@ int workbench_antialiasing_sample_count_get(WORKBENCH_PrivateData *wpd) /* Only draw using SMAA or no AA when navigating. */ return min_ii(wpd->preferences->viewport_aa, 1); } - else if (DRW_state_is_image_render()) { + if (DRW_state_is_image_render()) { if (draw_ctx->v3d) { return scene->display.viewport_aa; } - else { - return scene->display.render_aa; - } - } - else { - return wpd->preferences->viewport_aa; + + return scene->display.render_aa; } + + return wpd->preferences->viewport_aa; } void workbench_antialiasing_view_updated(WORKBENCH_Data *vedata) @@ -303,7 +301,7 @@ void workbench_antialiasing_cache_init(WORKBENCH_Data *vedata) const float *size = DRW_viewport_size_get(); const float *sizeinv = DRW_viewport_invert_size_get(); - float metrics[4] = {sizeinv[0], sizeinv[1], size[0], size[1]}; + const float metrics[4] = {sizeinv[0], sizeinv[1], size[0], size[1]}; { /* Stage 1: Edge detection. */ @@ -361,53 +359,52 @@ bool workbench_antialiasing_setup(WORKBENCH_Data *vedata) /* TAA accumulation has finish. Just copy the result back */ return false; } - else { - const float *viewport_size = DRW_viewport_size_get(); - const DRWView *default_view = DRW_view_default_get(); - float *transform_offset; - - switch (wpd->taa_sample_len) { - default: - case 5: - transform_offset = e_data.jitter_5[min_ii(wpd->taa_sample, 5)]; - break; - case 8: - transform_offset = e_data.jitter_8[min_ii(wpd->taa_sample, 8)]; - break; - case 11: - transform_offset = e_data.jitter_11[min_ii(wpd->taa_sample, 11)]; - break; - case 16: - transform_offset = e_data.jitter_16[min_ii(wpd->taa_sample, 16)]; - break; - case 32: - transform_offset = e_data.jitter_32[min_ii(wpd->taa_sample, 32)]; - break; - } - - /* construct new matrices from transform delta */ - float winmat[4][4], viewmat[4][4], persmat[4][4]; - DRW_view_winmat_get(default_view, winmat, false); - DRW_view_viewmat_get(default_view, viewmat, false); - DRW_view_persmat_get(default_view, persmat, false); - window_translate_m4(winmat, - persmat, - transform_offset[0] / viewport_size[0], - transform_offset[1] / viewport_size[1]); - - if (wpd->view) { - /* When rendering just update the view. This avoids recomputing the culling. */ - DRW_view_update_sub(wpd->view, viewmat, winmat); - } - else { - /* TAA is not making a big change to the matrices. - * Reuse the main view culling by creating a sub-view. */ - wpd->view = DRW_view_create_sub(default_view, viewmat, winmat); - } - DRW_view_set_active(wpd->view); - return true; + const float *viewport_size = DRW_viewport_size_get(); + const DRWView *default_view = DRW_view_default_get(); + float *transform_offset; + + switch (wpd->taa_sample_len) { + default: + case 5: + transform_offset = e_data.jitter_5[min_ii(wpd->taa_sample, 5)]; + break; + case 8: + transform_offset = e_data.jitter_8[min_ii(wpd->taa_sample, 8)]; + break; + case 11: + transform_offset = e_data.jitter_11[min_ii(wpd->taa_sample, 11)]; + break; + case 16: + transform_offset = e_data.jitter_16[min_ii(wpd->taa_sample, 16)]; + break; + case 32: + transform_offset = e_data.jitter_32[min_ii(wpd->taa_sample, 32)]; + break; + } + + /* construct new matrices from transform delta */ + float winmat[4][4], viewmat[4][4], persmat[4][4]; + DRW_view_winmat_get(default_view, winmat, false); + DRW_view_viewmat_get(default_view, viewmat, false); + DRW_view_persmat_get(default_view, persmat, false); + + window_translate_m4(winmat, + persmat, + transform_offset[0] / viewport_size[0], + transform_offset[1] / viewport_size[1]); + + if (wpd->view) { + /* When rendering just update the view. This avoids recomputing the culling. */ + DRW_view_update_sub(wpd->view, viewmat, winmat); + } + else { + /* TAA is not making a big change to the matrices. + * Reuse the main view culling by creating a sub-view. */ + wpd->view = DRW_view_create_sub(default_view, viewmat, winmat); } + DRW_view_set_active(wpd->view); + return true; } void workbench_antialiasing_draw_pass(WORKBENCH_Data *vedata) diff --git a/source/blender/draw/engines/workbench/workbench_effect_dof.c b/source/blender/draw/engines/workbench/workbench_effect_dof.c index e13f7bfdd92..f2f75d616ff 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_dof.c +++ b/source/blender/draw/engines/workbench/workbench_effect_dof.c @@ -155,7 +155,7 @@ void workbench_dof_engine_init(WORKBENCH_Data *vedata) } const float *full_size = DRW_viewport_size_get(); - int size[2] = {max_ii(1, (int)full_size[0] / 2), max_ii(1, (int)full_size[1] / 2)}; + const int size[2] = {max_ii(1, (int)full_size[0] / 2), max_ii(1, (int)full_size[1] / 2)}; #if 0 /* TODO(fclem) finish COC min_max optimisation */ /* NOTE: We Ceil here in order to not miss any edge texel if using a NPO2 texture. */ int shrink_h_size[2] = {ceilf(size[0] / 8.0f), size[1]}; diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c index 53119723fab..ca80b6a9002 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.c +++ b/source/blender/draw/engines/workbench/workbench_engine.c @@ -64,7 +64,7 @@ void workbench_engine_init(void *ved) workbench_update_world_ubo(wpd); if (txl->dummy_image_tx == NULL) { - float fpixel[4] = {1.0f, 0.0f, 1.0f, 1.0f}; + const float fpixel[4] = {1.0f, 0.0f, 1.0f, 1.0f}; txl->dummy_image_tx = DRW_texture_create_2d(1, 1, GPU_RGBA8, 0, fpixel); } wpd->dummy_image_tx = txl->dummy_image_tx; @@ -480,8 +480,8 @@ void workbench_draw_sample(void *ved) WORKBENCH_PrivateData *wpd = vedata->stl->wpd; WORKBENCH_PassList *psl = vedata->psl; DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); - float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - float clear_col_with_alpha[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float clear_col_with_alpha[4] = {0.0f, 0.0f, 0.0f, 1.0f}; const bool do_render = workbench_antialiasing_setup(vedata); const bool xray_is_visible = wpd->shading.xray_alpha > 0.0f; diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c index 4d5a5b163ed..538083b4beb 100644 --- a/source/blender/draw/engines/workbench/workbench_materials.c +++ b/source/blender/draw/engines/workbench/workbench_materials.c @@ -60,7 +60,7 @@ void workbench_material_ubo_data(WORKBENCH_PrivateData *wpd, hash = (hash * 13) ^ BLI_ghashutil_strhash_p_murmur(ob->id.lib->filepath); } float hue = BLI_hash_int_01(hash); - float hsv[3] = {hue, HSV_SATURATION, HSV_VALUE}; + const float hsv[3] = {hue, HSV_SATURATION, HSV_VALUE}; hsv_to_rgb_v(hsv, data->base_color); break; } @@ -261,11 +261,11 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd, if (ima) { if (ima->source == IMA_SRC_TILED) { - tex = GPU_texture_from_blender(ima, iuser, NULL, GL_TEXTURE_2D_ARRAY); - tex_tile_data = GPU_texture_from_blender(ima, iuser, NULL, GL_TEXTURE_1D_ARRAY); + tex = BKE_image_get_gpu_tiles(ima, iuser, NULL); + tex_tile_data = BKE_image_get_gpu_tilemap(ima, iuser, NULL); } else { - tex = GPU_texture_from_blender(ima, iuser, NULL, GL_TEXTURE_2D); + tex = BKE_image_get_gpu_texture(ima, iuser, NULL); } } diff --git a/source/blender/draw/engines/workbench/workbench_shader.c b/source/blender/draw/engines/workbench/workbench_shader.c index 835f10598d4..aab3cef00e6 100644 --- a/source/blender/draw/engines/workbench/workbench_shader.c +++ b/source/blender/draw/engines/workbench/workbench_shader.c @@ -28,6 +28,8 @@ #include "workbench_engine.h" #include "workbench_private.h" +extern char datatoc_common_math_lib_glsl[]; +extern char datatoc_common_math_geom_lib_glsl[]; extern char datatoc_common_hair_lib_glsl[]; extern char datatoc_common_pointcloud_lib_glsl[]; extern char datatoc_common_view_lib_glsl[]; @@ -119,6 +121,8 @@ void workbench_shader_library_ensure(void) if (e_data.lib == NULL) { e_data.lib = DRW_shader_library_create(); /* NOTE: Theses needs to be ordered by dependencies. */ + DRW_SHADER_LIB_ADD(e_data.lib, common_math_lib); + DRW_SHADER_LIB_ADD(e_data.lib, common_math_geom_lib); DRW_SHADER_LIB_ADD(e_data.lib, common_hair_lib); DRW_SHADER_LIB_ADD(e_data.lib, common_view_lib); DRW_SHADER_LIB_ADD(e_data.lib, common_pointcloud_lib); diff --git a/source/blender/draw/engines/workbench/workbench_shadow.c b/source/blender/draw/engines/workbench/workbench_shadow.c index 2cf5f3c4c13..56a028d5a7e 100644 --- a/source/blender/draw/engines/workbench/workbench_shadow.c +++ b/source/blender/draw/engines/workbench/workbench_shadow.c @@ -62,7 +62,7 @@ static void workbench_shadow_update(WORKBENCH_PrivateData *wpd) wpd->shadow_cached_direction, wpd->shadow_direction_ws, 1e-5f); if (wpd->shadow_changed) { - float up[3] = {0.0f, 0.0f, 1.0f}; + const float up[3] = {0.0f, 0.0f, 1.0f}; unit_m4(wpd->shadow_mat); /* TODO fix singularity. */ @@ -229,7 +229,7 @@ static float workbench_shadow_object_shadow_distance(WORKBENCH_PrivateData *wpd, { BoundBox *shadow_bbox = workbench_shadow_object_shadow_bbox_get(wpd, ob, oed); - int corners[4] = {0, 3, 4, 7}; + const int corners[4] = {0, 3, 4, 7}; float dist = 1e4f, dist_isect; for (int i = 0; i < 4; i++) { if (isect_ray_plane_v3(shadow_bbox->vec[corners[i]], diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c index 8e345f8275b..f71e77d5da5 100644 --- a/source/blender/draw/engines/workbench/workbench_volume.c +++ b/source/blender/draw/engines/workbench/workbench_volume.c @@ -38,15 +38,13 @@ #include "BKE_volume.h" #include "BKE_volume_render.h" -#include "GPU_draw.h" - void workbench_volume_engine_init(WORKBENCH_Data *vedata) { WORKBENCH_TextureList *txl = vedata->txl; if (txl->dummy_volume_tx == NULL) { - float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - float one[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f}; txl->dummy_volume_tx = GPU_texture_create_3d(1, 1, 1, GPU_RGBA8, zero, NULL); txl->dummy_shadow_tx = GPU_texture_create_3d(1, 1, 1, GPU_RGBA8, one, NULL); txl->dummy_coba_tx = GPU_texture_create_1d(1, GPU_RGBA8, zero, NULL); @@ -79,13 +77,10 @@ static void workbench_volume_modifier_cache_populate(WORKBENCH_Data *vedata, wpd->volumes_do = true; if (fds->use_coba) { - GPU_create_smoke_coba_field(fmd); - } - else if (!(fds->flags & FLUID_DOMAIN_USE_NOISE)) { - GPU_create_smoke(fmd, 0); + DRW_smoke_ensure_coba_field(fmd); } - else if (fds->flags & FLUID_DOMAIN_USE_NOISE) { - GPU_create_smoke(fmd, 1); + else { + DRW_smoke_ensure(fmd, fds->flags & FLUID_DOMAIN_USE_NOISE); } if ((!fds->use_coba && (fds->tex_density == NULL && fds->tex_color == NULL)) || @@ -293,7 +288,7 @@ void workbench_volume_draw_finish(WORKBENCH_Data *vedata) * all viewport in a redraw at least. */ LISTBASE_FOREACH (LinkData *, link, &wpd->smoke_domains) { FluidModifierData *fmd = (FluidModifierData *)link->data; - GPU_free_smoke(fmd); + DRW_smoke_free(fmd); } BLI_freelistN(&wpd->smoke_domains); } diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index ab6ea53261f..956bddfb357 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -197,6 +197,17 @@ void DRW_uniformbuffer_free(struct GPUUniformBuffer *ubo); } while (0) /* Shaders */ + +#ifndef __GPU_MATERIAL_H__ +/* FIXME: Meh avoid including all GPUMaterial. */ +typedef void (*GPUMaterialEvalCallbackFn)(struct GPUMaterial *mat, + int options, + const char **vert_code, + const char **geom_code, + const char **frag_lib, + const char **defines); +#endif + struct GPUShader *DRW_shader_create(const char *vert, const char *geom, const char *frag, @@ -236,7 +247,8 @@ struct GPUMaterial *DRW_shader_create_from_world(struct Scene *scene, const char *geom, const char *frag_lib, const char *defines, - bool deferred); + bool deferred, + GPUMaterialEvalCallbackFn callback); struct GPUMaterial *DRW_shader_create_from_material(struct Scene *scene, struct Material *ma, struct bNodeTree *ntree, @@ -247,7 +259,8 @@ struct GPUMaterial *DRW_shader_create_from_material(struct Scene *scene, const char *geom, const char *frag_lib, const char *defines, - bool deferred); + bool deferred, + GPUMaterialEvalCallbackFn callback); void DRW_shader_free(struct GPUShader *shader); #define DRW_SHADER_FREE_SAFE(shader) \ do { \ diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 20e346375a7..d59c891fbeb 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -361,8 +361,8 @@ GPUBatch *DRW_cache_fullscreen_quad_get(void) if (!SHC.drw_fullscreen_quad) { /* Use a triangle instead of a real quad */ /* https://www.slideshare.net/DevCentralAMD/vertex-shader-tricks-bill-bilodeau - slide 14 */ - float pos[3][2] = {{-1.0f, -1.0f}, {3.0f, -1.0f}, {-1.0f, 3.0f}}; - float uvs[3][2] = {{0.0f, 0.0f}, {2.0f, 0.0f}, {0.0f, 2.0f}}; + const float pos[3][2] = {{-1.0f, -1.0f}, {3.0f, -1.0f}, {-1.0f, 3.0f}}; + const float uvs[3][2] = {{0.0f, 0.0f}, {2.0f, 0.0f}, {0.0f, 2.0f}}; /* Position Only 2D format */ static GPUVertFormat format = {0}; @@ -400,7 +400,7 @@ GPUBatch *DRW_cache_quad_get(void) int v = 0; int flag = VCLASS_EMPTY_SCALED; - float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}}; + const float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}}; for (int a = 0; a < 4; a++) { GPU_vertbuf_vert_set(vbo, v++, &(Vert){{p[a][0], p[a][1], 0.0f}, flag}); } @@ -421,7 +421,7 @@ GPUBatch *DRW_cache_quad_wires_get(void) int v = 0; int flag = VCLASS_EMPTY_SCALED; - float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}}; + const float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}}; for (int a = 0; a < 5; a++) { GPU_vertbuf_vert_set(vbo, v++, &(Vert){{p[a % 4][0], p[a % 4][1], 0.0f}, flag}); } @@ -1650,7 +1650,7 @@ GPUBatch *DRW_cache_light_area_square_lines_get(void) int flag = VCLASS_LIGHT_AREA_SHAPE; for (int a = 0; a < 4; a++) { for (int b = 0; b < 2; b++) { - float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}}; + const float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}}; float x = p[(a + b) % 4][0]; float y = p[(a + b) % 4][1]; GPU_vertbuf_vert_set(vbo, v++, &(Vert){{x * 0.5f, y * 0.5f, 0.0f}, flag}); @@ -2659,7 +2659,7 @@ GPUBatch *DRW_cache_camera_frame_get(void) GPU_vertbuf_data_alloc(vbo, v_len); int v = 0; - float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}}; + const float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}}; /* Frame */ for (int a = 0; a < 4; a++) { for (int b = 0; b < 2; b++) { @@ -2740,7 +2740,7 @@ GPUBatch *DRW_cache_camera_tria_wire_get(void) GPU_vertbuf_data_alloc(vbo, v_len); int v = 0; - float p[3][2] = {{-1.0f, 1.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}}; + const float p[3][2] = {{-1.0f, 1.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}}; for (int a = 0; a < 3; a++) { for (int b = 0; b < 2; b++) { float x = p[(a + b) % 3][0]; @@ -2909,9 +2909,8 @@ GPUBatch *DRW_cache_curve_edge_wire_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_loose_edges(mesh_eval); } - else { - return DRW_curve_batch_cache_get_wire_edge(cu); - } + + return DRW_curve_batch_cache_get_wire_edge(cu); } GPUBatch *DRW_cache_curve_edge_normal_get(Object *ob) @@ -2947,9 +2946,8 @@ GPUBatch *DRW_cache_curve_surface_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_surface(mesh_eval); } - else { - return DRW_curve_batch_cache_get_triangles_with_normals(cu); - } + + return DRW_curve_batch_cache_get_triangles_with_normals(cu); } GPUBatch *DRW_cache_curve_loose_edges_get(Object *ob) @@ -2961,11 +2959,10 @@ GPUBatch *DRW_cache_curve_loose_edges_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_loose_edges(mesh_eval); } - else { - /* TODO */ - UNUSED_VARS(cu); - return NULL; - } + + /* TODO */ + UNUSED_VARS(cu); + return NULL; } GPUBatch *DRW_cache_curve_face_wireframe_get(Object *ob) @@ -2977,9 +2974,8 @@ GPUBatch *DRW_cache_curve_face_wireframe_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval); } - else { - return DRW_curve_batch_cache_get_wireframes_face(cu); - } + + return DRW_curve_batch_cache_get_wireframes_face(cu); } GPUBatch *DRW_cache_curve_edge_detection_get(Object *ob, bool *r_is_manifold) @@ -2990,9 +2986,8 @@ GPUBatch *DRW_cache_curve_edge_detection_get(Object *ob, bool *r_is_manifold) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_edge_detection(mesh_eval, r_is_manifold); } - else { - return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold); - } + + return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold); } /* Return list of batches */ @@ -3007,9 +3002,8 @@ GPUBatch **DRW_cache_curve_surface_shaded_get(Object *ob, if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len); } - else { - return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); - } + + return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); } /** \} */ @@ -3061,12 +3055,11 @@ GPUBatch *DRW_cache_text_edge_wire_get(Object *ob) if (!has_surface) { return NULL; } - else if (mesh_eval != NULL) { + if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_loose_edges(mesh_eval); } - else { - return DRW_curve_batch_cache_get_wire_edge(cu); - } + + return DRW_curve_batch_cache_get_wire_edge(cu); } GPUBatch *DRW_cache_text_surface_get(Object *ob) @@ -3080,9 +3073,8 @@ GPUBatch *DRW_cache_text_surface_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_surface(mesh_eval); } - else { - return DRW_curve_batch_cache_get_triangles_with_normals(cu); - } + + return DRW_curve_batch_cache_get_triangles_with_normals(cu); } GPUBatch *DRW_cache_text_edge_detection_get(Object *ob, bool *r_is_manifold) @@ -3096,9 +3088,8 @@ GPUBatch *DRW_cache_text_edge_detection_get(Object *ob, bool *r_is_manifold) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_edge_detection(mesh_eval, r_is_manifold); } - else { - return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold); - } + + return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold); } GPUBatch *DRW_cache_text_loose_edges_get(Object *ob) @@ -3112,9 +3103,8 @@ GPUBatch *DRW_cache_text_loose_edges_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_loose_edges(mesh_eval); } - else { - return DRW_curve_batch_cache_get_wire_edge(cu); - } + + return DRW_curve_batch_cache_get_wire_edge(cu); } GPUBatch *DRW_cache_text_face_wireframe_get(Object *ob) @@ -3128,9 +3118,8 @@ GPUBatch *DRW_cache_text_face_wireframe_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval); } - else { - return DRW_curve_batch_cache_get_wireframes_face(cu); - } + + return DRW_curve_batch_cache_get_wireframes_face(cu); } GPUBatch **DRW_cache_text_surface_shaded_get(Object *ob, @@ -3146,9 +3135,8 @@ GPUBatch **DRW_cache_text_surface_shaded_get(Object *ob, if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len); } - else { - return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); - } + + return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); } /** \} */ @@ -3166,9 +3154,8 @@ GPUBatch *DRW_cache_surf_surface_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_surface(mesh_eval); } - else { - return DRW_curve_batch_cache_get_triangles_with_normals(cu); - } + + return DRW_curve_batch_cache_get_triangles_with_normals(cu); } GPUBatch *DRW_cache_surf_edge_wire_get(Object *ob) @@ -3180,9 +3167,8 @@ GPUBatch *DRW_cache_surf_edge_wire_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_loose_edges(mesh_eval); } - else { - return DRW_curve_batch_cache_get_wire_edge(cu); - } + + return DRW_curve_batch_cache_get_wire_edge(cu); } GPUBatch *DRW_cache_surf_face_wireframe_get(Object *ob) @@ -3194,9 +3180,8 @@ GPUBatch *DRW_cache_surf_face_wireframe_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval); } - else { - return DRW_curve_batch_cache_get_wireframes_face(cu); - } + + return DRW_curve_batch_cache_get_wireframes_face(cu); } GPUBatch *DRW_cache_surf_edge_detection_get(Object *ob, bool *r_is_manifold) @@ -3207,9 +3192,8 @@ GPUBatch *DRW_cache_surf_edge_detection_get(Object *ob, bool *r_is_manifold) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_edge_detection(mesh_eval, r_is_manifold); } - else { - return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold); - } + + return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold); } GPUBatch *DRW_cache_surf_loose_edges_get(Object *ob) @@ -3221,11 +3205,10 @@ GPUBatch *DRW_cache_surf_loose_edges_get(Object *ob) if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_loose_edges(mesh_eval); } - else { - /* TODO */ - UNUSED_VARS(cu); - return NULL; - } + + /* TODO */ + UNUSED_VARS(cu); + return NULL; } /* Return list of batches */ @@ -3240,9 +3223,8 @@ GPUBatch **DRW_cache_surf_surface_shaded_get(Object *ob, if (mesh_eval != NULL) { return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len); } - else { - return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); - } + + return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); } /** \} */ @@ -3434,8 +3416,8 @@ GPUBatch *DRW_cache_cursor_get(bool crosshair_lines) const int vert_len = segments + 8; const int index_len = vert_len + 5; - uchar red[3] = {255, 0, 0}; - uchar white[3] = {255, 255, 255}; + const uchar red[3] = {255, 0, 0}; + const uchar white[3] = {255, 255, 255}; static GPUVertFormat format = {0}; static struct { diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c index cca8ebcf2a8..a22d4cc95a2 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.c +++ b/source/blender/draw/intern/draw_cache_extract_mesh.c @@ -474,10 +474,9 @@ BLI_INLINE const float *bm_vert_co_get(const MeshRenderData *mr, const BMVert *e if (vert_coords != NULL) { return vert_coords[BM_elem_index_get(eve)]; } - else { - UNUSED_VARS(mr); - return eve->co; - } + + UNUSED_VARS(mr); + return eve->co; } BLI_INLINE const float *bm_vert_no_get(const MeshRenderData *mr, const BMVert *eve) @@ -486,10 +485,9 @@ BLI_INLINE const float *bm_vert_no_get(const MeshRenderData *mr, const BMVert *e if (vert_normals != NULL) { return vert_normals[BM_elem_index_get(eve)]; } - else { - UNUSED_VARS(mr); - return eve->no; - } + + UNUSED_VARS(mr); + return eve->no; } BLI_INLINE const float *bm_face_no_get(const MeshRenderData *mr, const BMFace *efa) @@ -498,10 +496,9 @@ BLI_INLINE const float *bm_face_no_get(const MeshRenderData *mr, const BMFace *e if (poly_normals != NULL) { return poly_normals[BM_elem_index_get(efa)]; } - else { - UNUSED_VARS(mr); - return efa->no; - } + + UNUSED_VARS(mr); + return efa->no; } /** \} */ @@ -2937,7 +2934,7 @@ static float evaluate_vertex_weight(const MDeformVert *dvert, const DRW_MeshWeig if ((wstate->defgroup_active < 0) && (wstate->defgroup_len > 0)) { return -2.0f; } - else if (dvert == NULL) { + if (dvert == NULL) { return (wstate->alert_mode != OB_DRAW_GROUPUSER_NONE) ? -1.0f : 0.0f; } @@ -3614,12 +3611,14 @@ static void compute_normalize_edge_vectors(float auv[2][2], normalize_v3(av[1]); } -static short v2_to_short_angle(float v[2]) +static short v2_to_short_angle(const float v[2]) { return atan2f(v[1], v[0]) * (float)M_1_PI * SHRT_MAX; } -static void edituv_get_stretch_angle(float auv[2][2], float av[2][3], UVStretchAngle *r_stretch) +static void edituv_get_stretch_angle(float auv[2][2], + const float av[2][3], + UVStretchAngle *r_stretch) { /* Send UV's to the shader and let it compute the aspect corrected angle. */ r_stretch->uv_angles[0] = v2_to_short_angle(auv[0]); @@ -4296,7 +4295,7 @@ static void statvis_calc_sharp(const MeshRenderData *mr, float *r_sharp) /* non-manifold edge, yet... */ continue; } - else if (*pval != NULL) { + if (*pval != NULL) { const float *f1_no = mr->poly_normals[mp_index]; const float *f2_no = *pval; angle = angle_normalized_v3v3(f1_no, f2_no); diff --git a/source/blender/draw/intern/draw_cache_impl_gpencil.c b/source/blender/draw/intern/draw_cache_impl_gpencil.c index e8355c1d8da..0ab14574fa6 100644 --- a/source/blender/draw/intern/draw_cache_impl_gpencil.c +++ b/source/blender/draw/intern/draw_cache_impl_gpencil.c @@ -135,9 +135,8 @@ static GpencilBatchCache *gpencil_batch_cache_get(Object *ob, int cfra) gpencil_batch_cache_clear(cache); return gpencil_batch_cache_init(ob, cfra); } - else { - return cache; - } + + return cache; } void DRW_gpencil_batch_cache_dirty_tag(bGPdata *gpd) diff --git a/source/blender/draw/intern/draw_cache_impl_lattice.c b/source/blender/draw/intern/draw_cache_impl_lattice.c index 66a67d6b8fe..0f80b5159a7 100644 --- a/source/blender/draw/intern/draw_cache_impl_lattice.c +++ b/source/blender/draw/intern/draw_cache_impl_lattice.c @@ -83,10 +83,9 @@ static int lattice_render_verts_len_get(Lattice *lt) if ((lt->flag & LT_OUTSIDE) == 0) { return vert_len_calc(u, v, w); } - else { - /* TODO remove internal coords */ - return vert_len_calc(u, v, w); - } + + /* TODO remove internal coords */ + return vert_len_calc(u, v, w); } static int lattice_render_edges_len_get(Lattice *lt) @@ -102,10 +101,9 @@ static int lattice_render_edges_len_get(Lattice *lt) if ((lt->flag & LT_OUTSIDE) == 0) { return edge_len_calc(u, v, w); } - else { - /* TODO remove internal coords */ - return edge_len_calc(u, v, w); - } + + /* TODO remove internal coords */ + return edge_len_calc(u, v, w); } /* ---------------------------------------------------------------------- */ @@ -252,12 +250,11 @@ static bool lattice_batch_cache_valid(Lattice *lt) if (cache->is_dirty) { return false; } - else { - if ((cache->dims.u_len != lt->pntsu) || (cache->dims.v_len != lt->pntsv) || - (cache->dims.w_len != lt->pntsw) || - ((cache->show_only_outside != ((lt->flag & LT_OUTSIDE) != 0)))) { - return false; - } + + if ((cache->dims.u_len != lt->pntsu) || (cache->dims.v_len != lt->pntsv) || + (cache->dims.w_len != lt->pntsw) || + ((cache->show_only_outside != ((lt->flag & LT_OUTSIDE) != 0)))) { + return false; } return true; diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index 361c66eca6e..d6faeb16583 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -803,9 +803,8 @@ GPUBatch *DRW_mesh_batch_cache_get_loose_edges(Mesh *me) if (cache->no_loose_wire) { return NULL; } - else { - return DRW_batch_request(&cache->batch.loose_edges); - } + + return DRW_batch_request(&cache->batch.loose_edges); } GPUBatch *DRW_mesh_batch_cache_get_surface_weights(Mesh *me) diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index 331a1f80bec..3ecdbff1e96 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -128,9 +128,8 @@ static bool particle_batch_cache_valid(ParticleSystem *psys) if (cache->is_dirty == false) { return true; } - else { - return false; - } + + return false; return true; } @@ -647,14 +646,13 @@ static float particle_key_weight(const ParticleData *particle, int strand, float if (t == 1.0) { return hkeys[part->totkey - 1].weight; } - else { - float interp = t / edit_key_seg_t; - int index = (int)interp; - interp -= floorf(interp); /* Time between 2 edit key */ - float s1 = hkeys[index].weight; - float s2 = hkeys[index + 1].weight; - return s1 + interp * (s2 - s1); - } + + float interp = t / edit_key_seg_t; + int index = (int)interp; + interp -= floorf(interp); /* Time between 2 edit key */ + float s1 = hkeys[index].weight; + float s2 = hkeys[index + 1].weight; + return s1 + interp * (s2 - s1); } static int particle_batch_cache_fill_segments_edit( diff --git a/source/blender/draw/intern/draw_cache_impl_pointcloud.c b/source/blender/draw/intern/draw_cache_impl_pointcloud.c index 17902f27513..06cedb9f72c 100644 --- a/source/blender/draw/intern/draw_cache_impl_pointcloud.c +++ b/source/blender/draw/intern/draw_cache_impl_pointcloud.c @@ -158,6 +158,7 @@ static void pointcloud_batch_cache_ensure_pos(Object *ob, PointCloudBatchCache * const bool has_radius = pointcloud->radius != NULL; static GPUVertFormat format = {0}; + static GPUVertFormat format_no_radius = {0}; static uint pos; if (format.attr_len == 0) { /* initialize vertex format */ @@ -167,11 +168,11 @@ static void pointcloud_batch_cache_ensure_pos(Object *ob, PointCloudBatchCache * * If the vertex shader has more components than the array provides, the extras are given * values from the vector (0, 0, 0, 1) for the missing XYZW components. */ - int comp_len = has_radius ? 4 : 3; - pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, comp_len, GPU_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(&format_no_radius, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); } - cache->pos = GPU_vertbuf_create_with_format(&format); + cache->pos = GPU_vertbuf_create_with_format(has_radius ? &format : &format_no_radius); GPU_vertbuf_data_alloc(cache->pos, pointcloud->totpoint); if (has_radius) { diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index 095e928aa74..f0d73d5bb84 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -455,11 +455,11 @@ bool DRW_object_is_flat(Object *ob, int *r_axis) *r_axis = 0; return true; } - else if (dim[1] == 0.0f) { + if (dim[1] == 0.0f) { *r_axis = 1; return true; } - else if (dim[2] == 0.0f) { + if (dim[2] == 0.0f) { *r_axis = 2; return true; } @@ -489,7 +489,7 @@ static void DRW_evaluate_weight_to_color(const float weight, float result[4]) * increasing widens yellow/cyan vs red/green/blue. * Gamma 1.0 produces the original 2.79 color ramp. */ const float gamma = 1.5f; - float hsv[3] = {(2.0f / 3.0f) * (1.0f - weight), 1.0f, pow(0.5f + 0.5f * weight, gamma)}; + const float hsv[3] = {(2.0f / 3.0f) * (1.0f - weight), 1.0f, pow(0.5f + 0.5f * weight, gamma)}; hsv_to_rgb_v(hsv, result); diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index d7bb9b78e09..6060dce47ac 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -26,8 +26,10 @@ struct DRWPass; struct DRWShadingGroup; struct GPUMaterial; struct ModifierData; +struct FluidModifierData; struct Object; struct ParticleSystem; +struct RegionView3D; struct ViewLayer; #define UBO_FIRST_COLOR colorWire @@ -158,14 +160,14 @@ void DRW_globals_update(void); void DRW_globals_free(void); struct DRWView *DRW_view_create_with_zoffset(const struct DRWView *parent_view, - const RegionView3D *rv3d, + const struct RegionView3D *rv3d, float offset); 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); -bool DRW_object_is_flat(Object *ob, int *r_axis); -bool DRW_object_axis_orthogonal_to_view(Object *ob, int axis); +bool DRW_object_is_flat(struct Object *ob, int *r_axis); +bool DRW_object_axis_orthogonal_to_view(struct Object *ob, int axis); /* draw_hair.c */ @@ -187,6 +189,16 @@ void DRW_hair_init(void); void DRW_hair_update(void); void DRW_hair_free(void); +/* draw_fluid.c */ + +/* Fluid simulation. */ +void DRW_smoke_ensure(struct FluidModifierData *fmd, int highres); +void DRW_smoke_ensure_coba_field(struct FluidModifierData *fmd); +void DRW_smoke_ensure_velocity(struct FluidModifierData *fmd); + +void DRW_smoke_free(struct FluidModifierData *fmd); +void DRW_smoke_free_velocity(struct FluidModifierData *fmd); + /* draw_common.c */ struct DRW_Global { /** If needed, contains all global/Theme colors diff --git a/source/blender/gpu/intern/gpu_draw_smoke.c b/source/blender/draw/intern/draw_fluid.c index e0b94e20574..33311dc698f 100644 --- a/source/blender/gpu/intern/gpu_draw_smoke.c +++ b/source/blender/draw/intern/draw_fluid.c @@ -35,10 +35,10 @@ #include "BKE_colorband.h" -#include "GPU_draw.h" -#include "GPU_glew.h" #include "GPU_texture.h" +#include "draw_common.h" /* Own include. */ + #ifdef WITH_FLUID # include "manta_fluid_API.h" #endif @@ -62,7 +62,8 @@ static void create_flame_spectrum_texture(float *data) # define MAX_FIRE_ALPHA 0.06f # define FULL_ON_FIRE 100 - float *spec_pixels = MEM_mallocN(TFUNC_WIDTH * 4 * 16 * 16 * sizeof(float), "spec_pixels"); + float *spec_pixels = (float *)MEM_mallocN(TFUNC_WIDTH * 4 * 16 * 16 * sizeof(float), + "spec_pixels"); blackbody_temperature_to_rgb_table(data, TFUNC_WIDTH, 1500, 3000); @@ -105,7 +106,7 @@ static void create_color_ramp(const struct ColorBand *coba, float *data) static GPUTexture *create_transfer_function(int type, const struct ColorBand *coba) { - float *data = MEM_mallocN(sizeof(float) * 4 * TFUNC_WIDTH, __func__); + float *data = (float *)MEM_mallocN(sizeof(float) * 4 * TFUNC_WIDTH, __func__); switch (type) { case TFUNC_FLAME_SPECTRUM: @@ -184,7 +185,7 @@ static GPUTexture *create_field_texture(FluidDomainSettings *fds) } GPUTexture *tex = GPU_texture_create_nD( - fds->res[0], fds->res[1], fds->res[2], 3, field, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL); + UNPACK3(fds->res), 3, field, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL); swizzle_texture_channel_single(tex); return tex; @@ -203,7 +204,7 @@ static GPUTexture *create_density_texture(FluidDomainSettings *fds, int highres) } GPUTexture *tex = GPU_texture_create_nD( - dim[0], dim[1], dim[2], 3, data, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL); + UNPACK3(dim), 3, data, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL); swizzle_texture_channel_single(tex); @@ -221,7 +222,7 @@ static GPUTexture *create_color_texture(FluidDomainSettings *fds, int highres) int cell_count = (highres) ? manta_noise_get_cells(fds->fluid) : fds->total_cells; int *dim = (highres) ? fds->res_noise : fds->res; - float *data = MEM_callocN(sizeof(float) * cell_count * 4, "smokeColorTexture"); + float *data = (float *)MEM_callocN(sizeof(float) * cell_count * 4, "smokeColorTexture"); if (data == NULL) { return NULL; @@ -276,7 +277,7 @@ static GPUTexture *create_flame_texture(FluidDomainSettings *fds, int highres) /** \name Public API * \{ */ -void GPU_free_smoke(FluidModifierData *fmd) +void DRW_smoke_free(FluidModifierData *fmd) { if (fmd->type & MOD_FLUID_TYPE_DOMAIN && fmd->domain) { if (fmd->domain->tex_density) { @@ -316,7 +317,7 @@ void GPU_free_smoke(FluidModifierData *fmd) } } -void GPU_create_smoke_coba_field(FluidModifierData *fmd) +void DRW_smoke_ensure_coba_field(FluidModifierData *fmd) { #ifndef WITH_FLUID UNUSED_VARS(fmd); @@ -334,7 +335,7 @@ void GPU_create_smoke_coba_field(FluidModifierData *fmd) #endif } -void GPU_create_smoke(FluidModifierData *fmd, int highres) +void DRW_smoke_ensure(FluidModifierData *fmd, int highres) { #ifndef WITH_FLUID UNUSED_VARS(fmd, highres); @@ -355,9 +356,7 @@ void GPU_create_smoke(FluidModifierData *fmd, int highres) fds->tex_flame_coba = create_transfer_function(TFUNC_FLAME_SPECTRUM, NULL); } if (!fds->tex_shadow) { - fds->tex_shadow = GPU_texture_create_nD(fds->res[0], - fds->res[1], - fds->res[2], + fds->tex_shadow = GPU_texture_create_nD(UNPACK3(fds->res), 3, manta_smoke_get_shadow(fds->fluid), GPU_R8, @@ -370,7 +369,7 @@ void GPU_create_smoke(FluidModifierData *fmd, int highres) #endif /* WITH_FLUID */ } -void GPU_create_smoke_velocity(FluidModifierData *fmd) +void DRW_smoke_ensure_velocity(FluidModifierData *fmd) { #ifndef WITH_FLUID UNUSED_VARS(fmd); @@ -387,19 +386,16 @@ void GPU_create_smoke_velocity(FluidModifierData *fmd) } if (!fds->tex_velocity_x) { - fds->tex_velocity_x = GPU_texture_create_3d( - fds->res[0], fds->res[1], fds->res[2], GPU_R16F, vel_x, NULL); - fds->tex_velocity_y = GPU_texture_create_3d( - fds->res[0], fds->res[1], fds->res[2], GPU_R16F, vel_y, NULL); - fds->tex_velocity_z = GPU_texture_create_3d( - fds->res[0], fds->res[1], fds->res[2], GPU_R16F, vel_z, NULL); + fds->tex_velocity_x = GPU_texture_create_3d(UNPACK3(fds->res), GPU_R16F, vel_x, NULL); + fds->tex_velocity_y = GPU_texture_create_3d(UNPACK3(fds->res), GPU_R16F, vel_y, NULL); + fds->tex_velocity_z = GPU_texture_create_3d(UNPACK3(fds->res), GPU_R16F, vel_z, NULL); } } #endif /* WITH_FLUID */ } -/* TODO Unify with the other GPU_free_smoke. */ -void GPU_free_smoke_velocity(FluidModifierData *fmd) +/* TODO Unify with the other DRW_smoke_free. */ +void DRW_smoke_free_velocity(FluidModifierData *fmd) { if (fmd->type & MOD_FLUID_TYPE_DOMAIN && fmd->domain) { if (fmd->domain->tex_velocity_x) { diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c index cbdcbbf9090..1cbf3ee9d54 100644 --- a/source/blender/draw/intern/draw_hair.c +++ b/source/blender/draw/intern/draw_hair.c @@ -114,7 +114,7 @@ void DRW_hair_init(void) g_dummy_vbo = GPU_vertbuf_create_with_format(&format); - float vert[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float vert[4] = {0.0f, 0.0f, 0.0f, 0.0f}; GPU_vertbuf_data_alloc(g_dummy_vbo, 1); GPU_vertbuf_attr_fill(g_dummy_vbo, dummy_id, vert); /* Create vbo immediately to bind to texture buffer. */ diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 2beab021cfb..4a5e07476a9 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -792,9 +792,8 @@ DrawDataList *DRW_drawdatalist_from_id(ID *id) IdDdtTemplate *idt = (IdDdtTemplate *)id; return &idt->drawdata; } - else { - return NULL; - } + + return NULL; } DrawData *DRW_drawdata_get(ID *id, DrawEngineType *engine_type) @@ -2031,7 +2030,7 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph, } } - int viewport_size[2] = {BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)}; + const int viewport_size[2] = {BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)}; struct GPUViewport *viewport = GPU_viewport_create(); GPU_viewport_size_set(viewport, viewport_size); @@ -2723,7 +2722,7 @@ void DRW_engines_free(void) void DRW_render_context_enable(Render *render) { if (G.background && DST.gl_context == NULL) { - WM_init_opengl(G_MAIN); + WM_init_opengl(); } if (GPU_use_main_context_workaround()) { @@ -2854,7 +2853,7 @@ void DRW_opengl_context_disable_ex(bool restore) void DRW_opengl_context_enable(void) { if (G.background && DST.gl_context == NULL) { - WM_init_opengl(G_MAIN); + WM_init_opengl(); } DRW_opengl_context_enable_ex(true); } diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index 9d8050504ab..661a27c10b7 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -594,28 +594,26 @@ static DRWResourceHandle drw_resource_handle(DRWShadingGroup *shgroup, DRWResourceHandle handle = 0; return handle; } - else { - return drw_resource_handle_new(obmat, NULL); - } + + return drw_resource_handle_new(obmat, NULL); + } + + if (DST.ob_handle == 0) { + DST.ob_handle = drw_resource_handle_new(obmat, ob); + DST.ob_state_obinfo_init = false; } - else { - if (DST.ob_handle == 0) { - DST.ob_handle = drw_resource_handle_new(obmat, ob); - DST.ob_state_obinfo_init = false; - } - if (shgroup->objectinfo) { - if (!DST.ob_state_obinfo_init) { - DST.ob_state_obinfo_init = true; - DRWObjectInfos *ob_infos = DRW_memblock_elem_from_handle(DST.vmempool->obinfos, - &DST.ob_handle); + if (shgroup->objectinfo) { + if (!DST.ob_state_obinfo_init) { + DST.ob_state_obinfo_init = true; + DRWObjectInfos *ob_infos = DRW_memblock_elem_from_handle(DST.vmempool->obinfos, + &DST.ob_handle); - drw_call_obinfos_init(ob_infos, ob); - } + drw_call_obinfos_init(ob_infos, ob); } - - return DST.ob_handle; } + + return DST.ob_handle; } static void command_type_set(uint64_t *command_type_bits, int index, eDRWCommandType type) @@ -1292,13 +1290,10 @@ static DRWShadingGroup *drw_shgroup_material_create_ex(GPUPass *gpupass, DRWPass } static void drw_shgroup_material_texture(DRWShadingGroup *grp, - GPUMaterialTexture *tex, + GPUTexture *gputex, const char *name, - eGPUSamplerState state, - int textarget) + eGPUSamplerState state) { - GPUTexture *gputex = GPU_texture_from_blender(tex->ima, tex->iuser, NULL, textarget); - DRW_shgroup_uniform_texture_ex(grp, name, gputex, state); GPUTexture **gputex_ref = BLI_memblock_alloc(DST.vmempool->images); @@ -1314,15 +1309,16 @@ void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, struct GPUMaterial LISTBASE_FOREACH (GPUMaterialTexture *, tex, &textures) { if (tex->ima) { /* Image */ + GPUTexture *gputex; if (tex->tiled_mapping_name[0]) { - drw_shgroup_material_texture( - grp, tex, tex->sampler_name, tex->sampler_state, GL_TEXTURE_2D_ARRAY); - drw_shgroup_material_texture( - grp, tex, tex->tiled_mapping_name, tex->sampler_state, GL_TEXTURE_1D_ARRAY); + gputex = BKE_image_get_gpu_tiles(tex->ima, tex->iuser, NULL); + drw_shgroup_material_texture(grp, gputex, tex->sampler_name, tex->sampler_state); + gputex = BKE_image_get_gpu_tilemap(tex->ima, tex->iuser, NULL); + drw_shgroup_material_texture(grp, gputex, tex->tiled_mapping_name, tex->sampler_state); } else { - drw_shgroup_material_texture( - grp, tex, tex->sampler_name, tex->sampler_state, GL_TEXTURE_2D); + gputex = BKE_image_get_gpu_texture(tex->ima, tex->iuser, NULL); + drw_shgroup_material_texture(grp, gputex, tex->sampler_name, tex->sampler_state); } } else if (tex->colorband) { @@ -1906,9 +1902,8 @@ float DRW_view_near_distance_get(const DRWView *view) if (DRW_view_is_persp_get(view)) { return -projmat[3][2] / (projmat[2][2] - 1.0f); } - else { - return -(projmat[3][2] + 1.0f) / projmat[2][2]; - } + + return -(projmat[3][2] + 1.0f) / projmat[2][2]; } float DRW_view_far_distance_get(const DRWView *view) @@ -1919,9 +1914,8 @@ float DRW_view_far_distance_get(const DRWView *view) if (DRW_view_is_persp_get(view)) { return -projmat[3][2] / (projmat[2][2] + 1.0f); } - else { - return -(projmat[3][2] - 1.0f) / projmat[2][2]; - } + + return -(projmat[3][2] - 1.0f) / projmat[2][2]; } void DRW_view_viewmat_get(const DRWView *view, float mat[4][4], bool inverse) @@ -2028,18 +2022,16 @@ static int pass_shgroup_dist_sort(const void *a, const void *b) if (shgrp_a->z_sorting.distance < shgrp_b->z_sorting.distance) { return 1; } - else if (shgrp_a->z_sorting.distance > shgrp_b->z_sorting.distance) { + if (shgrp_a->z_sorting.distance > shgrp_b->z_sorting.distance) { return -1; } - else { - /* If distances are the same, keep original order. */ - if (shgrp_a->z_sorting.original_index > shgrp_b->z_sorting.original_index) { - return -1; - } - else { - return 0; - } + + /* If distances are the same, keep original order. */ + if (shgrp_a->z_sorting.original_index > shgrp_b->z_sorting.original_index) { + return -1; } + + return 0; } /* ------------------ Shading group sorting --------------------- */ diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index b6f51ada5a1..4b63ea89e44 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -446,6 +446,7 @@ void DRW_state_reset(void) DRW_state_reset_ex(DRW_STATE_DEFAULT); GPU_texture_unbind_all(); + GPU_uniformbuffer_unbind_all(); /* Should stay constant during the whole rendering. */ GPU_point_size(5); @@ -517,7 +518,7 @@ static bool draw_culling_box_test(const float (*frustum_planes)[4], const BoundB * Go to next plane. */ break; } - else if (v == 7) { + if (v == 7) { /* 8 points behind this plane. */ return false; } @@ -669,8 +670,7 @@ BLI_INLINE void draw_geometry_bind(DRWShadingGroup *shgroup, GPUBatch *geom) DST.batch = geom; - GPU_batch_program_set_no_use( - geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader)); + GPU_batch_set_shader_no_bind(geom, shgroup->shader); geom->program_in_use = true; /* XXX hacking #GPUBatch */ @@ -773,10 +773,11 @@ static bool ubo_bindings_validate(DRWShadingGroup *shgroup) DRWPass *parent_pass = DRW_memblock_elem_from_handle(DST.vmempool->passes, &shgroup->pass_handle); - printf("Pass : %s, Shader : %s, Block : %s\n", + printf("Pass : %s, Shader : %s, Block : %s, Binding %d\n", parent_pass->name, shgroup->shader->name, - blockname); + blockname, + binding); } } # endif @@ -994,9 +995,8 @@ static void draw_call_single_do(DRWShadingGroup *shgroup, draw_select_buffer(shgroup, state, batch, &handle); return; } - else { - GPU_select_load_id(state->select_id); - } + + GPU_select_load_id(state->select_id); } draw_geometry_execute(shgroup, @@ -1106,6 +1106,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) /* Unbinding can be costly. Skip in normal condition. */ if (G.debug & G_DEBUG_GPU) { GPU_texture_unbind_all(); + GPU_uniformbuffer_unbind_all(); } } GPU_shader_bind(shgroup->shader); diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c index 34069438e47..1c260721efb 100644 --- a/source/blender/draw/intern/draw_manager_shader.c +++ b/source/blender/draw/intern/draw_manager_shader.c @@ -447,7 +447,8 @@ GPUMaterial *DRW_shader_create_from_world(struct Scene *scene, const char *geom, const char *frag_lib, const char *defines, - bool deferred) + bool deferred, + GPUMaterialEvalCallbackFn callback) { GPUMaterial *mat = NULL; if (DRW_state_is_image_render() || !deferred) { @@ -467,7 +468,8 @@ GPUMaterial *DRW_shader_create_from_world(struct Scene *scene, geom, frag_lib, defines, - wo->id.name); + wo->id.name, + callback); } if (GPU_material_status(mat) == GPU_MAT_QUEUED) { @@ -487,7 +489,8 @@ GPUMaterial *DRW_shader_create_from_material(struct Scene *scene, const char *geom, const char *frag_lib, const char *defines, - bool deferred) + bool deferred, + GPUMaterialEvalCallbackFn callback) { GPUMaterial *mat = NULL; if (DRW_state_is_image_render() || !deferred) { @@ -507,7 +510,8 @@ GPUMaterial *DRW_shader_create_from_material(struct Scene *scene, geom, frag_lib, defines, - ma->id.name); + ma->id.name, + callback); } if (GPU_material_status(mat) == GPU_MAT_QUEUED) { diff --git a/source/blender/draw/intern/draw_select_buffer.c b/source/blender/draw/intern/draw_select_buffer.c index 84c8d0f861f..ee5561e1e38 100644 --- a/source/blender/draw/intern/draw_select_buffer.c +++ b/source/blender/draw/intern/draw_select_buffer.c @@ -395,7 +395,7 @@ uint DRW_select_buffer_find_nearest_to_point(struct Depsgraph *depsgraph, int center_x = width / 2; int center_y = height / 2; - /* Manhatten distance in keeping with other screen-based selection. */ + /* Manhattan distance in keeping with other screen-based selection. */ *dist = (uint)(abs(hit_x - center_x) + abs(hit_y - center_y)); /* Indices start at 1 here. */ diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c index 3c470f802ec..1458ff5341c 100644 --- a/source/blender/draw/intern/draw_view.c +++ b/source/blender/draw/intern/draw_view.c @@ -88,7 +88,7 @@ static bool is_cursor_visible(const DRWContextState *draw_ctx, Scene *scene, Vie /* no exception met? then don't draw cursor! */ return false; } - else if (draw_ctx->object_mode & OB_MODE_WEIGHT_GPENCIL) { + if (draw_ctx->object_mode & OB_MODE_WEIGHT_GPENCIL) { /* grease pencil hide always in some modes */ return false; } @@ -184,8 +184,7 @@ void DRW_draw_cursor(void) GPUBatch *cursor_batch = DRW_cache_cursor_get(is_aligned); GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_FLAT_COLOR); - GPU_batch_program_set( - cursor_batch, GPU_shader_get_program(shader), GPU_shader_get_interface(shader)); + GPU_batch_set_shader(cursor_batch, shader); GPU_batch_draw(cursor_batch); diff --git a/source/blender/draw/intern/shaders/common_hair_lib.glsl b/source/blender/draw/intern/shaders/common_hair_lib.glsl index ffff631e34b..8684d82f228 100644 --- a/source/blender/draw/intern/shaders/common_hair_lib.glsl +++ b/source/blender/draw/intern/shaders/common_hair_lib.glsl @@ -95,7 +95,7 @@ void hair_get_interp_attrs( * For final drawing, the vertex index and the number of vertex per segment */ -#ifndef HAIR_PHASE_SUBDIV +#if !defined(HAIR_PHASE_SUBDIV) && defined(GPU_VERTEX_SHADER) int hair_get_strand_id(void) { return gl_VertexID / (hairStrandsRes * hairThicknessRes); @@ -206,4 +206,24 @@ vec3 hair_get_strand_pos(void) return texelFetch(hairPointBuffer, id).point_position; } +vec2 hair_get_barycentric(void) +{ + /* To match cycles without breaking into individual segment we encode if we need to invert + * the first component into the second component. We invert if the barycentricTexCo.y + * is NOT 0.0 or 1.0. */ + int id = hair_get_base_id(); + return vec2(float((id % 2) == 1), float(((id % 4) % 3) > 0)); +} + #endif + +/* To be fed the result of hair_get_barycentric from vertex shader. */ +vec2 hair_resolve_barycentric(vec2 vert_barycentric) +{ + if (fract(vert_barycentric.y) != 0.0) { + return vec2(vert_barycentric.x, 0.0); + } + else { + return vec2(1.0 - vert_barycentric.x, 0.0); + } +} diff --git a/source/blender/draw/intern/shaders/common_math_geom_lib.glsl b/source/blender/draw/intern/shaders/common_math_geom_lib.glsl index e337376d7c4..643d7e7d942 100644 --- a/source/blender/draw/intern/shaders/common_math_geom_lib.glsl +++ b/source/blender/draw/intern/shaders/common_math_geom_lib.glsl @@ -116,4 +116,4 @@ vec3 normal_decode(vec2 enc, vec3 view) return n; } -/** \} */
\ No newline at end of file +/** \} */ diff --git a/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl b/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl index 36b67f2bd60..625e8bb1ff8 100644 --- a/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl +++ b/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl @@ -36,4 +36,4 @@ vec3 pointcloud_get_pos(void) vec3 outpos, outnor; pointcloud_get_pos_and_nor(outpos, outnor); return outpos; -}
\ No newline at end of file +} diff --git a/source/blender/draw/intern/shaders/common_view_lib.glsl b/source/blender/draw/intern/shaders/common_view_lib.glsl index 095bc64a19e..a55d2cd8c1a 100644 --- a/source/blender/draw/intern/shaders/common_view_lib.glsl +++ b/source/blender/draw/intern/shaders/common_view_lib.glsl @@ -22,6 +22,16 @@ layout(std140) uniform viewBlock vec4 CameraTexCoFactors; }; +#define ViewNear (ViewVecs[0].w) +#define ViewFar (ViewVecs[1].w) + +#define cameraForward ViewMatrixInverse[2].xyz +#define cameraPos ViewMatrixInverse[3].xyz +#define cameraVec \ + ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward) +#define viewCameraVec \ + ((ProjectionMatrix[3][3] == 0.0) ? normalize(-viewPosition) : vec3(0.0, 0.0, 1.0)) + #ifdef world_clip_planes_calc_clip_distance # undef world_clip_planes_calc_clip_distance # define world_clip_planes_calc_clip_distance(p) \ @@ -104,10 +114,13 @@ uniform int resourceId; /* Use this to declare and pass the value if * the fragment shader uses the resource_id. */ -# define RESOURCE_ID_VARYING flat out int resourceIDFrag; -# define RESOURCE_ID_VARYING_GEOM flat out int resourceIDGeom; -# define PASS_RESOURCE_ID resourceIDFrag = resource_id; -# define PASS_RESOURCE_ID_GEOM resourceIDGeom = resource_id; +# ifdef USE_GEOMETRY_SHADER +# define RESOURCE_ID_VARYING flat out int resourceIDGeom; +# define PASS_RESOURCE_ID resourceIDGeom = resource_id; +# else +# define RESOURCE_ID_VARYING flat out int resourceIDFrag; +# define PASS_RESOURCE_ID resourceIDFrag = resource_id; +# endif #endif /* If used in a fragment / geometry shader, we pass @@ -118,7 +131,7 @@ uniform int resourceId; flat in int resourceIDGeom[]; # define resource_id resourceIDGeom -# define PASS_RESOURCE_ID(i) resourceIDFrag = resource_id[i]; +# define PASS_RESOURCE_ID resourceIDFrag = resource_id[0]; #endif #ifdef GPU_FRAGMENT_SHADER @@ -171,9 +184,12 @@ uniform mat4 ModelMatrixInverse; * Note: This is only valid because we are only using the mat3 of the ViewMatrixInverse. * ViewMatrix * transpose(ModelMatrixInverse) **/ -#define normal_object_to_view(n) (mat3(ViewMatrix) * (transpose(mat3(ModelMatrixInverse)) * n)) -#define normal_object_to_world(n) (transpose(mat3(ModelMatrixInverse)) * n) -#define normal_world_to_object(n) (transpose(mat3(ModelMatrix)) * n) +#define NormalMatrix transpose(mat3(ModelMatrixInverse)) +#define NormalMatrixInverse transpose(mat3(ModelMatrix)) + +#define normal_object_to_view(n) (mat3(ViewMatrix) * (NormalMatrix * n)) +#define normal_object_to_world(n) (NormalMatrix * n) +#define normal_world_to_object(n) (NormalMatrixInverse * n) #define normal_world_to_view(n) (mat3(ViewMatrix) * n) #define normal_view_to_world(n) (mat3(ViewMatrixInverse) * n) @@ -199,3 +215,78 @@ uniform mat4 ModelMatrixInverse; #define DRW_BASE_FROM_DUPLI (1 << 2) #define DRW_BASE_FROM_SET (1 << 3) #define DRW_BASE_ACTIVE (1 << 4) + +/* ---- Opengl Depth conversion ---- */ + +float linear_depth(bool is_persp, float z, float zf, float zn) +{ + if (is_persp) { + return (zn * zf) / (z * (zn - zf) + zf); + } + else { + return (z * 2.0 - 1.0) * zf; + } +} + +float buffer_depth(bool is_persp, float z, float zf, float zn) +{ + if (is_persp) { + return (zf * (zn - z)) / (z * (zn - zf)); + } + else { + return (z / (zf * 2.0)) + 0.5; + } +} + +float get_view_z_from_depth(float depth) +{ + if (ProjectionMatrix[3][3] == 0.0) { + float d = 2.0 * depth - 1.0; + return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]); + } + else { + return ViewVecs[0].z + depth * ViewVecs[1].z; + } +} + +float get_depth_from_view_z(float z) +{ + if (ProjectionMatrix[3][3] == 0.0) { + float d = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2]; + return d * 0.5 + 0.5; + } + else { + return (z - ViewVecs[0].z) / ViewVecs[1].z; + } +} + +vec2 get_uvs_from_view(vec3 view) +{ + vec4 ndc = ProjectionMatrix * vec4(view, 1.0); + return (ndc.xy / ndc.w) * 0.5 + 0.5; +} + +vec3 get_view_space_from_depth(vec2 uvcoords, float depth) +{ + if (ProjectionMatrix[3][3] == 0.0) { + 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; + } +} + +vec3 get_world_space_from_depth(vec2 uvcoords, float depth) +{ + return (ViewMatrixInverse * vec4(get_view_space_from_depth(uvcoords, depth), 1.0)).xyz; +} + +vec3 get_view_vector_from_screen_uv(vec2 uv) +{ + if (ProjectionMatrix[3][3] == 0.0) { + return normalize(vec3(ViewVecs[0].xy + uv * ViewVecs[1].xy, 1.0)); + } + else { + return vec3(0.0, 0.0, 1.0); + } +} diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 50733afe6fb..8280b58c21a 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -427,7 +427,7 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac) ac->spacetype = (area) ? area->spacetype : 0; ac->regiontype = (region) ? region->regiontype : 0; - /* initialise default y-scale factor */ + /* Initialize default y-scale factor. */ animedit_get_yscale_factor(ac); /* get data context info */ diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c index 8df9c99896e..e60270bc3f0 100644 --- a/source/blender/editors/armature/pose_slide.c +++ b/source/blender/editors/armature/pose_slide.c @@ -251,7 +251,7 @@ static int pose_slide_init(bContext *C, wmOperator *op, ePoseSlide_Modes mode) */ BLI_dlrbTree_init(&pso->keys); - /* initialise numeric input */ + /* Initialize numeric input. */ initNumInput(&pso->num); pso->num.idx_max = 0; /* one axis */ pso->num.val_flag[0] |= NUM_NO_NEGATIVE; @@ -1310,7 +1310,7 @@ static int pose_slide_push_invoke(bContext *C, wmOperator *op, const wmEvent *ev pso = op->customdata; - /* initialise percentage so that it won't pop on first mouse move */ + /* Initialize percentage so that it won't pop on first mouse move. */ pose_slide_mouse_update_percentage(pso, op, event); /* do common setup work */ @@ -1370,7 +1370,7 @@ static int pose_slide_relax_invoke(bContext *C, wmOperator *op, const wmEvent *e pso = op->customdata; - /* initialise percentage so that it won't pop on first mouse move */ + /* Initialize percentage so that it won't pop on first mouse move. */ pose_slide_mouse_update_percentage(pso, op, event); /* do common setup work */ @@ -1429,7 +1429,7 @@ static int pose_slide_push_rest_invoke(bContext *C, wmOperator *op, const wmEven pso = op->customdata; - /* initialise percentage so that it won't pop on first mouse move */ + /* Initialize percentage so that it won't pop on first mouse move. */ pose_slide_mouse_update_percentage(pso, op, event); /* do common setup work */ @@ -1489,7 +1489,7 @@ static int pose_slide_relax_rest_invoke(bContext *C, wmOperator *op, const wmEve pso = op->customdata; - /* initialise percentage so that it won't pop on first mouse move */ + /* Initialize percentage so that it won't pop on first mouse move. */ pose_slide_mouse_update_percentage(pso, op, event); /* do common setup work */ @@ -1549,7 +1549,7 @@ static int pose_slide_breakdown_invoke(bContext *C, wmOperator *op, const wmEven pso = op->customdata; - /* initialise percentage so that it won't pop on first mouse move */ + /* Initialize percentage so that it won't pop on first mouse move. */ pose_slide_mouse_update_percentage(pso, op, event); /* do common setup work */ diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 91a8ea0fa3a..69a05c9ae31 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -1137,7 +1137,7 @@ int ED_curve_updateAnimPaths(Main *bmain, Curve *cu) /** \name Edit Mode Conversion (Make & Load) * \{ */ -static int *initialize_index_map(Object *obedit, int *r_old_totvert) +static int *init_index_map(Object *obedit, int *r_old_totvert) { Curve *curve = (Curve *)obedit->data; EditNurb *editnurb = curve->editnurb; @@ -1225,7 +1225,7 @@ static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit) if ((object->parent) && (object->parent->data == curve) && ELEM(object->partype, PARVERT1, PARVERT3)) { if (old_to_new_map == NULL) { - old_to_new_map = initialize_index_map(obedit, &old_totvert); + old_to_new_map = init_index_map(obedit, &old_totvert); } if (object->par1 < old_totvert) { @@ -1254,7 +1254,7 @@ static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit) int i, j; if (old_to_new_map == NULL) { - old_to_new_map = initialize_index_map(obedit, &old_totvert); + old_to_new_map = init_index_map(obedit, &old_totvert); } for (i = j = 0; i < hmd->totindex; i++) { @@ -1716,7 +1716,10 @@ static bool isNurbselV(Nurb *nu, int *u, int flag) return 1; } -static void rotateflagNurb(ListBase *editnurb, short flag, const float cent[3], float rotmat[3][3]) +static void rotateflagNurb(ListBase *editnurb, + short flag, + const float cent[3], + const float rotmat[3][3]) { /* all verts with (flag & 'flag') rotate */ Nurb *nu; diff --git a/source/blender/editors/curve/editcurve_add.c b/source/blender/editors/curve/editcurve_add.c index bacdd5b69b5..75d90df3291 100644 --- a/source/blender/editors/curve/editcurve_add.c +++ b/source/blender/editors/curve/editcurve_add.c @@ -397,8 +397,8 @@ Nurb *ED_curve_add_nurbs_primitive( break; case CU_PRIM_SPHERE: /* sphere */ if (cutype == CU_NURBS) { - float tmp_cent[3] = {0.f, 0.f, 0.f}; - float tmp_vec[3] = {0.f, 0.f, 1.f}; + const float tmp_cent[3] = {0.f, 0.f, 0.f}; + const float tmp_vec[3] = {0.f, 0.f, 1.f}; nu->pntsu = 5; nu->pntsv = 1; @@ -451,8 +451,8 @@ Nurb *ED_curve_add_nurbs_primitive( break; case CU_PRIM_DONUT: /* torus */ if (cutype == CU_NURBS) { - float tmp_cent[3] = {0.f, 0.f, 0.f}; - float tmp_vec[3] = {0.f, 0.f, 1.f}; + const float tmp_cent[3] = {0.f, 0.f, 0.f}; + const float tmp_vec[3] = {0.f, 0.f, 1.f}; xzproj = 1; nu = ED_curve_add_nurbs_primitive(C, obedit, mat, CU_NURBS | CU_PRIM_CIRCLE, 0); diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index b759277572c..4529209b297 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -76,9 +76,9 @@ static int kill_selection(Object *obedit, int ins); /** \name Internal Utilities * \{ */ -static wchar_t findaccent(wchar_t char1, uint code) +static char32_t findaccent(char32_t char1, uint code) { - wchar_t new = 0; + char32_t new = 0; if (char1 == 'a') { if (code == '`') { @@ -648,7 +648,7 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, const int nchars = 0, nbytes = 0; char *s; int a; - float rot[3] = {0.f, 0.f, 0.f}; + const float rot[3] = {0.f, 0.f, 0.f}; obedit = BKE_object_add(bmain, scene, view_layer, OB_FONT, NULL); base = view_layer->basact; @@ -682,7 +682,7 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, const cu->strinfo = MEM_callocN((nchars + 4) * sizeof(CharInfo), "strinfo"); cu->len = 0; - cu->len_wchar = nchars - 1; + cu->len_char32 = nchars - 1; cu->pos = 0; s = cu->str; @@ -703,7 +703,7 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, const } } - cu->pos = cu->len_wchar; + cu->pos = cu->len_char32; *s = '\0'; WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, obedit); @@ -1661,7 +1661,7 @@ static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event) uintptr_t ascii = event->ascii; int alt = event->alt, shift = event->shift, ctrl = event->ctrl; int event_type = event->type, event_val = event->val; - wchar_t inserted_text[2] = {0}; + char32_t inserted_text[2] = {0}; if (RNA_struct_property_is_set(op->ptr, "text")) { return insert_text_exec(C, op); @@ -1733,7 +1733,7 @@ static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event) /* store as utf8 in RNA string */ char inserted_utf8[8] = {0}; - BLI_strncpy_wchar_as_utf8(inserted_utf8, inserted_text, sizeof(inserted_utf8)); + BLI_str_utf32_as_utf8(inserted_utf8, inserted_text, sizeof(inserted_utf8)); RNA_string_set(op->ptr, "text", inserted_utf8); } @@ -1867,7 +1867,7 @@ void ED_curve_editfont_make(Object *obedit) { Curve *cu = obedit->data; EditFont *ef = cu->editfont; - int len_wchar; + int len_char32; if (ef == NULL) { ef = cu->editfont = MEM_callocN(sizeof(EditFont), "editfont"); @@ -1876,10 +1876,10 @@ void ED_curve_editfont_make(Object *obedit) ef->textbufinfo = MEM_callocN((MAXTEXT + 4) * sizeof(CharInfo), "texteditbufinfo"); } - /* Convert the original text to wchar_t */ - len_wchar = BLI_str_utf8_as_utf32(ef->textbuf, cu->str, MAXTEXT + 4); - BLI_assert(len_wchar == cu->len_wchar); - ef->len = len_wchar; + /* Convert the original text to chat32_t. */ + len_char32 = BLI_str_utf8_as_utf32(ef->textbuf, cu->str, MAXTEXT + 4); + BLI_assert(len_char32 == cu->len_char32); + ef->len = len_char32; BLI_assert(ef->len >= 0); memcpy(ef->textbufinfo, cu->strinfo, ef->len * sizeof(CharInfo)); @@ -1908,7 +1908,7 @@ void ED_curve_editfont_load(Object *obedit) MEM_freeN(cu->str); /* Calculate the actual string length in UTF-8 variable characters */ - cu->len_wchar = ef->len; + cu->len_char32 = ef->len; cu->len = BLI_str_utf32_as_utf8_len(ef->textbuf); /* Alloc memory for UTF-8 variable char length string */ @@ -1920,8 +1920,8 @@ void ED_curve_editfont_load(Object *obedit) if (cu->strinfo) { MEM_freeN(cu->strinfo); } - cu->strinfo = MEM_callocN((cu->len_wchar + 4) * sizeof(CharInfo), "texteditinfo"); - memcpy(cu->strinfo, ef->textbufinfo, cu->len_wchar * sizeof(CharInfo)); + cu->strinfo = MEM_callocN((cu->len_char32 + 4) * sizeof(CharInfo), "texteditinfo"); + memcpy(cu->strinfo, ef->textbufinfo, cu->len_char32 * sizeof(CharInfo)); /* Other vars */ cu->pos = ef->pos; diff --git a/source/blender/editors/gizmo_library/gizmo_draw_utils.c b/source/blender/editors/gizmo_library/gizmo_draw_utils.c index 71a364c60d7..033673a99a8 100644 --- a/source/blender/editors/gizmo_library/gizmo_draw_utils.c +++ b/source/blender/editors/gizmo_library/gizmo_draw_utils.c @@ -29,7 +29,6 @@ #include "ED_view3d.h" #include "GPU_batch.h" -#include "GPU_glew.h" #include "GPU_immediate.h" #include "MEM_guardedalloc.h" diff --git a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c index f31e004264c..341f43d0662 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c @@ -239,7 +239,7 @@ static int gizmo_arrow_test_select(bContext *UNUSED(C), wmGizmo *gz, const int m WM_gizmo_calc_matrix_final(gz, matrix_final); /* Arrow in pixel space. */ - float arrow_start[2] = {matrix_final[3][0], matrix_final[3][1]}; + const float arrow_start[2] = {matrix_final[3][0], matrix_final[3][1]}; float arrow_end[2]; { float co[3] = {0, 0, arrow_length}; diff --git a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c index 04b93f35681..c5231b3cd96 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c @@ -99,7 +99,7 @@ static void button2d_geom_draw_backdrop(const wmGizmo *gz, else { /* Draw fill. */ if ((fill_alpha != 0.0f) || (select == true)) { - float fill_color[4] = {UNPACK3(color), fill_alpha * color[3]}; + const float fill_color[4] = {UNPACK3(color), fill_alpha * color[3]}; immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformColor4fv(fill_color); imm_draw_circle_fill_2d(pos, 0, 0, 1.0f, CIRCLE_RESOLUTION); diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c index 85f84af5f14..406d66dfd8f 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c @@ -999,7 +999,7 @@ static int gizmo_cage2d_modal(bContext *C, if (data->dial == NULL) { MUL_V2_V3_M4_FINAL(test_co, data->orig_matrix_offset[3]); - data->dial = BLI_dial_initialize(test_co, FLT_EPSILON); + data->dial = BLI_dial_init(test_co, FLT_EPSILON); MUL_V2_V3_M4_FINAL(test_co, data->orig_mouse); BLI_dial_angle(data->dial, test_co); diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c index 8955a666e22..0bc65fe10a5 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c @@ -257,7 +257,7 @@ static void cage3d_draw_circle_handles(const RegionView3D *rv3d, immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformColor3fv(color); - float sign[3] = {-1.0f, 0.0f, 1.0f}; + const float sign[3] = {-1.0f, 0.0f, 1.0f}; for (int x = 0; x < 3; x++) { for (int y = 0; y < 3; y++) { for (int z = 0; z < 3; z++) { diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c index 6f700f6c4b8..30e4fe0b531 100644 --- a/source/blender/editors/gpencil/annotate_paint.c +++ b/source/blender/editors/gpencil/annotate_paint.c @@ -200,7 +200,7 @@ typedef struct tGPsdata { /* Macros for accessing sensitivity thresholds... */ /* minimum number of pixels mouse should move before new point created */ -#define MIN_MANHATTEN_PX (U.gp_manhattendist) +#define MIN_MANHATTAN_PX (U.gp_manhattandist) /* minimum length of new segment before new point can be added */ #define MIN_EUCLIDEAN_PX (U.gp_euclideandist) @@ -271,7 +271,7 @@ static void annotation_get_3d_reference(tGPsdata *p, float vec[3]) /* Stroke Editing ---------------------------- */ /* check if the current mouse position is suitable for adding a new point */ -static bool annotation_stroke_filtermval(tGPsdata *p, const float mval[2], float pmval[2]) +static bool annotation_stroke_filtermval(tGPsdata *p, const float mval[2], const float pmval[2]) { int dx = (int)fabsf(mval[0] - pmval[0]); int dy = (int)fabsf(mval[1] - pmval[1]); @@ -297,7 +297,7 @@ static bool annotation_stroke_filtermval(tGPsdata *p, const float mval[2], float return false; } - if ((dx > MIN_MANHATTEN_PX) && (dy > MIN_MANHATTEN_PX)) { + if ((dx > MIN_MANHATTAN_PX) && (dy > MIN_MANHATTAN_PX)) { return true; } @@ -573,14 +573,14 @@ static short annotation_stroke_addpoint(tGPsdata *p, /* Arrow end corner. */ if (gpd->runtime.sbuffer_sflag & GP_STROKE_USE_ARROW_END) { pt++; - float e_heading[2] = {start[0] - end[0], start[1] - end[1]}; + const float e_heading[2] = {start[0] - end[0], start[1] - end[1]}; /* Calculate points for ending arrow. */ annotation_stroke_arrow_calc_points( pt, e_heading, end, gpd->runtime.arrow_end, gpd->runtime.arrow_end_style); } /* Arrow start corner. */ if (gpd->runtime.sbuffer_sflag & GP_STROKE_USE_ARROW_START) { - float s_heading[2] = {end[0] - start[0], end[1] - start[1]}; + const float s_heading[2] = {end[0] - start[0], end[1] - start[1]}; /* Calculate points for starting arrow. */ annotation_stroke_arrow_calc_points( NULL, s_heading, start, gpd->runtime.arrow_start, gpd->runtime.arrow_start_style); @@ -603,7 +603,7 @@ static short annotation_stroke_addpoint(tGPsdata *p, /* store settings */ copy_v2_v2(&pt->x, mval); pt->pressure = pressure; - /* unused for annotations, but initialise for easier conversions to GP Object */ + /* Unused for annotations, but initialize for easier conversions to GP Object. */ pt->strength = 1.0f; /* point time */ @@ -704,7 +704,7 @@ static void annotation_stroke_arrow_init_point( tGPsdata *p, tGPspoint *ptc, bGPDspoint *pt, const float co[8], const int co_idx) { /* Note: provided co_idx should be always pair number as it's [x1, y1, x2, y2, x3, y3]. */ - float real_co[2] = {co[co_idx], co[co_idx + 1]}; + const float real_co[2] = {co[co_idx], co[co_idx + 1]}; copy_v2_v2(&ptc->x, real_co); annotation_stroke_convertcoords(p, &ptc->x, &pt->x, NULL); annotation_stroke_arrow_init_point_default(pt); diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index 96b0296a7de..348fb614977 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -861,6 +861,154 @@ void GPENCIL_OT_frame_clean_loose(wmOperatorType *ot) INT_MAX); } +/* ********************* Clean Duplicated Frames ************************** */ +static bool gpencil_frame_is_equal(bGPDframe *gpf_a, bGPDframe *gpf_b) +{ + if ((gpf_a == NULL) || (gpf_b == NULL)) { + return false; + } + /* If the number of strokes is different, cannot be equal. */ + int totstrokes_a = BLI_listbase_count(&gpf_a->strokes); + int totstrokes_b = BLI_listbase_count(&gpf_b->strokes); + if ((totstrokes_a == 0) || (totstrokes_b == 0) || (totstrokes_a != totstrokes_b)) { + return false; + } + /* Loop all strokes and check. */ + bGPDstroke *gps_a = gpf_a->strokes.first; + bGPDstroke *gps_b = gpf_b->strokes.first; + for (int i = 0; i < totstrokes_a; i++) { + /* If the number of points is different, cannot be equal. */ + if (gps_a->totpoints != gps_b->totpoints) { + return false; + } + /* Check other variables. */ + if (!equals_v4v4(gps_a->vert_color_fill, gps_b->vert_color_fill)) { + return false; + } + if (gps_a->thickness != gps_b->thickness) { + return false; + } + if (gps_a->mat_nr != gps_b->mat_nr) { + return false; + } + if (gps_a->caps[0] != gps_b->caps[0]) { + return false; + } + if (gps_a->caps[1] != gps_b->caps[1]) { + return false; + } + if (gps_a->hardeness != gps_b->hardeness) { + return false; + } + if (!equals_v2v2(gps_a->aspect_ratio, gps_b->aspect_ratio)) { + return false; + } + if (gps_a->uv_rotation != gps_b->uv_rotation) { + return false; + } + if (!equals_v2v2(gps_a->uv_translation, gps_b->uv_translation)) { + return false; + } + if (gps_a->uv_scale != gps_b->uv_scale) { + return false; + } + + /* Loop points and check if equals or not. */ + for (int p = 0; p < gps_a->totpoints; p++) { + bGPDspoint *pt_a = &gps_a->points[p]; + bGPDspoint *pt_b = &gps_b->points[p]; + if (!equals_v3v3(&pt_a->x, &pt_b->x)) { + return false; + } + if (pt_a->pressure != pt_b->pressure) { + return false; + } + if (pt_a->strength != pt_b->strength) { + return false; + } + if (pt_a->uv_fac != pt_b->uv_fac) { + return false; + } + if (pt_a->uv_rot != pt_b->uv_rot) { + return false; + } + if (!equals_v4v4(pt_a->vert_color, pt_b->vert_color)) { + return false; + } + } + + /* Look at next pair of strokes. */ + gps_a = gps_a->next; + gps_b = gps_b->next; + } + + return true; +} + +static int gpencil_frame_clean_duplicate_exec(bContext *C, wmOperator *op) +{ +#define SELECTED 1 + + bool changed = false; + Object *ob = CTX_data_active_object(C); + bGPdata *gpd = (bGPdata *)ob->data; + const int type = RNA_enum_get(op->ptr, "type"); + + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { + /* Only editable and visible layers are considered. */ + if (BKE_gpencil_layer_is_editable(gpl) && (gpl->frames.first != NULL)) { + bGPDframe *gpf = gpl->frames.first; + + if ((type == SELECTED) && ((gpf->flag & GP_FRAME_SELECT) == 0)) { + continue; + } + + while (gpf != NULL) { + if (gpencil_frame_is_equal(gpf, gpf->next)) { + /* Remove frame. */ + BKE_gpencil_layer_frame_delete(gpl, gpf->next); + /* Tag for recalc. */ + changed = true; + } + else { + gpf = gpf->next; + } + } + } + } + + /* notifiers */ + if (changed) { + DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + } + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_frame_clean_duplicate(wmOperatorType *ot) +{ + static const EnumPropertyItem clean_type[] = { + {0, "ALL", 0, "All Frames", ""}, + {1, "SELECTED", 0, "Selected Frames", ""}, + {0, NULL, 0, NULL, NULL}, + }; + + /* identifiers */ + ot->name = "Clean Duplicated Frames"; + ot->idname = "GPENCIL_OT_frame_clean_duplicate"; + ot->description = "Remove any duplicated frame"; + + /* callbacks */ + ot->exec = gpencil_frame_clean_duplicate_exec; + ot->poll = gpencil_active_layer_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + ot->prop = RNA_def_enum(ot->srna, "type", clean_type, 0, "Type", ""); +} + /* *********************** Hide Layers ******************************** */ static int gpencil_hide_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 286efeeff01..99e98df3397 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -94,6 +94,8 @@ /** \name Stroke Edit Mode Management * \{ */ +static void gpencil_flip_stroke(bGPDstroke *gps); + /* poll callback for all stroke editing operators */ static bool gpencil_stroke_edit_poll(bContext *C) { @@ -1126,6 +1128,11 @@ static void gpencil_add_move_points(bGPDframe *gpf, bGPDstroke *gps) pt->flag |= GP_SPOINT_SELECT; } + /* Flip stroke if it was only one point to consider extrude point as last point. */ + if (gps->totpoints == 2) { + gpencil_flip_stroke(gps); + } + /* Calc geometry data. */ BKE_gpencil_stroke_geometry_update(gps); @@ -1764,7 +1771,7 @@ static int gpencil_blank_frame_add_exec(bContext *C, wmOperator *op) const bool all_layers = RNA_boolean_get(op->ptr, "all_layers"); - /* Initialise datablock and an active layer if nothing exists yet */ + /* Initialize data-block and an active layer if nothing exists yet. */ if (ELEM(NULL, gpd, active_gpl)) { /* Let's just be lazy, and call the "Add New Layer" operator, * which sets everything up as required. */ @@ -3369,7 +3376,7 @@ static void gpencil_stroke_join_strokes(bGPDstroke *gps_a, bGPDspoint point; bGPDspoint *pt; int i; - float delta[3] = {1.0f, 1.0f, 1.0f}; + const float delta[3] = {1.0f, 1.0f, 1.0f}; float deltatime = 0.0f; /* sanity checks */ @@ -4283,14 +4290,14 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op) base_new = ED_object_add_duplicate(bmain, scene, view_layer, base_prev, dupflag); ob_dst = base_new->object; ob_dst->mode = OB_MODE_OBJECT; - /* Duplication will increment bGPdata usercount, but since we create a new greasepencil datablock - * for ob_dst (which gets its own user automatically), we have to decrement the usercount again. - */ + /* Duplication will increment #bGPdata user-count, but since we create a new grease-pencil + * data-block for ob_dst (which gets its own user automatically), + * we have to decrement the user-count again. */ gpd_dst = BKE_gpencil_data_addnew(bmain, gpd_src->id.name + 2); id_us_min(ob_dst->data); ob_dst->data = (bGPdata *)gpd_dst; - /* loop old datablock and separate parts */ + /* Loop old data-block and separate parts. */ if ((mode == GP_SEPARATE_POINT) || (mode == GP_SEPARATE_STROKE)) { CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { gpl_dst = NULL; diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index 517225e5a81..a70bbfc9d48 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -104,6 +104,8 @@ typedef struct tGPDfill { struct bGPdata *gpd; /** current material */ struct Material *mat; + /** current brush */ + struct Brush *brush; /** layer */ struct bGPDlayer *gpl; /** frame */ @@ -233,6 +235,8 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4]) Object *ob = tgpf->ob; bGPdata *gpd = tgpf->gpd; + Brush *brush = tgpf->brush; + BrushGpencilSettings *brush_settings = brush->gpencil_settings; tGPDdraw tgpw; tgpw.rv3d = tgpf->rv3d; @@ -249,6 +253,12 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4]) GPU_blend(true); + bGPDlayer *gpl_active = BKE_gpencil_layer_active_get(gpd); + BLI_assert(gpl_active != NULL); + + const int gpl_active_index = BLI_findindex(&gpd->layers, gpl_active); + BLI_assert(gpl_active_index >= 0); + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { /* calculate parent position */ BKE_gpencil_parent_matrix_get(tgpw.depsgraph, ob, gpl, tgpw.diff_mat); @@ -258,6 +268,44 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4]) continue; } + /* Decide if layer is included or not depending of the layer mode. */ + const int gpl_index = BLI_findindex(&gpd->layers, gpl); + switch (brush_settings->fill_layer_mode) { + case GP_FILL_GPLMODE_ACTIVE: { + if (gpl_index != gpl_active_index) { + continue; + } + break; + } + case GP_FILL_GPLMODE_ABOVE: { + if (gpl_index != gpl_active_index + 1) { + continue; + } + break; + } + case GP_FILL_GPLMODE_BELOW: { + if (gpl_index != gpl_active_index - 1) { + continue; + } + break; + } + case GP_FILL_GPLMODE_ALL_ABOVE: { + if (gpl_index <= gpl_active_index) { + continue; + } + break; + } + case GP_FILL_GPLMODE_ALL_BELOW: { + if (gpl_index >= gpl_active_index) { + continue; + } + break; + } + case GP_FILL_GPLMODE_VISIBLE: + default: + break; + } + /* if active layer and no keyframe, create a new one */ if (gpl == tgpf->gpl) { if ((gpl->actframe == NULL) || (gpl->actframe->framenum != tgpf->active_cfra)) { @@ -408,7 +456,7 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf) GPU_matrix_set(tgpf->rv3d->viewmat); /* draw strokes */ - float ink[4] = {1.0f, 0.0f, 0.0f, 1.0f}; + const float ink[4] = {1.0f, 0.0f, 0.0f, 1.0f}; gpencil_draw_datablock(tgpf, ink); GPU_matrix_pop_projection(); @@ -416,10 +464,10 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf) /* create a image to see result of template */ if (ibuf->rect_float) { - GPU_offscreen_read_pixels(offscreen, GL_FLOAT, ibuf->rect_float); + GPU_offscreen_read_pixels(offscreen, GPU_DATA_FLOAT, ibuf->rect_float); } else if (ibuf->rect) { - GPU_offscreen_read_pixels(offscreen, GL_UNSIGNED_BYTE, ibuf->rect); + GPU_offscreen_read_pixels(offscreen, GPU_DATA_UNSIGNED_BYTE, ibuf->rect); } if (ibuf->rect_float && ibuf->rect) { IMB_rect_from_float(ibuf); @@ -1247,6 +1295,7 @@ static tGPDfill *gpencil_session_init_fill(bContext *C, wmOperator *UNUSED(op)) /* save filling parameters */ Brush *brush = BKE_paint_brush(&ts->gp_paint->paint); + tgpf->brush = brush; tgpf->flag = brush->gpencil_settings->flag; tgpf->fill_leak = brush->gpencil_settings->fill_leak; tgpf->fill_threshold = brush->gpencil_settings->fill_threshold; diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index 66ac7948596..fa75c2a7cee 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -484,6 +484,7 @@ void GPENCIL_OT_active_frames_delete_all(struct wmOperatorType *ot); void GPENCIL_OT_frame_duplicate(struct wmOperatorType *ot); void GPENCIL_OT_frame_clean_fill(struct wmOperatorType *ot); void GPENCIL_OT_frame_clean_loose(struct wmOperatorType *ot); +void GPENCIL_OT_frame_clean_duplicate(struct wmOperatorType *ot); void GPENCIL_OT_convert(struct wmOperatorType *ot); void GPENCIL_OT_bake_mesh_animation(struct wmOperatorType *ot); diff --git a/source/blender/editors/gpencil/gpencil_mesh.c b/source/blender/editors/gpencil/gpencil_mesh.c index 11f42f7d3ac..a6088e31ff8 100644 --- a/source/blender/editors/gpencil/gpencil_mesh.c +++ b/source/blender/editors/gpencil/gpencil_mesh.c @@ -196,7 +196,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) bool newob = false; if (STREQ(target, "*NEW")) { ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0; - float loc[3] = {0.0f, 0.0f, 0.0f}; + const float loc[3] = {0.0f, 0.0f, 0.0f}; ob_gpencil = ED_gpencil_add_object(C, loc, local_view_bits); newob = true; } diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index efee05f7da3..3892f451e18 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -600,6 +600,7 @@ void ED_operatortypes_gpencil(void) WM_operatortype_append(GPENCIL_OT_frame_duplicate); WM_operatortype_append(GPENCIL_OT_frame_clean_fill); WM_operatortype_append(GPENCIL_OT_frame_clean_loose); + WM_operatortype_append(GPENCIL_OT_frame_clean_duplicate); WM_operatortype_append(GPENCIL_OT_convert); WM_operatortype_append(GPENCIL_OT_bake_mesh_animation); diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 1880045e238..611fe158948 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -268,7 +268,7 @@ typedef struct tGPsdata { /* Macros for accessing sensitivity thresholds... */ /* minimum number of pixels mouse should move before new point created */ -#define MIN_MANHATTEN_PX (U.gp_manhattendist) +#define MIN_MANHATTEN_PX (U.gp_manhattandist) /* minimum length of new segment before new point can be added */ #define MIN_EUCLIDEAN_PX (U.gp_euclideandist) @@ -362,7 +362,7 @@ static void gpencil_get_3d_reference(tGPsdata *p, float vec[3]) /* Stroke Editing ---------------------------- */ /* check if the current mouse position is suitable for adding a new point */ -static bool gpencil_stroke_filtermval(tGPsdata *p, const float mval[2], float mvalo[2]) +static bool gpencil_stroke_filtermval(tGPsdata *p, const float mval[2], const float mvalo[2]) { Brush *brush = p->brush; int dx = (int)fabsf(mval[0] - mvalo[0]); @@ -519,7 +519,7 @@ static void gpencil_brush_angle(bGPdata *gpd, Brush *brush, tGPspoint *pt, const /* default angle of brush in radians */ float angle = brush->gpencil_settings->draw_angle; /* angle vector of the brush with full thickness */ - float v0[2] = {cos(angle), sin(angle)}; + const float v0[2] = {cos(angle), sin(angle)}; /* Apply to first point (only if there are 2 points because before no data to do it ) */ if (gpd->runtime.sbuffer_used == 1) { @@ -1817,15 +1817,15 @@ static void gpencil_init_drawing_brush(bContext *C, tGPsdata *p) changed = true; } /* Be sure curves are initializated. */ - BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_sensitivity); - BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_strength); - BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_jitter); - BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_rand_pressure); - BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_rand_strength); - BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_rand_uv); - BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_rand_hue); - BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_rand_saturation); - BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_rand_value); + BKE_curvemapping_init(paint->brush->gpencil_settings->curve_sensitivity); + BKE_curvemapping_init(paint->brush->gpencil_settings->curve_strength); + BKE_curvemapping_init(paint->brush->gpencil_settings->curve_jitter); + BKE_curvemapping_init(paint->brush->gpencil_settings->curve_rand_pressure); + BKE_curvemapping_init(paint->brush->gpencil_settings->curve_rand_strength); + BKE_curvemapping_init(paint->brush->gpencil_settings->curve_rand_uv); + BKE_curvemapping_init(paint->brush->gpencil_settings->curve_rand_hue); + BKE_curvemapping_init(paint->brush->gpencil_settings->curve_rand_saturation); + BKE_curvemapping_init(paint->brush->gpencil_settings->curve_rand_value); /* assign to temp tGPsdata */ p->brush = paint->brush; @@ -3247,7 +3247,7 @@ static void gpencil_brush_angle_segment(tGPsdata *p, tGPspoint *pt_prev, tGPspoi float fac; /* angle vector of the brush with full thickness */ - float v0[2] = {cos(angle), sin(angle)}; + const float v0[2] = {cos(angle), sin(angle)}; mvec[0] = pt->x - pt_prev->x; mvec[1] = pt->y - pt_prev->y; @@ -3269,7 +3269,7 @@ static void gpencil_brush_angle_segment(tGPsdata *p, tGPspoint *pt_prev, tGPspoi * + PtA - 1 * / * CTL is the vertice of the triangle created between PtA and PtB */ -static void gpencil_add_arc_points(tGPsdata *p, float mval[2], int segments) +static void gpencil_add_arc_points(tGPsdata *p, const float mval[2], int segments) { bGPdata *gpd = p->gpd; BrushGpencilSettings *brush_settings = p->brush->gpencil_settings; diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c index 20f959e2e2c..28ea9535a80 100644 --- a/source/blender/editors/gpencil/gpencil_primitive.c +++ b/source/blender/editors/gpencil/gpencil_primitive.c @@ -378,7 +378,10 @@ static void gpencil_primitive_add_segment(tGPDprimitive *tgpi) } /* Helper: set control point */ -static void gpencil_primitive_set_cp(tGPDprimitive *tgpi, float p[2], float color[4], int size) +static void gpencil_primitive_set_cp(tGPDprimitive *tgpi, + const float p[2], + float color[4], + int size) { if (tgpi->flag == IN_PROGRESS) { return; @@ -696,7 +699,6 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi) bool is_depth = (bool)(*align_flag & (GP_PROJECT_DEPTH_VIEW | GP_PROJECT_DEPTH_STROKE)); const bool is_camera = (bool)(ts->gp_sculpt.lock_axis == 0) && (tgpi->rv3d->persp == RV3D_CAMOB) && (!is_depth); - const bool is_vertex_stroke = GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush); if (tgpi->type == GP_STROKE_BOX) { gps->totpoints = (tgpi->tot_edges * 4 + tgpi->tot_stored_edges); @@ -742,13 +744,13 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi) gpencil_session_validatebuffer(tgpi); gpencil_init_colors(tgpi); if (gset->flag & GP_SCULPT_SETT_FLAG_PRIMITIVE_CURVE) { - BKE_curvemapping_initialize(ts->gp_sculpt.cur_primitive); + BKE_curvemapping_init(ts->gp_sculpt.cur_primitive); } if (brush_settings->flag & GP_BRUSH_USE_JITTER_PRESSURE) { - BKE_curvemapping_initialize(brush_settings->curve_jitter); + BKE_curvemapping_init(brush_settings->curve_jitter); } if (brush_settings->flag & GP_BRUSH_USE_STRENGTH_PRESSURE) { - BKE_curvemapping_initialize(brush_settings->curve_strength); + BKE_curvemapping_init(brush_settings->curve_strength); } /* get an array of depths, far depths are blended */ @@ -1021,12 +1023,7 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi) pt->time = 0.0f; pt->flag = 0; pt->uv_fac = tpt->uv_fac; - if (is_vertex_stroke) { - copy_v4_v4(pt->vert_color, tpt->vert_color); - } - else { - zero_v4(pt->vert_color); - } + ED_gpencil_point_vertex_color_set(ts, brush, pt, tpt); if (gps->dvert != NULL) { MDeformVert *dvert = &gps->dvert[i]; @@ -1092,7 +1089,7 @@ static void gpencil_primitive_update(bContext *C, wmOperator *op, tGPDprimitive gpencil_primitive_update_strokes(C, tgpi); } -/* Initialise mouse points */ +/* Initialize mouse points. */ static void gpencil_primitive_interaction_begin(tGPDprimitive *tgpi, const wmEvent *event) { copy_v2fl_v2i(tgpi->mval, event->mval); diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c index 20eeab65623..43c8b766c52 100644 --- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c +++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c @@ -444,7 +444,9 @@ typedef struct tGPSB_Grab_StrokeData { int size; } tGPSB_Grab_StrokeData; -/* initialise custom data for handling this stroke */ +/** + * Initialize custom data for handling this stroke. + */ static void gpencil_brush_grab_stroke_init(tGP_BrushEditData *gso, bGPDstroke *gps) { tGPSB_Grab_StrokeData *data = NULL; @@ -910,13 +912,13 @@ typedef struct tGPSB_CloneBrushData { GHash *new_colors; } tGPSB_CloneBrushData; -/* Initialise "clone" brush data */ +/* Initialize "clone" brush data. */ static void gpencil_brush_clone_init(bContext *C, tGP_BrushEditData *gso) { tGPSB_CloneBrushData *data; bGPDstroke *gps; - /* init custom data */ + /* Initialize custom-data. */ gso->customdata = data = MEM_callocN(sizeof(tGPSB_CloneBrushData), "CloneBrushData"); /* compute midpoint of strokes on clipboard */ @@ -1188,7 +1190,7 @@ static bool gpencil_sculpt_brush_init(bContext *C, wmOperator *op) Paint *paint = &ts->gp_sculptpaint->paint; gso->brush = paint->brush; - BKE_curvemapping_initialize(gso->brush->curve); + BKE_curvemapping_init(gso->brush->curve); /* save mask */ gso->mask = ts->gpencil_selectmode_sculpt; @@ -1200,10 +1202,10 @@ static bool gpencil_sculpt_brush_init(bContext *C, wmOperator *op) /* Init multi-edit falloff curve data before doing anything, * so we won't have to do it again later. */ if (gso->is_multiframe) { - BKE_curvemapping_initialize(ts->gp_sculpt.cur_falloff); + BKE_curvemapping_init(ts->gp_sculpt.cur_falloff); } - /* initialise custom data for brushes */ + /* Initialize custom data for brushes. */ char tool = gso->brush->gpencil_sculpt_tool; switch (tool) { case GPSCULPT_TOOL_CLONE: { @@ -1229,13 +1231,13 @@ static bool gpencil_sculpt_brush_init(bContext *C, wmOperator *op) op->customdata = NULL; return false; } - /* initialise customdata */ + /* Initialize custom-data. */ gpencil_brush_clone_init(C, gso); break; } case GPSCULPT_TOOL_GRAB: { - /* initialise the cache needed for this brush */ + /* Initialize the cache needed for this brush. */ gso->stroke_customdata = BLI_ghash_ptr_new("GP Grab Brush - Strokes Hash"); break; } @@ -1936,7 +1938,7 @@ static int gpencil_sculpt_brush_invoke(bContext *C, wmOperator *op, const wmEven gso = op->customdata; - /* initialise type-specific data (used for the entire session) */ + /* Initialize type-specific data (used for the entire session). */ char tool = gso->brush->gpencil_sculpt_tool; switch (tool) { /* Brushes requiring timer... */ diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index f77bb394567..aaf88e1a0b0 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -1080,7 +1080,7 @@ void ED_gpencil_project_stroke_to_plane(const Scene *scene, } } else { - float scale[3] = {1.0f, 1.0f, 1.0f}; + const float scale[3] = {1.0f, 1.0f, 1.0f}; plane_normal[2] = 1.0f; float mat[4][4]; loc_eul_size_to_mat4(mat, cursor->location, cursor->rotation_euler, scale); @@ -1285,7 +1285,7 @@ void ED_gpencil_project_point_to_plane(const Scene *scene, } } else { - float scale[3] = {1.0f, 1.0f, 1.0f}; + const float scale[3] = {1.0f, 1.0f, 1.0f}; plane_normal[2] = 1.0f; float mat[4][4]; loc_eul_size_to_mat4(mat, cursor->location, cursor->rotation_euler, scale); @@ -1469,7 +1469,7 @@ void ED_gpencil_reset_layers_parent(Depsgraph *depsgraph, Object *obact, bGPdata /* Helper function to create new OB_GPENCIL Object */ Object *ED_gpencil_add_object(bContext *C, const float loc[3], ushort local_view_bits) { - float rot[3] = {0.0f}; + const float rot[3] = {0.0f}; Object *ob = ED_object_add_type(C, OB_GPENCIL, NULL, loc, rot, false, local_view_bits); @@ -1500,7 +1500,7 @@ void ED_gpencil_add_defaults(bContext *C, Object *ob) if (ts->gp_sculpt.cur_falloff == NULL) { ts->gp_sculpt.cur_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); CurveMapping *gp_falloff_curve = ts->gp_sculpt.cur_falloff; - BKE_curvemapping_initialize(gp_falloff_curve); + BKE_curvemapping_init(gp_falloff_curve); BKE_curvemap_reset(gp_falloff_curve->cm, &gp_falloff_curve->clipr, CURVE_PRESET_GAUSS, @@ -1723,7 +1723,7 @@ void ED_gpencil_vgroup_deselect(bContext *C, Object *ob) /* Cursor drawing */ /* check if cursor is in drawing region */ -static bool gpencil_check_cursor_region(bContext *C, int mval_i[2]) +static bool gpencil_check_cursor_region(bContext *C, const int mval_i[2]) { ARegion *region = CTX_wm_region(C); ScrArea *area = CTX_wm_area(C); @@ -2311,7 +2311,9 @@ static void gpencil_insert_point( MEM_SAFE_FREE(temp_points); } -static float gpencil_calc_factor(float p2d_a1[2], float p2d_a2[2], float r_hit2d[2]) +static float gpencil_calc_factor(const float p2d_a1[2], + const float p2d_a2[2], + const float r_hit2d[2]) { float dist1 = len_squared_v2v2(p2d_a1, p2d_a2); float dist2 = len_squared_v2v2(p2d_a1, r_hit2d); @@ -2688,7 +2690,11 @@ void ED_gpencil_tag_scene_gpencil(Scene *scene) void ED_gpencil_fill_vertex_color_set(ToolSettings *ts, Brush *brush, bGPDstroke *gps) { - if (GPENCIL_USE_VERTEX_COLOR_FILL(ts, brush)) { + const bool is_vertex = (GPENCIL_USE_VERTEX_COLOR_FILL(ts, brush) && + (brush->gpencil_settings->brush_draw_mode != GP_BRUSH_MODE_MATERIAL)) || + (!GPENCIL_USE_VERTEX_COLOR_FILL(ts, brush) && + (brush->gpencil_settings->brush_draw_mode == GP_BRUSH_MODE_VERTEXCOLOR)); + if (is_vertex) { copy_v3_v3(gps->vert_color_fill, brush->rgb); gps->vert_color_fill[3] = brush->gpencil_settings->vertex_factor; srgb_to_linearrgb_v4(gps->vert_color_fill, gps->vert_color_fill); @@ -2703,7 +2709,12 @@ void ED_gpencil_point_vertex_color_set(ToolSettings *ts, bGPDspoint *pt, tGPspoint *tpt) { - if (GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush)) { + const bool is_vertex = (GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush) && + (brush->gpencil_settings->brush_draw_mode != GP_BRUSH_MODE_MATERIAL)) || + (!GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush) && + (brush->gpencil_settings->brush_draw_mode == GP_BRUSH_MODE_VERTEXCOLOR)); + + if (is_vertex) { if (tpt == NULL) { copy_v3_v3(pt->vert_color, brush->rgb); pt->vert_color[3] = brush->gpencil_settings->vertex_factor; @@ -2859,6 +2870,18 @@ void ED_gpencil_sbuffer_vertex_color_set(Depsgraph *depsgraph, bGPdata *gpd_eval = (bGPdata *)ob_eval->data; MaterialGPencilStyle *gp_style = material->gp_style; + const bool is_vertex_fill = + (GPENCIL_USE_VERTEX_COLOR_FILL(ts, brush) && + (brush->gpencil_settings->brush_draw_mode != GP_BRUSH_MODE_MATERIAL)) || + (!GPENCIL_USE_VERTEX_COLOR_FILL(ts, brush) && + (brush->gpencil_settings->brush_draw_mode == GP_BRUSH_MODE_VERTEXCOLOR)); + + const bool is_vertex_stroke = + (GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush) && + (brush->gpencil_settings->brush_draw_mode != GP_BRUSH_MODE_MATERIAL)) || + (!GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush) && + (brush->gpencil_settings->brush_draw_mode == GP_BRUSH_MODE_VERTEXCOLOR)); + int idx = gpd->runtime.sbuffer_used; tGPspoint *tpt = (tGPspoint *)gpd->runtime.sbuffer + idx; @@ -2868,14 +2891,14 @@ void ED_gpencil_sbuffer_vertex_color_set(Depsgraph *depsgraph, srgb_to_linearrgb_v4(vertex_color, vertex_color); /* Copy fill vertex color. */ - if (GPENCIL_USE_VERTEX_COLOR_FILL(ts, brush)) { + if (is_vertex_fill) { copy_v4_v4(gpd->runtime.vert_color_fill, vertex_color); } else { copy_v4_v4(gpd->runtime.vert_color_fill, gp_style->fill_rgba); } /* Copy stroke vertex color. */ - if (GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush)) { + if (is_vertex_stroke) { copy_v4_v4(tpt->vert_color, vertex_color); } else { diff --git a/source/blender/editors/gpencil/gpencil_vertex_paint.c b/source/blender/editors/gpencil/gpencil_vertex_paint.c index c36bc4388d7..b0dff6589da 100644 --- a/source/blender/editors/gpencil/gpencil_vertex_paint.c +++ b/source/blender/editors/gpencil/gpencil_vertex_paint.c @@ -727,7 +727,7 @@ static bool gpencil_vertexpaint_brush_init(bContext *C, wmOperator *op) gso->brush = paint->brush; srgb_to_linearrgb_v3_v3(gso->linear_color, gso->brush->rgb); - BKE_curvemapping_initialize(gso->brush->curve); + BKE_curvemapping_init(gso->brush->curve); gso->is_painting = false; gso->first = true; @@ -759,7 +759,7 @@ static bool gpencil_vertexpaint_brush_init(bContext *C, wmOperator *op) /* Init multi-edit falloff curve data before doing anything, * so we won't have to do it again later. */ if (gso->is_multiframe) { - BKE_curvemapping_initialize(ts->gp_sculpt.cur_falloff); + BKE_curvemapping_init(ts->gp_sculpt.cur_falloff); } /* Setup space conversions. */ diff --git a/source/blender/editors/gpencil/gpencil_weight_paint.c b/source/blender/editors/gpencil/gpencil_weight_paint.c index 4392ec92824..9d3e9c6ae45 100644 --- a/source/blender/editors/gpencil/gpencil_weight_paint.c +++ b/source/blender/editors/gpencil/gpencil_weight_paint.c @@ -295,7 +295,7 @@ static bool gpencil_weightpaint_brush_init(bContext *C, wmOperator *op) gso->bmain = CTX_data_main(C); gso->brush = paint->brush; - BKE_curvemapping_initialize(gso->brush->curve); + BKE_curvemapping_init(gso->brush->curve); gso->is_painting = false; gso->first = true; @@ -326,7 +326,7 @@ static bool gpencil_weightpaint_brush_init(bContext *C, wmOperator *op) /* Init multi-edit falloff curve data before doing anything, * so we won't have to do it again later. */ if (gso->is_multiframe) { - BKE_curvemapping_initialize(ts->gp_sculpt.cur_falloff); + BKE_curvemapping_init(ts->gp_sculpt.cur_falloff); } /* Setup space conversions. */ diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h index e0ce72e5c3c..1d688b2ad68 100644 --- a/source/blender/editors/include/BIF_glutil.h +++ b/source/blender/editors/include/BIF_glutil.h @@ -23,6 +23,8 @@ #pragma once +#include "GPU_texture.h" + #ifdef __cplusplus extern "C" { #endif @@ -65,21 +67,19 @@ void immDrawPixelsTex(IMMDrawPixelsTexState *state, float y, int img_w, int img_h, - int format, - int type, - int zoomfilter, + eGPUTextureFormat gpu_format, + bool use_filter, void *rect, float xzoom, float yzoom, - float color[4]); + const float color[4]); void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state, float x, float y, int img_w, int img_h, - int format, - int type, - int zoomfilter, + eGPUTextureFormat gpu_format, + bool use_filter, void *rect, float clip_min_x, float clip_min_y, @@ -87,29 +87,27 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state, float clip_max_y, float xzoom, float yzoom, - float color[4]); + const float color[4]); void immDrawPixelsTexScaled(IMMDrawPixelsTexState *state, float x, float y, int img_w, int img_h, - int format, - int type, - int zoomfilter, + eGPUTextureFormat gpu_format, + bool use_filter, void *rect, float scaleX, float scaleY, float xzoom, float yzoom, - float color[4]); + const float color[4]); void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, float x, float y, int img_w, int img_h, - int format, - int type, - int zoomfilter, + eGPUTextureFormat gpu_format, + bool use_filter, void *rect, float scaleX, float scaleY, @@ -119,7 +117,7 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, float clip_max_y, float xzoom, float yzoom, - float color[4]); + const float color[4]); /* Image buffer drawing functions, with display transform * @@ -132,7 +130,7 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, void ED_draw_imbuf(struct ImBuf *ibuf, float x, float y, - int zoomfilter, + bool use_filter, struct ColorManagedViewSettings *view_settings, struct ColorManagedDisplaySettings *display_settings, float zoom_x, @@ -140,7 +138,7 @@ void ED_draw_imbuf(struct ImBuf *ibuf, void ED_draw_imbuf_clipping(struct ImBuf *ibuf, float x, float y, - int zoomfilter, + bool use_filter, struct ColorManagedViewSettings *view_settings, struct ColorManagedDisplaySettings *display_settings, float clip_min_x, @@ -154,14 +152,14 @@ void ED_draw_imbuf_ctx(const struct bContext *C, struct ImBuf *ibuf, float x, float y, - int zoomfilter, + bool use_filter, float zoom_x, float zoom_y); void ED_draw_imbuf_ctx_clipping(const struct bContext *C, struct ImBuf *ibuf, float x, float y, - int zoomfilter, + bool use_filter, float clip_min_x, float clip_min_y, float clip_max_x, diff --git a/source/blender/editors/include/ED_buttons.h b/source/blender/editors/include/ED_buttons.h index 8206f5a8619..ccef62eb8d2 100644 --- a/source/blender/editors/include/ED_buttons.h +++ b/source/blender/editors/include/ED_buttons.h @@ -26,6 +26,10 @@ extern "C" { #endif +struct SpaceProperties; + +int ED_buttons_tabs_list(struct SpaceProperties *sbuts, int *context_tabs_array); + #ifdef __cplusplus } #endif diff --git a/source/blender/editors/include/ED_numinput.h b/source/blender/editors/include/ED_numinput.h index 447b7b76c72..6c5aacafc7a 100644 --- a/source/blender/editors/include/ED_numinput.h +++ b/source/blender/editors/include/ED_numinput.h @@ -102,8 +102,12 @@ bool handleNumInput(struct bContext *C, NumInput *n, const struct wmEvent *event #define NUM_MODAL_INCREMENT_UP 18 #define NUM_MODAL_INCREMENT_DOWN 19 -bool user_string_to_number( - bContext *C, const char *str, const struct UnitSettings *unit, int type, double *r_value); +bool user_string_to_number(bContext *C, + const char *str, + const struct UnitSettings *unit, + int type, + const char *error_prefix, + double *r_value); /** \} */ diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 59567803f35..29fe766b2d0 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -72,7 +72,7 @@ void ED_region_exit(struct bContext *C, struct ARegion *region); void ED_region_remove(struct bContext *C, struct ScrArea *area, struct ARegion *region); void ED_region_pixelspace(struct ARegion *region); void ED_region_update_rect(struct ARegion *region); -void ED_region_floating_initialize(struct ARegion *region); +void ED_region_floating_init(struct ARegion *region); void ED_region_tag_redraw(struct ARegion *region); void ED_region_tag_redraw_partial(struct ARegion *region, const struct rcti *rct, bool rebuild); void ED_region_tag_redraw_cursor(struct ARegion *region); @@ -170,7 +170,7 @@ void ED_spacetypes_keymap(struct wmKeyConfig *keyconf); int ED_area_header_switchbutton(const struct bContext *C, struct uiBlock *block, int yco); /* areas */ -void ED_area_initialize(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *area); +void ED_area_init(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *area); void ED_area_exit(struct bContext *C, struct ScrArea *area); int ED_screen_area_active(const struct bContext *C); void ED_screen_global_areas_refresh(struct wmWindow *win); @@ -220,7 +220,7 @@ ScrArea *ED_screen_areas_iter_next(const bScreen *screen, const ScrArea *area); vert_name->next) /* screens */ -void ED_screens_initialize(struct Main *bmain, struct wmWindowManager *wm); +void ED_screens_init(struct Main *bmain, struct wmWindowManager *wm); void ED_screen_draw_edges(struct wmWindow *win); void ED_screen_draw_join_shape(struct ScrArea *sa1, struct ScrArea *sa2); void ED_screen_draw_split_preview(struct ScrArea *area, const int dir, const float fac); @@ -286,6 +286,12 @@ bool ED_workspace_delete(struct WorkSpace *workspace, struct bContext *C, struct wmWindowManager *wm) ATTR_NONNULL(); void ED_workspace_scene_data_sync(struct WorkSpaceInstanceHook *hook, Scene *scene) ATTR_NONNULL(); +struct WorkSpaceLayout *ED_workspace_screen_change_ensure_unused_layout( + struct Main *bmain, + struct WorkSpace *workspace, + struct WorkSpaceLayout *layout_new, + const struct WorkSpaceLayout *layout_fallback_base, + struct wmWindow *win) ATTR_NONNULL(); struct WorkSpaceLayout *ED_workspace_layout_add(struct Main *bmain, struct WorkSpace *workspace, struct wmWindow *win, diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 739a2184fb5..ddbea592238 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -698,17 +698,6 @@ float ED_view3d_grid_view_scale(struct Scene *scene, void ED_scene_draw_fps(const struct Scene *scene, int xoffset, int *yoffset); -/* view matrix properties utilities */ -/* unused */ -#if 0 -void ED_view3d_operator_properties_viewmat(struct wmOperatorType *ot); -void ED_view3d_operator_properties_viewmat_set(struct bContext *C, struct wmOperator *op); -void ED_view3d_operator_properties_viewmat_get(struct wmOperator *op, - int *winx, - int *winy, - float persmat[4][4]); -#endif - /* render */ void ED_view3d_stop_render_preview(struct wmWindowManager *wm, struct ARegion *region); void ED_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrArea *area); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index d682597da8e..e8352bc6b21 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -57,6 +57,7 @@ struct bNodeSocket; struct bNodeTree; struct bScreen; struct rcti; +struct uiButSearch; struct uiFontStyle; struct uiList; struct uiStyle; @@ -100,7 +101,7 @@ typedef struct uiPopupBlockHandle uiPopupBlockHandle; /* use for clamping popups within the screen */ #define UI_SCREEN_MARGIN 10 -/* uiBlock->dt and uiBut->dt */ +/** #uiBlock.emboss and #uiBut.emboss */ enum { UI_EMBOSS = 0, /* use widget style for drawing */ UI_EMBOSS_NONE = 1, /* Nothing, only icon and/or text */ @@ -371,6 +372,7 @@ typedef enum { UI_BTYPE_SEPR_SPACER = 56 << 9, /** Resize handle (resize uilist). */ UI_BTYPE_GRIP = 57 << 9, + UI_BTYPE_DECORATOR = 58 << 9, } eButType; #define BUTTYPE (63 << 9) @@ -388,8 +390,6 @@ enum { UI_GRAD_L_ALT = 10, }; -#define UI_PALETTE_COLOR 20 - /* Drawing * * Functions to draw various shapes, taking theme settings into account. @@ -500,7 +500,7 @@ typedef int (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg); /* Search types. */ typedef struct ARegion *(*uiButSearchCreateFn)(struct bContext *C, struct ARegion *butregion, - uiBut *but); + struct uiButSearch *search_but); typedef void (*uiButSearchUpdateFn)(const struct bContext *C, void *arg, const char *str, @@ -537,7 +537,7 @@ typedef bool (*uiMenuStepFunc)(struct bContext *C, int direction, void *arg1); bool UI_but_has_tooltip_label(const uiBut *but); bool UI_but_is_tool(const uiBut *but); bool UI_but_is_utf8(const uiBut *but); -#define UI_but_is_decorator(but) ((but)->func == ui_but_anim_decorate_cb) +#define UI_but_is_decorator(but) ((but)->type == UI_BTYPE_DECORATOR) bool UI_block_is_empty_ex(const uiBlock *block, const bool skip_title); bool UI_block_is_empty(const uiBlock *block); @@ -656,7 +656,7 @@ bool UI_popup_block_name_exists(const struct bScreen *screen, const char *name); uiBlock *UI_block_begin(const struct bContext *C, struct ARegion *region, const char *name, - short dt); + char emboss); void UI_block_end_ex(const struct bContext *C, uiBlock *block, const int xy[2], int r_xy[2]); void UI_block_end(const struct bContext *C, uiBlock *block); void UI_block_draw(const struct bContext *C, struct uiBlock *block); @@ -670,7 +670,7 @@ enum { }; void UI_block_theme_style_set(uiBlock *block, char theme_style); char UI_block_emboss_get(uiBlock *block); -void UI_block_emboss_set(uiBlock *block, char dt); +void UI_block_emboss_set(uiBlock *block, char emboss); void UI_block_free(const struct bContext *C, uiBlock *block); void UI_blocklist_free(const struct bContext *C, struct ListBase *lb); @@ -1929,8 +1929,6 @@ uiLayout *uiLayoutGridFlow(uiLayout *layout, uiLayout *uiLayoutBox(uiLayout *layout); uiLayout *uiLayoutListBox(uiLayout *layout, struct uiList *ui_list, - struct PointerRNA *ptr, - struct PropertyRNA *prop, struct PointerRNA *actptr, struct PropertyRNA *actprop); uiLayout *uiLayoutAbsolute(uiLayout *layout, bool align); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 286cb1571bd..a84ca33a7d7 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -52,7 +52,6 @@ #include "BKE_screen.h" #include "BKE_unit.h" -#include "GPU_glew.h" #include "GPU_matrix.h" #include "GPU_state.h" @@ -808,7 +807,12 @@ static bool ui_but_update_from_old_block(const bContext *C, SWAP(ListBase, but->extra_op_icons, oldbut->extra_op_icons); - SWAP(struct uiButSearchData *, oldbut->search, but->search); + if (oldbut->type == UI_BTYPE_SEARCH_MENU) { + uiButSearch *search_oldbut = (uiButSearch *)oldbut, *search_but = (uiButSearch *)but; + + SWAP(uiButSearchArgFreeFn, search_oldbut->arg_free_fn, search_but->arg_free_fn); + SWAP(void *, search_oldbut->arg, search_but->arg); + } /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position * when scrolling without moving mouse (see [#28432]) */ @@ -816,10 +820,10 @@ static bool ui_but_update_from_old_block(const bContext *C, oldbut->hardmax = but->hardmax; } - /* Selectively copy a1, a2 since their use differs across all button types - * (and we'll probably split these out later) */ - if (ELEM(oldbut->type, UI_BTYPE_PROGRESS_BAR)) { - oldbut->a1 = but->a1; + if (oldbut->type == UI_BTYPE_PROGRESS_BAR) { + uiButProgressbar *progress_oldbut = (uiButProgressbar *)oldbut; + uiButProgressbar *progress_but = (uiButProgressbar *)but; + progress_oldbut->progress = progress_but->progress; } if (!BLI_listbase_is_empty(&block->butstore)) { @@ -1493,7 +1497,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) continue; } } - else if (but->dt != UI_EMBOSS_PULLDOWN) { + else if (but->emboss != UI_EMBOSS_PULLDOWN) { continue; } @@ -1774,7 +1778,7 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x ui_but_anim_flag(but, &anim_eval_context); ui_but_override_flag(CTX_data_main(C), but); if (UI_but_is_decorator(but)) { - ui_but_anim_decorate_update_from_flag(but); + ui_but_anim_decorate_update_from_flag((uiButDecorator *)but); } ui_but_predefined_extra_operator_icons_add(but); } @@ -2022,6 +2026,7 @@ int ui_but_is_pushed_ex(uiBut *but, double *value) case UI_BTYPE_HOTKEY_EVENT: case UI_BTYPE_KEY_EVENT: case UI_BTYPE_COLOR: + case UI_BTYPE_DECORATOR: is_push = -1; break; case UI_BTYPE_BUT_TOGGLE: @@ -2324,7 +2329,8 @@ bool ui_but_supports_cycling(const uiBut *but) { return ((ELEM(but->type, UI_BTYPE_ROW, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER, UI_BTYPE_LISTBOX)) || (but->type == UI_BTYPE_MENU && ui_but_menu_step_poll(but)) || - (but->type == UI_BTYPE_COLOR && but->a1 != -1) || (but->menu_step_func != NULL)); + (but->type == UI_BTYPE_COLOR && ((uiButColor *)but)->is_pallete_color) || + (but->menu_step_func != NULL)); } double ui_but_value_get(uiBut *but) @@ -2807,25 +2813,39 @@ char *ui_but_string_get_dynamic(uiBut *but, int *r_str_size) return str; } -static bool ui_set_but_string_eval_num_unit(bContext *C, - uiBut *but, - const char *str, - double *r_value) +/** + * Report a generic error prefix when evaluating a string with #BPY_execute_string_as_number + * as the Python error on it's own doesn't provide enough context. + */ +#define UI_NUMBER_EVAL_ERROR_PREFIX IFACE_("Error evaluating number, see Info editor for details") + +static bool ui_number_from_string_units( + bContext *C, const char *str, const int unit_type, const UnitSettings *unit, double *r_value) { + return user_string_to_number(C, str, unit, unit_type, UI_NUMBER_EVAL_ERROR_PREFIX, r_value); +} + +static bool ui_number_from_string_units_with_but(bContext *C, + const char *str, + const uiBut *but, + double *r_value) +{ + const int unit_type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but)); const UnitSettings *unit = but->block->unit; - int type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but)); - return user_string_to_number(C, str, unit, type, r_value); + return ui_number_from_string_units(C, str, unit_type, unit, r_value); } static bool ui_number_from_string(bContext *C, const char *str, double *r_value) { + bool ok; #ifdef WITH_PYTHON - return BPY_execute_string_as_number(C, NULL, str, true, r_value); + ok = BPY_execute_string_as_number(C, NULL, str, UI_NUMBER_EVAL_ERROR_PREFIX, r_value); #else UNUSED_VARS(C); *r_value = atof(str); - return true; + ok = true; #endif + return ok; } static bool ui_number_from_string_factor(bContext *C, const char *str, double *r_value) @@ -2859,7 +2879,7 @@ static bool ui_number_from_string_percentage(bContext *C, const char *str, doubl return ui_number_from_string(C, str, r_value); } -bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double *r_value) +bool ui_but_string_eval_number(bContext *C, const uiBut *but, const char *str, double *r_value) { if (str[0] == '\0') { *r_value = 0.0; @@ -2873,7 +2893,7 @@ bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double if (ui_but_is_float(but)) { if (ui_but_is_unit(but)) { - return ui_set_but_string_eval_num_unit(C, but, str, r_value); + return ui_number_from_string_units_with_but(C, str, but, r_value); } if (subtype == PROP_FACTOR) { return ui_number_from_string_factor(C, str, r_value); @@ -2932,10 +2952,10 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str) RNA_property_pointer_set(&but->rnapoin, but->rnaprop, PointerRNA_NULL, NULL); return true; } + + uiButSearch *search_but = (but->type == UI_BTYPE_SEARCH_MENU) ? (uiButSearch *)but : NULL; /* RNA pointer */ PointerRNA rptr; - PointerRNA ptr = but->rnasearchpoin; - PropertyRNA *prop = but->rnasearchprop; /* This is kind of hackish, in theory think we could only ever use the second member of * this if/else, since ui_searchbox_apply() is supposed to always set that pointer when @@ -2943,12 +2963,16 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str) * to try to break as little as possible existing code. All this is band-aids anyway. * Fact remains, using editstr as main 'reference' over whole search button thingy * is utterly weak and should be redesigned imho, but that's not a simple task. */ - if (prop && RNA_property_collection_lookup_string(&ptr, prop, str, &rptr)) { + if (search_but && search_but->rnasearchprop && + RNA_property_collection_lookup_string( + &search_but->rnasearchpoin, search_but->rnasearchprop, str, &rptr)) { RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr, NULL); } - else if (but->func_arg2 != NULL) { - RNA_pointer_create( - NULL, RNA_property_pointer_type(&but->rnapoin, but->rnaprop), but->func_arg2, &rptr); + else if (search_but->item_active != NULL) { + RNA_pointer_create(NULL, + RNA_property_pointer_type(&but->rnapoin, but->rnaprop), + search_but->item_active, + &rptr); RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr, NULL); } @@ -3013,7 +3037,7 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str) /* number editing */ double value; - if (ui_but_string_set_eval_num(C, but, str, &value) == false) { + if (ui_but_string_eval_number(C, but, str, &value) == false) { WM_report_banner_show(); return false; } @@ -3218,6 +3242,28 @@ void ui_but_range_set_soft(uiBut *but) /* ******************* Free ********************/ +/** + * Free data specific to a certain button type. + * For now just do in a switch-case, we could instead have a callback stored in #uiBut and set that + * in #ui_but_alloc_info(). + */ +static void ui_but_free_type_specific(uiBut *but) +{ + switch (but->type) { + case UI_BTYPE_SEARCH_MENU: { + uiButSearch *search_but = (uiButSearch *)but; + + if (search_but->arg_free_fn) { + search_but->arg_free_fn(search_but->arg); + search_but->arg = NULL; + } + break; + } + default: + break; + } +} + /* can be called with C==NULL */ static void ui_but_free(const bContext *C, uiBut *but) { @@ -3238,13 +3284,7 @@ static void ui_but_free(const bContext *C, uiBut *but) MEM_freeN(but->hold_argN); } - if (but->search != NULL) { - if (but->search->arg_free_fn) { - but->search->arg_free_fn(but->search->arg); - but->search->arg = NULL; - } - MEM_freeN(but->search); - } + ui_but_free_type_specific(but); if (but->active) { /* XXX solve later, buttons should be free-able without context ideally, @@ -3377,7 +3417,7 @@ void UI_block_region_set(uiBlock *block, ARegion *region) block->oldblock = oldblock; } -uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, short dt) +uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, char emboss) { uiBlock *block; wmWindow *window; @@ -3388,7 +3428,7 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, sh block = MEM_callocN(sizeof(uiBlock), "uiBlock"); block->active = 1; - block->dt = dt; + block->emboss = emboss; block->evil_C = (void *)C; /* XXX */ if (scn) { @@ -3427,12 +3467,12 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, sh char UI_block_emboss_get(uiBlock *block) { - return block->dt; + return block->emboss; } -void UI_block_emboss_set(uiBlock *block, char dt) +void UI_block_emboss_set(uiBlock *block, char emboss) { - block->dt = dt; + block->emboss = emboss; } void UI_block_theme_style_set(uiBlock *block, char theme_style) @@ -3723,16 +3763,109 @@ void ui_block_cm_to_display_space_v3(uiBlock *block, float pixel[3]) IMB_colormanagement_scene_linear_to_display_v3(pixel, display); } -static uiBut *ui_but_alloc(const eButType type) +static void ui_but_alloc_info(const eButType type, + size_t *r_alloc_size, + const char **r_alloc_str, + bool *r_has_custom_type) { + size_t alloc_size; + const char *alloc_str; + bool has_custom_type = true; + switch (type) { + case UI_BTYPE_COLOR: + alloc_size = sizeof(uiButColor); + alloc_str = "uiButColor"; + break; + case UI_BTYPE_DECORATOR: + alloc_size = sizeof(uiButDecorator); + alloc_str = "uiButDecorator"; + break; case UI_BTYPE_TAB: - return MEM_callocN(sizeof(uiButTab), "uiButTab"); + alloc_size = sizeof(uiButTab); + alloc_str = "uiButTab"; + break; + case UI_BTYPE_SEARCH_MENU: + alloc_size = sizeof(uiButSearch); + alloc_str = "uiButSearch"; + break; + case UI_BTYPE_PROGRESS_BAR: + alloc_size = sizeof(uiButProgressbar); + alloc_str = "uiButProgressbar"; + break; default: - return MEM_callocN(sizeof(uiBut), "uiBut"); + alloc_size = sizeof(uiBut); + alloc_str = "uiBut"; + has_custom_type = false; + break; + } + + if (r_alloc_size) { + *r_alloc_size = alloc_size; + } + if (r_alloc_str) { + *r_alloc_str = alloc_str; + } + if (r_has_custom_type) { + *r_has_custom_type = has_custom_type; } } +static uiBut *ui_but_alloc(const eButType type) +{ + size_t alloc_size; + const char *alloc_str; + + ui_but_alloc_info(type, &alloc_size, &alloc_str, NULL); + + return MEM_callocN(alloc_size, alloc_str); +} + +/** + * Reallocate the button (new address is returned) for a new button type. + * This should generally be avoided and instead the correct type be created right away. + * + * \note Only the #uiBut data can be kept. If the old button used a derived type (e.g. #uiButTab), + * the data that is not inside #uiBut will be lost. + */ +uiBut *ui_but_change_type(uiBut *but, eButType new_type) +{ + if (but->type != new_type) { + size_t alloc_size; + const char *alloc_str; + uiBut *insert_after_but = but->prev; + bool new_has_custom_type, old_has_custom_type; + + /* Remove old button address */ + BLI_remlink(&but->block->buttons, but); + + ui_but_alloc_info(but->type, NULL, NULL, &old_has_custom_type); + ui_but_alloc_info(new_type, &alloc_size, &alloc_str, &new_has_custom_type); + + if (new_has_custom_type || old_has_custom_type) { + const void *old_but_ptr = but; + /* Button may have pointer to a member within itself, this will have to be updated. */ + const bool has_str_ptr_to_self = but->str == but->strdata; + + but = MEM_recallocN_id(but, alloc_size, alloc_str); + but->type = new_type; + if (has_str_ptr_to_self) { + but->str = but->strdata; + } + + BLI_insertlinkafter(&but->block->buttons, insert_after_but, but); + + if (but->layout) { + const bool found_layout = ui_layout_replace_but_ptr(but->layout, old_but_ptr, but); + BLI_assert(found_layout); + UNUSED_VARS_NDEBUG(found_layout); + } + } + } + + return but; +} + /** * \brief ui_def_but is the function that draws many button types * @@ -3812,7 +3945,7 @@ static uiBut *ui_def_but(uiBlock *block, but->tip = tip; but->disabled_info = block->lockstr; - but->dt = block->dt; + but->emboss = block->emboss; but->pie_dir = UI_RADIAL_NONE; but->block = block; /* pointer back, used for frontbuffer status, and picker */ @@ -3878,6 +4011,7 @@ static uiBut *ui_def_but(uiBlock *block, if (ELEM(but->type, UI_BTYPE_BLOCK, UI_BTYPE_BUT, + UI_BTYPE_DECORATOR, UI_BTYPE_LABEL, UI_BTYPE_PULLDOWN, UI_BTYPE_ROUNDBOX, @@ -4345,7 +4479,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, } if (type == UI_BTYPE_MENU) { - if (but->dt == UI_EMBOSS_PULLDOWN) { + if (but->emboss == UI_EMBOSS_PULLDOWN) { ui_but_submenu_enable(block, but); } } @@ -6372,54 +6506,55 @@ void UI_but_func_search_set(uiBut *but, uiButHandleFunc search_exec_fn, void *active) { + uiButSearch *search_but = (uiButSearch *)but; + + BLI_assert(but->type == UI_BTYPE_SEARCH_MENU); + /* needed since callers don't have access to internal functions * (as an alternative we could expose it) */ if (search_create_fn == NULL) { search_create_fn = ui_searchbox_create_generic; } - struct uiButSearchData *search = but->search; - if (search != NULL) { - if (search->arg_free_fn != NULL) { - search->arg_free_fn(but->search->arg); - search->arg = NULL; - } - } - else { - search = MEM_callocN(sizeof(*but->search), __func__); - but->search = search; + if (search_but->arg_free_fn != NULL) { + search_but->arg_free_fn(search_but->arg); + search_but->arg = NULL; } - search->create_fn = search_create_fn; - search->update_fn = search_update_fn; + search_but->popup_create_fn = search_create_fn; + search_but->items_update_fn = search_update_fn; + search_but->item_active = active; - search->arg = arg; - search->arg_free_fn = search_arg_free_fn; + search_but->arg = arg; + search_but->arg_free_fn = search_arg_free_fn; if (search_exec_fn) { #ifdef DEBUG - if (but->func) { + if (search_but->but.func) { /* watch this, can be cause of much confusion, see: T47691 */ printf("%s: warning, overwriting button callback with search function callback!\n", __func__); } #endif - UI_but_func_set(but, search_exec_fn, search->arg, active); + /* Handling will pass the active item as arg2 later, so keep it NULL here. */ + UI_but_func_set(but, search_exec_fn, search_but->arg, NULL); } /* search buttons show red-alert if item doesn't exist, not for menus */ if (0 == (but->block->flag & UI_BLOCK_LOOP)) { /* skip empty buttons, not all buttons need input, we only show invalid */ if (but->drawstr[0]) { - ui_but_search_refresh(but); + ui_but_search_refresh(search_but); } } } void UI_but_func_search_set_context_menu(uiBut *but, uiButSearchContextMenuFn context_menu_fn) { - struct uiButSearchData *search = but->search; - search->context_menu_fn = context_menu_fn; + uiButSearch *but_search = (uiButSearch *)but; + BLI_assert(but->type == UI_BTYPE_SEARCH_MENU); + + but_search->item_context_menu_fn = context_menu_fn; } /** @@ -6428,14 +6563,18 @@ void UI_but_func_search_set_context_menu(uiBut *but, uiButSearchContextMenuFn co */ void UI_but_func_search_set_sep_string(uiBut *but, const char *search_sep_string) { - struct uiButSearchData *search = but->search; - search->sep_string = search_sep_string; + uiButSearch *but_search = (uiButSearch *)but; + BLI_assert(but->type == UI_BTYPE_SEARCH_MENU); + + but_search->item_sep_string = search_sep_string; } void UI_but_func_search_set_tooltip(uiBut *but, uiButSearchTooltipFn tooltip_fn) { - struct uiButSearchData *search = but->search; - search->tooltip_fn = tooltip_fn; + uiButSearch *but_search = (uiButSearch *)but; + BLI_assert(but->type == UI_BTYPE_SEARCH_MENU); + + but_search->item_tooltip_fn = tooltip_fn; } /* Callbacks for operator search button. */ diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c index 8d12a1dd1ad..cc58082cb02 100644 --- a/source/blender/editors/interface/interface_anim.c +++ b/source/blender/editors/interface/interface_anim.c @@ -120,35 +120,41 @@ void ui_but_anim_flag(uiBut *but, const AnimationEvalContext *anim_eval_context) } } -static uiBut *ui_but_anim_decorate_find_attached_button(uiBut *but_decorate) +static uiBut *ui_but_anim_decorate_find_attached_button(uiButDecorator *but_decorate) { uiBut *but_iter = NULL; - BLI_assert(UI_but_is_decorator(but_decorate)); - BLI_assert(but_decorate->rnasearchpoin.data && but_decorate->rnasearchprop); + BLI_assert(UI_but_is_decorator(&but_decorate->but)); + BLI_assert(but_decorate->rnapoin.data && but_decorate->rnaprop); - LISTBASE_CIRCULAR_BACKWARD_BEGIN (&but_decorate->block->buttons, but_iter, but_decorate->prev) { - if (but_iter != but_decorate && - ui_but_rna_equals_ex(but_iter, - &but_decorate->rnasearchpoin, - but_decorate->rnasearchprop, - POINTER_AS_INT(but_decorate->custom_data))) { + LISTBASE_CIRCULAR_BACKWARD_BEGIN ( + &but_decorate->but.block->buttons, but_iter, but_decorate->but.prev) { + if (but_iter != (uiBut *)but_decorate && + ui_but_rna_equals_ex( + but_iter, &but_decorate->rnapoin, but_decorate->rnaprop, but_decorate->rnaindex)) { return but_iter; } } - LISTBASE_CIRCULAR_BACKWARD_END(&but_decorate->block->buttons, but_iter, but_decorate->prev); + LISTBASE_CIRCULAR_BACKWARD_END( + &but_decorate->but.block->buttons, but_iter, but_decorate->but.prev); return NULL; } -void ui_but_anim_decorate_update_from_flag(uiBut *but) +void ui_but_anim_decorate_update_from_flag(uiButDecorator *decorator_but) { - const uiBut *but_anim = ui_but_anim_decorate_find_attached_button(but); + if (!decorator_but->rnapoin.data || !decorator_but->rnaprop) { + /* Nothing to do. */ + return; + } + + const uiBut *but_anim = ui_but_anim_decorate_find_attached_button(decorator_but); + uiBut *but = &decorator_but->but; if (!but_anim) { printf("Could not find button with matching property to decorate (%s.%s)\n", - RNA_struct_identifier(but->rnasearchpoin.type), - RNA_property_identifier(but->rnasearchprop)); + RNA_struct_identifier(decorator_but->rnapoin.type), + RNA_property_identifier(decorator_but->rnaprop)); return; } @@ -325,7 +331,7 @@ void ui_but_anim_paste_driver(bContext *C) void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void *UNUSED(arg_dummy)) { wmWindowManager *wm = CTX_wm_manager(C); - uiBut *but_decorate = arg_but; + uiButDecorator *but_decorate = arg_but; uiBut *but_anim = ui_but_anim_decorate_find_attached_button(but_decorate); if (!but_anim) { @@ -333,7 +339,7 @@ void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void *UNUSED(arg_dummy) } /* FIXME(campbell), swapping active pointer is weak. */ - SWAP(struct uiHandleButtonData *, but_anim->active, but_decorate->active); + SWAP(struct uiHandleButtonData *, but_anim->active, but_decorate->but.active); wm->op_undo_depth++; if (but_anim->flag & UI_BUT_DRIVEN) { @@ -357,6 +363,6 @@ void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void *UNUSED(arg_dummy) WM_operator_properties_free(&props_ptr); } - SWAP(struct uiHandleButtonData *, but_anim->active, but_decorate->active); + SWAP(struct uiHandleButtonData *, but_anim->active, but_decorate->but.active); wm->op_undo_depth--; } diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c index a08c5c45b6f..46876fca9a5 100644 --- a/source/blender/editors/interface/interface_context_menu.c +++ b/source/blender/editors/interface/interface_context_menu.c @@ -407,7 +407,7 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um) "'%s').label", idname); char *expr_result = NULL; - if (BPY_execute_string_as_string(C, expr_imports, expr, true, &expr_result)) { + if (BPY_execute_string_as_string(C, expr_imports, expr, __func__, &expr_result)) { STRNCPY(drawstr, expr_result); MEM_freeN(expr_result); } @@ -962,7 +962,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but) const PropertyType prop_type = RNA_property_type(but->rnaprop); if (((prop_type == PROP_POINTER) || (prop_type == PROP_STRING && but->type == UI_BTYPE_SEARCH_MENU && - but->search->update_fn == ui_rna_collection_search_update_fn)) && + ((uiButSearch *)but)->items_update_fn == ui_rna_collection_search_update_fn)) && ui_jump_to_target_button_poll(C)) { uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Jump to Target"), diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index cc5d21c3df3..05f6e61ff40 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -773,9 +773,8 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region), (float)rect->ymin, ibuf->x, ibuf->y, - GL_RGBA, - GL_UNSIGNED_BYTE, - GL_NEAREST, + GPU_RGBA8, + false, ibuf->rect, 1.0f, 1.0f, @@ -841,7 +840,7 @@ static void draw_scope_end(const rctf *rect, GLint *scissor) /* outline */ UI_draw_roundbox_corner_set(UI_CNR_ALL); - float color[4] = {0.0f, 0.0f, 0.0f, 0.5f}; + const float color[4] = {0.0f, 0.0f, 0.0f, 0.5f}; UI_draw_roundbox_4fv( false, rect->xmin - 1, rect->ymin, rect->xmax + 1, rect->ymax + 1, 3.0f, color); } @@ -859,7 +858,7 @@ static void histogram_draw_one(float r, const bool is_line, uint pos_attr) { - float color[4] = {r, g, b, alpha}; + const float color[4] = {r, g, b, alpha}; /* that can happen */ if (res == 0) { @@ -1033,7 +1032,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region), Scopes *scopes = (Scopes *)but->poin; int scissor[4]; float colors[3][3]; - float colorsycc[3][3] = {{1, 0, 1}, {1, 1, 0}, {0, 1, 1}}; + const float colorsycc[3][3] = {{1, 0, 1}, {1, 1, 0}, {0, 1, 1}}; /* colors pre multiplied by alpha for speed up */ float colors_alpha[3][3], colorsycc_alpha[3][3]; float min, max; @@ -1173,7 +1172,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region), /* LUMA (1 channel) */ if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) { - float col[3] = {alpha, alpha, alpha}; + const float col[3] = {alpha, alpha, alpha}; GPU_matrix_push(); GPU_matrix_translate_2f(rect.xmin, yofs); @@ -1466,7 +1465,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(region), if (scopes->ok && scopes->vecscope != NULL) { /* pixel point cloud */ - float col[3] = {alpha, alpha, alpha}; + const float col[3] = {alpha, alpha, alpha}; GPU_blend_set_func(GPU_ONE, GPU_ONE); GPU_point_size(1.0); @@ -1774,7 +1773,7 @@ void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const void ui_draw_but_UNITVEC(uiBut *but, const uiWidgetColors *wcol, const rcti *rect) { /* sphere color */ - float diffuse[3] = {1.0f, 1.0f, 1.0f}; + const float diffuse[3] = {1.0f, 1.0f, 1.0f}; float light[3]; const float size = 0.5f * min_ff(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)); @@ -1938,7 +1937,7 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol, /* Do this first to not mess imm context */ if (but->a1 == UI_GRAD_H) { /* magic trigger for curve backgrounds */ - float col[3] = {0.0f, 0.0f, 0.0f}; /* dummy arg */ + const float col[3] = {0.0f, 0.0f, 0.0f}; /* dummy arg */ rcti grid = { .xmin = rect->xmin + zoomx * (-offsx), @@ -2257,12 +2256,12 @@ void ui_draw_but_CURVEPROFILE(ARegion *region, /* Also add the last points on the right and bottom edges to close off the fill polygon. */ bool add_left_tri = profile->view_rect.xmin < 0.0f; bool add_bottom_tri = profile->view_rect.ymin < 0.0f; - uint tot_points = (uint)PROF_N_TABLE(profile->path_len) + 1 + add_left_tri + add_bottom_tri; + uint tot_points = (uint)PROF_TABLE_LEN(profile->path_len) + 1 + add_left_tri + add_bottom_tri; uint tot_triangles = tot_points - 2; /* Create array of the positions of the table's points. */ float(*table_coords)[2] = MEM_mallocN(sizeof(*table_coords) * tot_points, "table x coords"); - for (i = 0; i < (uint)PROF_N_TABLE(profile->path_len); + for (i = 0; i < (uint)PROF_TABLE_LEN(profile->path_len); i++) { /* Only add the points from the table here. */ table_coords[i][0] = pts[i].x; table_coords[i][1] = pts[i].y; @@ -2484,7 +2483,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region), (rect.ymax + 1) - (rect.ymin - 1)); if (scopes->track_disabled) { - float color[4] = {0.7f, 0.3f, 0.3f, 0.3f}; + const float color[4] = {0.7f, 0.3f, 0.3f, 0.3f}; UI_draw_roundbox_corner_set(UI_CNR_ALL); UI_draw_roundbox_4fv( true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color); @@ -2533,7 +2532,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region), float col_sel[4], col_outline[4]; if (scopes->use_track_mask) { - float color[4] = {0.0f, 0.0f, 0.0f, 0.3f}; + const float color[4] = {0.0f, 0.0f, 0.0f, 0.3f}; UI_draw_roundbox_corner_set(UI_CNR_ALL); UI_draw_roundbox_4fv( true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color); @@ -2545,9 +2544,8 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region), rect.ymin + 1, drawibuf->x, drawibuf->y, - GL_RGBA, - GL_UNSIGNED_BYTE, - GL_LINEAR, + GPU_RGBA8, + true, drawibuf->rect, 1.0f, 1.0f, @@ -2567,7 +2565,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region), /* Do stipple cross with geometry */ immBegin(GPU_PRIM_LINES, 7 * 2 * 2); - float pos_sel[8] = {-10.0f, -7.0f, -4.0f, -1.0f, 2.0f, 5.0f, 8.0f, 11.0f}; + const float pos_sel[8] = {-10.0f, -7.0f, -4.0f, -1.0f, 2.0f, 5.0f, 8.0f, 11.0f}; for (int axe = 0; axe < 2; axe++) { for (int i = 0; i < 7; i++) { float x1 = pos_sel[i] * (1 - axe); @@ -2597,7 +2595,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region), } if (!ok) { - float color[4] = {0.0f, 0.0f, 0.0f, 0.3f}; + const float color[4] = {0.0f, 0.0f, 0.0f, 0.3f}; UI_draw_roundbox_corner_set(UI_CNR_ALL); UI_draw_roundbox_4fv( true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color); @@ -2775,7 +2773,7 @@ void ui_draw_dropshadow( GPU_batch_draw(batch); /* outline emphasis */ - float color[4] = {0.0f, 0.0f, 0.0f, 0.4f}; + const float color[4] = {0.0f, 0.0f, 0.0f, 0.4f}; UI_draw_roundbox_4fv(false, rct->xmin - 0.5f, rct->ymin - 0.5f, diff --git a/source/blender/editors/interface/interface_eyedropper_color.c b/source/blender/editors/interface/interface_eyedropper_color.c index 93b052b3b69..c86e35f91db 100644 --- a/source/blender/editors/interface/interface_eyedropper_color.c +++ b/source/blender/editors/interface/interface_eyedropper_color.c @@ -39,8 +39,6 @@ #include "RNA_access.h" -#include "GPU_glew.h" - #include "UI_interface.h" #include "IMB_colormanagement.h" @@ -174,7 +172,7 @@ void eyedropper_color_sample_fl(bContext *C, int mx, int my, float r_col[3]) ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, mx, my); if (region) { SpaceNode *snode = area->spacedata.first; - int mval[2] = {mx - region->winrct.xmin, my - region->winrct.ymin}; + const int mval[2] = {mx - region->winrct.xmin, my - region->winrct.ymin}; if (ED_space_node_color_sample(bmain, snode, region, mval, r_col)) { return; @@ -196,7 +194,7 @@ void eyedropper_color_sample_fl(bContext *C, int mx, int my, float r_col[3]) if (win) { /* Fallback to simple opengl picker. */ - int mval[2] = {mx, my}; + const int mval[2] = {mx, my}; WM_window_pixel_sample_read(wm, win, mval, r_col); IMB_colormanagement_display_to_scene_linear_v3(r_col, display); } diff --git a/source/blender/editors/interface/interface_eyedropper_colorband.c b/source/blender/editors/interface/interface_eyedropper_colorband.c index 7b8357f5ef1..b757341ae13 100644 --- a/source/blender/editors/interface/interface_eyedropper_colorband.c +++ b/source/blender/editors/interface/interface_eyedropper_colorband.c @@ -179,8 +179,8 @@ static void eyedropper_colorband_sample_segment(bContext *C, /* Since the mouse tends to move rather rapidly we use #BLI_bitmap_draw_2d_line_v2v2i * to interpolate between the reported coordinates */ struct EyedropperColorband_Context userdata = {C, eye}; - int p1[2] = {eye->last_x, eye->last_y}; - int p2[2] = {mx, my}; + const int p1[2] = {eye->last_x, eye->last_y}; + const int p2[2] = {mx, my}; BLI_bitmap_draw_2d_line_v2v2i(p1, p2, eyedropper_colorband_sample_callback, &userdata); } diff --git a/source/blender/editors/interface/interface_eyedropper_gpencil_color.c b/source/blender/editors/interface/interface_eyedropper_gpencil_color.c index 978d8ac09de..aa5b4d2c255 100644 --- a/source/blender/editors/interface/interface_eyedropper_gpencil_color.c +++ b/source/blender/editors/interface/interface_eyedropper_gpencil_color.c @@ -106,8 +106,11 @@ static void eyedropper_gpencil_exit(bContext *C, wmOperator *op) MEM_SAFE_FREE(op->customdata); } -static void eyedropper_add_material( - bContext *C, float col_conv[4], const bool only_stroke, const bool only_fill, const bool both) +static void eyedropper_add_material(bContext *C, + const float col_conv[4], + const bool only_stroke, + const bool only_fill, + const bool both) { Main *bmain = CTX_data_main(C); Object *ob = CTX_data_active_object(C); @@ -193,7 +196,7 @@ static void eyedropper_add_material( } /* Create a new palette color and palette if needed. */ -static void eyedropper_add_palette_color(bContext *C, float col_conv[4]) +static void eyedropper_add_palette_color(bContext *C, const float col_conv[4]) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index bcb4f7c672f..999ddca65b9 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -767,11 +767,12 @@ static void ui_apply_but_func(bContext *C, uiBut *but) after->rnapoin = but->rnapoin; after->rnaprop = but->rnaprop; - if (but->search != NULL) { - after->search_arg_free_fn = but->search->arg_free_fn; - after->search_arg = but->search->arg; - but->search->arg_free_fn = NULL; - but->search->arg = NULL; + if (but->type == UI_BTYPE_SEARCH_MENU) { + uiButSearch *search_but = (uiButSearch *)but; + after->search_arg_free_fn = search_but->arg_free_fn; + after->search_arg = search_but->arg; + search_but->arg_free_fn = NULL; + search_but->arg = NULL; } if (but->context) { @@ -1047,8 +1048,19 @@ static void ui_apply_but_TEX(bContext *C, uiBut *but, uiHandleButtonData *data) but->rename_orig = data->origstr; data->origstr = NULL; } + + void *orig_arg2 = but->func_arg2; + + /* If arg2 isn't in use already, pass the active search item through it. */ + if ((but->func_arg2 == NULL) && (but->type == UI_BTYPE_SEARCH_MENU)) { + uiButSearch *search_but = (uiButSearch *)but; + but->func_arg2 = search_but->item_active; + } + ui_apply_but_func(C, but); + but->func_arg2 = orig_arg2; + data->retval = but->retval; data->applied = true; } @@ -2087,6 +2099,7 @@ static void ui_apply_but( /* handle different types */ switch (but->type) { case UI_BTYPE_BUT: + case UI_BTYPE_DECORATOR: ui_apply_but_BUT(C, but, data); break; case UI_BTYPE_TEXT: @@ -2367,7 +2380,7 @@ static void ui_but_paste_numeric_value(bContext *C, { double value; - if (ui_but_string_set_eval_num(C, but, buf_paste, &value)) { + if (ui_but_string_eval_number(C, but, buf_paste, &value)) { button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); data->value = value; ui_but_string_set(C, but, buf_paste); @@ -3023,7 +3036,7 @@ static bool ui_textedit_insert_buf(uiBut *but, static bool ui_textedit_insert_ascii(uiBut *but, uiHandleButtonData *data, char ascii) { - char buf[2] = {ascii, '\0'}; + const char buf[2] = {ascii, '\0'}; if (UI_but_is_utf8(but) && (BLI_str_utf8_size(buf) == -1)) { printf( @@ -3321,7 +3334,9 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data) /* optional searchbox */ if (but->type == UI_BTYPE_SEARCH_MENU) { - data->searchbox = but->search->create_fn(C, data->region, but); + uiButSearch *search_but = (uiButSearch *)but; + + data->searchbox = search_but->popup_create_fn(C, data->region, search_but); ui_searchbox_update(C, data->searchbox, but, true); /* true = reset */ } @@ -4390,7 +4405,7 @@ static int ui_do_but_TEX( if (ELEM(event->type, EVT_PADENTER, EVT_RETKEY) && (!UI_but_is_utf8(but))) { /* pass - allow filesel, enter to execute */ } - else if (but->dt == UI_EMBOSS_NONE && !event->ctrl) { + else if (but->emboss == UI_EMBOSS_NONE && !event->ctrl) { /* pass */ } else { @@ -5698,21 +5713,24 @@ static bool ui_numedit_but_UNITVEC( return changed; } -static void ui_palette_set_active(uiBut *but) +static void ui_palette_set_active(uiButColor *color_but) { - if ((int)(but->a1) == UI_PALETTE_COLOR) { - Palette *palette = (Palette *)but->rnapoin.owner_id; - PaletteColor *color = but->rnapoin.data; + if (color_but->is_pallete_color) { + Palette *palette = (Palette *)color_but->but.rnapoin.owner_id; + PaletteColor *color = color_but->but.rnapoin.data; palette->active_color = BLI_findindex(&palette->colors, color); } } static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { + BLI_assert(but->type == UI_BTYPE_COLOR); + uiButColor *color_but = (uiButColor *)but; + if (data->state == BUTTON_STATE_HIGHLIGHT) { /* first handle click on icondrag type button */ if (event->type == LEFTMOUSE && but->dragpoin && event->val == KM_PRESS) { - ui_palette_set_active(but); + ui_palette_set_active(color_but); if (ui_but_contains_point_px_icon(but, data->region, event)) { button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG); data->dragstartx = event->x; @@ -5722,7 +5740,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co } #ifdef USE_DRAG_TOGGLE if (event->type == LEFTMOUSE && event->val == KM_PRESS) { - ui_palette_set_active(but); + ui_palette_set_active(color_but); button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG); data->dragstartx = event->x; data->dragstarty = event->y; @@ -5731,7 +5749,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co #endif /* regular open menu */ if (ELEM(event->type, LEFTMOUSE, EVT_PADENTER, EVT_RETKEY) && event->val == KM_PRESS) { - ui_palette_set_active(but); + ui_palette_set_active(color_but); button_activate_state(C, but, BUTTON_STATE_MENU_OPEN); return WM_UI_HANDLER_BREAK; } @@ -5762,8 +5780,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co ui_apply_but(C, but->block, but, data, true); return WM_UI_HANDLER_BREAK; } - if ((int)(but->a1) == UI_PALETTE_COLOR && event->type == EVT_DELKEY && - event->val == KM_PRESS) { + if (color_but->is_pallete_color && (event->type == EVT_DELKEY) && (event->val == KM_PRESS)) { Palette *palette = (Palette *)but->rnapoin.owner_id; PaletteColor *color = but->rnapoin.data; @@ -5794,7 +5811,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co } if (event->type == LEFTMOUSE && event->val == KM_RELEASE) { - if ((int)(but->a1) == UI_PALETTE_COLOR) { + if (color_but->is_pallete_color) { if (!event->ctrl) { float color[3]; Paint *paint = BKE_paint_get_active_from_context(C); @@ -6955,7 +6972,7 @@ static bool ui_numedit_but_CURVEPROFILE(uiBlock *block, fy *= mval_factor; /* Move all selected points. */ - float delta[2] = {fx, fy}; + const float delta[2] = {fx, fy}; for (a = 0; a < profile->path_len; a++) { /* Don't move the last and first control points. */ if ((pts[a].flag & PROF_SELECT) && (a != 0) && (a != profile->path_len)) { @@ -7129,7 +7146,7 @@ static int ui_do_but_CURVEPROFILE( dist_min_sq = square_f(U.dpi_fac * 8.0f); /* 8 pixel radius from each table point. */ /* Loop through the path's high resolution table and find what's near the click. */ - for (int i = 1; i <= PROF_N_TABLE(profile->path_len); i++) { + for (int i = 1; i <= PROF_TABLE_LEN(profile->path_len); i++) { copy_v2_v2(f_xy_prev, f_xy); BLI_rctf_transform_pt_v(&but->rect, &profile->view_rect, f_xy, &table[i].x); @@ -7522,6 +7539,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * switch (but->type) { case UI_BTYPE_BUT: + case UI_BTYPE_DECORATOR: retval = ui_do_but_BUT(C, but, data, event); break; case UI_BTYPE_KEY_EVENT: @@ -7597,13 +7615,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * retval = ui_do_but_BUT(C, but, data, event); break; case UI_BTYPE_COLOR: - if (but->a1 == -1) { - /* signal to prevent calling up color picker */ - retval = ui_do_but_EXIT(C, but, data, event); - } - else { - retval = ui_do_but_COLOR(C, but, data, event); - } + retval = ui_do_but_COLOR(C, but, data, event); break; case UI_BTYPE_UNITVEC: retval = ui_do_but_UNITVEC(C, block, but, data, event); @@ -8430,7 +8442,7 @@ void UI_context_update_anim_flag(const bContext *C) ui_but_anim_flag(but, &anim_eval_context); ui_but_override_flag(CTX_data_main(C), but); if (UI_but_is_decorator(but)) { - ui_but_anim_decorate_update_from_flag(but); + ui_but_anim_decorate_update_from_flag((uiButDecorator *)but); } ED_region_tag_redraw(region); diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 586f5e07997..a7b7bad2fe6 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -1517,18 +1517,8 @@ static void icon_draw_rect(float x, immUniform1f("factor", desaturate); } - immDrawPixelsTex(&state, - draw_x, - draw_y, - draw_w, - draw_h, - GL_RGBA, - GL_UNSIGNED_BYTE, - GL_NEAREST, - rect, - 1.0f, - 1.0f, - col); + immDrawPixelsTex( + &state, draw_x, draw_y, draw_w, draw_h, GPU_RGBA8, false, rect, 1.0f, 1.0f, col); if (ima) { IMB_freeImBuf(ima); diff --git a/source/blender/editors/interface/interface_icons_event.c b/source/blender/editors/interface/interface_icons_event.c index fed29571185..4be2dbc0b4e 100644 --- a/source/blender/editors/interface/interface_icons_event.c +++ b/source/blender/editors/interface/interface_icons_event.c @@ -143,7 +143,7 @@ void icon_draw_rect_input(float x, }; if ((event_type >= EVT_AKEY) && (event_type <= EVT_ZKEY)) { - char str[2] = {'A' + (event_type - EVT_AKEY), '\0'}; + const char str[2] = {'A' + (event_type - EVT_AKEY), '\0'}; icon_draw_rect_input_text(&rect, color, str, 13); } else if ((event_type >= EVT_F1KEY) && (event_type <= EVT_F12KEY)) { diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index ab5d8806837..41110883729 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -147,19 +147,11 @@ enum { /* max amount of items a radial menu (pie menu) can contain */ #define PIE_MAX_ITEMS 8 -struct uiButSearchData { - uiButSearchCreateFn create_fn; - uiButSearchUpdateFn update_fn; - void *arg; - uiButSearchArgFreeFn arg_free_fn; - uiButSearchContextMenuFn context_menu_fn; - uiButSearchTooltipFn tooltip_fn; - - const char *sep_string; -}; - struct uiBut { struct uiBut *next, *prev; + + /* Pointer back to the layout item holding this button. */ + uiLayout *layout; int flag, drawflag; eButType type; eButPointerType pointype; @@ -185,8 +177,6 @@ struct uiBut { * - UI_BTYPE_LABEL: Use `(a1 == 1.0f)` to use a2 as a blending factor (imaginative!). * - UI_BTYPE_SCROLL: Use as scroll size. * - UI_BTYPE_SEARCH_MENU: Use as number or rows. - * - UI_BTYPE_COLOR: Use as indication of color palette. - * - UI_BTYPE_PROGRESS_BAR: Use to store progress (0..1). */ float a1; @@ -196,7 +186,6 @@ struct uiBut { * - UI_BTYPE_NUM: Use to store RNA 'precision' value, for dragging and click-step. * - UI_BTYPE_LABEL: If `(a1 == 1.0f)` use a2 as a blending factor. * - UI_BTYPE_SEARCH_MENU: Use as number or columns. - * - UI_BTYPE_COLOR: Use as index in palette (not so good, needs refactor). */ float a2; @@ -214,8 +203,6 @@ struct uiBut { uiButCompleteFunc autocomplete_func; void *autofunc_arg; - struct uiButSearchData *search; - uiButHandleRenameFunc rename_func; void *rename_arg1; void *rename_orig; @@ -232,8 +219,8 @@ struct uiBut { const char *disabled_info; BIFIconID icon; - /** drawtype: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied from the block */ - char dt; + /** emboss: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied from the #uiBlock.emboss */ + char emboss; /** direction in a pie menu, used for collision detection (RadialDirection) */ signed char pie_dir; /** could be made into a single flag */ @@ -256,9 +243,6 @@ struct uiBut { struct PropertyRNA *rnaprop; int rnaindex; - struct PointerRNA rnasearchpoin; - struct PropertyRNA *rnasearchprop; - /* Operator data */ struct wmOperatorType *optype; struct PointerRNA *opptr; @@ -294,11 +278,56 @@ struct uiBut { uiBlock *block; }; +/** Derived struct for #UI_BTYPE_COLOR */ +typedef struct uiButColor { + uiBut but; + + bool is_pallete_color; + int palette_color_index; +} uiButColor; + +/** Derived struct for #UI_BTYPE_TAB */ typedef struct uiButTab { uiBut but; struct MenuType *menu; } uiButTab; +/** Derived struct for #UI_BTYPE_SEARCH_MENU */ +typedef struct uiButSearch { + uiBut but; + + uiButSearchCreateFn popup_create_fn; + uiButSearchUpdateFn items_update_fn; + void *item_active; + + void *arg; + uiButSearchArgFreeFn arg_free_fn; + + uiButSearchContextMenuFn item_context_menu_fn; + uiButSearchTooltipFn item_tooltip_fn; + + const char *item_sep_string; + + struct PointerRNA rnasearchpoin; + struct PropertyRNA *rnasearchprop; +} uiButSearch; + +/** Derived struct for #UI_BTYPE_DECORATOR */ +typedef struct uiButDecorator { + uiBut but; + + struct PointerRNA rnapoin; + struct PropertyRNA *rnaprop; + int rnaindex; +} uiButDecorator; + +typedef struct uiButProgressbar { + uiBut but; + + /* 0..1 range */ + float progress; +} uiButProgressbar; + /** * Additional, superimposed icon for a button, invoking an operator. */ @@ -404,8 +433,8 @@ struct uiBlock { char direction; /** UI_BLOCK_THEME_STYLE_* */ char theme_style; - /** drawtype: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied to buttons */ - char dt; + /** UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied to #uiBut.emboss */ + char emboss; bool auto_open; char _pad[5]; double auto_open_last; @@ -493,6 +522,8 @@ extern void ui_window_to_region_rcti(const struct ARegion *region, extern void ui_region_to_window(const struct ARegion *region, int *x, int *y); extern void ui_region_winrct_get_no_margin(const struct ARegion *region, struct rcti *r_rect); +uiBut *ui_but_change_type(uiBut *but, eButType new_type); + extern double ui_but_value_get(uiBut *but); extern void ui_but_value_set(uiBut *but, double value); extern void ui_but_hsv_set(uiBut *but); @@ -516,10 +547,10 @@ extern void ui_but_string_get(uiBut *but, char *str, const size_t maxlen) ATTR_N extern char *ui_but_string_get_dynamic(uiBut *but, int *r_str_size); extern void ui_but_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen) ATTR_NONNULL(); extern bool ui_but_string_set(struct bContext *C, uiBut *but, const char *str) ATTR_NONNULL(); -extern bool ui_but_string_set_eval_num(struct bContext *C, - uiBut *but, - const char *str, - double *value) ATTR_NONNULL(); +extern bool ui_but_string_eval_number(struct bContext *C, + const uiBut *but, + const char *str, + double *value) ATTR_NONNULL(); extern int ui_but_string_get_max_length(uiBut *but); /* Clear & exit the active button's string. */ extern void ui_but_active_string_clear_and_exit(struct bContext *C, uiBut *but) ATTR_NONNULL(); @@ -662,13 +693,13 @@ ColorPicker *ui_block_colorpicker_create(struct uiBlock *block); /* Searchbox for string button */ struct ARegion *ui_searchbox_create_generic(struct bContext *C, struct ARegion *butregion, - uiBut *but); + uiButSearch *search_but); struct ARegion *ui_searchbox_create_operator(struct bContext *C, struct ARegion *butregion, - uiBut *but); + uiButSearch *search_but); struct ARegion *ui_searchbox_create_menu(struct bContext *C, struct ARegion *butregion, - uiBut *but); + uiButSearch *search_but); bool ui_searchbox_inside(struct ARegion *region, int x, int y); int ui_searchbox_find_index(struct ARegion *region, const char *name); @@ -681,7 +712,7 @@ bool ui_searchbox_event(struct bContext *C, const struct wmEvent *event); bool ui_searchbox_apply(uiBut *but, struct ARegion *region); void ui_searchbox_free(struct bContext *C, struct ARegion *region); -void ui_but_search_refresh(uiBut *but); +void ui_but_search_refresh(uiButSearch *but); /* interface_region_menu_popup.c */ int ui_but_menu_step(uiBut *but, int step); @@ -925,11 +956,12 @@ void ui_resources_free(void); /* interface_layout.c */ void ui_layout_add_but(uiLayout *layout, uiBut *but); -void ui_but_add_search(uiBut *but, - PointerRNA *ptr, - PropertyRNA *prop, - PointerRNA *searchptr, - PropertyRNA *searchprop); +bool ui_layout_replace_but_ptr(uiLayout *layout, const void *old_but_ptr, uiBut *new_but); +uiBut *ui_but_add_search(uiBut *but, + PointerRNA *ptr, + PropertyRNA *prop, + PointerRNA *searchptr, + PropertyRNA *searchprop); void ui_layout_list_set_labels_active(uiLayout *layout); /* menu callback */ void ui_item_menutype_func(struct bContext *C, struct uiLayout *layout, void *arg_mt); @@ -950,7 +982,7 @@ bool ui_but_anim_expression_create(uiBut *but, const char *str); void ui_but_anim_autokey(struct bContext *C, uiBut *but, struct Scene *scene, float cfra); void ui_but_anim_decorate_cb(struct bContext *C, void *arg_but, void *arg_dummy); -void ui_but_anim_decorate_update_from_flag(uiBut *but); +void ui_but_anim_decorate_update_from_flag(uiButDecorator *but); /* interface_query.c */ bool ui_but_is_editable(const uiBut *but) ATTR_WARN_UNUSED_RESULT; diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index f1d1ef589a5..888cacb64eb 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -674,7 +674,7 @@ static void ui_item_array(uiLayout *layout, /* show checkboxes for rna on a non-emboss block (menu for eg) */ if (type == PROP_BOOLEAN && - ELEM(layout->root->block->dt, UI_EMBOSS_NONE, UI_EMBOSS_PULLDOWN)) { + ELEM(layout->root->block->emboss, UI_EMBOSS_NONE, UI_EMBOSS_PULLDOWN)) { boolarr = MEM_callocN(sizeof(bool) * len, __func__); RNA_property_boolean_get_array(ptr, prop, boolarr); } @@ -2278,7 +2278,7 @@ void uiItemFullR(uiLayout *layout, /* property with separate label */ else if (type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER) { but = ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h, flag); - ui_but_add_search(but, ptr, prop, NULL, NULL); + but = ui_but_add_search(but, ptr, prop, NULL, NULL); if (layout->redalert) { UI_but_flag_enable(but, UI_BUT_REDALERT); @@ -2333,7 +2333,7 @@ void uiItemFullR(uiLayout *layout, /* Mark non-embossed textfields inside a listbox. */ if (but && (block->flag & UI_BLOCK_LIST_ITEM) && (but->type == UI_BTYPE_TEXT) && - (but->dt & UI_EMBOSS_NONE)) { + (but->emboss & UI_EMBOSS_NONE)) { UI_but_flag_enable(but, UI_BUT_LIST_ITEM); } @@ -2651,7 +2651,10 @@ static void ui_rna_collection_search_arg_free_fn(void *ptr) MEM_freeN(ptr); } -void ui_but_add_search( +/** + * \note May reallocate \a but, so the possibly new address is returned. + */ +uiBut *ui_but_add_search( uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop) { StructRNA *ptype; @@ -2669,11 +2672,13 @@ void ui_but_add_search( /* turn button into search button */ if (searchprop) { uiRNACollectionSearch *coll_search = MEM_mallocN(sizeof(*coll_search), __func__); + uiButSearch *search_but; - but->type = UI_BTYPE_SEARCH_MENU; + but = ui_but_change_type(but, UI_BTYPE_SEARCH_MENU); + search_but = (uiButSearch *)but; + search_but->rnasearchpoin = *searchptr; + search_but->rnasearchprop = searchprop; but->hardmax = MAX2(but->hardmax, 256.0f); - but->rnasearchpoin = *searchptr; - but->rnasearchprop = searchprop; but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT; if (RNA_property_is_unlink(prop)) { but->flag |= UI_BUT_VALUE_CLEAR; @@ -2707,6 +2712,8 @@ void ui_but_add_search( * so other code might have already set but->type to search menu... */ but->flag |= UI_BUT_DISABLED; } + + return but; } void uiItemPointerR_prop(uiLayout *layout, @@ -2939,29 +2946,28 @@ void uiItemMContents(uiLayout *layout, const char *menuname) void uiItemDecoratorR_prop(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index) { uiBlock *block = layout->root->block; - uiBut *but = NULL; - uiLayout *col; + UI_block_layout_set_current(block, layout); col = uiLayoutColumn(layout, false); col->space = 0; col->emboss = UI_EMBOSS_NONE; if (ELEM(NULL, ptr, prop) || !RNA_property_animateable(ptr, prop)) { - but = uiDefIconBut(block, - UI_BTYPE_BUT, - 0, - ICON_BLANK1, - 0, - 0, - UI_UNIT_X, - UI_UNIT_Y, - NULL, - 0.0, - 0.0, - 0.0, - 0.0, - ""); + uiBut *but = uiDefIconBut(block, + UI_BTYPE_DECORATOR, + 0, + ICON_BLANK1, + 0, + 0, + UI_UNIT_X, + UI_UNIT_Y, + NULL, + 0.0, + 0.0, + 0.0, + 0.0, + ""); but->flag |= UI_BUT_DISABLED; return; } @@ -2971,27 +2977,28 @@ void uiItemDecoratorR_prop(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, /* Loop for the array-case, but only do in case of an expanded array. */ for (int i = 0; i < (is_expand ? RNA_property_array_length(ptr, prop) : 1); i++) { - but = uiDefIconBut(block, - UI_BTYPE_BUT, - 0, - ICON_DOT, - 0, - 0, - UI_UNIT_X, - UI_UNIT_Y, - NULL, - 0.0, - 0.0, - 0.0, - 0.0, - TIP_("Animate property")); - UI_but_func_set(but, ui_but_anim_decorate_cb, but, NULL); - but->flag |= UI_BUT_UNDO | UI_BUT_DRAG_LOCK; + uiButDecorator *decorator_but = (uiButDecorator *)uiDefIconBut(block, + UI_BTYPE_DECORATOR, + 0, + ICON_DOT, + 0, + 0, + UI_UNIT_X, + UI_UNIT_Y, + NULL, + 0.0, + 0.0, + 0.0, + 0.0, + TIP_("Animate property")); + + UI_but_func_set(&decorator_but->but, ui_but_anim_decorate_cb, decorator_but, NULL); + decorator_but->but.flag |= UI_BUT_UNDO | UI_BUT_DRAG_LOCK; /* Reusing RNA search members, setting actual RNA data has many side-effects. */ - but->rnasearchpoin = *ptr; - but->rnasearchprop = prop; + decorator_but->rnapoin = *ptr; + decorator_but->rnaprop = prop; /* ui_def_but_rna() sets non-array buttons to have a RNA index of 0. */ - but->custom_data = POINTER_FROM_INT((!is_array || is_expand) ? i : index); + decorator_but->rnaindex = (!is_array || is_expand) ? i : index; } } @@ -3831,7 +3838,7 @@ static void ui_litem_layout_radial(uiLayout *litem) bitem->but->rect.xmax += 1.5f * UI_UNIT_X; /* enable drawing as pie item if supported by widget */ if (ui_item_is_radial_drawable(bitem)) { - bitem->but->dt = UI_EMBOSS_RADIAL; + bitem->but->emboss = UI_EMBOSS_RADIAL; bitem->but->drawflag |= UI_BUT_ICON_LEFT; } } @@ -4819,8 +4826,6 @@ void ui_layout_list_set_labels_active(uiLayout *layout) uiLayout *uiLayoutListBox(uiLayout *layout, uiList *ui_list, - PointerRNA *ptr, - PropertyRNA *prop, PointerRNA *actptr, PropertyRNA *actprop) { @@ -4829,8 +4834,6 @@ uiLayout *uiLayoutListBox(uiLayout *layout, but->custom_data = ui_list; - but->rnasearchpoin = *ptr; - but->rnasearchprop = prop; but->rnapoin = *actptr; but->rnaprop = actprop; @@ -5039,7 +5042,7 @@ float uiLayoutGetUnitsY(uiLayout *layout) int uiLayoutGetEmboss(uiLayout *layout) { if (layout->emboss == UI_EMBOSS_UNDEFINED) { - return layout->root->block->dt; + return layout->root->block->emboss; } return layout->emboss; } @@ -5407,6 +5410,7 @@ void ui_layout_add_but(uiLayout *layout, uiBut *but) else { BLI_addtail(&layout->items, bitem); } + but->layout = layout; if (layout->context) { but->context = layout->context; @@ -5414,8 +5418,32 @@ void ui_layout_add_but(uiLayout *layout, uiBut *but) } if (layout->emboss != UI_EMBOSS_UNDEFINED) { - but->dt = layout->emboss; + but->emboss = layout->emboss; + } +} + +bool ui_layout_replace_but_ptr(uiLayout *layout, const void *old_but_ptr, uiBut *new_but) +{ + ListBase *child_list = layout->child_items_layout ? &layout->child_items_layout->items : + &layout->items; + + LISTBASE_FOREACH (uiItem *, item, child_list) { + if (item->type == ITEM_BUTTON) { + uiButtonItem *bitem = (uiButtonItem *)item; + + if (bitem->but == old_but_ptr) { + bitem->but = new_but; + return true; + } + } + else { + if (ui_layout_replace_but_ptr((uiLayout *)item, old_but_ptr, new_but)) { + return true; + } + } } + + return false; } void uiLayoutSetFixedSize(uiLayout *layout, bool fixed_size) diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 39c1b8bb909..5a49f3e70d0 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -1148,10 +1148,11 @@ static bool jump_to_target_button(bContext *C, bool poll) /* For string properties with prop_search, look up the search collection item. */ if (type == PROP_STRING) { const uiBut *but = UI_context_active_but_get(C); + const uiButSearch *search_but = (but->type == UI_BTYPE_SEARCH_MENU) ? (uiButSearch *)but : + NULL; - if (but->type == UI_BTYPE_SEARCH_MENU && but->search && - but->search->update_fn == ui_rna_collection_search_update_fn) { - uiRNACollectionSearch *coll_search = but->search->arg; + if (search_but && search_but->items_update_fn == ui_rna_collection_search_update_fn) { + uiRNACollectionSearch *coll_search = search_but->arg; char str_buf[MAXBONENAME]; char *str_ptr = RNA_property_string_get_alloc(&ptr, prop, str_buf, sizeof(str_buf), NULL); @@ -1807,7 +1808,7 @@ static void UI_OT_drop_color(wmOperatorType *ot) ot->flag = OPTYPE_INTERNAL; RNA_def_float_color(ot->srna, "color", 3, NULL, 0.0, FLT_MAX, "Color", "Source color", 0.0, 1.0); - RNA_def_boolean(ot->srna, "gamma", 0, "Gamma Corrected", "The source color is gamma corrected "); + RNA_def_boolean(ot->srna, "gamma", 0, "Gamma Corrected", "The source color is gamma corrected"); } /** \} */ diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c index 4634f4b95c9..edb5d51a392 100644 --- a/source/blender/editors/interface/interface_query.c +++ b/source/blender/editors/interface/interface_query.c @@ -90,7 +90,7 @@ bool ui_but_is_interactive(const uiBut *but, const bool labeledit) if (but->flag & UI_SCROLLED) { return false; } - if ((but->type == UI_BTYPE_TEXT) && (but->dt == UI_EMBOSS_NONE) && !labeledit) { + if ((but->type == UI_BTYPE_TEXT) && (but->emboss == UI_EMBOSS_NONE) && !labeledit) { return false; } if ((but->type == UI_BTYPE_LISTROW) && labeledit) { @@ -113,7 +113,7 @@ bool UI_but_is_utf8(const uiBut *but) #ifdef USE_UI_POPOVER_ONCE bool ui_but_is_popover_once_compat(const uiBut *but) { - return ((but->type == UI_BTYPE_BUT) || ui_but_is_toggle(but)); + return (ELEM(but->type, UI_BTYPE_BUT, UI_BTYPE_DECORATOR) || ui_but_is_toggle(but)); } #endif diff --git a/source/blender/editors/interface/interface_region_hud.c b/source/blender/editors/interface/interface_region_hud.c index 1f8af7b9e6e..1773a7b3057 100644 --- a/source/blender/editors/interface/interface_region_hud.c +++ b/source/blender/editors/interface/interface_region_hud.c @@ -367,7 +367,7 @@ void ED_area_type_hud_ensure(bContext *C, ScrArea *area) ED_area_update_region_sizes(wm, win, area); } - ED_region_floating_initialize(region); + ED_region_floating_init(region); ED_region_tag_redraw(region); /* Reset zoom level (not well supported). */ diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c index 2ad7e517c60..13c85952f52 100644 --- a/source/blender/editors/interface/interface_region_popup.c +++ b/source/blender/editors/interface/interface_region_popup.c @@ -759,7 +759,7 @@ uiBlock *ui_popup_block_refresh(bContext *C, ui_popup_block_scrolltest(block); /* adds subwindow */ - ED_region_floating_initialize(region); + ED_region_floating_init(region); /* get winmat now that we actually have the subwindow */ wmGetProjectionMatrix(block->winmat, ®ion->winrct); diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c index a9e87f4cc07..2010d89165e 100644 --- a/source/blender/editors/interface/interface_region_search.c +++ b/source/blender/editors/interface/interface_region_search.c @@ -302,8 +302,11 @@ bool ui_searchbox_inside(ARegion *region, int x, int y) bool ui_searchbox_apply(uiBut *but, ARegion *region) { uiSearchboxData *data = region->regiondata; + uiButSearch *search_but = (uiButSearch *)but; - but->func_arg2 = NULL; + BLI_assert(but->type == UI_BTYPE_SEARCH_MENU); + + search_but->item_active = NULL; if (data->active != -1) { const char *name = data->items.names[data->active] + @@ -316,7 +319,7 @@ bool ui_searchbox_apply(uiBut *but, ARegion *region) BLI_strncpy(but->editstr, name, name_sep ? (name_sep - name) + 1 : data->items.maxstrlen); - but->func_arg2 = data->items.pointers[data->active]; + search_but->item_active = data->items.pointers[data->active]; return true; } @@ -340,8 +343,13 @@ static struct ARegion *wm_searchbox_tooltip_init(struct bContext *C, LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { LISTBASE_FOREACH (uiBut *, but, &block->buttons) { - if (but->search && but->search->tooltip_fn) { - return but->search->tooltip_fn(C, region, but->search->arg, but->func_arg2); + if (but->type != UI_BTYPE_SEARCH_MENU) { + continue; + } + + uiButSearch *search_but = (uiButSearch *)but; + if (search_but->item_tooltip_fn) { + return search_but->item_tooltip_fn(C, region, search_but->arg, search_but->item_active); } } } @@ -352,10 +360,13 @@ bool ui_searchbox_event( bContext *C, ARegion *region, uiBut *but, ARegion *butregion, const wmEvent *event) { uiSearchboxData *data = region->regiondata; + uiButSearch *search_but = (uiButSearch *)but; int type = event->type, val = event->val; bool handled = false; bool tooltip_timer_started = false; + BLI_assert(but->type == UI_BTYPE_SEARCH_MENU); + if (type == MOUSEPAN) { ui_pan_to_scroll(event, &type, &val); } @@ -373,7 +384,7 @@ bool ui_searchbox_event( break; case RIGHTMOUSE: if (val) { - if (but->search->context_menu_fn) { + if (search_but->item_context_menu_fn) { if (data->active != -1) { /* Check the cursor is over the active element * (a little confusing if this isn't the case, although it does work). */ @@ -383,7 +394,7 @@ bool ui_searchbox_event( &rect, event->x - region->winrct.xmin, event->y - region->winrct.ymin)) { void *active = data->items.pointers[data->active]; - if (but->search->context_menu_fn(C, but->search->arg, active, event)) { + if (search_but->item_context_menu_fn(C, search_but->arg, active, event)) { handled = true; } } @@ -417,7 +428,7 @@ bool ui_searchbox_event( if (is_inside) { if (data->active != -1) { ScrArea *area = CTX_wm_area(C); - but->func_arg2 = data->items.pointers[data->active]; + search_but->item_active = data->items.pointers[data->active]; WM_tooltip_timer_init(C, CTX_wm_window(C), area, butregion, wm_searchbox_tooltip_init); tooltip_timer_started = true; } @@ -437,18 +448,24 @@ bool ui_searchbox_event( } /** Wrap #uiButSearchUpdateFn callback. */ -static void ui_searchbox_update_fn(bContext *C, uiBut *but, const char *str, uiSearchItems *items) +static void ui_searchbox_update_fn(bContext *C, + uiButSearch *search_but, + const char *str, + uiSearchItems *items) { wmWindow *win = CTX_wm_window(C); WM_tooltip_clear(C, win); - but->search->update_fn(C, but->search->arg, str, items); + search_but->items_update_fn(C, search_but->arg, str, items); } /* region is the search box itself */ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool reset) { + uiButSearch *search_but = (uiButSearch *)but; uiSearchboxData *data = region->regiondata; + BLI_assert(but->type == UI_BTYPE_SEARCH_MENU); + /* reset vars */ data->items.totitem = 0; data->items.more = 0; @@ -460,9 +477,9 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re data->active = -1; /* handle active */ - if (but->search->update_fn && but->func_arg2) { - data->items.active = but->func_arg2; - ui_searchbox_update_fn(C, but, but->editstr, &data->items); + if (search_but->items_update_fn && search_but->item_active) { + data->items.active = search_but->item_active; + ui_searchbox_update_fn(C, search_but, but->editstr, &data->items); data->items.active = NULL; /* found active item, calculate real offset by centering it */ @@ -491,8 +508,8 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re } /* callback */ - if (but->search->update_fn) { - ui_searchbox_update_fn(C, but, but->editstr, &data->items); + if (search_but->items_update_fn) { + ui_searchbox_update_fn(C, search_but, but->editstr, &data->items); } /* handle case where editstr is equal to one of items */ @@ -523,13 +540,16 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re int ui_searchbox_autocomplete(bContext *C, ARegion *region, uiBut *but, char *str) { + uiButSearch *search_but = (uiButSearch *)but; uiSearchboxData *data = region->regiondata; int match = AUTOCOMPLETE_NO_MATCH; + BLI_assert(but->type == UI_BTYPE_SEARCH_MENU); + if (str[0]) { data->items.autocpl = UI_autocomplete_begin(str, ui_but_string_get_max_length(but)); - ui_searchbox_update_fn(C, but, but->editstr, &data->items); + ui_searchbox_update_fn(C, search_but, but->editstr, &data->items); match = UI_autocomplete_end(data->items.autocpl, str); data->items.autocpl = NULL; @@ -673,10 +693,11 @@ static void ui_searchbox_region_free_cb(ARegion *region) region->regiondata = NULL; } -ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiBut *but) +ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiButSearch *search_but) { wmWindow *win = CTX_wm_window(C); const uiStyle *style = UI_style_get(); + uiBut *but = &search_but->but; static ARegionType type; ARegion *region; uiSearchboxData *data; @@ -725,7 +746,7 @@ ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiBut *but if (but->optype != NULL || (but->drawflag & UI_BUT_HAS_SHORTCUT) != 0) { data->use_sep = true; } - data->sep_string = but->search->sep_string; + data->sep_string = search_but->item_sep_string; /* compute position */ if (but->block->flag & UI_BLOCK_SEARCH_MENU) { @@ -819,7 +840,7 @@ ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiBut *but } /* adds subwindow */ - ED_region_floating_initialize(region); + ED_region_floating_init(region); /* notify change and redraw */ ED_region_tag_redraw(region); @@ -945,12 +966,12 @@ static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARe } } -ARegion *ui_searchbox_create_operator(bContext *C, ARegion *butregion, uiBut *but) +ARegion *ui_searchbox_create_operator(bContext *C, ARegion *butregion, uiButSearch *search_but) { ARegion *region; - UI_but_drawflag_enable(but, UI_BUT_HAS_SHORTCUT); - region = ui_searchbox_create_generic(C, butregion, but); + UI_but_drawflag_enable(&search_but->but, UI_BUT_HAS_SHORTCUT); + region = ui_searchbox_create_generic(C, butregion, search_but); region->type->draw = ui_searchbox_region_draw_cb__operator; @@ -967,12 +988,12 @@ static void ui_searchbox_region_draw_cb__menu(const bContext *UNUSED(C), ARegion /* Currently unused. */ } -ARegion *ui_searchbox_create_menu(bContext *C, ARegion *butregion, uiBut *but) +ARegion *ui_searchbox_create_menu(bContext *C, ARegion *butregion, uiButSearch *search_but) { ARegion *region; - UI_but_drawflag_enable(but, UI_BUT_HAS_SHORTCUT); - region = ui_searchbox_create_generic(C, butregion, but); + UI_but_drawflag_enable(&search_but->but, UI_BUT_HAS_SHORTCUT); + region = ui_searchbox_create_generic(C, butregion, search_but); if (false) { region->type->draw = ui_searchbox_region_draw_cb__menu; @@ -983,8 +1004,9 @@ ARegion *ui_searchbox_create_menu(bContext *C, ARegion *butregion, uiBut *but) /* sets red alert if button holds a string it can't find */ /* XXX weak: search_func adds all partial matches... */ -void ui_but_search_refresh(uiBut *but) +void ui_but_search_refresh(uiButSearch *search_but) { + uiBut *but = &search_but->but; uiSearchItems *items; int x1; @@ -1004,7 +1026,7 @@ void ui_but_search_refresh(uiBut *but) items->names[x1] = MEM_callocN(but->hardmax + 1, "search names"); } - ui_searchbox_update_fn(but->block->evil_C, but, but->drawstr, items); + ui_searchbox_update_fn(but->block->evil_C, search_but, but->drawstr, items); /* only redalert when we are sure of it, this can miss cases when >10 matches */ if (items->totitem == 0) { diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c index 46814e11b9e..41b41cb3d75 100644 --- a/source/blender/editors/interface/interface_region_tooltip.c +++ b/source/blender/editors/interface/interface_region_tooltip.c @@ -433,7 +433,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is if (has_valid_context == false) { expr_result = BLI_strdup(has_valid_context_error); } - else if (BPY_execute_string_as_string(C, expr_imports, expr, true, &expr_result)) { + else if (BPY_execute_string_as_string(C, expr_imports, expr, __func__, &expr_result)) { if (STREQ(expr_result, "")) { MEM_freeN(expr_result); expr_result = NULL; @@ -490,7 +490,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is if (has_valid_context == false) { expr_result = BLI_strdup(has_valid_context_error); } - else if (BPY_execute_string_as_string(C, expr_imports, expr, true, &expr_result)) { + else if (BPY_execute_string_as_string(C, expr_imports, expr, __func__, &expr_result)) { if (STREQ(expr_result, ".")) { MEM_freeN(expr_result); expr_result = NULL; @@ -594,7 +594,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is if (has_valid_context == false) { shortcut = BLI_strdup(has_valid_context_error); } - else if (BPY_execute_string_as_intptr(C, expr_imports, expr, true, &expr_result)) { + else if (BPY_execute_string_as_intptr(C, expr_imports, expr, __func__, &expr_result)) { if (expr_result != 0) { wmKeyMap *keymap = (wmKeyMap *)expr_result; LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) { @@ -659,7 +659,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is /* pass */ } else if (BPY_execute_string_as_string_and_size( - C, expr_imports, expr, true, &expr_result, &expr_result_len)) { + C, expr_imports, expr, __func__, &expr_result, &expr_result_len)) { /* pass. */ } } @@ -736,7 +736,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is if (has_valid_context == false) { /* pass */ } - else if (BPY_execute_string_as_intptr(C, expr_imports, expr, true, &expr_result)) { + else if (BPY_execute_string_as_intptr(C, expr_imports, expr, __func__, &expr_result)) { if (expr_result != 0) { { uiTooltipField *field = text_field_add(data, @@ -1386,7 +1386,7 @@ static ARegion *ui_tooltip_create_with_data(bContext *C, } /* adds subwindow */ - ED_region_floating_initialize(region); + ED_region_floating_init(region); /* notify change and redraw */ ED_region_tag_redraw(region); diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index 64070725f2b..5310ff0e3ec 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -334,7 +334,7 @@ void UI_fontstyle_draw_simple_backdrop(const uiFontStyle *fs, const float margin = height / 4.0f; /* backdrop */ - float color[4] = {col_bg[0], col_bg[1], col_bg[2], 0.5f}; + const float color[4] = {col_bg[0], col_bg[1], col_bg[2], 0.5f}; UI_draw_roundbox_corner_set(UI_CNR_ALL); UI_draw_roundbox_aa(true, diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index d3487b635ce..c7d3d7bf501 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -5512,22 +5512,24 @@ void uiTemplatePalette(uiLayout *layout, } RNA_pointer_create(&palette->id, &RNA_PaletteColor, color, &color_ptr); - uiDefButR(block, - UI_BTYPE_COLOR, - 0, - "", - 0, - 0, - UI_UNIT_X, - UI_UNIT_Y, - &color_ptr, - "color", - -1, - 0.0, - 1.0, - UI_PALETTE_COLOR, - col_id, - ""); + uiButColor *color_but = (uiButColor *)uiDefButR(block, + UI_BTYPE_COLOR, + 0, + "", + 0, + 0, + UI_UNIT_X, + UI_UNIT_Y, + &color_ptr, + "color", + -1, + 0.0, + 1.0, + 0.0, + 0.0, + ""); + color_but->is_pallete_color = true; + color_but->palette_color_index = col_id; row_cols++; col_id++; } @@ -6210,7 +6212,7 @@ void uiTemplateList(uiLayout *layout, switch (layout_type) { case UILST_LAYOUT_DEFAULT: /* layout */ - box = uiLayoutListBox(layout, ui_list, dataptr, prop, active_dataptr, activeprop); + box = uiLayoutListBox(layout, ui_list, active_dataptr, activeprop); glob = uiLayoutColumn(box, true); row = uiLayoutRow(glob, false); col = uiLayoutColumn(row, true); @@ -6348,7 +6350,7 @@ void uiTemplateList(uiLayout *layout, } break; case UILST_LAYOUT_GRID: - box = uiLayoutListBox(layout, ui_list, dataptr, prop, active_dataptr, activeprop); + box = uiLayoutListBox(layout, ui_list, active_dataptr, activeprop); glob = uiLayoutColumn(box, true); row = uiLayoutRow(glob, false); col = uiLayoutColumn(row, true); @@ -6789,22 +6791,24 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C) struct ProgressTooltip_Store *tip_arg = MEM_mallocN(sizeof(*tip_arg), __func__); tip_arg->wm = wm; tip_arg->owner = owner; - uiBut *but_progress = uiDefIconTextBut(block, - UI_BTYPE_PROGRESS_BAR, - 0, - 0, - text, - UI_UNIT_X, - 0, - UI_UNIT_X * 6.0f, - UI_UNIT_Y, - NULL, - 0.0f, - 0.0f, - progress, - 0, - NULL); - UI_but_func_tooltip_set(but_progress, progress_tooltip_func, tip_arg); + uiButProgressbar *but_progress = (uiButProgressbar *)uiDefIconTextBut(block, + UI_BTYPE_PROGRESS_BAR, + 0, + 0, + text, + UI_UNIT_X, + 0, + UI_UNIT_X * 6.0f, + UI_UNIT_Y, + NULL, + 0.0f, + 0.0f, + 0.0f, + 0, + NULL); + + but_progress->progress = progress; + UI_but_func_tooltip_set(&but_progress->but, progress_tooltip_func, tip_arg); } if (!wm->is_interface_locked) { @@ -7348,6 +7352,9 @@ void uiTemplateCacheFile(uiLayout *layout, uiItemR(row, &fileptr, "scale", 0, IFACE_("Manual Scale"), ICON_NONE); } + uiItemR(layout, &fileptr, "velocity_name", 0, NULL, ICON_NONE); + uiItemR(layout, &fileptr, "velocity_unit", 0, NULL, ICON_NONE); + /* TODO: unused for now, so no need to expose. */ #if 0 row = uiLayoutRow(layout, false); diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index 208fd7136da..4a1c7be918e 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -148,7 +148,7 @@ uiBut *uiDefAutoButR(uiBlock *block, if (RNA_property_array_check(prop) && index == -1) { if (ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA)) { but = uiDefButR_prop( - block, UI_BTYPE_COLOR, 0, name, x1, y1, x2, y2, ptr, prop, -1, 0, 0, -1, -1, NULL); + block, UI_BTYPE_COLOR, 0, name, x1, y1, x2, y2, ptr, prop, -1, 0, 0, 0, 0, NULL); } else { return NULL; diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 9ba1a2c73f4..7c33c5e7048 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -518,7 +518,7 @@ GPUBatch *ui_batch_roundbox_shadow_get(void) void UI_draw_anti_tria( float x1, float y1, float x2, float y2, float x3, float y3, const float color[4]) { - float tri_arr[3][2] = {{x1, y1}, {x2, y2}, {x3, y3}}; + const float tri_arr[3][2] = {{x1, y1}, {x2, y2}, {x3, y3}}; float draw_color[4]; copy_v4_v4(draw_color, color); @@ -1356,7 +1356,7 @@ static void widget_draw_preview(BIFIconID icon, float alpha, const rcti *rect) static int ui_but_draw_menu_icon(const uiBut *but) { - return (but->flag & UI_BUT_ICON_SUBMENU) && (but->dt == UI_EMBOSS_PULLDOWN); + return (but->flag & UI_BUT_ICON_SUBMENU) && (but->emboss == UI_EMBOSS_PULLDOWN); } /* icons have been standardized... and this call draws in untransformed coordinates */ @@ -1400,7 +1400,7 @@ static void widget_draw_icon( alpha *= but->a2; } } - else if (ELEM(but->type, UI_BTYPE_BUT)) { + else if (ELEM(but->type, UI_BTYPE_BUT, UI_BTYPE_DECORATOR)) { if (but->flag & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) { alpha *= 0.5f; } @@ -1417,7 +1417,7 @@ static void widget_draw_icon( but->str && but->str[0] == '\0') { xs = rect->xmin + 2.0f * ofs; } - else if (but->dt == UI_EMBOSS_NONE || but->type == UI_BTYPE_LABEL) { + else if (but->emboss == UI_EMBOSS_NONE || but->type == UI_BTYPE_LABEL) { xs = rect->xmin + 2.0f * ofs; } else { @@ -2375,7 +2375,7 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle, /* pass (even if its a menu toolbar) */ } else if (ui_block_is_pie_menu(but->block)) { - if (but->dt == UI_EMBOSS_RADIAL) { + if (but->emboss == UI_EMBOSS_RADIAL) { rect->xmin += 0.3f * U.widget_unit; } } @@ -2568,7 +2568,7 @@ static void widget_state(uiWidgetType *wt, int state, int drawflag) } if (state & UI_BUT_REDALERT) { - uchar red[4] = {255, 0, 0}; + const uchar red[4] = {255, 0, 0}; if (wt->draw) { color_blend_v3_v3(wt->wcol.inner, red, 0.4f); } @@ -2585,7 +2585,7 @@ static void widget_state(uiWidgetType *wt, int state, int drawflag) } if (state & UI_BUT_NODE_ACTIVE) { - uchar blue[4] = {86, 128, 194}; + const uchar blue[4] = {86, 128, 194}; color_blend_v3_v3(wt->wcol.inner, blue, 0.3f); } } @@ -3609,6 +3609,7 @@ static void widget_scroll( static void widget_progressbar( uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) { + uiButProgressbar *but_progressbar = (uiButProgressbar *)but; uiWidgetBase wtb, wtb_bar; rcti rect_prog = *rect, rect_bar = *rect; @@ -3616,7 +3617,7 @@ static void widget_progressbar( widget_init(&wtb_bar); /* round corners */ - float value = but->a1; + float value = but_progressbar->progress; float offs = wcol->roundness * BLI_rcti_size_y(&rect_prog); float w = value * BLI_rcti_size_x(&rect_prog); @@ -3768,6 +3769,8 @@ static void widget_numslider( static void widget_swatch( uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign) { + BLI_assert(but->type == UI_BTYPE_COLOR); + uiButColor *color_but = (uiButColor *)but; uiWidgetBase wtb; float rad, col[4]; @@ -3822,8 +3825,8 @@ static void widget_swatch( } widgetbase_draw_ex(&wtb, wcol, show_alpha_checkers); - if (but->a1 == UI_PALETTE_COLOR && - ((Palette *)but->rnapoin.owner_id)->active_color == (int)but->a2) { + if (color_but->is_pallete_color && + ((Palette *)but->rnapoin.owner_id)->active_color == color_but->palette_color_index) { float width = rect->xmax - rect->xmin; float height = rect->ymax - rect->ymin; /* find color luminance and change it slightly */ @@ -4071,7 +4074,7 @@ static void widget_state_label(uiWidgetType *wt, int state, int drawflag) } if (state & UI_BUT_REDALERT) { - uchar red[4] = {255, 0, 0}; + const uchar red[4] = {255, 0, 0}; color_blend_v3_v3(wt->wcol.text, red, 0.4f); } } @@ -4502,7 +4505,7 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu uiWidgetType *wt = NULL; /* handle menus separately */ - if (but->dt == UI_EMBOSS_PULLDOWN) { + if (but->emboss == UI_EMBOSS_PULLDOWN) { switch (but->type) { case UI_BTYPE_LABEL: widget_draw_text_icon(&style->widgetlabel, &tui->wcol_menu_back, but, rect); @@ -4515,7 +4518,7 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu break; } } - else if (but->dt == UI_EMBOSS_NONE) { + else if (but->emboss == UI_EMBOSS_NONE) { /* "nothing" */ switch (but->type) { case UI_BTYPE_LABEL: @@ -4526,11 +4529,11 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu break; } } - else if (but->dt == UI_EMBOSS_RADIAL) { + else if (but->emboss == UI_EMBOSS_RADIAL) { wt = widget_type(UI_WTYPE_MENU_ITEM_RADIAL); } else { - BLI_assert(but->dt == UI_EMBOSS); + BLI_assert(but->emboss == UI_EMBOSS); switch (but->type) { case UI_BTYPE_LABEL: @@ -4552,6 +4555,7 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu break; case UI_BTYPE_BUT: + case UI_BTYPE_DECORATOR: #ifdef USE_UI_TOOLBAR_HACK if ((but->icon != ICON_NONE) && UI_but_is_tool(but)) { wt = widget_type(UI_WTYPE_TOOLBAR_ITEM); @@ -4779,7 +4783,7 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu } if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) { - if (but->dt != UI_EMBOSS_PULLDOWN) { + if (but->emboss != UI_EMBOSS_PULLDOWN) { disabled = true; } } diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index 0cbf73280a3..3efed43e08c 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -242,7 +242,7 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy) bool tot_changed = false, do_init; const uiStyle *style = UI_style_get(); - do_init = (v2d->flag & V2D_IS_INITIALISED) == 0; + do_init = (v2d->flag & V2D_IS_INIT) == 0; /* see eView2D_CommonViewTypes in UI_view2d.h for available view presets */ switch (type) { @@ -374,8 +374,8 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy) break; } - /* set initialized flag so that View2D doesn't get reinitialised next time again */ - v2d->flag |= V2D_IS_INITIALISED; + /* set initialized flag so that View2D doesn't get reinitialized next time again */ + v2d->flag |= V2D_IS_INIT; /* store view size */ v2d->winx = winx; diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 64cacd44e3d..d62058699d9 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -56,7 +56,7 @@ static bool view2d_poll(bContext *C) { ARegion *region = CTX_wm_region(C); - return (region != NULL) && (region->v2d.flag & V2D_IS_INITIALISED); + return (region != NULL) && (region->v2d.flag & V2D_IS_INIT); } /** \} */ diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index 3786ed2789c..c617c921d70 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -735,7 +735,7 @@ void ED_mask_draw_region( } if (draw_flag & MASK_DRAWFLAG_OVERLAY) { - float red[4] = {1.0f, 0.0f, 0.0f, 0.0f}; + const float red[4] = {1.0f, 0.0f, 0.0f, 0.0f}; float *buffer = mask_rasterize(mask_eval, width, height); if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) { @@ -753,8 +753,7 @@ void ED_mask_draw_region( IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR); GPU_shader_uniform_vector( state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red); - immDrawPixelsTex( - &state, 0.0f, 0.0f, width, height, GL_RED, GL_FLOAT, GL_NEAREST, buffer, 1.0f, 1.0f, NULL); + immDrawPixelsTex(&state, 0.0f, 0.0f, width, height, GL_R16F, false, buffer, 1.0f, 1.0f, NULL); GPU_matrix_pop(); diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index 61b40dd3e60..dd4b8146154 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -1158,12 +1158,12 @@ void MESH_OT_bevel(wmOperatorType *ot) PROFILE_HARD_MIN, 1.0f); - prop = RNA_def_enum(ot->srna, - "affect", - prop_affect_items, - BEVEL_AFFECT_EDGES, - "Affect", - "Affect Edges or Vertices"); + RNA_def_enum(ot->srna, + "affect", + prop_affect_items, + BEVEL_AFFECT_EDGES, + "Affect", + "Affect Edges or Vertices"); RNA_def_boolean(ot->srna, "clamp_overlap", diff --git a/source/blender/editors/mesh/editmesh_extrude_spin.c b/source/blender/editors/mesh/editmesh_extrude_spin.c index 9f1d499bb6a..6dde45a4f5f 100644 --- a/source/blender/editors/mesh/editmesh_extrude_spin.c +++ b/source/blender/editors/mesh/editmesh_extrude_spin.c @@ -57,7 +57,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op) { ViewLayer *view_layer = CTX_data_view_layer(C); float cent[3], axis[3]; - float d[3] = {0.0f, 0.0f, 0.0f}; + const float d[3] = {0.0f, 0.0f, 0.0f}; RNA_float_get_array(op->ptr, "center", cent); RNA_float_get_array(op->ptr, "axis", axis); diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 347f6806d13..6f4f75e802a 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1628,9 +1628,9 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd) plane_from_point_normal_v3(plane, v1, plane); } - /* First use bvh tree to find faces, knife edges, and knife verts that might + /* First use BVH tree to find faces, knife edges, and knife verts that might * intersect the cut plane with rays v1-v3 and v2-v4. - * This deduplicates the candidates before doing more expensive intersection tests. */ + * This de-duplicates the candidates before doing more expensive intersection tests. */ tree = BKE_bmbvh_tree_get(kcd->bmbvh); results = BLI_bvhtree_intersect_plane(tree, plane, &tot); @@ -2632,7 +2632,7 @@ static void knifetool_update_mval(KnifeTool_OpData *kcd, const float mval[2]) static void knifetool_update_mval_i(KnifeTool_OpData *kcd, const int mval_i[2]) { - float mval[2] = {UNPACK2(mval_i)}; + const float mval[2] = {UNPACK2(mval_i)}; knifetool_update_mval(kcd, mval); } diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c index ed22d381a02..ef78d31a6bb 100644 --- a/source/blender/editors/mesh/editmesh_knife_project.c +++ b/source/blender/editors/mesh/editmesh_knife_project.c @@ -164,7 +164,7 @@ void MESH_OT_knife_project(wmOperatorType *ot) /* description */ ot->name = "Knife Project"; ot->idname = "MESH_OT_knife_project"; - ot->description = "Use other objects outlines & boundaries to project knife cuts"; + ot->description = "Use other objects outlines and boundaries to project knife cuts"; /* callbacks */ ot->exec = knifeproject_exec; diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 89a90dcf12d..62c646a81e4 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -343,8 +343,11 @@ static BMVert *edbm_ripsel_edloop_pair_start_vert(BMEdge *e) return (edbm_ripsel_edge_uid_step(e, &v_test)) ? e->v1 : e->v2; } -static void edbm_ripsel_deselect_helper( - BMesh *bm, EdgeLoopPair *eloop_pairs, ARegion *region, float projectMat[4][4], float fmval[2]) +static void edbm_ripsel_deselect_helper(BMesh *bm, + EdgeLoopPair *eloop_pairs, + ARegion *region, + float projectMat[4][4], + const float fmval[2]) { EdgeLoopPair *lp; diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 1ea25353598..d2e9b57e950 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -205,7 +205,7 @@ static BMElem *edbm_select_id_bm_elem_get(Base **bases, const uint sel_id, uint /* -------------------------------------------------------------------- */ /** \name Find Nearest Vert/Edge/Face * - * \note Screen-space manhatten distances are used here, + * \note Screen-space manhattan distances are used here, * since its faster and good enough for the purpose of selection. * * \note \a dist_bias is used so we can bias against selected items. @@ -415,7 +415,7 @@ struct NearestEdgeUserData_Hit { int index; BMEdge *edge; - /* edges only, un-biased manhatten distance to which ever edge we pick + /* edges only, un-biased manhattan distance to which ever edge we pick * (not used for choosing) */ float dist_center; }; diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 4de7143682a..29860de88f1 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -7219,7 +7219,7 @@ void MESH_OT_wireframe(wmOperatorType *ot) PropertyRNA *prop; /* identifiers */ - ot->name = "Wire Frame"; + ot->name = "Wireframe"; ot->idname = "MESH_OT_wireframe"; ot->description = "Create a solid wire-frame from faces"; diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 9c364d41e24..81b8cd70353 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -205,7 +205,7 @@ void ED_object_rotation_from_quat(float rot[3], const float viewquat[4], const c switch (align_axis) { case 'X': { /* Same as 'rv3d->viewinv[1]' */ - float axis_y[4] = {0.0f, 1.0f, 0.0f}; + const float axis_y[4] = {0.0f, 1.0f, 0.0f}; float quat_y[4], quat[4]; axis_angle_to_quat(quat_y, axis_y, M_PI_2); mul_qt_qtqt(quat, viewquat, quat_y); @@ -692,6 +692,46 @@ void OBJECT_OT_lightprobe_add(wmOperatorType *ot) * \{ */ /* for object add operator */ + +static const char *get_effector_defname(ePFieldType type) +{ + switch (type) { + case PFIELD_FORCE: + return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Force"); + case PFIELD_VORTEX: + return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Vortex"); + case PFIELD_MAGNET: + return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Magnet"); + case PFIELD_WIND: + return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Wind"); + case PFIELD_GUIDE: + return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "CurveGuide"); + case PFIELD_TEXTURE: + return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "TextureField"); + case PFIELD_HARMONIC: + return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Harmonic"); + case PFIELD_CHARGE: + return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Charge"); + case PFIELD_LENNARDJ: + return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Lennard-Jones"); + case PFIELD_BOID: + return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Boid"); + case PFIELD_TURBULENCE: + return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Turbulence"); + case PFIELD_DRAG: + return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Drag"); + case PFIELD_FLUIDFLOW: + return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "FluidField"); + case PFIELD_NULL: + return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Field"); + case NUM_PFIELD_TYPES: + break; + } + + BLI_assert(false); + return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Field"); +} + static int effector_add_exec(bContext *C, wmOperator *op) { Object *ob; @@ -712,8 +752,8 @@ static int effector_add_exec(bContext *C, wmOperator *op) if (type == PFIELD_GUIDE) { Curve *cu; - const char *name = CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "CurveGuide"); - ob = ED_object_add_type(C, OB_CURVE, name, loc, rot, false, local_view_bits); + ob = ED_object_add_type( + C, OB_CURVE, get_effector_defname(type), loc, rot, false, local_view_bits); cu = ob->data; cu->flag |= CU_PATH | CU_3D; @@ -726,8 +766,8 @@ static int effector_add_exec(bContext *C, wmOperator *op) } } else { - const char *name = CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Field"); - ob = ED_object_add_type(C, OB_EMPTY, name, loc, rot, false, local_view_bits); + ob = ED_object_add_type( + C, OB_EMPTY, get_effector_defname(type), loc, rot, false, local_view_bits); BKE_object_obdata_size_init(ob, dia); if (ELEM(type, PFIELD_WIND, PFIELD_VORTEX)) { ob->empty_drawtype = OB_SINGLE_ARROW; @@ -1237,7 +1277,7 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op) break; } - /* if this is a new object, initialise default stuff (colors, etc.) */ + /* If this is a new object, initialize default stuff (colors, etc.) */ if (newob) { /* set default viewport color to black */ copy_v3_fl(ob->color, 0.0f); diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index baa24ab2f4e..ae1aae27b7f 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -60,8 +60,6 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -#include "GPU_draw.h" /* GPU_free_image */ - #include "WM_api.h" #include "WM_types.h" @@ -530,7 +528,7 @@ static void multiresbake_freejob(void *bkv) /* delete here, since this delete will be called from main thread */ for (link = data->images.first; link; link = link->next) { Image *ima = (Image *)link->data; - GPU_free_image(ima); + BKE_image_free_gputextures(ima); } MEM_freeN(data->ob_image.array); diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index c4cb21a67f3..cb92fab3cb0 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -68,8 +68,6 @@ #include "ED_screen.h" #include "ED_uvedit.h" -#include "GPU_draw.h" - #include "object_intern.h" /* prototypes */ @@ -308,7 +306,7 @@ static void refresh_images(BakeImages *bake_images) Image *ima = bake_images->data[i].image; LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { if (tile->ok == IMA_OK_LOADED) { - GPU_free_image(ima); + BKE_image_free_gputextures(ima); DEG_id_tag_update(&ima->id, 0); break; } @@ -675,7 +673,7 @@ static void build_image_lookup(Main *bmain, Object *ob, BakeImages *bake_images) /* * returns the total number of pixels */ -static size_t initialize_internal_images(BakeImages *bake_images, ReportList *reports) +static size_t init_internal_images(BakeImages *bake_images, ReportList *reports) { int i; size_t tot_size = 0; @@ -830,7 +828,7 @@ static int bake(Render *re, build_image_lookup(bmain, ob_low, &bake_images); if (is_save_internal) { - num_pixels = initialize_internal_images(&bake_images, reports); + num_pixels = init_internal_images(&bake_images, reports); if (num_pixels == 0) { goto cleanup; diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index e93bd8bd94e..8d6d2e3e31d 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -345,7 +345,8 @@ static bool object_modifier_remove( object_remove_particle_system(bmain, scene, ob); return true; } - else if (md->type == eModifierType_Softbody) { + + if (md->type == eModifierType_Softbody) { if (ob->soft) { sbFree(ob); ob->softflag = 0; /* TODO(Sybren): this should probably be moved into sbFree() */ @@ -888,12 +889,11 @@ int ED_object_modifier_copy( BLI_insertlinkafter(&ob->modifiers, md, nmd); return true; } - else { - nmd = BKE_modifier_new(md->type); - BKE_modifier_copydata(md, nmd); - BLI_insertlinkafter(&ob->modifiers, md, nmd); - BKE_modifier_unique_name(&ob->modifiers, nmd); - } + + nmd = BKE_modifier_new(md->type); + BKE_modifier_copydata(md, nmd); + BLI_insertlinkafter(&ob->modifiers, md, nmd); + BKE_modifier_unique_name(&ob->modifiers, nmd); return 1; } @@ -1458,9 +1458,7 @@ static int modifier_apply_as_shapekey_invoke(bContext *C, wmOperator *op, const if (edit_modifier_invoke_properties(C, op, event, &retval)) { return modifier_apply_as_shapekey_exec(C, op); } - else { - return retval; - } + return retval; } static char *modifier_apply_as_shapekey_get_description(struct bContext *UNUSED(C), @@ -2813,7 +2811,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op) /* make a copy of ocean to use for baking - threadsafety */ ocean = BKE_ocean_add(); - BKE_ocean_init_from_modifier(ocean, omd); + BKE_ocean_init_from_modifier(ocean, omd, omd->resolution); #if 0 BKE_ocean_bake(ocean, och); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 9520b03f3a6..f4de8f712c8 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2283,7 +2283,8 @@ static int make_override_library_invoke(bContext *C, wmOperator *op, const wmEve /* This invoke just calls another instance of this operator... */ return OPERATOR_INTERFACE; } - else if (ID_IS_LINKED(obact)) { + + if (ID_IS_LINKED(obact)) { /* Show menu with list of directly linked collections containing the active object. */ WM_enum_search_invoke(C, op, event); return OPERATOR_CANCELLED; diff --git a/source/blender/editors/object/object_remesh.c b/source/blender/editors/object/object_remesh.c index 8981851394d..8d8f01dd61a 100644 --- a/source/blender/editors/object/object_remesh.c +++ b/source/blender/editors/object/object_remesh.c @@ -72,7 +72,6 @@ #include "RNA_define.h" #include "RNA_enum_types.h" -#include "GPU_draw.h" #include "GPU_immediate.h" #include "GPU_immediate_util.h" #include "GPU_matrix.h" @@ -407,7 +406,7 @@ static int voxel_size_edit_modal(bContext *C, wmOperator *op, const wmEvent *eve return OPERATOR_FINISHED; } - float mval[2] = {event->mval[0], event->mval[1]}; + const float mval[2] = {event->mval[0], event->mval[1]}; float d = cd->init_mval[0] - mval[0]; @@ -471,7 +470,7 @@ static int voxel_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *ev BoundBox *bb = BKE_mesh_boundbox_get(cd->active_object); /* Indices of the Bounding Box faces. */ - int BB_faces[6][4] = { + const int BB_faces[6][4] = { {3, 0, 4, 7}, {1, 2, 6, 5}, {3, 2, 1, 0}, @@ -526,7 +525,7 @@ static int voxel_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *ev float d_a[3], d_b[3]; float d_a_proj[2], d_b_proj[2]; float preview_plane_proj[4][3]; - float y_axis_proj[2] = {0.0f, 1.0f}; + const float y_axis_proj[2] = {0.0f, 1.0f}; mid_v3_v3v3(text_pos, cd->preview_plane[0], cd->preview_plane[2]); diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index f2d7ad3ac11..52b572fb0dd 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -1907,7 +1907,7 @@ static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const for (int x = -ofs; x <= ofs; x += ofs / 2) { for (int y = -ofs; y <= ofs; y += ofs / 2) { if (x != 0 && y != 0) { - int mval_ofs[2] = {event->mval[0] + x, event->mval[1] + y}; + const int mval_ofs[2] = {event->mval[0] + x, event->mval[1] + y}; float n[3]; if (ED_view3d_depth_read_cached_normal(&xfd->vc, mval_ofs, n)) { add_v3_v3(normal, n); diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 749c6cd640e..82a1139c860 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -4346,7 +4346,7 @@ static int brush_add(const bContext *C, PEData *data, short number) } pa->size = 1.0f; - initialize_particle(&sim, pa); + init_particle(&sim, pa); reset_particle(&sim, pa, 0.0, 1.0); point->flag |= PEP_EDIT_RECALC; if (pe_x_mirror(ob)) { diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 673df69bf9b..d279958df8a 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -79,7 +79,6 @@ #include "RNA_define.h" #include "GPU_framebuffer.h" -#include "GPU_glew.h" #include "GPU_matrix.h" #include "render_intern.h" @@ -351,7 +350,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R G.f &= ~G_FLAG_RENDER_VIEWPORT; gp_rect = MEM_mallocN(sizex * sizey * sizeof(uchar) * 4, "offscreen rect"); - GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, gp_rect); + GPU_offscreen_read_pixels(oglrender->ofs, GPU_DATA_UNSIGNED_BYTE, gp_rect); for (i = 0; i < sizex * sizey * 4; i += 4) { blend_color_mix_byte(&render_rect[i], &render_rect[i], &gp_rect[i]); @@ -963,7 +962,7 @@ static void screen_opengl_render_cancel(bContext *C, wmOperator *op) } /* share between invoke and exec */ -static bool screen_opengl_render_anim_initialize(bContext *C, wmOperator *op) +static bool screen_opengl_render_anim_init(bContext *C, wmOperator *op) { /* initialize animation */ OGLRender *oglrender; @@ -1257,7 +1256,7 @@ static int screen_opengl_render_invoke(bContext *C, wmOperator *op, const wmEven } if (anim) { - if (!screen_opengl_render_anim_initialize(C, op)) { + if (!screen_opengl_render_anim_init(C, op)) { return OPERATOR_CANCELLED; } } @@ -1293,7 +1292,7 @@ static int screen_opengl_render_exec(bContext *C, wmOperator *op) bool ret = true; - if (!screen_opengl_render_anim_initialize(C, op)) { + if (!screen_opengl_render_anim_init(C, op)) { return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 19e4f652963..85fc6927063 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -82,7 +82,6 @@ #include "BIF_glutil.h" -#include "GPU_glew.h" #include "GPU_shader.h" #include "RE_engine.h" @@ -632,18 +631,8 @@ static bool ed_preview_draw_rect(ScrArea *area, int split, int first, rcti *rect } IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); - immDrawPixelsTex(&state, - fx, - fy, - rres.rectx, - rres.recty, - GL_RGBA, - GL_UNSIGNED_BYTE, - GL_NEAREST, - rect_byte, - 1.0f, - 1.0f, - NULL); + immDrawPixelsTex( + &state, fx, fy, rres.rectx, rres.recty, GPU_RGBA8, false, rect_byte, 1.0f, 1.0f, NULL); MEM_freeN(rect_byte); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index f87f631c643..58fb934ebf0 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -291,7 +291,7 @@ static void region_draw_azone_tab_arrow(ScrArea *area, ARegion *region, AZone *a /* Workaround for different color spaces between normal areas and the ones using GPUViewports. */ float alpha = WM_region_use_viewport(area, region) ? 0.6f : 0.4f; - float color[4] = {0.05f, 0.05f, 0.05f, alpha}; + const float color[4] = {0.05f, 0.05f, 0.05f, alpha}; UI_draw_roundbox_aa( true, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, color); @@ -813,7 +813,7 @@ void ED_workspace_status_text(bContext *C, const char *str) /* ************************************************************ */ -static void area_azone_initialize(wmWindow *win, const bScreen *screen, ScrArea *area) +static void area_azone_init(wmWindow *win, const bScreen *screen, ScrArea *area) { AZone *az; @@ -883,7 +883,7 @@ static void area_azone_initialize(wmWindow *win, const bScreen *screen, ScrArea } } -static void fullscreen_azone_initialize(ScrArea *area, ARegion *region) +static void fullscreen_azone_init(ScrArea *area, ARegion *region) { AZone *az; @@ -1007,10 +1007,10 @@ static bool region_azone_edge_poll(const ARegion *region, const bool is_fullscre return true; } -static void region_azone_edge_initialize(ScrArea *area, - ARegion *region, - AZEdge edge, - const bool is_fullscreen) +static void region_azone_edge_init(ScrArea *area, + ARegion *region, + AZEdge edge, + const bool is_fullscreen) { AZone *az = NULL; const bool is_hidden = (region->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)); @@ -1033,9 +1033,9 @@ static void region_azone_edge_initialize(ScrArea *area, } } -static void region_azone_scrollbar_initialize(ScrArea *area, - ARegion *region, - AZScrollDirection direction) +static void region_azone_scrollbar_init(ScrArea *area, + ARegion *region, + AZScrollDirection direction) { rcti scroller_vert = (direction == AZ_SCROLL_VERT) ? region->v2d.vert : region->v2d.hor; AZone *az = MEM_callocN(sizeof(*az), __func__); @@ -1061,16 +1061,16 @@ static void region_azone_scrollbar_initialize(ScrArea *area, BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); } -static void region_azones_scrollbars_initialize(ScrArea *area, ARegion *region) +static void region_azones_scrollbars_init(ScrArea *area, ARegion *region) { const View2D *v2d = ®ion->v2d; if ((v2d->scroll & V2D_SCROLL_VERTICAL) && ((v2d->scroll & V2D_SCROLL_VERTICAL_HANDLES) == 0)) { - region_azone_scrollbar_initialize(area, region, AZ_SCROLL_VERT); + region_azone_scrollbar_init(area, region, AZ_SCROLL_VERT); } if ((v2d->scroll & V2D_SCROLL_HORIZONTAL) && ((v2d->scroll & V2D_SCROLL_HORIZONTAL_HANDLES) == 0)) { - region_azone_scrollbar_initialize(area, region, AZ_SCROLL_HOR); + region_azone_scrollbar_init(area, region, AZ_SCROLL_HOR); } } @@ -1083,16 +1083,16 @@ static void region_azones_add_edge(ScrArea *area, /* edge code (t b l r) is along which area edge azone will be drawn */ if (alignment == RGN_ALIGN_TOP) { - region_azone_edge_initialize(area, region, AE_BOTTOM_TO_TOPLEFT, is_fullscreen); + region_azone_edge_init(area, region, AE_BOTTOM_TO_TOPLEFT, is_fullscreen); } else if (alignment == RGN_ALIGN_BOTTOM) { - region_azone_edge_initialize(area, region, AE_TOP_TO_BOTTOMRIGHT, is_fullscreen); + region_azone_edge_init(area, region, AE_TOP_TO_BOTTOMRIGHT, is_fullscreen); } else if (alignment == RGN_ALIGN_RIGHT) { - region_azone_edge_initialize(area, region, AE_LEFT_TO_TOPRIGHT, is_fullscreen); + region_azone_edge_init(area, region, AE_LEFT_TO_TOPRIGHT, is_fullscreen); } else if (alignment == RGN_ALIGN_LEFT) { - region_azone_edge_initialize(area, region, AE_RIGHT_TO_TOPLEFT, is_fullscreen); + region_azone_edge_init(area, region, AE_RIGHT_TO_TOPLEFT, is_fullscreen); } } @@ -1116,10 +1116,10 @@ static void region_azones_add(const bScreen *screen, ScrArea *area, ARegion *reg } if (is_fullscreen) { - fullscreen_azone_initialize(area, region); + fullscreen_azone_init(area, region); } - region_azones_scrollbars_initialize(area, region); + region_azones_scrollbars_init(area, region); } /* dir is direction to check, not the splitting edge direction! */ @@ -1828,7 +1828,7 @@ void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *ar region_rect_recursive(area, area->regionbase.first, &rect, &overlap_rect, 0); /* Dynamically sized regions may have changed region sizes, so we have to force azone update. */ - area_azone_initialize(win, screen, area); + area_azone_init(win, screen, area); LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { region_subwindow(region); @@ -1847,7 +1847,7 @@ void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *ar } /* called in screen_refresh, or screens_init, also area size changes */ -void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *area) +void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area) { WorkSpace *workspace = WM_window_get_active_workspace(win); const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook); @@ -1890,7 +1890,7 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *area) } /* clear all azones, add the area triangle widgets */ - area_azone_initialize(win, screen, area); + area_azone_init(win, screen, area); /* region windows, default and own handlers */ for (region = area->regionbase.first; region; region = region->next) { @@ -1944,7 +1944,7 @@ void ED_region_update_rect(ARegion *region) } /* externally called for floating regions like menus */ -void ED_region_floating_initialize(ARegion *region) +void ED_region_floating_init(ARegion *region) { BLI_assert(region->alignment == RGN_ALIGN_FLOAT); @@ -1980,7 +1980,7 @@ void ED_region_visibility_change_update(bContext *C, ScrArea *area, ARegion *reg WM_event_remove_handlers(C, ®ion->handlers); } - ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), area); + ED_area_init(CTX_wm_manager(C), CTX_wm_window(C), area); ED_area_tag_redraw(area); } @@ -2066,8 +2066,8 @@ void ED_area_swapspace(bContext *C, ScrArea *sa1, ScrArea *sa2) ED_area_data_copy(tmp, sa1, false); ED_area_data_copy(sa1, sa2, true); ED_area_data_copy(sa2, tmp, true); - ED_area_initialize(CTX_wm_manager(C), win, sa1); - ED_area_initialize(CTX_wm_manager(C), win, sa2); + ED_area_init(CTX_wm_manager(C), win, sa1); + ED_area_init(CTX_wm_manager(C), win, sa2); BKE_screen_area_free(tmp); MEM_freeN(tmp); @@ -2126,7 +2126,7 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi area->spacetype = type; area->type = st; - /* If st->new may be called, don't use context until then. The + /* If st->create may be called, don't use context until then. The * area->type->context() callback has changed but data may be invalid * (e.g. with properties editor) until space-data is properly created */ @@ -2166,7 +2166,7 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi if (st) { /* Don't get scene from context here which may depend on space-data. */ Scene *scene = WM_window_get_active_scene(win); - sl = st->new (area, scene); + sl = st->create(area, scene); BLI_addhead(&area->spacedata, sl); /* swap regions */ @@ -2204,7 +2204,7 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi } } - ED_area_initialize(CTX_wm_manager(C), win, area); + ED_area_init(CTX_wm_manager(C), win, area); /* tell WM to refresh, cursor types etc */ WM_event_add_mousemove(win); diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index 5c3b1944164..05eac574d9d 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -95,9 +95,8 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, float y, int img_w, int img_h, - int format, - int type, - int zoomfilter, + eGPUTextureFormat gpu_format, + bool use_filter, void *rect, float scaleX, float scaleY, @@ -107,29 +106,38 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, float clip_max_y, float xzoom, float yzoom, - float color[4]) + const float color[4]) { int subpart_x, subpart_y, tex_w = 256, tex_h = 256; int seamless, offset_x, offset_y, nsubparts_x, nsubparts_y; int components; const bool use_clipping = ((clip_min_x < clip_max_x) && (clip_min_y < clip_max_y)); - float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + const float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - if (type != GL_FLOAT) { - BLI_assert(type == GL_UNSIGNED_BYTE); - type = GL_UNSIGNED_BYTE; + if (ELEM(gpu_format, GPU_RGBA8, GPU_RGBA16F)) { + components = 4; + } + else if (ELEM(gpu_format, GPU_RGB16F)) { + components = 3; + } + else if (ELEM(gpu_format, GPU_R8, GPU_R16F)) { + components = 1; + } + else { + BLI_assert(!"Incompatible format passed to immDrawPixels"); + return; } - eGPUTextureFormat gpu_format = (type == GL_FLOAT) ? GPU_RGBA16F : GPU_RGBA8; - eGPUDataFormat gpu_data = (type == GL_FLOAT) ? GPU_DATA_FLOAT : GPU_DATA_UNSIGNED_BYTE; - GPUTexture *texture = GPU_texture_create_nD( - tex_w, tex_h, 0, 2, NULL, gpu_format, gpu_data, 0, false, NULL); + const bool use_float_data = ELEM(gpu_format, GPU_RGBA16F, GPU_RGB16F, GPU_R16F); + eGPUDataFormat gpu_data = (use_float_data) ? GPU_DATA_FLOAT : GPU_DATA_UNSIGNED_BYTE; + size_t stride = components * ((use_float_data) ? sizeof(float) : sizeof(uchar)); - /* TODO replace GL_NEAREST/LINEAR in callers. */ - GPU_texture_filter_mode(texture, (zoomfilter == GL_LINEAR)); - GPU_texture_wrap_mode(texture, false, true); + GPUTexture *tex = GPU_texture_create_2d(tex_w, tex_h, gpu_format, NULL, NULL); - GPU_texture_bind(texture, 0); + GPU_texture_filter_mode(tex, use_filter); + GPU_texture_wrap_mode(tex, false, true); + + GPU_texture_bind(tex, 0); /* setup seamless 2=on, 0=off */ seamless = ((tex_w < img_w || tex_h < img_h) && tex_w > 2 && tex_h > 2) ? 2 : 0; @@ -140,20 +148,6 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, nsubparts_x = (img_w + (offset_x - 1)) / (offset_x); nsubparts_y = (img_h + (offset_y - 1)) / (offset_y); - if (format == GL_RGBA) { - components = 4; - } - else if (format == GL_RGB) { - components = 3; - } - else if (format == GL_RED) { - components = 1; - } - else { - BLI_assert(!"Incompatible format passed to glaDrawPixelsTexScaled"); - return; - } - /* optional */ /* NOTE: Shader could be null for GLSL OCIO drawing, it is fine, since * it does not need color. @@ -199,26 +193,32 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, { int src_y = subpart_y * offset_y; int src_x = subpart_x * offset_x; - size_t stride = components * ((type == GL_FLOAT) ? sizeof(float) : sizeof(uchar)); #define DATA(_y, _x) ((char *)rect + stride * ((size_t)(_y)*img_w + (_x))) { void *data = DATA(src_y, src_x); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, format, type, data); + GPU_texture_update_sub(tex, gpu_data, data, 0, 0, 0, subpart_w, subpart_h, 0); } /* Add an extra border of pixels so linear interpolation looks ok * at edges of full image. */ if (subpart_w < tex_w) { void *data = DATA(src_y, src_x + subpart_w - 1); - glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, 0, 1, subpart_h, format, type, data); + const int offset[2] = {subpart_w, 0}; + const int extent[2] = {1, subpart_h}; + GPU_texture_update_sub(tex, gpu_data, data, UNPACK2(offset), 0, UNPACK2(extent), 0); } if (subpart_h < tex_h) { void *data = DATA(src_y + subpart_h - 1, src_x); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, subpart_h, subpart_w, 1, format, type, data); + const int offset[2] = {0, subpart_h}; + const int extent[2] = {subpart_w, 1}; + GPU_texture_update_sub(tex, gpu_data, data, UNPACK2(offset), 0, UNPACK2(extent), 0); } + if (subpart_w < tex_w && subpart_h < tex_h) { void *data = DATA(src_y + subpart_h - 1, src_x + subpart_w - 1); - glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, subpart_h, 1, 1, format, type, data); + const int offset[2] = {subpart_w, subpart_h}; + const int extent[2] = {1, 1}; + GPU_texture_update_sub(tex, gpu_data, data, UNPACK2(offset), 0, UNPACK2(extent), 0); } #undef DATA } @@ -253,8 +253,8 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, immUnbindProgram(); } - GPU_texture_unbind(texture); - GPU_texture_free(texture); + GPU_texture_unbind(tex); + GPU_texture_free(tex); /* Restore default. */ GPU_unpack_row_length_set(0); @@ -265,24 +265,22 @@ void immDrawPixelsTexScaled(IMMDrawPixelsTexState *state, float y, int img_w, int img_h, - int format, - int type, - int zoomfilter, + eGPUTextureFormat gpu_format, + bool use_filter, void *rect, float scaleX, float scaleY, float xzoom, float yzoom, - float color[4]) + const float color[4]) { immDrawPixelsTexScaled_clipping(state, x, y, img_w, img_h, - format, - type, - zoomfilter, + gpu_format, + use_filter, rect, scaleX, scaleY, @@ -300,22 +298,20 @@ void immDrawPixelsTex(IMMDrawPixelsTexState *state, float y, int img_w, int img_h, - int format, - int type, - int zoomfilter, + eGPUTextureFormat gpu_format, + bool use_filter, void *rect, float xzoom, float yzoom, - float color[4]) + const float color[4]) { immDrawPixelsTexScaled_clipping(state, x, y, img_w, img_h, - format, - type, - zoomfilter, + gpu_format, + use_filter, rect, 1.0f, 1.0f, @@ -333,9 +329,8 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state, float y, int img_w, int img_h, - int format, - int type, - int zoomfilter, + eGPUTextureFormat gpu_format, + bool use_filter, void *rect, float clip_min_x, float clip_min_y, @@ -343,16 +338,15 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state, float clip_max_y, float xzoom, float yzoom, - float color[4]) + const float color[4]) { immDrawPixelsTexScaled_clipping(state, x, y, img_w, img_h, - format, - type, - zoomfilter, + gpu_format, + use_filter, rect, 1.0f, 1.0f, @@ -371,7 +365,7 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state, void ED_draw_imbuf_clipping(ImBuf *ibuf, float x, float y, - int zoomfilter, + bool use_filter, ColorManagedViewSettings *view_settings, ColorManagedDisplaySettings *display_settings, float clip_min_x, @@ -421,13 +415,13 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf, if (ok) { if (ibuf->rect_float) { - int format = 0; + eGPUTextureFormat format = 0; if (ibuf->channels == 3) { - format = GL_RGB; + format = GPU_RGB16F; } else if (ibuf->channels == 4) { - format = GL_RGBA; + format = GPU_RGBA16F; } else { BLI_assert(!"Incompatible number of channels for GLSL display"); @@ -440,8 +434,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf, ibuf->x, ibuf->y, format, - GL_FLOAT, - zoomfilter, + use_filter, ibuf->rect_float, clip_min_x, clip_min_y, @@ -459,9 +452,8 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf, y, ibuf->x, ibuf->y, - GL_RGBA, - GL_UNSIGNED_BYTE, - zoomfilter, + GPU_RGBA8, + use_filter, ibuf->rect, clip_min_x, clip_min_y, @@ -493,9 +485,8 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf, y, ibuf->x, ibuf->y, - GL_RGBA, - GL_UNSIGNED_BYTE, - zoomfilter, + GPU_RGBA8, + use_filter, display_buffer, clip_min_x, clip_min_y, @@ -513,7 +504,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf, void ED_draw_imbuf(ImBuf *ibuf, float x, float y, - int zoomfilter, + bool use_filter, ColorManagedViewSettings *view_settings, ColorManagedDisplaySettings *display_settings, float zoom_x, @@ -522,7 +513,7 @@ void ED_draw_imbuf(ImBuf *ibuf, ED_draw_imbuf_clipping(ibuf, x, y, - zoomfilter, + use_filter, view_settings, display_settings, 0.0f, @@ -537,7 +528,7 @@ void ED_draw_imbuf_ctx_clipping(const bContext *C, ImBuf *ibuf, float x, float y, - int zoomfilter, + bool use_filter, float clip_min_x, float clip_min_y, float clip_max_x, @@ -553,7 +544,7 @@ void ED_draw_imbuf_ctx_clipping(const bContext *C, ED_draw_imbuf_clipping(ibuf, x, y, - zoomfilter, + use_filter, view_settings, display_settings, clip_min_x, @@ -565,9 +556,9 @@ void ED_draw_imbuf_ctx_clipping(const bContext *C, } void ED_draw_imbuf_ctx( - const bContext *C, ImBuf *ibuf, float x, float y, int zoomfilter, float zoom_x, float zoom_y) + const bContext *C, ImBuf *ibuf, float x, float y, bool use_filter, float zoom_x, float zoom_y) { - ED_draw_imbuf_ctx_clipping(C, ibuf, x, y, zoomfilter, 0.0f, 0.0f, 0.0f, 0.0f, zoom_x, zoom_y); + ED_draw_imbuf_ctx_clipping(C, ibuf, x, y, use_filter, 0.0f, 0.0f, 0.0f, 0.0f, zoom_x, zoom_y); } int ED_draw_imbuf_method(ImBuf *ibuf) diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 7983ac889ef..c17a34f97b9 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -475,7 +475,6 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_id_pointer_set(result, &obpose->id); } return 1; - return -1; /* found but not available */ } if (CTX_data_equals(member, "sequences")) { Editing *ed = BKE_sequencer_editing_get(scene, false); diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c index 1608e842376..40a452a5363 100644 --- a/source/blender/editors/screen/screen_draw.c +++ b/source/blender/editors/screen/screen_draw.c @@ -619,7 +619,7 @@ void ED_screen_preview_render(const bScreen *screen, int size_x, int size_y, uin screen_preview_draw(screen, size_x, size_y); - GPU_offscreen_read_pixels(offscreen, GL_UNSIGNED_BYTE, r_rect); + GPU_offscreen_read_pixels(offscreen, GPU_DATA_UNSIGNED_BYTE, r_rect); GPU_offscreen_unbind(offscreen, true); GPU_offscreen_free(offscreen); diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index b6f210d7f13..62720d8ca37 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -516,7 +516,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win) ED_screen_areas_iter (win, screen, area) { /* set spacetype and region callbacks, calls init() */ /* sets subwindows for regions, adds handlers */ - ED_area_initialize(wm, win, area); + ED_area_init(wm, win, area); } /* wake up animtimer */ @@ -536,7 +536,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win) } /* file read, set all screens, ... */ -void ED_screens_initialize(Main *bmain, wmWindowManager *wm) +void ED_screens_init(Main *bmain, wmWindowManager *wm) { wmWindow *win; @@ -897,7 +897,7 @@ static void screen_global_area_refresh(wmWindow *win, else { area = screen_area_create_with_geometry(&win->global_areas, rect, space_type); SpaceType *stype = BKE_spacetype_from_id(space_type); - SpaceLink *slink = stype->new (area, WM_window_get_active_scene(win)); + SpaceLink *slink = stype->create(area, WM_window_get_active_scene(win)); area->regionbase = slink->regionbase; @@ -985,39 +985,14 @@ void ED_screen_global_areas_refresh(wmWindow *win) /* -------------------------------------------------------------------- */ /* Screen changing */ -static bScreen *screen_fullscreen_find_associated_normal_screen(const Main *bmain, bScreen *screen) -{ - for (bScreen *screen_iter = bmain->screens.first; screen_iter; - screen_iter = screen_iter->id.next) { - if ((screen_iter != screen) && ELEM(screen_iter->state, SCREENMAXIMIZED, SCREENFULL)) { - ScrArea *area = screen_iter->areabase.first; - if (area && area->full == screen) { - return screen_iter; - } - } - } - - return screen; -} - /** * \return the screen to activate. * \warning The returned screen may not always equal \a screen_new! */ -bScreen *screen_change_prepare( +void screen_change_prepare( bScreen *screen_old, bScreen *screen_new, Main *bmain, bContext *C, wmWindow *win) { - /* validate screen, it's called with notifier reference */ - if (BLI_findindex(&bmain->screens, screen_new) == -1) { - return NULL; - } - - screen_new = screen_fullscreen_find_associated_normal_screen(bmain, screen_new); - - /* check for valid winid */ - if (!(screen_new->winid == 0 || screen_new->winid == win->winid)) { - return NULL; - } + BLI_assert(BLI_findindex(&bmain->screens, screen_new) != -1); if (screen_old != screen_new) { wmTimer *wt = screen_old->animtimer; @@ -1038,11 +1013,7 @@ bScreen *screen_change_prepare( if (wt) { screen_new->animtimer = wt; } - - return screen_new; } - - return NULL; } void screen_change_update(bContext *C, wmWindow *win, bScreen *screen) @@ -1075,12 +1046,20 @@ bool ED_screen_change(bContext *C, bScreen *screen) { Main *bmain = CTX_data_main(C); wmWindow *win = CTX_wm_window(C); + WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); + WorkSpaceLayout *layout = BKE_workspace_layout_find(workspace, screen); bScreen *screen_old = CTX_wm_screen(C); - bScreen *screen_new = screen_change_prepare(screen_old, screen, bmain, C, win); - if (screen_new) { - WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); - WM_window_set_active_screen(win, workspace, screen); + /* Get the actual layout/screen to be activated (guaranteed to be unused, even if that means + * having to duplicate an existing one). */ + WorkSpaceLayout *layout_new = ED_workspace_screen_change_ensure_unused_layout( + bmain, workspace, layout, layout, win); + bScreen *screen_new = BKE_workspace_layout_screen_get(layout_new); + + screen_change_prepare(screen_old, screen_new, bmain, C, win); + + if (screen_old != screen_new) { + WM_window_set_active_screen(win, workspace, screen_new); screen_change_update(C, win, screen_new); return true; diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h index 21168a992b5..a5b5e222ae9 100644 --- a/source/blender/editors/screen/screen_intern.h +++ b/source/blender/editors/screen/screen_intern.h @@ -49,11 +49,11 @@ bScreen *screen_add(struct Main *bmain, const char *name, const rcti *rect); void screen_data_copy(bScreen *to, bScreen *from); void screen_new_activate_prepare(const wmWindow *win, bScreen *screen_new); void screen_change_update(struct bContext *C, wmWindow *win, bScreen *screen); -bScreen *screen_change_prepare(bScreen *screen_old, - bScreen *screen_new, - struct Main *bmain, - struct bContext *C, - wmWindow *win); +void screen_change_prepare(bScreen *screen_old, + bScreen *screen_new, + struct Main *bmain, + struct bContext *C, + wmWindow *win); ScrArea *area_split( const wmWindow *win, bScreen *screen, ScrArea *area, char dir, float fac, int merge); int screen_area_join(struct bContext *C, bScreen *screen, ScrArea *sa1, ScrArea *sa2); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index fde1498bc5e..f4d36a15d30 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -5184,7 +5184,7 @@ static void region_blend_end(bContext *C, ARegion *region, const bool is_running else { if (rgi->hidden) { rgi->region->flag |= rgi->hidden; - ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), rgi->area); + ED_area_init(CTX_wm_manager(C), CTX_wm_window(C), rgi->area); } /* area decoration needs redraw in end */ ED_area_tag_redraw(rgi->area); @@ -5215,7 +5215,7 @@ void ED_region_visibility_change_update_animated(bContext *C, ScrArea *area, ARe /* blend in, reinitialize regions because it got unhidden */ if (rgi->hidden == 0) { - ED_area_initialize(wm, win, area); + ED_area_init(wm, win, area); } else { WM_event_remove_handlers(C, ®ion->handlers); diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c index 478a0adfd9a..b20dc80d158 100644 --- a/source/blender/editors/screen/workspace_edit.c +++ b/source/blender/editors/screen/workspace_edit.c @@ -88,22 +88,15 @@ static void workspace_change_update(WorkSpace *workspace_new, #endif } -static bool workspace_change_find_new_layout_cb(const WorkSpaceLayout *layout, void *UNUSED(arg)) -{ - /* return false to stop the iterator if we've found a layout that can be activated */ - return workspace_layout_set_poll(layout) ? false : true; -} - static WorkSpaceLayout *workspace_change_get_new_layout(Main *bmain, WorkSpace *workspace_new, wmWindow *win) { - /* ED_workspace_duplicate may have stored a layout to activate - * once the workspace gets activated. */ WorkSpaceLayout *layout_old = WM_window_get_active_layout(win); WorkSpaceLayout *layout_new; - bScreen *screen_new; + /* ED_workspace_duplicate may have stored a layout to activate + * once the workspace gets activated. */ if (win->workspace_hook->temp_workspace_store) { layout_new = win->workspace_hook->temp_layout_store; } @@ -113,20 +106,9 @@ static WorkSpaceLayout *workspace_change_get_new_layout(Main *bmain, layout_new = workspace_new->layouts.first; } } - screen_new = BKE_workspace_layout_screen_get(layout_new); - - if (screen_new->winid) { - /* screen is already used, try to find a free one */ - WorkSpaceLayout *layout_temp = BKE_workspace_layout_iter_circular( - workspace_new, layout_new, workspace_change_find_new_layout_cb, NULL, false); - if (!layout_temp) { - /* fallback solution: duplicate layout from old workspace */ - layout_temp = ED_workspace_layout_duplicate(bmain, workspace_new, layout_old, win); - } - layout_new = layout_temp; - } - return layout_new; + return ED_workspace_screen_change_ensure_unused_layout( + bmain, workspace_new, layout_new, layout_old, win); } /** @@ -153,10 +135,7 @@ bool ED_workspace_change(WorkSpace *workspace_new, bContext *C, wmWindowManager return false; } - screen_new = screen_change_prepare(screen_old, screen_new, bmain, C, win); - if (BKE_workspace_layout_screen_get(layout_new) != screen_new) { - layout_new = BKE_workspace_layout_find(workspace_new, screen_new); - } + screen_change_prepare(screen_old, screen_new, bmain, C, win); if (screen_new == NULL) { return false; diff --git a/source/blender/editors/screen/workspace_layout_edit.c b/source/blender/editors/screen/workspace_layout_edit.c index 0af81e0db21..8a36cffa1f1 100644 --- a/source/blender/editors/screen/workspace_layout_edit.c +++ b/source/blender/editors/screen/workspace_layout_edit.c @@ -160,6 +160,66 @@ bool ED_workspace_layout_delete(WorkSpace *workspace, WorkSpaceLayout *layout_ol return false; } +static bool workspace_change_find_new_layout_cb(const WorkSpaceLayout *layout, void *UNUSED(arg)) +{ + /* return false to stop the iterator if we've found a layout that can be activated */ + return workspace_layout_set_poll(layout) ? false : true; +} + +static bScreen *screen_fullscreen_find_associated_normal_screen(const Main *bmain, bScreen *screen) +{ + for (bScreen *screen_iter = bmain->screens.first; screen_iter; + screen_iter = screen_iter->id.next) { + if ((screen_iter != screen) && ELEM(screen_iter->state, SCREENMAXIMIZED, SCREENFULL)) { + ScrArea *area = screen_iter->areabase.first; + if (area && area->full == screen) { + return screen_iter; + } + } + } + + return screen; +} + +static bool screen_is_used_by_other_window(const wmWindow *win, const bScreen *screen) +{ + return BKE_screen_is_used(screen) && (screen->winid != win->winid); +} + +/** + * Make sure there is a non-fullscreen layout to switch to that is not used yet by an other window. + * Needed for workspace or screen switching to ensure valid screens. + * + * \param layout_fallback_base: As last resort, this layout is duplicated and returned. + */ +WorkSpaceLayout *ED_workspace_screen_change_ensure_unused_layout( + Main *bmain, + WorkSpace *workspace, + WorkSpaceLayout *layout_new, + const WorkSpaceLayout *layout_fallback_base, + wmWindow *win) +{ + WorkSpaceLayout *layout_temp = layout_new; + bScreen *screen_temp = BKE_workspace_layout_screen_get(layout_new); + + screen_temp = screen_fullscreen_find_associated_normal_screen(bmain, screen_temp); + layout_temp = BKE_workspace_layout_find(workspace, screen_temp); + + if (screen_is_used_by_other_window(win, screen_temp)) { + /* Screen is already used, try to find a free one. */ + layout_temp = BKE_workspace_layout_iter_circular( + workspace, layout_new, workspace_change_find_new_layout_cb, NULL, false); + screen_temp = layout_temp ? BKE_workspace_layout_screen_get(layout_temp) : NULL; + + if (!layout_temp || screen_is_used_by_other_window(win, screen_temp)) { + /* Fallback solution: duplicate layout. */ + layout_temp = ED_workspace_layout_duplicate(bmain, workspace, layout_fallback_base, win); + } + } + + return layout_temp; +} + static bool workspace_layout_cycle_iter_cb(const WorkSpaceLayout *layout, void *UNUSED(arg)) { /* return false to stop iterator when we have found a layout to activate */ diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index d0082769575..ba32b53a9e0 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -56,7 +56,6 @@ #include "DEG_depsgraph.h" -#include "GPU_draw.h" #include "GPU_immediate.h" #include "GPU_immediate_util.h" #include "GPU_matrix.h" @@ -456,7 +455,7 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom) } buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex"); - BKE_curvemapping_initialize(br->curve); + BKE_curvemapping_init(br->curve); LoadTexData data = { .br = br, @@ -540,54 +539,6 @@ static int project_brush_radius(ViewContext *vc, float radius, const float locat return 0; } -static bool sculpt_get_brush_geometry(bContext *C, - ViewContext *vc, - int x, - int y, - int *pixel_radius, - float location[3], - UnifiedPaintSettings *ups) -{ - Scene *scene = CTX_data_scene(C); - Paint *paint = BKE_paint_get_active_from_context(C); - float mouse[2]; - bool hit = false; - - mouse[0] = x; - mouse[1] = y; - - if (vc->obact->sculpt && vc->obact->sculpt->pbvh) { - if (!ups->stroke_active) { - hit = SCULPT_stroke_get_location(C, location, mouse); - } - else { - hit = ups->last_hit; - copy_v3_v3(location, ups->last_location); - } - } - - if (hit) { - Brush *brush = BKE_paint_brush(paint); - - *pixel_radius = project_brush_radius( - vc, BKE_brush_unprojected_radius_get(scene, brush), location); - - if (*pixel_radius == 0) { - *pixel_radius = BKE_brush_size_get(scene, brush); - } - - mul_m4_v3(vc->obact->obmat, location); - } - else { - Sculpt *sd = CTX_data_tool_settings(C)->sculpt; - Brush *brush = BKE_paint_brush(&sd->paint); - - *pixel_radius = BKE_brush_size_get(scene, brush); - } - - return hit; -} - /* Draw an overlay that shows what effect the brush's texture will * have on brush strength. */ static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups, @@ -924,7 +875,7 @@ BLI_INLINE void draw_rect_point(uint pos, imm_draw_box_wire_2d(pos, minx, miny, maxx, maxy); } -BLI_INLINE void draw_bezier_handle_lines(uint pos, float sel_col[4], BezTriple *bez) +BLI_INLINE void draw_bezier_handle_lines(uint pos, const float sel_col[4], BezTriple *bez) { immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f); GPU_line_width(3.0f); @@ -1042,10 +993,10 @@ static void paint_draw_curve_cursor(Brush *brush, ViewContext *vc) /* Special actions taken when paint cursor goes over mesh */ /* TODO: sculpt only for now. */ -static void paint_cursor_on_hit(UnifiedPaintSettings *ups, - Brush *brush, - ViewContext *vc, - const float location[3]) +static void paint_cursor_update_unprojected_radius(UnifiedPaintSettings *ups, + Brush *brush, + ViewContext *vc, + const float location[3]) { float unprojected_radius, projected_radius; @@ -1077,18 +1028,6 @@ static void paint_cursor_on_hit(UnifiedPaintSettings *ups, } } -static bool ommit_cursor_drawing(Paint *paint, ePaintMode mode, Brush *brush) -{ - if (paint->flags & PAINT_SHOW_BRUSH) { - if (ELEM(mode, PAINT_MODE_TEXTURE_2D, PAINT_MODE_TEXTURE_3D) && - brush->imagepaint_tool == PAINT_TOOL_FILL) { - return true; - } - return false; - } - return true; -} - static void cursor_draw_point_screen_space(const uint gpuattr, const ARegion *region, const float true_location[3], @@ -1188,8 +1127,27 @@ static void cursor_draw_point_with_symmetry(const uint gpuattr, } } -static void sculpt_geometry_preview_lines_draw(const uint gpuattr, SculptSession *ss) +static void sculpt_geometry_preview_lines_draw(const uint gpuattr, + Brush *brush, + const bool is_multires, + SculptSession *ss) { + if (!(brush->flag & BRUSH_GRAB_ACTIVE_VERTEX)) { + return; + } + + if (is_multires) { + return; + } + + if (BKE_pbvh_type(ss->pbvh) != PBVH_FACES) { + return; + } + + if (!ss->deform_modifiers_active) { + return; + } + immUniformColor4f(1.0f, 1.0f, 1.0f, 0.6f); /* Cursor normally draws on top, but for this part we need depth tests. */ @@ -1215,30 +1173,21 @@ static void sculpt_geometry_preview_lines_draw(const uint gpuattr, SculptSession static void SCULPT_layer_brush_height_preview_draw(const uint gpuattr, const Brush *brush, - const float obmat[4][4], - const float location[3], - const float normal[3], const float rds, const float line_width, const float outline_col[3], const float alpha) { - float cursor_trans[4][4], cursor_rot[4][4]; - float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f}; - float quat[4]; - float height_preview_trans[3]; - copy_m4_m4(cursor_trans, obmat); - madd_v3_v3v3fl(height_preview_trans, location, normal, brush->height); - translate_m4( - cursor_trans, height_preview_trans[0], height_preview_trans[1], height_preview_trans[2]); - rotation_between_vecs_to_quat(quat, z_axis, normal); - quat_to_mat4(cursor_rot, quat); + float cursor_trans[4][4]; + unit_m4(cursor_trans); + translate_m4(cursor_trans, 0.0f, 0.0f, brush->height); + GPU_matrix_push(); GPU_matrix_mul(cursor_trans); - GPU_matrix_mul(cursor_rot); GPU_line_width(line_width); immUniformColor3fvAlpha(outline_col, alpha * 0.5f); imm_draw_circle_wire_3d(gpuattr, 0, 0, rds, 80); + GPU_matrix_pop(); } static bool paint_use_2d_cursor(ePaintMode mode) @@ -1249,428 +1198,668 @@ static bool paint_use_2d_cursor(ePaintMode mode) return false; } -static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) +typedef enum PaintCursorDrawingType { + PAINT_CURSOR_CURVE, + PAINT_CURSOR_2D, + PAINT_CURSOR_3D, +} PaintCursorDrawingType; + +typedef struct PaintCursorContext { + bContext *C; + ARegion *region; + wmWindow *win; + wmWindowManager *wm; + Depsgraph *depsgraph; + Scene *scene; + UnifiedPaintSettings *ups; + Brush *brush; + Paint *paint; + ePaintMode mode; + ViewContext vc; + + /* Sculpt related data. */ + Sculpt *sd; + SculptSession *ss; + int prev_active_vertex_index; + bool is_stroke_active; + bool is_cursor_over_mesh; + bool is_multires; + float radius; + + /* 3D view cursor position and normal. */ + float location[3]; + float scene_space_location[3]; + float normal[3]; + + /* Cursor main colors. */ + float outline_col[3]; + float outline_alpha; + + /* GPU attribute for drawing. */ + uint pos; + + PaintCursorDrawingType cursor_type; + + /* This variable is set after drawing the overlay, not on initialization. It can't be used for + * checking if alpha overlay is enabled before drawing it. */ + bool alpha_overlay_drawn; + + float zoomx; + int x, y; + float translation[2]; + + float final_radius; + int pixel_radius; + +} PaintCursorContext; + +static bool paint_cursor_context_init(bContext *C, + const int x, + const int y, + PaintCursorContext *pcontext) { ARegion *region = CTX_wm_region(C); if (region && region->regiontype != RGN_TYPE_WINDOW) { - return; + return false; } - const wmWindowManager *wm = CTX_wm_manager(C); - Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); - Scene *scene = CTX_data_scene(C); - UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; - Paint *paint = BKE_paint_get_active_from_context(C); - Brush *brush = BKE_paint_brush(paint); - ePaintMode mode = BKE_paintmode_get_active_from_context(C); + pcontext->C = C; + pcontext->region = region; + pcontext->wm = CTX_wm_manager(C); + pcontext->win = CTX_wm_window(C); + pcontext->depsgraph = CTX_data_depsgraph_pointer(C); + pcontext->scene = CTX_data_scene(C); + pcontext->ups = &pcontext->scene->toolsettings->unified_paint_settings; + pcontext->paint = BKE_paint_get_active_from_context(C); + pcontext->brush = BKE_paint_brush(pcontext->paint); + pcontext->mode = BKE_paintmode_get_active_from_context(C); + + ED_view3d_viewcontext_init(C, &pcontext->vc, pcontext->depsgraph); + + if (pcontext->brush->flag & BRUSH_CURVE) { + pcontext->cursor_type = PAINT_CURSOR_CURVE; + } + else if (paint_use_2d_cursor(pcontext->mode)) { + pcontext->cursor_type = PAINT_CURSOR_2D; + } + else { + pcontext->cursor_type = PAINT_CURSOR_3D; + } - /* 2d or 3d painting? */ - const bool use_2d_cursor = paint_use_2d_cursor(mode); + pcontext->x = x; + pcontext->y = y; + pcontext->translation[0] = (float)x; + pcontext->translation[1] = (float)y; - /* check that brush drawing is enabled */ - if (ommit_cursor_drawing(paint, mode, brush)) { - return; + float zoomx, zoomy; + get_imapaint_zoom(C, &zoomx, &zoomy); + pcontext->zoomx = max_ff(zoomx, zoomy); + pcontext->final_radius = (BKE_brush_size_get(pcontext->scene, pcontext->brush) * zoomx); + + /* There is currently no way to check if the direction is invertex before starting the stroke, so + * this does not reflect the state of the brush in the UI. */ + if (((pcontext->ups->draw_inverted == 0) ^ ((pcontext->brush->flag & BRUSH_DIR_IN) == 0)) && + BKE_brush_sculpt_has_secondary_color(pcontext->brush)) { + copy_v3_v3(pcontext->outline_col, pcontext->brush->sub_col); + } + else { + copy_v3_v3(pcontext->outline_col, pcontext->brush->add_col); } + pcontext->outline_alpha = pcontext->brush->add_col[3]; - /* Can't use stroke vc here because this will be called during - * mouse over too, not just during a stroke. */ - ViewContext vc; - ED_view3d_viewcontext_init(C, &vc, depsgraph); + Object *active_object = pcontext->vc.obact; + pcontext->ss = active_object ? active_object->sculpt : NULL; - if (vc.rv3d && (vc.rv3d->rflag & RV3D_NAVIGATING)) { - return; - } + pcontext->is_stroke_active = pcontext->ups->stroke_active; - /* Skip everything and draw brush here. */ - if (brush->flag & BRUSH_CURVE) { - paint_draw_curve_cursor(brush, &vc); - return; + return true; +} + +static void paint_cursor_update_pixel_radius(PaintCursorContext *pcontext) +{ + if (pcontext->is_cursor_over_mesh) { + Brush *brush = BKE_paint_brush(pcontext->paint); + pcontext->pixel_radius = project_brush_radius( + &pcontext->vc, + BKE_brush_unprojected_radius_get(pcontext->scene, brush), + pcontext->location); + + if (pcontext->pixel_radius == 0) { + pcontext->pixel_radius = BKE_brush_size_get(pcontext->scene, brush); + } + + copy_v3_v3(pcontext->scene_space_location, pcontext->location); + mul_m4_v3(pcontext->vc.obact->obmat, pcontext->scene_space_location); } + else { + Sculpt *sd = CTX_data_tool_settings(pcontext->C)->sculpt; + Brush *brush = BKE_paint_brush(&sd->paint); - float zoomx, zoomy; - get_imapaint_zoom(C, &zoomx, &zoomy); - zoomx = max_ff(zoomx, zoomy); + pcontext->pixel_radius = BKE_brush_size_get(pcontext->scene, brush); + } +} - /* Set various defaults. */ - const float *outline_col = brush->add_col; - const float outline_alpha = brush->add_col[3]; - float translation[2] = {x, y}; - float final_radius = (BKE_brush_size_get(scene, brush) * zoomx); +static void paint_cursor_sculpt_session_update_and_init(PaintCursorContext *pcontext) +{ + BLI_assert(pcontext->ss != NULL); + BLI_assert(pcontext->mode == PAINT_MODE_SCULPT); + + bContext *C = pcontext->C; + SculptSession *ss = pcontext->ss; + Brush *brush = pcontext->brush; + Scene *scene = pcontext->scene; + UnifiedPaintSettings *ups = pcontext->ups; + ViewContext *vc = &pcontext->vc; + SculptCursorGeometryInfo gi; + + const float mouse[2] = { + pcontext->x - pcontext->region->winrct.xmin, + pcontext->y - pcontext->region->winrct.ymin, + }; - /* Don't calculate rake angles while a stroke is active because the rake variables are global - * and we may get interference with the stroke itself. - * For line strokes, such interference is visible. */ + /* This updates the active vertex, which is needed for most of the Sculpt/Vertex Colors tools to + * work correctly */ + pcontext->prev_active_vertex_index = ss->active_vertex_index; if (!ups->stroke_active) { - paint_calculate_rake_rotation(ups, brush, translation); + pcontext->is_cursor_over_mesh = SCULPT_cursor_geometry_info_update( + C, &gi, mouse, (pcontext->brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE)); + copy_v3_v3(pcontext->location, gi.location); + copy_v3_v3(pcontext->normal, gi.normal); + } + else { + pcontext->is_cursor_over_mesh = ups->last_hit; + copy_v3_v3(pcontext->location, ups->last_location); } - /* Draw overlay. */ - bool alpha_overlay_active = paint_draw_alpha_overlay(ups, brush, &vc, x, y, zoomx, mode); + paint_cursor_update_pixel_radius(pcontext); - if (ups->draw_anchored) { - final_radius = ups->anchored_size; - copy_v2_fl2(translation, - ups->anchored_initial_mouse[0] + region->winrct.xmin, - ups->anchored_initial_mouse[1] + region->winrct.ymin); + if (BKE_brush_use_locked_size(scene, brush)) { + BKE_brush_size_set(scene, brush, pcontext->pixel_radius); } - /* Make lines pretty. */ - GPU_line_width(2.0f); + if (pcontext->is_cursor_over_mesh) { + paint_cursor_update_unprojected_radius(ups, brush, vc, pcontext->scene_space_location); + } - /* TODO: also set blend mode? */ - GPU_blend(true); + pcontext->is_multires = ss->pbvh != NULL && BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS; - GPU_line_smooth(true); + pcontext->sd = CTX_data_tool_settings(pcontext->C)->sculpt; +} - if (use_2d_cursor) { - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); +static void paint_update_mouse_cursor(PaintCursorContext *pcontext) +{ + WM_cursor_set(pcontext->win, WM_CURSOR_PAINT); +} - immUniformColor3fvAlpha(outline_col, outline_alpha); +static void paint_draw_2D_view_brush_cursor(PaintCursorContext *pcontext) +{ + immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha); + + /* Draw brush outline. */ + if (pcontext->ups->stroke_active && BKE_brush_use_size_pressure(pcontext->brush)) { + imm_draw_circle_wire_2d(pcontext->pos, + pcontext->translation[0], + pcontext->translation[1], + pcontext->final_radius * pcontext->ups->size_pressure_value, + 40); + /* Outer at half alpha. */ + immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.5f); + } - /* Draw brush outline. */ - if (ups->stroke_active && BKE_brush_use_size_pressure(brush)) { - imm_draw_circle_wire_2d( - pos, translation[0], translation[1], final_radius * ups->size_pressure_value, 40); - /* Outer at half alpha. */ - immUniformColor3fvAlpha(outline_col, outline_alpha * 0.5f); - } + GPU_line_width(1.0f); + imm_draw_circle_wire_2d(pcontext->pos, + pcontext->translation[0], + pcontext->translation[1], + pcontext->final_radius, + 40); + +} + +static void paint_draw_legacy_3D_view_brush_cursor(PaintCursorContext *pcontext) +{ + GPU_line_width(1.0f); + immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha); + imm_draw_circle_wire_3d(pcontext->pos, + pcontext->translation[0], + pcontext->translation[1], + pcontext->final_radius, + 40); +} - GPU_line_width(1.0f); - imm_draw_circle_wire_2d(pos, translation[0], translation[1], final_radius, 40); +static void paint_draw_3D_view_inactive_brush_cursor(PaintCursorContext *pcontext) +{ + GPU_line_width(1.0f); + /* Reduce alpha to increase the contrast when the cursor is over the mesh. */ + immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.8); + imm_draw_circle_wire_3d(pcontext->pos, + pcontext->translation[0], + pcontext->translation[1], + pcontext->final_radius, + 80); + immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.35f); + imm_draw_circle_wire_3d(pcontext->pos, + pcontext->translation[0], + pcontext->translation[1], + pcontext->final_radius * clamp_f(pcontext->brush->alpha, 0.0f, 1.0f), + 80); +} + +static void paint_cursor_update_object_space_radius(PaintCursorContext *pcontext) +{ + if (!BKE_brush_use_locked_size(pcontext->scene, pcontext->brush)) { + pcontext->radius = paint_calc_object_space_radius( + &pcontext->vc, pcontext->location, BKE_brush_size_get(pcontext->scene, pcontext->brush)); } else { - /* 3D Painting. */ - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - - /* TODO: as sculpt and other paint modes are unified, this - * special mode of drawing will go away. */ - Object *obact = vc.obact; - SculptSession *ss = obact ? obact->sculpt : NULL; - if ((mode == PAINT_MODE_SCULPT) && ss) { - float location[3]; - int pixel_radius; - - /* Test if brush is over the mesh. */ - bool hit = sculpt_get_brush_geometry(C, &vc, x, y, &pixel_radius, location, ups); - - if (BKE_brush_use_locked_size(scene, brush)) { - BKE_brush_size_set(scene, brush, pixel_radius); - } + pcontext->radius = BKE_brush_unprojected_radius_get(pcontext->scene, pcontext->brush); + } +} - /* Check if brush is subtracting, use different color then */ - /* TODO: no way currently to know state of pen flip or - * invert key modifier without starting a stroke. */ - if (((ups->draw_inverted == 0) ^ ((brush->flag & BRUSH_DIR_IN) == 0)) && - BKE_brush_sculpt_has_secondary_color(brush)) { - outline_col = brush->sub_col; - } +static void paint_cursor_drawing_setup_cursor_space(PaintCursorContext *pcontext) +{ + float cursor_trans[4][4], cursor_rot[4][4]; + const float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f}; + float quat[4]; + copy_m4_m4(cursor_trans, pcontext->vc.obact->obmat); + translate_m4(cursor_trans, pcontext->location[0], pcontext->location[1], pcontext->location[2]); + rotation_between_vecs_to_quat(quat, z_axis, pcontext->normal); + quat_to_mat4(cursor_rot, quat); + GPU_matrix_mul(cursor_trans); + GPU_matrix_mul(cursor_rot); +} + +static void paint_cursor_draw_main_inactive_cursor(PaintCursorContext *pcontext) +{ + immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha); + GPU_line_width(2.0f); + imm_draw_circle_wire_3d(pcontext->pos, 0, 0, pcontext->radius, 80); + + GPU_line_width(1.0f); + immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.5f); + imm_draw_circle_wire_3d( + pcontext->pos, 0, 0, pcontext->radius * clamp_f(pcontext->brush->alpha, 0.0f, 1.0f), 80); +} + +static void paint_cursor_pose_brush_segments_draw(PaintCursorContext *pcontext) +{ + SculptSession *ss = pcontext->ss; + immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f); + GPU_line_width(2.0f); - /* Only do if brush is over the mesh. */ - if (hit) { - paint_cursor_on_hit(ups, brush, &vc, location); + immBegin(GPU_PRIM_LINES, ss->pose_ik_chain_preview->tot_segments * 2); + for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) { + immVertex3fv(pcontext->pos, ss->pose_ik_chain_preview->segments[i].initial_orig); + immVertex3fv(pcontext->pos, ss->pose_ik_chain_preview->segments[i].initial_head); + } + + immEnd(); +} + +static void paint_cursor_pose_brush_origins_draw(PaintCursorContext *pcontext) +{ + + SculptSession *ss = pcontext->ss; + immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f); + for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) { + cursor_draw_point_screen_space(pcontext->pos, + pcontext->region, + ss->pose_ik_chain_preview->segments[i].initial_orig, + pcontext->vc.obact->obmat, + 3); + } +} + +static void paint_cursor_draw_3d_view_brush_cursor_inactive(PaintCursorContext *pcontext) +{ + Brush *brush = pcontext->brush; + + /* 2D fallof is better represented with the default 2D cursor, there is no need to draw anything + * else. */ + if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) { + paint_draw_legacy_3D_view_brush_cursor(pcontext); + return; + } + + if (pcontext->alpha_overlay_drawn) { + paint_draw_legacy_3D_view_brush_cursor(pcontext); + return; + } + + if (!pcontext->is_cursor_over_mesh) { + paint_draw_3D_view_inactive_brush_cursor(pcontext); + return; + } + + paint_cursor_update_object_space_radius(pcontext); + + const bool update_previews = pcontext->prev_active_vertex_index != + SCULPT_active_vertex_get(pcontext->ss); + + /* Setup drawing. */ + wmViewport(&pcontext->region->winrct); + + /* Drawing of Cursor overlays in 2D screen space. */ + + /* Cursor location symmetry points. */ + + const float *active_vertex_co = SCULPT_active_vertex_co_get(pcontext->ss); + if (len_v3v3(active_vertex_co, pcontext->location) < pcontext->radius) { + immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha); + cursor_draw_point_with_symmetry(pcontext->pos, + pcontext->region, + active_vertex_co, + pcontext->sd, + pcontext->vc.obact, + pcontext->radius); + } + + /* Pose brush updates and rotation origins. */ + + if (brush->sculpt_tool == SCULPT_TOOL_POSE) { + /* Just after switching to the Pose Brush, the active vertex can be the same and the + * cursor won't be tagged to update, so always initialize the preview chain if it is + * null before drawing it. */ + SculptSession *ss = pcontext->ss; + if (update_previews || !ss->pose_ik_chain_preview) { + BKE_sculpt_update_object_for_edit( + pcontext->depsgraph, pcontext->vc.obact, true, false, false); + + /* Free the previous pose brush preview. */ + if (ss->pose_ik_chain_preview) { + SCULPT_pose_ik_chain_free(ss->pose_ik_chain_preview); } + + /* Generate a new pose brush preview from the current cursor location. */ + ss->pose_ik_chain_preview = SCULPT_pose_ik_chain_init( + pcontext->sd, pcontext->vc.obact, ss, brush, pcontext->location, pcontext->radius); } - immUniformColor3fvAlpha(outline_col, outline_alpha); + /* Draw the pose brush rotation origins. */ + paint_cursor_pose_brush_origins_draw(pcontext); + } - if (ups->stroke_active && BKE_brush_use_size_pressure(brush) && mode != PAINT_MODE_SCULPT) { - imm_draw_circle_wire_3d( - pos, translation[0], translation[1], final_radius * ups->size_pressure_value, 40); - /* Outer at half alpha. */ - immUniformColor3fvAlpha(outline_col, outline_alpha * 0.5f); - } + /* Setup 3D perspective drawing. */ + GPU_matrix_push_projection(); + ED_view3d_draw_setup_view(pcontext->wm, + pcontext->win, + pcontext->depsgraph, + pcontext->scene, + pcontext->region, + CTX_wm_view3d(pcontext->C), + NULL, + NULL, + NULL); - /* Only sculpt mode cursor for now. */ - /* Disable for PBVH_GRIDS. */ - bool is_multires = ss && ss->pbvh && BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS; + GPU_matrix_push(); + GPU_matrix_mul(pcontext->vc.obact->obmat); - SculptCursorGeometryInfo gi; - float mouse[2] = {x - region->winrct.xmin, y - region->winrct.ymin}; - int prev_active_vertex_index = -1; - bool is_cursor_over_mesh = false; + /* Drawing Cursor overlays in 3D object space. */ + if (brush->sculpt_tool == SCULPT_TOOL_GRAB && (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX)) { + SCULPT_geometry_preview_lines_update(pcontext->C, pcontext->ss, pcontext->radius); + sculpt_geometry_preview_lines_draw( + pcontext->pos, pcontext->brush, pcontext->is_multires, pcontext->ss); + } - /* Update the active vertex. */ - if ((mode == PAINT_MODE_SCULPT) && ss && !ups->stroke_active) { - prev_active_vertex_index = ss->active_vertex_index; - is_cursor_over_mesh = SCULPT_cursor_geometry_info_update( - C, &gi, mouse, (brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE)); + if (brush->sculpt_tool == SCULPT_TOOL_POSE) { + paint_cursor_pose_brush_segments_draw(pcontext); + } + + GPU_matrix_pop(); + + /* Drawing Cursor overlays in Paint Cursor space (as additional info on top of the brush cursor) + */ + GPU_matrix_push(); + paint_cursor_drawing_setup_cursor_space(pcontext); + /* Main inactive cursor. */ + paint_cursor_draw_main_inactive_cursor(pcontext); + + /* Cloth brush local simulation areas. */ + if (brush->sculpt_tool == SCULPT_TOOL_CLOTH && + brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_LOCAL) { + const float white[3] = {1.0f, 1.0f, 1.0f}; + const float zero_v[3] = {0.0f}; + /* This functions sets its own drawing space in order to draw the simulation limits when the + * cursor is active. When used here, this cursor overlay is already in cursor space, so its + * position and normal should be set to 0. */ + SCULPT_cloth_simulation_limits_draw( + pcontext->pos, brush, zero_v, zero_v, pcontext->radius, 1.0f, white, 0.25f); + } + + /* Layer brush height. */ + if (brush->sculpt_tool == SCULPT_TOOL_LAYER) { + SCULPT_layer_brush_height_preview_draw(pcontext->pos, + brush, + pcontext->radius, + 1.0f, + pcontext->outline_col, + pcontext->outline_alpha); + } + + GPU_matrix_pop(); + + /* Reset drawing. */ + GPU_matrix_pop_projection(); + wmWindowViewport(pcontext->win); +} + +static void paint_cursor_cursor_draw_3d_view_brush_cursor_active(PaintCursorContext *pcontext) +{ + BLI_assert(pcontext->ss != NULL); + BLI_assert(pcontext->mode == PAINT_MODE_SCULPT); + + SculptSession *ss = pcontext->ss; + Brush *brush = pcontext->brush; + + /* The cursor can be updated as active before creating the StrokeCache, so this needs to be + * checked. */ + if (!ss->cache) { + return; + } + + /* Most of the brushes initialize the necessary data for the custom cursor drawing after the + * first brush step, so make sure that it is not drawn before being initialized. */ + if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) { + return; + } + + /* Setup drawing. */ + wmViewport(&pcontext->region->winrct); + GPU_matrix_push_projection(); + ED_view3d_draw_setup_view(pcontext->wm, + pcontext->win, + pcontext->depsgraph, + pcontext->scene, + pcontext->region, + CTX_wm_view3d(pcontext->C), + NULL, + NULL, + NULL); + GPU_matrix_push(); + GPU_matrix_mul(pcontext->vc.obact->obmat); + + /* Draw the special active cursors different tools may have. */ + + if (brush->sculpt_tool == SCULPT_TOOL_GRAB) { + sculpt_geometry_preview_lines_draw(pcontext->pos, brush, pcontext->is_multires, ss); + } + + if (brush->sculpt_tool == SCULPT_TOOL_MULTIPLANE_SCRAPE) { + SCULPT_multiplane_scrape_preview_draw( + pcontext->pos, brush, ss, pcontext->outline_col, pcontext->outline_alpha); + } + + if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) { + if (brush->cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_PLANE) { + SCULPT_cloth_plane_falloff_preview_draw( + pcontext->pos, ss, pcontext->outline_col, pcontext->outline_alpha); } - /* Use special paint crosshair cursor in all paint modes. */ - wmWindow *win = CTX_wm_window(C); - WM_cursor_set(win, WM_CURSOR_PAINT); - - if ((mode == PAINT_MODE_SCULPT) && ss && - (brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE)) { - Sculpt *sd = CTX_data_tool_settings(C)->sculpt; - - if (!ups->stroke_active) { - bool update_previews = false; - if (is_cursor_over_mesh && !alpha_overlay_active) { - - if (prev_active_vertex_index != ss->active_vertex_index) { - update_previews = true; - } - - float rds; - if (!BKE_brush_use_locked_size(scene, brush)) { - rds = paint_calc_object_space_radius( - &vc, gi.location, BKE_brush_size_get(scene, brush)); - } - else { - rds = BKE_brush_unprojected_radius_get(scene, brush); - } - - wmViewport(®ion->winrct); - - /* Draw 3D active vertex preview with symmetry. */ - if (len_v3v3(gi.active_vertex_co, gi.location) < rds) { - cursor_draw_point_with_symmetry(pos, region, gi.active_vertex_co, sd, vc.obact, rds); - } - - /* Draw pose brush origins. */ - if (brush->sculpt_tool == SCULPT_TOOL_POSE) { - immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f); - - /* Just after switching to the Pose Brush, the active vertex can be the same and the - * cursor won't be tagged to update, so always initialize the preview chain if it is - * null before drawing it. */ - if (update_previews || !ss->pose_ik_chain_preview) { - BKE_sculpt_update_object_for_edit(depsgraph, vc.obact, true, false, false); - - /* Free the previous pose brush preview. */ - if (ss->pose_ik_chain_preview) { - SCULPT_pose_ik_chain_free(ss->pose_ik_chain_preview); - } - - /* Generate a new pose brush preview from the current cursor location. */ - ss->pose_ik_chain_preview = SCULPT_pose_ik_chain_init( - sd, vc.obact, ss, brush, gi.location, rds); - } - - /* Draw the pose brush rotation origins. */ - for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) { - cursor_draw_point_screen_space(pos, - region, - ss->pose_ik_chain_preview->segments[i].initial_orig, - vc.obact->obmat, - 3); - } - } - - /* Draw 3D brush cursor. */ - GPU_matrix_push_projection(); - ED_view3d_draw_setup_view(wm, - CTX_wm_window(C), - CTX_data_depsgraph_pointer(C), - CTX_data_scene(C), - region, - CTX_wm_view3d(C), - NULL, - NULL, - NULL); - - float cursor_trans[4][4], cursor_rot[4][4]; - float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f}; - float quat[4]; - - copy_m4_m4(cursor_trans, vc.obact->obmat); - translate_m4(cursor_trans, gi.location[0], gi.location[1], gi.location[2]); - rotation_between_vecs_to_quat(quat, z_axis, gi.normal); - quat_to_mat4(cursor_rot, quat); - - GPU_matrix_push(); - GPU_matrix_mul(cursor_trans); - GPU_matrix_mul(cursor_rot); - immUniformColor3fvAlpha(outline_col, outline_alpha); - GPU_line_width(2.0f); - imm_draw_circle_wire_3d(pos, 0, 0, rds, 80); - - GPU_line_width(1.0f); - immUniformColor3fvAlpha(outline_col, outline_alpha * 0.5f); - imm_draw_circle_wire_3d(pos, 0, 0, rds * clamp_f(brush->alpha, 0.0f, 1.0f), 80); - GPU_matrix_pop(); - - /* Cloth brush simulation areas. */ - if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) { - GPU_matrix_push(); - const float white[3] = {1.0f, 1.0f, 1.0f}; - SCULPT_cloth_simulation_limits_draw( - pos, brush, vc.obact->obmat, gi.location, gi.normal, rds, 1.0f, white, 0.25f); - GPU_matrix_pop(); - } - - /* Layer brush height. */ - if (brush->sculpt_tool == SCULPT_TOOL_LAYER) { - GPU_matrix_push(); - SCULPT_layer_brush_height_preview_draw(pos, - brush, - vc.obact->obmat, - gi.location, - gi.normal, - rds, - 1.0f, - outline_col, - outline_alpha); - GPU_matrix_pop(); - } - - /* Update and draw dynamic mesh preview lines. */ - GPU_matrix_push(); - GPU_matrix_mul(vc.obact->obmat); - if (brush->sculpt_tool == SCULPT_TOOL_GRAB && (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) && - !is_multires) { - if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && ss->deform_modifiers_active) { - SCULPT_geometry_preview_lines_update(C, ss, rds); - sculpt_geometry_preview_lines_draw(pos, ss); - } - } - - /* Draw pose brush line preview. */ - if (brush->sculpt_tool == SCULPT_TOOL_POSE) { - immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f); - GPU_line_width(2.0f); - - immBegin(GPU_PRIM_LINES, ss->pose_ik_chain_preview->tot_segments * 2); - for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) { - immVertex3fv(pos, ss->pose_ik_chain_preview->segments[i].initial_orig); - immVertex3fv(pos, ss->pose_ik_chain_preview->segments[i].initial_head); - } - - immEnd(); - } - - GPU_matrix_pop(); - - GPU_matrix_pop_projection(); - - wmWindowViewport(win); - } - else { - /* Draw default cursor when the mouse is not over the mesh or there are no supported - * overlays active. */ - GPU_line_width(1.0f); - /* Reduce alpha to increase the contrast when the cursor is over the mesh. */ - immUniformColor3fvAlpha(outline_col, outline_alpha * 0.8); - imm_draw_circle_wire_3d(pos, translation[0], translation[1], final_radius, 80); - immUniformColor3fvAlpha(outline_col, outline_alpha * 0.35f); - imm_draw_circle_wire_3d(pos, - translation[0], - translation[1], - final_radius * clamp_f(brush->alpha, 0.0f, 1.0f), - 80); - } - } - else { - if (vc.obact->sculpt->cache && - !SCULPT_stroke_is_first_brush_step_of_symmetry_pass(vc.obact->sculpt->cache)) { - wmViewport(®ion->winrct); - - /* Draw cached dynamic mesh preview lines. */ - if (brush->sculpt_tool == SCULPT_TOOL_GRAB && (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) && - !is_multires) { - if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && ss->deform_modifiers_active) { - GPU_matrix_push_projection(); - ED_view3d_draw_setup_view(wm, - CTX_wm_window(C), - CTX_data_depsgraph_pointer(C), - CTX_data_scene(C), - region, - CTX_wm_view3d(C), - NULL, - NULL, - NULL); - GPU_matrix_push(); - GPU_matrix_mul(vc.obact->obmat); - sculpt_geometry_preview_lines_draw(pos, ss); - GPU_matrix_pop(); - GPU_matrix_pop_projection(); - } - } - - if (brush->sculpt_tool == SCULPT_TOOL_MULTIPLANE_SCRAPE && - brush->flag2 & BRUSH_MULTIPLANE_SCRAPE_PLANES_PREVIEW && - !SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) { - GPU_matrix_push_projection(); - ED_view3d_draw_setup_view(wm, - CTX_wm_window(C), - CTX_data_depsgraph_pointer(C), - CTX_data_scene(C), - region, - CTX_wm_view3d(C), - NULL, - NULL, - NULL); - GPU_matrix_push(); - GPU_matrix_mul(vc.obact->obmat); - SCULPT_multiplane_scrape_preview_draw(pos, ss, outline_col, outline_alpha); - GPU_matrix_pop(); - GPU_matrix_pop_projection(); - } - - if (brush->sculpt_tool == SCULPT_TOOL_CLOTH && - !SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) { - GPU_matrix_push_projection(); - ED_view3d_draw_setup_view(CTX_wm_manager(C), - CTX_wm_window(C), - CTX_data_depsgraph_pointer(C), - CTX_data_scene(C), - region, - CTX_wm_view3d(C), - NULL, - NULL, - NULL); - - /* Plane falloff preview */ - if (brush->cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_PLANE) { - GPU_matrix_push(); - GPU_matrix_mul(vc.obact->obmat); - SCULPT_cloth_plane_falloff_preview_draw(pos, ss, outline_col, outline_alpha); - GPU_matrix_pop(); - } - - /* Display the simulation limits if sculpting outside them. */ - /* This does not makes much sense of plane fallof as the fallof is infinte. */ - else if (brush->cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_RADIAL) { - if (len_v3v3(ss->cache->true_location, ss->cache->true_initial_location) > - ss->cache->radius * (1.0f + brush->cloth_sim_limit)) { - const float red[3] = {1.0f, 0.2f, 0.2f}; - GPU_matrix_push(); - SCULPT_cloth_simulation_limits_draw(pos, - brush, - vc.obact->obmat, - ss->cache->true_initial_location, - ss->cache->true_initial_normal, - ss->cache->radius, - 2.0f, - red, - 0.8f); - GPU_matrix_pop(); - } - } - - GPU_matrix_pop_projection(); - } - - wmWindowViewport(win); - } + else if (brush->cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_RADIAL && + brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_LOCAL) { + /* Display the simulation limits if sculpting outside them. */ + /* This does not makes much sense of plane fallof as the fallof is infinte or global. */ + + if (len_v3v3(ss->cache->true_location, ss->cache->true_initial_location) > + ss->cache->radius * (1.0f + brush->cloth_sim_limit)) { + const float red[3] = {1.0f, 0.2f, 0.2f}; + SCULPT_cloth_simulation_limits_draw(pcontext->pos, + brush, + ss->cache->true_initial_location, + ss->cache->true_initial_normal, + ss->cache->radius, + 2.0f, + red, + 0.8f); } } - else { - /* Draw default cursor in unsupported modes. */ - GPU_line_width(1.0f); - imm_draw_circle_wire_3d(pos, translation[0], translation[1], final_radius, 40); + } + + GPU_matrix_pop(); + + /* This Cloth brush cursor overlay always works in cursor space. */ + paint_cursor_drawing_setup_cursor_space(pcontext); + + GPU_matrix_pop_projection(); + wmWindowViewport(pcontext->win); +} + +static void paint_cursor_draw_3D_view_brush_cursor(PaintCursorContext *pcontext) +{ + + /* These paint tools are not using the SculptSession, so they need to use the default 2D brush + * cursor in the 3D view. */ + if (pcontext->mode != PAINT_MODE_SCULPT || !pcontext->ss) { + paint_draw_legacy_3D_view_brush_cursor(pcontext); + return; + } + + paint_cursor_sculpt_session_update_and_init(pcontext); + + if (pcontext->is_stroke_active) { + paint_cursor_cursor_draw_3d_view_brush_cursor_active(pcontext); + } + else { + paint_cursor_draw_3d_view_brush_cursor_inactive(pcontext); + } +} + +static bool paint_cursor_is_3d_view_navigating(PaintCursorContext *pcontext) +{ + ViewContext *vc = &pcontext->vc; + return vc->rv3d && (vc->rv3d->rflag & RV3D_NAVIGATING); +} + +static bool paint_cursor_is_brush_cursor_enabled(PaintCursorContext *pcontext) +{ + if (pcontext->paint->flags & PAINT_SHOW_BRUSH) { + if (ELEM(pcontext->mode, PAINT_MODE_TEXTURE_2D, PAINT_MODE_TEXTURE_3D) && + pcontext->brush->imagepaint_tool == PAINT_TOOL_FILL) { + return false; } + return true; } + return false; +} - immUnbindProgram(); +static void paint_cursor_update_rake_rotation(PaintCursorContext *pcontext) +{ + /* Don't calculate rake angles while a stroke is active because the rake variables are global + * and we may get interference with the stroke itself. + * For line strokes, such interference is visible. */ + if (!pcontext->ups->stroke_active) { + paint_calculate_rake_rotation(pcontext->ups, pcontext->brush, pcontext->translation); + } +} - /* Restore GL state. */ +static void paint_cursor_check_and_draw_alpha_overlays(PaintCursorContext *pcontext) +{ + pcontext->alpha_overlay_drawn = paint_draw_alpha_overlay(pcontext->ups, + pcontext->brush, + &pcontext->vc, + pcontext->x, + pcontext->y, + pcontext->zoomx, + pcontext->mode); +} + +static void paint_cursor_update_anchored_location(PaintCursorContext *pcontext) +{ + UnifiedPaintSettings *ups = pcontext->ups; + if (ups->draw_anchored) { + pcontext->final_radius = ups->anchored_size; + copy_v2_fl2(pcontext->translation, + ups->anchored_initial_mouse[0] + pcontext->region->winrct.xmin, + ups->anchored_initial_mouse[1] + pcontext->region->winrct.ymin); + } +} + +static void paint_cursor_setup_2D_drawing(PaintCursorContext *pcontext) +{ + GPU_line_width(2.0f); + GPU_blend(true); + GPU_line_smooth(true); + pcontext->pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); +} + +static void paint_cursor_setup_3D_drawing(PaintCursorContext *pcontext) +{ + GPU_line_width(2.0f); + GPU_blend(true); + GPU_line_smooth(true); + pcontext->pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); +} + +static void paint_cursor_restore_drawing_state(void) +{ + immUnbindProgram(); GPU_blend(false); GPU_line_smooth(false); } +static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) +{ + PaintCursorContext pcontext; + if (!paint_cursor_context_init(C, x, y, &pcontext)) { + return; + } + + if (!paint_cursor_is_brush_cursor_enabled(&pcontext)) { + return; + } + if (paint_cursor_is_3d_view_navigating(&pcontext)) { + return; + } + + switch (pcontext.cursor_type) { + case PAINT_CURSOR_CURVE: + paint_draw_curve_cursor(pcontext.brush, &pcontext.vc); + break; + case PAINT_CURSOR_2D: + paint_cursor_update_rake_rotation(&pcontext); + paint_cursor_check_and_draw_alpha_overlays(&pcontext); + paint_cursor_update_anchored_location(&pcontext); + + paint_cursor_setup_2D_drawing(&pcontext); + paint_draw_2D_view_brush_cursor(&pcontext); + paint_cursor_restore_drawing_state(); + break; + case PAINT_CURSOR_3D: + paint_update_mouse_cursor(&pcontext); + + paint_cursor_update_rake_rotation(&pcontext); + paint_cursor_check_and_draw_alpha_overlays(&pcontext); + paint_cursor_update_anchored_location(&pcontext); + + paint_cursor_setup_3D_drawing(&pcontext); + paint_cursor_draw_3D_view_brush_cursor(&pcontext); + paint_cursor_restore_drawing_state(); + break; + } +} + /* Public API */ void paint_cursor_start(Paint *p, bool (*poll)(bContext *C)) diff --git a/source/blender/editors/sculpt_paint/paint_curve.c b/source/blender/editors/sculpt_paint/paint_curve.c index 74e022bf84f..458f021ddb4 100644 --- a/source/blender/editors/sculpt_paint/paint_curve.c +++ b/source/blender/editors/sculpt_paint/paint_curve.c @@ -193,7 +193,7 @@ static void paintcurve_point_add(bContext *C, wmOperator *op, const int loc[2]) PaintCurvePoint *pcp; wmWindow *window = CTX_wm_window(C); ARegion *region = CTX_wm_region(C); - float vec[3] = {loc[0], loc[1], 0.0}; + const float vec[3] = {loc[0], loc[1], 0.0}; int add_index; int i; @@ -251,7 +251,7 @@ static void paintcurve_point_add(bContext *C, wmOperator *op, const int loc[2]) static int paintcurve_add_point_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - int loc[2] = {event->mval[0], event->mval[1]}; + const int loc[2] = {event->mval[0], event->mval[1]}; paintcurve_point_add(C, op, loc); RNA_int_set_array(op->ptr, "location", loc); return OPERATOR_FINISHED; @@ -480,7 +480,7 @@ static bool paintcurve_point_select( static int paintcurve_select_point_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - int loc[2] = {UNPACK2(event->mval)}; + const int loc[2] = {UNPACK2(event->mval)}; bool toggle = RNA_boolean_get(op->ptr, "toggle"); bool extend = RNA_boolean_get(op->ptr, "extend"); if (paintcurve_point_select(C, op, loc, toggle, extend)) { diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 7ee3d991eb7..431ab998f62 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -74,7 +74,6 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "GPU_draw.h" #include "GPU_immediate.h" #include "GPU_state.h" @@ -182,7 +181,7 @@ void imapaint_image_update( int h = imapaintpartial.y2 - imapaintpartial.y1; if (w && h) { /* Testing with partial update in uv editor too */ - GPU_paint_update_image(image, iuser, imapaintpartial.x1, imapaintpartial.y1, w, h); + BKE_image_update_gputexture(image, iuser, imapaintpartial.x1, imapaintpartial.y1, w, h); } } } @@ -1164,9 +1163,9 @@ void ED_object_texture_paint_mode_enter_ex(Main *bmain, Scene *scene, Object *ob BKE_paint_toolslots_brush_validate(bmain, &imapaint->paint); if (U.glreslimit != 0) { - GPU_free_images(bmain); + BKE_image_free_all_gputextures(bmain); } - GPU_paint_set_mipmap(bmain, 0); + BKE_image_paint_set_mipmap(bmain, 0); toggle_paint_cursor(scene, true); @@ -1189,9 +1188,9 @@ void ED_object_texture_paint_mode_exit_ex(Main *bmain, Scene *scene, Object *ob) ob->mode &= ~OB_MODE_TEXTURE_PAINT; if (U.glreslimit != 0) { - GPU_free_images(bmain); + BKE_image_free_all_gputextures(bmain); } - GPU_paint_set_mipmap(bmain, 1); + BKE_image_paint_set_mipmap(bmain, 1); toggle_paint_cursor(scene, false); Mesh *me = BKE_mesh_from_object(ob); @@ -1334,7 +1333,7 @@ void ED_imapaint_bucket_fill(struct bContext *C, ED_image_undo_push_begin(op->type->name, PAINT_MODE_TEXTURE_2D); - float mouse_init[2] = {mouse[0], mouse[1]}; + const float mouse_init[2] = {mouse[0], mouse[1]}; paint_2d_bucket_fill(C, color, NULL, mouse_init, NULL, NULL); ED_image_undo_push_end(); diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c index a7f09390a3d..d614c800350 100644 --- a/source/blender/editors/sculpt_paint/paint_image_2d.c +++ b/source/blender/editors/sculpt_paint/paint_image_2d.c @@ -57,8 +57,6 @@ #include "UI_view2d.h" -#include "GPU_draw.h" - #include "paint_intern.h" /* Brush Painting for 2D image editor */ @@ -1784,7 +1782,7 @@ void paint_2d_redraw(const bContext *C, void *ps, bool final) if (final) { if (s->image && !(s->sima && s->sima->lock)) { - GPU_free_image(s->image); + BKE_image_free_gputextures(s->image); } /* compositor listener deals with updating */ @@ -2165,7 +2163,7 @@ void paint_2d_gradient_fill( for (x_px = 0; x_px < ibuf->x; x_px++) { for (y_px = 0; y_px < ibuf->y; y_px++) { float f; - float p[2] = {x_px - image_init[0], y_px - image_init[1]}; + const float p[2] = {x_px - image_init[0], y_px - image_init[1]}; switch (br->gradient_fill_mode) { case BRUSH_GRADIENT_LINEAR: { @@ -2193,7 +2191,7 @@ void paint_2d_gradient_fill( for (x_px = 0; x_px < ibuf->x; x_px++) { for (y_px = 0; y_px < ibuf->y; y_px++) { float f; - float p[2] = {x_px - image_init[0], y_px - image_init[1]}; + const float p[2] = {x_px - image_init[0], y_px - image_init[1]}; switch (br->gradient_fill_mode) { case BRUSH_GRADIENT_LINEAR: { diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 5af3a3f4241..d16c66848b8 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -100,8 +100,6 @@ #include "RNA_define.h" #include "RNA_enum_types.h" -#include "GPU_draw.h" - #include "IMB_colormanagement.h" //#include "bmesh_tools.h" @@ -2930,7 +2928,7 @@ static void project_bucket_clip_face(const bool is_ortho, /* checks if pt is inside a convex 2D polyline, the polyline must be ordered rotating clockwise * otherwise it would have to test for mixed (line_point_side_v2 > 0.0f) cases */ -static bool IsectPoly2Df(const float pt[2], float uv[][2], const int tot) +static bool IsectPoly2Df(const float pt[2], const float uv[][2], const int tot) { int i; if (line_point_side_v2(uv[tot - 1], uv[0], pt) < 0.0f) { @@ -2945,7 +2943,7 @@ static bool IsectPoly2Df(const float pt[2], float uv[][2], const int tot) return true; } -static bool IsectPoly2Df_twoside(const float pt[2], float uv[][2], const int tot) +static bool IsectPoly2Df_twoside(const float pt[2], const float uv[][2], const int tot) { const bool side = (line_point_side_v2(uv[tot - 1], uv[0], pt) > 0.0f); @@ -3311,7 +3309,7 @@ static void project_paint_face_init(const ProjPaintState *ps, has_x_isect = 0; for (x = bounds_px.xmin; x < bounds_px.xmax; x++) { - float puv[2] = {(float)x, (float)y}; + const float puv[2] = {(float)x, (float)y}; bool in_bounds; // uv[0] = (((float)x) + 0.5f) / (float)ibuf->x; /* use offset uvs instead */ @@ -5758,7 +5756,7 @@ void paint_proj_stroke(const bContext *C, View3D *v3d = CTX_wm_view3d(C); ARegion *region = CTX_wm_region(C); float *cursor = scene->cursor.location; - int mval_i[2] = {(int)pos[0], (int)pos[1]}; + const int mval_i[2] = {(int)pos[0], (int)pos[1]}; view3d_operator_needs_opengl(C); @@ -6125,8 +6123,8 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - float pos[2] = {0.0, 0.0}; - float lastpos[2] = {0.0, 0.0}; + const float pos[2] = {0.0, 0.0}; + const float lastpos[2] = {0.0, 0.0}; int a; project_paint_op(&ps, lastpos, pos); @@ -6134,7 +6132,7 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op) project_image_refresh_tagged(&ps); for (a = 0; a < ps.image_tot; a++) { - GPU_free_image(ps.projImages[a].ima); + BKE_image_free_gputextures(ps.projImages[a].ima); WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ps.projImages[a].ima); } @@ -6175,7 +6173,7 @@ static bool texture_paint_image_from_view_poll(bContext *C) CTX_wm_operator_poll_msg_set(C, "No 3D viewport found to create image from"); return false; } - if (G.background || !GPU_is_initialized()) { + if (G.background || !GPU_is_init()) { return false; } return true; diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index d532ef977fe..65f78a2d988 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -340,6 +340,7 @@ typedef enum { void PAINT_OT_mask_flood_fill(struct wmOperatorType *ot); void PAINT_OT_mask_lasso_gesture(struct wmOperatorType *ot); +void PAINT_OT_mask_box_gesture(struct wmOperatorType *ot); /* paint_curve.c */ void PAINTCURVE_OT_new(struct wmOperatorType *ot); diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index 6e0402fc6e0..7e5825835fb 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -25,6 +25,7 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" +#include "DNA_vec_types.h" #include "BLI_bitmap_draw_2d.h" #include "BLI_lasso_2d.h" @@ -290,27 +291,32 @@ static void mask_box_select_task_cb(void *__restrict userdata, } } -bool ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *rect, bool select) +static int paint_mask_gesture_box_exec(bContext *C, wmOperator *op) { + ViewContext vc; Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - Sculpt *sd = vc->scene->toolsettings->sculpt; + ED_view3d_viewcontext_init(C, &vc, depsgraph); + + Sculpt *sd = vc.scene->toolsettings->sculpt; BoundBox bb; float clip_planes[4][4]; float clip_planes_final[4][4]; - ARegion *region = vc->region; - Object *ob = vc->obact; - PaintMaskFloodMode mode; + ARegion *region = vc.region; + Object *ob = vc.obact; bool multires; PBVH *pbvh; PBVHNode **nodes; int totnode; int symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; - mode = PAINT_MASK_FLOOD_VALUE; - float value = select ? 1.0f : 0.0f; + const PaintMaskFloodMode mode = RNA_enum_get(op->ptr, "mode"); + const float value = RNA_float_get(op->ptr, "value"); + + rcti rect; + WM_operator_properties_border_to_rcti(op, &rect); /* Transform the clip planes in object space. */ - ED_view3d_clipping_calc(&bb, clip_planes, vc->region, vc->obact, rect); + ED_view3d_clipping_calc(&bb, clip_planes, vc.region, vc.obact, &rect); BKE_sculpt_update_object_for_edit(depsgraph, ob, false, true, false); pbvh = ob->sculpt->pbvh; @@ -383,7 +389,7 @@ typedef struct LassoMaskData { * Lasso select. This could be defined as part of #VIEW3D_OT_select_lasso, * still the shortcuts conflict, so we will use a separate operator. */ -static bool is_effected_lasso(LassoMaskData *data, float co[3]) +static bool is_effected_lasso(LassoMaskData *data, const float co[3]) { float scr_co_f[2]; int scr_co_s[2]; @@ -589,3 +595,33 @@ void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot) 0.0f, 1.0f); } + +void PAINT_OT_mask_box_gesture(wmOperatorType *ot) +{ + ot->name = "Mask Box Gesture"; + ot->idname = "PAINT_OT_mask_box_gesture"; + ot->description = "Add mask within the box as you move the brush"; + + ot->invoke = WM_gesture_box_invoke; + ot->modal = WM_gesture_box_modal; + ot->exec = paint_mask_gesture_box_exec; + + ot->poll = SCULPT_mode_poll; + + ot->flag = OPTYPE_REGISTER; + + /* Properties. */ + WM_operator_properties_border(ot); + + RNA_def_enum(ot->srna, "mode", mode_items, PAINT_MASK_FLOOD_VALUE, "Mode", NULL); + RNA_def_float( + ot->srna, + "value", + 1.0f, + 0.0f, + 1.0f, + "Value", + "Mask level to use when mode is 'Value'; zero means no masking and one is fully masked", + 0.0f, + 1.0f); +} diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index d65f158174f..43ff03ea7e2 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -913,7 +913,7 @@ static int stencil_control_invoke(bContext *C, wmOperator *op, const wmEvent *ev { Paint *paint = BKE_paint_get_active_from_context(C); Brush *br = BKE_paint_brush(paint); - float mvalf[2] = {event->mval[0], event->mval[1]}; + const float mvalf[2] = {event->mval[0], event->mval[1]}; ARegion *region = CTX_wm_region(C); StencilControlData *scd; int mask = RNA_enum_get(op->ptr, "texmode"); @@ -968,7 +968,7 @@ static void stencil_control_calculate(StencilControlData *scd, const int mval[2] #define PIXEL_MARGIN 5 float mdiff[2]; - float mvalf[2] = {mval[0], mval[1]}; + const float mvalf[2] = {mval[0], mval[1]}; switch (scd->mode) { case STENCIL_TRANSLATE: sub_v2_v2v2(mdiff, mvalf, scd->init_mouse); @@ -1356,6 +1356,7 @@ void ED_operatortypes_paint(void) /* paint masking */ WM_operatortype_append(PAINT_OT_mask_flood_fill); WM_operatortype_append(PAINT_OT_mask_lasso_gesture); + WM_operatortype_append(PAINT_OT_mask_box_gesture); } void ED_keymap_paint(wmKeyConfig *keyconf) diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index caecc7b708a..38a09cd97bd 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -920,9 +920,9 @@ PaintStroke *paint_stroke_new(bContext *C, ups->average_stroke_counter = 0; /* initialize here to avoid initialization conflict with threaded strokes */ - BKE_curvemapping_initialize(br->curve); + BKE_curvemapping_init(br->curve); if (p->flags & PAINT_USE_CAVITY_MASK) { - BKE_curvemapping_initialize(p->cavity_curve); + BKE_curvemapping_init(p->cavity_curve); } BKE_paint_set_overlay_override(br->overlay_flags); @@ -1198,7 +1198,10 @@ static void paint_line_strokes_spacing(bContext *C, *length_residue = length; } -static void paint_stroke_line_end(bContext *C, wmOperator *op, PaintStroke *stroke, float mouse[2]) +static void paint_stroke_line_end(bContext *C, + wmOperator *op, + PaintStroke *stroke, + const float mouse[2]) { Brush *br = stroke->brush; if (stroke->stroke_started && (br->flag & BRUSH_LINE)) { diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 6c5d6f4ee4e..b7e5a73cbb3 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -169,7 +169,7 @@ float paint_get_tex_pixel(const MTex *mtex, float u, float v, struct ImagePool * { float intensity; float rgba_dummy[4]; - float co[3] = {u, v, 0.0f}; + const float co[3] = {u, v, 0.0f}; RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, rgba_dummy); @@ -185,7 +185,7 @@ void paint_get_tex_pixel_col(const MTex *mtex, bool convert_to_linear, struct ColorSpace *colorspace) { - float co[3] = {u, v, 0.0f}; + const float co[3] = {u, v, 0.0f}; float intensity; const bool hasrgb = RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, rgba); @@ -238,7 +238,7 @@ void paint_stroke_operator_properties(wmOperatorType *ot) /* 3D Paint */ -static void imapaint_project(float matrix[4][4], const float co[3], float pco[4]) +static void imapaint_project(const float matrix[4][4], const float co[3], float pco[4]) { copy_v3_v3(pco, co); pco[3] = 1.0f; 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 6965946d2ce..73014f9f2de 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c @@ -757,8 +757,8 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) int y_start = RNA_int_get(op->ptr, "ystart"); int x_end = RNA_int_get(op->ptr, "xend"); int y_end = RNA_int_get(op->ptr, "yend"); - float sco_start[2] = {x_start, y_start}; - float sco_end[2] = {x_end, y_end}; + const float sco_start[2] = {x_start, y_start}; + const float sco_end[2] = {x_end, y_end}; const bool is_interactive = (gesture != NULL); Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); @@ -811,7 +811,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) VPaint *wp = ts->wpaint; struct Brush *brush = BKE_paint_brush(&wp->paint); - BKE_curvemapping_initialize(brush->curve); + BKE_curvemapping_init(brush->curve); data.brush = brush; data.weightpaint = BKE_brush_weight_get(scene, brush); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index e838d87aeff..d0b834a3dc0 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -196,7 +196,7 @@ void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3]) } } -static const float *sculpt_vertex_persistent_co_get(SculptSession *ss, int index) +const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, int index) { if (ss->persistent_base) { return ss->persistent_base[index].co; @@ -204,7 +204,7 @@ static const float *sculpt_vertex_persistent_co_get(SculptSession *ss, int index return SCULPT_vertex_co_get(ss, index); } -static void sculpt_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3]) +void SCULPT_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3]) { if (ss->persistent_base) { copy_v3_v3(no, ss->persistent_base[index].no); @@ -581,7 +581,8 @@ static bool sculpt_check_unique_face_set_for_edge_in_base_mesh(SculptSession *ss p1 = vert_map->indices[i]; break; } - else if (p2 == -1) { + + if (p2 == -1) { p2 = vert_map->indices[i]; break; } @@ -2966,7 +2967,7 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) /* XXX - this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise * initialize before threads so they can do curve mapping. */ - BKE_curvemapping_initialize(brush->curve); + BKE_curvemapping_init(brush->curve); /* Threaded loop over nodes. */ SculptThreadedTaskData data = { @@ -3043,7 +3044,7 @@ static void do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to /* XXX - this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise * initialize before threads so they can do curve mapping. */ - BKE_curvemapping_initialize(brush->curve); + BKE_curvemapping_init(brush->curve); /* Threaded loop over nodes. */ SculptThreadedTaskData data = { @@ -3273,7 +3274,7 @@ static void do_slide_relax_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t return; } - BKE_curvemapping_initialize(brush->curve); + BKE_curvemapping_init(brush->curve); SculptThreadedTaskData data = { .sd = sd, @@ -4341,9 +4342,9 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata, float normal[3]; if (use_persistent_base) { - sculpt_vertex_persistent_normal_get(ss, vi, normal); + SCULPT_vertex_persistent_normal_get(ss, vi, normal); mul_v3_fl(normal, brush->height); - madd_v3_v3v3fl(final_co, sculpt_vertex_persistent_co_get(ss, vi), normal, *disp_factor); + madd_v3_v3v3fl(final_co, SCULPT_vertex_persistent_co_get(ss, vi), normal, *disp_factor); } else { normal_short_to_float_v3(normal, orig_data.no); @@ -5513,15 +5514,21 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); } else if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) { - SculptSearchSphereData data = { - .ss = ss, - .sd = sd, - .radius_squared = square_f(ss->cache->initial_radius * (1.0 + brush->cloth_sim_limit)), - .original = false, - .ignore_fully_ineffective = false, - .center = ss->cache->initial_location, - }; - BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode); + if (brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_LOCAL) { + SculptSearchSphereData data = { + .ss = ss, + .sd = sd, + .radius_squared = square_f(ss->cache->initial_radius * (1.0 + brush->cloth_sim_limit)), + .original = false, + .ignore_fully_ineffective = false, + .center = ss->cache->initial_location, + }; + BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode); + } + else { + /* Gobal simulation, get all nodes. */ + BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); + } } else { const bool use_original = sculpt_tool_needs_original(brush->sculpt_tool) ? true : @@ -6390,7 +6397,7 @@ static void sculpt_update_cache_invariants( brush = br; cache->saved_smooth_size = BKE_brush_size_get(scene, brush); BKE_brush_size_set(scene, brush, size); - BKE_curvemapping_initialize(brush->curve); + BKE_curvemapping_init(brush->curve); } } } @@ -6458,7 +6465,7 @@ static void sculpt_update_cache_invariants( #define PIXEL_INPUT_THRESHHOLD 5 if (brush->sculpt_tool == SCULPT_TOOL_ROTATE) { - cache->dial = BLI_dial_initialize(cache->initial_mouse, PIXEL_INPUT_THRESHHOLD); + cache->dial = BLI_dial_init(cache->initial_mouse, PIXEL_INPUT_THRESHHOLD); } #undef PIXEL_INPUT_THRESHHOLD @@ -8160,6 +8167,14 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float return; } + if (!ss->deform_modifiers_active) { + return; + } + + if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) { + return; + } + BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false); if (!ss->pmap) { diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c index 4232be91034..21fba6479e8 100644 --- a/source/blender/editors/sculpt_paint/sculpt_cloth.c +++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c @@ -43,7 +43,9 @@ #include "DNA_scene_types.h" #include "BKE_brush.h" +#include "BKE_bvhutils.h" #include "BKE_ccg.h" +#include "BKE_collision.h" #include "BKE_colortools.h" #include "BKE_context.h" #include "BKE_image.h" @@ -69,6 +71,7 @@ #include "BKE_subsurf.h" #include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" #include "WM_api.h" #include "WM_message.h" @@ -85,7 +88,6 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "GPU_draw.h" #include "GPU_immediate.h" #include "GPU_immediate_util.h" #include "GPU_matrix.h" @@ -101,6 +103,33 @@ #include <stdlib.h> #include <string.h> +static float cloth_brush_simulation_falloff_get(const Brush *brush, + const float radius, + const float location[3], + const float co[3]) +{ + /* Global simulation does not have any falloff as the entire mesh is being simulated. */ + if (brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_GLOBAL) { + return 1.0f; + } + + const float distance = len_v3v3(location, co); + const float limit = radius + (radius * brush->cloth_sim_limit); + const float falloff = radius + (radius * brush->cloth_sim_limit * brush->cloth_sim_falloff); + + if (distance > limit) { + /* Outiside the limits. */ + return 0.0f; + } + if (distance < falloff) { + /* Before the falloff area. */ + return 1.0f; + } + /* Do a smoothstep transition inside the falloff area. */ + float p = 1.0f - ((distance - falloff) / (limit - falloff)); + return 3.0f * p * p - 2.0f * p * p * p; +} + #define CLOTH_LENGTH_CONSTRAINTS_BLOCK 100000 #define CLOTH_SIMULATION_ITERATIONS 5 #define CLOTH_MAX_CONSTRAINTS_PER_VERTEX 1024 @@ -113,19 +142,8 @@ static bool cloth_brush_sim_has_length_constraint(SculptClothSimulation *cloth_s return BLI_edgeset_haskey(cloth_sim->created_length_constraints, v1, v2); } -static void cloth_brush_add_length_constraint(SculptSession *ss, - SculptClothSimulation *cloth_sim, - const int v1, - const int v2) +static void cloth_brush_reallocate_constraints(SculptClothSimulation *cloth_sim) { - cloth_sim->length_constraints[cloth_sim->tot_length_constraints].v1 = v1; - cloth_sim->length_constraints[cloth_sim->tot_length_constraints].v2 = v2; - cloth_sim->length_constraints[cloth_sim->tot_length_constraints].length = len_v3v3( - SCULPT_vertex_co_get(ss, v1), SCULPT_vertex_co_get(ss, v2)); - - cloth_sim->tot_length_constraints++; - - /* Reallocation if the array capacity is exceeded. */ if (cloth_sim->tot_length_constraints >= cloth_sim->capacity_length_constraints) { cloth_sim->capacity_length_constraints += CLOTH_LENGTH_CONSTRAINTS_BLOCK; cloth_sim->length_constraints = MEM_reallocN_id(cloth_sim->length_constraints, @@ -133,23 +151,119 @@ static void cloth_brush_add_length_constraint(SculptSession *ss, sizeof(SculptClothLengthConstraint), "length constraints"); } +} + +static void cloth_brush_add_length_constraint(SculptSession *ss, + SculptClothSimulation *cloth_sim, + const int v1, + const int v2, + const bool use_persistent) +{ + SculptClothLengthConstraint *length_constraint = + &cloth_sim->length_constraints[cloth_sim->tot_length_constraints]; + + length_constraint->elem_index_a = v1; + length_constraint->elem_index_b = v2; + + length_constraint->elem_position_a = cloth_sim->pos[v1]; + length_constraint->elem_position_b = cloth_sim->pos[v2]; + + if (use_persistent) { + length_constraint->length = len_v3v3(SCULPT_vertex_persistent_co_get(ss, v1), + SCULPT_vertex_persistent_co_get(ss, v2)); + } + else { + length_constraint->length = len_v3v3(SCULPT_vertex_co_get(ss, v1), + SCULPT_vertex_co_get(ss, v2)); + } + length_constraint->strength = 1.0f; + + cloth_sim->tot_length_constraints++; + + /* Reallocation if the array capacity is exceeded. */ + cloth_brush_reallocate_constraints(cloth_sim); /* Add the constraint to the GSet to avoid creating it again. */ BLI_edgeset_add(cloth_sim->created_length_constraints, v1, v2); } +static void cloth_brush_add_softbody_constraint(SculptClothSimulation *cloth_sim, + const int v, + const float strength) +{ + SculptClothLengthConstraint *length_constraint = + &cloth_sim->length_constraints[cloth_sim->tot_length_constraints]; + + length_constraint->elem_index_a = v; + length_constraint->elem_index_b = v; + + length_constraint->elem_position_a = cloth_sim->pos[v]; + length_constraint->elem_position_b = cloth_sim->init_pos[v]; + + length_constraint->length = 0.0f; + length_constraint->strength = strength; + + cloth_sim->tot_length_constraints++; + + /* Reallocation if the array capacity is exceeded. */ + cloth_brush_reallocate_constraints(cloth_sim); +} + +static void cloth_brush_add_deformation_constraint(SculptClothSimulation *cloth_sim, + const int v, + const float strength) +{ + SculptClothLengthConstraint *length_constraint = + &cloth_sim->length_constraints[cloth_sim->tot_length_constraints]; + + length_constraint->elem_index_a = v; + length_constraint->elem_index_b = v; + + length_constraint->elem_position_a = cloth_sim->pos[v]; + length_constraint->elem_position_b = cloth_sim->deformation_pos[v]; + + length_constraint->length = 0.0f; + length_constraint->strength = strength; + + cloth_sim->tot_length_constraints++; + + /* Reallocation if the array capacity is exceeded. */ + cloth_brush_reallocate_constraints(cloth_sim); +} + static void do_cloth_brush_build_constraints_task_cb_ex( void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) { SculptThreadedTaskData *data = userdata; SculptSession *ss = data->ob->sculpt; + const Brush *brush = data->brush; PBVHVertexIter vd; + const bool pin_simulation_boundary = ss->cache != NULL && brush != NULL && + brush->flag2 & BRUSH_CLOTH_PIN_SIMULATION_BOUNDARY; + + const bool use_persistent = brush != NULL && brush->flag & BRUSH_PERSISTENT; + + /* Brush can be NULL in tools that use the solver without relying of constraints with deformation + * positions. */ + const bool cloth_is_deform_brush = ss->cache != NULL && brush != NULL && + SCULPT_is_cloth_deform_brush(brush); + float radius_squared = 0.0f; + if (cloth_is_deform_brush) { + radius_squared = ss->cache->initial_radius * ss->cache->initial_radius; + } + + /* Only limit the contraint creation to a radius when the simulation is local. */ + const float cloth_sim_radius_squared = brush->cloth_simulation_area_type == + BRUSH_CLOTH_SIMULATION_AREA_LOCAL ? + data->cloth_sim_radius * data->cloth_sim_radius : + FLT_MAX; + BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (len_squared_v3v3(vd.co, data->cloth_sim_initial_location) < - data->cloth_sim_radius * data->cloth_sim_radius) { + const float len_squared = len_squared_v3v3(vd.co, data->cloth_sim_initial_location); + if (len_squared < cloth_sim_radius_squared) { SculptVertexNeighborIter ni; int build_indices[CLOTH_MAX_CONSTRAINTS_PER_VERTEX]; @@ -162,6 +276,11 @@ static void do_cloth_brush_build_constraints_task_cb_ex( } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); + if (brush->cloth_constraint_softbody_strength > 0.0f) { + cloth_brush_add_softbody_constraint( + data->cloth_sim, vd.index, brush->cloth_constraint_softbody_strength); + } + /* As we don't know the order of the neighbor vertices, we create all possible combinations * between the neighbor and the original vertex as length constraints. */ /* This results on a pattern that contains structural, shear and bending constraints for all @@ -172,35 +291,29 @@ static void do_cloth_brush_build_constraints_task_cb_ex( if (c_i != c_j && !cloth_brush_sim_has_length_constraint( data->cloth_sim, build_indices[c_i], build_indices[c_j])) { cloth_brush_add_length_constraint( - ss, data->cloth_sim, build_indices[c_i], build_indices[c_j]); + ss, data->cloth_sim, build_indices[c_i], build_indices[c_j], use_persistent); } } } } - } - BKE_pbvh_vertex_iter_end; -} -static float cloth_brush_simulation_falloff_get(const Brush *brush, - const float radius, - const float location[3], - const float co[3]) -{ - const float distance = len_v3v3(location, co); - const float limit = radius + (radius * brush->cloth_sim_limit); - const float falloff = radius + (radius * brush->cloth_sim_limit * brush->cloth_sim_falloff); + if (cloth_is_deform_brush && len_squared < radius_squared) { + const float fade = BKE_brush_curve_strength(brush, sqrtf(len_squared), ss->cache->radius); + cloth_brush_add_deformation_constraint(data->cloth_sim, vd.index, fade); + } - if (distance > limit) { - /* Outiside the limits. */ - return 0.0f; - } - if (distance < falloff) { - /* Before the falloff area. */ - return 1.0f; + if (pin_simulation_boundary) { + const float sim_falloff = cloth_brush_simulation_falloff_get( + brush, ss->cache->initial_radius, ss->cache->location, vd.co); + /* Vertex is inside the area of the simulation without any falloff aplied. */ + if (sim_falloff < 1.0f) { + /* Create constraints with more strength the closer the vertex is to the simulation + * boundary. */ + cloth_brush_add_softbody_constraint(data->cloth_sim, vd.index, 1.0f - sim_falloff); + } + } } - /* Do a smoothstep transition inside the falloff area. */ - float p = 1.0f - ((distance - falloff) / (limit - falloff)); - return 3.0f * p * p - 2.0f * p * p * p; + BKE_pbvh_vertex_iter_end; } static void cloth_brush_apply_force_to_vertex(SculptSession *UNUSED(ss), @@ -323,9 +436,10 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata, mul_v3_v3fl(force, offset, -fade); break; case BRUSH_CLOTH_DEFORM_GRAB: - /* Grab writes the positions in the simulation directly without applying forces. */ - madd_v3_v3v3fl( - cloth_sim->pos[vd.index], orig_data.co, ss->cache->grab_delta_symmetry, fade); + madd_v3_v3v3fl(cloth_sim->deformation_pos[vd.index], + orig_data.co, + ss->cache->grab_delta_symmetry, + fade); zero_v3(force); break; case BRUSH_CLOTH_DEFORM_PINCH_POINT: @@ -366,9 +480,36 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } +static ListBase *cloth_brush_collider_cache_create(Depsgraph *depsgraph) +{ + ListBase *cache = NULL; + DEG_OBJECT_ITER_BEGIN (depsgraph, + ob, + DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE | + DEG_ITER_OBJECT_FLAG_DUPLI) { + CollisionModifierData *cmd = (CollisionModifierData *)BKE_modifiers_findby_type( + ob, eModifierType_Collision); + if (cmd && cmd->bvhtree) { + if (cache == NULL) { + cache = MEM_callocN(sizeof(ListBase), "ColliderCache array"); + } + + ColliderCache *col = MEM_callocN(sizeof(ColliderCache), "ColliderCache"); + col->ob = ob; + col->collmd = cmd; + collision_move_object(cmd, 1.0, 0.0, true); + BLI_addtail(cache, col); + } + } + DEG_OBJECT_ITER_END; + return cache; +} + static SculptClothSimulation *cloth_brush_simulation_create(SculptSession *ss, + Brush *brush, const float cloth_mass, - const float cloth_damping) + const float cloth_damping, + const bool use_collisions) { const int totverts = SCULPT_vertex_count_get(ss); SculptClothSimulation *cloth_sim; @@ -380,19 +521,130 @@ static SculptClothSimulation *cloth_brush_simulation_create(SculptSession *ss, "cloth length constraints"); cloth_sim->capacity_length_constraints = CLOTH_LENGTH_CONSTRAINTS_BLOCK; - cloth_sim->acceleration = MEM_callocN(sizeof(float) * 3 * totverts, "cloth sim acceleration"); - cloth_sim->pos = MEM_callocN(sizeof(float) * 3 * totverts, "cloth sim pos"); - cloth_sim->prev_pos = MEM_callocN(sizeof(float) * 3 * totverts, "cloth sim prev pos"); - cloth_sim->init_pos = MEM_callocN(sizeof(float) * 3 * totverts, "cloth sim init pos"); - cloth_sim->length_constraint_tweak = MEM_callocN(sizeof(float) * totverts, - "cloth sim length tweak"); + cloth_sim->acceleration = MEM_calloc_arrayN( + totverts, 3 * sizeof(float), "cloth sim acceleration"); + cloth_sim->pos = MEM_calloc_arrayN(totverts, 3 * sizeof(float), "cloth sim pos"); + cloth_sim->prev_pos = MEM_calloc_arrayN(totverts, 3 * sizeof(float), "cloth sim prev pos"); + cloth_sim->last_iteration_pos = MEM_calloc_arrayN( + totverts, sizeof(float) * 3, "cloth sim last iteration pos"); + cloth_sim->init_pos = MEM_calloc_arrayN(totverts, 3 * sizeof(float), "cloth sim init pos"); + cloth_sim->length_constraint_tweak = MEM_calloc_arrayN( + totverts, sizeof(float), "cloth sim length tweak"); + + /* Brush can be NULL for tools that need the solver but don't rely on constraint to deformation + * positions. */ + if (brush && SCULPT_is_cloth_deform_brush(brush)) { + cloth_sim->deformation_pos = MEM_calloc_arrayN( + totverts, 3 * sizeof(float), "cloth sim deformation positions"); + } cloth_sim->mass = cloth_mass; cloth_sim->damping = cloth_damping; + if (use_collisions) { + cloth_sim->collider_list = cloth_brush_collider_cache_create(ss->depsgraph); + } + return cloth_sim; } +typedef struct ClothBrushCollision { + CollisionModifierData *col_data; + struct IsectRayPrecalc isect_precalc; +} ClothBrushCollision; + +static void cloth_brush_collision_cb(void *userdata, + int index, + const BVHTreeRay *ray, + BVHTreeRayHit *hit) +{ + ClothBrushCollision *col = (ClothBrushCollision *)userdata; + CollisionModifierData *col_data = col->col_data; + MVertTri *verttri = &col_data->tri[index]; + MVert *mverts = col_data->x; + float *tri[3], no[3], co[3]; + + tri[0] = mverts[verttri->tri[0]].co; + tri[1] = mverts[verttri->tri[1]].co; + tri[2] = mverts[verttri->tri[2]].co; + float dist = 0.0f; + + bool tri_hit = isect_ray_tri_watertight_v3( + ray->origin, &col->isect_precalc, UNPACK3(tri), &dist, NULL); + normal_tri_v3(no, UNPACK3(tri)); + madd_v3_v3v3fl(co, ray->origin, ray->direction, dist); + + if (tri_hit && dist < hit->dist) { + hit->index = index; + hit->dist = dist; + + copy_v3_v3(hit->co, co); + copy_v3_v3(hit->no, no); + } +} + +static void cloth_brush_solve_collision(Object *object, + SculptClothSimulation *cloth_sim, + const int i) +{ + const int raycast_flag = BVH_RAYCAST_DEFAULT & ~(BVH_RAYCAST_WATERTIGHT); + + ColliderCache *collider_cache; + BVHTreeRayHit hit; + + float obmat_inv[4][4]; + invert_m4_m4(obmat_inv, object->obmat); + + for (collider_cache = cloth_sim->collider_list->first; collider_cache; + collider_cache = collider_cache->next) { + float ray_start[3], ray_normal[3]; + float pos_world_space[3], prev_pos_world_space[3]; + + mul_v3_m4v3(pos_world_space, object->obmat, cloth_sim->pos[i]); + mul_v3_m4v3(prev_pos_world_space, object->obmat, cloth_sim->last_iteration_pos[i]); + sub_v3_v3v3(ray_normal, pos_world_space, prev_pos_world_space); + copy_v3_v3(ray_start, prev_pos_world_space); + hit.index = -1; + hit.dist = len_v3(ray_normal); + normalize_v3(ray_normal); + + ClothBrushCollision col; + CollisionModifierData *collmd = collider_cache->collmd; + col.col_data = collmd; + isect_ray_tri_watertight_v3_precalc(&col.isect_precalc, ray_normal); + + BLI_bvhtree_ray_cast_ex(collmd->bvhtree, + ray_start, + ray_normal, + 0.3f, + &hit, + cloth_brush_collision_cb, + &col, + raycast_flag); + + if (hit.index != -1) { + + float collision_disp[3]; + float movement_disp[3]; + mul_v3_v3fl(collision_disp, hit.no, 0.005f); + sub_v3_v3v3(movement_disp, pos_world_space, prev_pos_world_space); + float friction_plane[4]; + float pos_on_friction_plane[3]; + plane_from_point_normal_v3(friction_plane, hit.co, hit.no); + closest_to_plane_v3(pos_on_friction_plane, friction_plane, pos_world_space); + sub_v3_v3v3(movement_disp, pos_on_friction_plane, hit.co); + + /* TODO(pablodp606): This can be exposed in a brush/filter property as friction. */ + mul_v3_fl(movement_disp, 0.35f); + + copy_v3_v3(cloth_sim->pos[i], hit.co); + add_v3_v3(cloth_sim->pos[i], movement_disp); + add_v3_v3(cloth_sim->pos[i], collision_disp); + mul_v3_m4v3(cloth_sim->pos[i], obmat_inv, cloth_sim->pos[i]); + } + } +} + static void do_cloth_brush_solve_simulation_task_cb_ex( void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) { @@ -423,14 +675,22 @@ static void do_cloth_brush_solve_simulation_task_cb_ex( const float mask_v = (1.0f - (vd.mask ? *vd.mask : 0.0f)) * SCULPT_automasking_factor_get(ss, vd.index); + madd_v3_v3fl(cloth_sim->pos[i], pos_diff, mask_v); madd_v3_v3fl(cloth_sim->pos[i], cloth_sim->acceleration[i], mask_v); - copy_v3_v3(cloth_sim->prev_pos[i], temp); + if (cloth_sim->collider_list != NULL) { + cloth_brush_solve_collision(data->ob, cloth_sim, i); + } + + copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]); + copy_v3_v3(cloth_sim->prev_pos[i], temp); + copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]); copy_v3_fl(cloth_sim->acceleration[i], 0.0f); copy_v3_v3(vd.co, cloth_sim->pos[vd.index]); + if (vd.mvert) { vd.mvert->flag |= ME_VERT_PBVH_UPDATE; } @@ -484,11 +744,11 @@ static void cloth_brush_satisfy_constraints(SculptSession *ss, for (int i = 0; i < cloth_sim->tot_length_constraints; i++) { const SculptClothLengthConstraint *constraint = &cloth_sim->length_constraints[i]; - const int v1 = constraint->v1; - const int v2 = constraint->v2; + const int v1 = constraint->elem_index_a; + const int v2 = constraint->elem_index_b; float v1_to_v2[3]; - sub_v3_v3v3(v1_to_v2, cloth_sim->pos[v2], cloth_sim->pos[v1]); + sub_v3_v3v3(v1_to_v2, constraint->elem_position_b, constraint->elem_position_a); const float current_distance = len_v3(v1_to_v2); float correction_vector[3]; float correction_vector_half[3]; @@ -524,8 +784,14 @@ static void cloth_brush_satisfy_constraints(SculptSession *ss, cloth_sim->init_pos[v2]) : 1.0f; - madd_v3_v3fl(cloth_sim->pos[v1], correction_vector_half, 1.0f * mask_v1 * sim_factor_v1); - madd_v3_v3fl(cloth_sim->pos[v2], correction_vector_half, -1.0f * mask_v2 * sim_factor_v2); + madd_v3_v3fl(cloth_sim->pos[v1], + correction_vector_half, + 1.0f * mask_v1 * sim_factor_v1 * constraint->strength); + if (v1 != v2) { + madd_v3_v3fl(cloth_sim->pos[v2], + correction_vector_half, + -1.0f * mask_v2 * sim_factor_v2 * constraint->strength); + } } } } @@ -577,7 +843,7 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod .mat = imat, }; - BKE_curvemapping_initialize(brush->curve); + BKE_curvemapping_init(brush->curve); /* Init the grab delta. */ copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry); @@ -648,11 +914,20 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode /* The simulation structure only needs to be created on the first symmetry pass. */ if (SCULPT_stroke_is_first_brush_step(ss->cache) || !ss->cache->cloth_sim) { + const bool is_cloth_deform_brush = SCULPT_is_cloth_deform_brush(brush); ss->cache->cloth_sim = cloth_brush_simulation_create( - ss, brush->cloth_mass, brush->cloth_damping); + ss, + brush, + brush->cloth_mass, + brush->cloth_damping, + (brush->flag2 & BRUSH_CLOTH_USE_COLLISION)); for (int i = 0; i < totverts; i++) { - copy_v3_v3(ss->cache->cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, i)); + copy_v3_v3(ss->cache->cloth_sim->last_iteration_pos[i], SCULPT_vertex_co_get(ss, i)); copy_v3_v3(ss->cache->cloth_sim->init_pos[i], SCULPT_vertex_co_get(ss, i)); + copy_v3_v3(ss->cache->cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, i)); + if (is_cloth_deform_brush) { + copy_v3_v3(ss->cache->cloth_sim->deformation_pos[i], SCULPT_vertex_co_get(ss, i)); + } } } @@ -680,18 +955,22 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim) { MEM_SAFE_FREE(cloth_sim->pos); + MEM_SAFE_FREE(cloth_sim->last_iteration_pos); MEM_SAFE_FREE(cloth_sim->prev_pos); MEM_SAFE_FREE(cloth_sim->acceleration); MEM_SAFE_FREE(cloth_sim->length_constraints); MEM_SAFE_FREE(cloth_sim->length_constraint_tweak); + MEM_SAFE_FREE(cloth_sim->deformation_pos); MEM_SAFE_FREE(cloth_sim->init_pos); + if (cloth_sim->collider_list) { + BKE_collider_cache_free(&cloth_sim->collider_list); + } MEM_SAFE_FREE(cloth_sim); } /* Cursor drawing function. */ void SCULPT_cloth_simulation_limits_draw(const uint gpuattr, const Brush *brush, - const float obmat[4][4], const float location[3], const float normal[3], const float rds, @@ -700,12 +979,13 @@ void SCULPT_cloth_simulation_limits_draw(const uint gpuattr, const float alpha) { float cursor_trans[4][4], cursor_rot[4][4]; - float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f}; + const float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f}; float quat[4]; - copy_m4_m4(cursor_trans, obmat); + unit_m4(cursor_trans); translate_m4(cursor_trans, location[0], location[1], location[2]); rotation_between_vecs_to_quat(quat, z_axis, normal); quat_to_mat4(cursor_rot, quat); + GPU_matrix_push(); GPU_matrix_mul(cursor_trans); GPU_matrix_mul(cursor_rot); @@ -715,6 +995,7 @@ void SCULPT_cloth_simulation_limits_draw(const uint gpuattr, gpuattr, 0, 0, rds + (rds * brush->cloth_sim_limit * brush->cloth_sim_falloff), 320); immUniformColor3fvAlpha(outline_col, alpha * 0.7f); imm_draw_circle_wire_3d(gpuattr, 0, 0, rds + rds * brush->cloth_sim_limit, 80); + GPU_matrix_pop(); } void SCULPT_cloth_plane_falloff_preview_draw(const uint gpuattr, @@ -861,6 +1142,7 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false); const int totverts = SCULPT_vertex_count_get(ss); + for (int i = 0; i < totverts; i++) { copy_v3_v3(ss->filter_cache->cloth_sim->pos[i], SCULPT_vertex_co_get(ss, i)); } @@ -892,7 +1174,7 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent *event) { Object *ob = CTX_data_active_object(C); - Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); Sculpt *sd = CTX_data_tool_settings(C)->sculpt; SculptSession *ss = ob->sculpt; @@ -913,11 +1195,15 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent const float cloth_mass = RNA_float_get(op->ptr, "cloth_mass"); const float cloth_damping = RNA_float_get(op->ptr, "cloth_damping"); - ss->filter_cache->cloth_sim = cloth_brush_simulation_create(ss, cloth_mass, cloth_damping); + const bool use_collisions = RNA_boolean_get(op->ptr, "use_collisions"); + ss->filter_cache->cloth_sim = cloth_brush_simulation_create( + ss, NULL, cloth_mass, cloth_damping, use_collisions); + copy_v3_v3(ss->filter_cache->cloth_sim_pinch_point, SCULPT_active_vertex_co_get(ss)); const int totverts = SCULPT_vertex_count_get(ss); for (int i = 0; i < totverts; i++) { + copy_v3_v3(ss->filter_cache->cloth_sim->last_iteration_pos[i], SCULPT_vertex_co_get(ss, i)); copy_v3_v3(ss->filter_cache->cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, i)); copy_v3_v3(ss->filter_cache->cloth_sim->init_pos[i], SCULPT_vertex_co_get(ss, i)); } @@ -989,4 +1275,9 @@ void SCULPT_OT_cloth_filter(struct wmOperatorType *ot) false, "Use Face Sets", "Apply the filter only to the Face Set under the cursor"); + ot->prop = RNA_def_boolean(ot->srna, + "use_collisions", + false, + "Use Collisions", + "Collide with other collider objects in the scene"); } diff --git a/source/blender/editors/sculpt_paint/sculpt_detail.c b/source/blender/editors/sculpt_paint/sculpt_detail.c index 463233fd6fb..e08f477c981 100644 --- a/source/blender/editors/sculpt_paint/sculpt_detail.c +++ b/source/blender/editors/sculpt_paint/sculpt_detail.c @@ -179,7 +179,7 @@ static void sample_detail_voxel(bContext *C, ViewContext *vc, int mx, int my) SCULPT_vertex_random_access_init(ss); /* Update the active vertex. */ - float mouse[2] = {mx, my}; + const float mouse[2] = {mx, my}; SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false); BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false); @@ -219,7 +219,7 @@ static void sample_detail_dyntopo(bContext *C, ViewContext *vc, ARegion *region, SCULPT_stroke_modifiers_check(C, ob, brush); - float mouse[2] = {mx - region->winrct.xmin, my - region->winrct.ymin}; + const float mouse[2] = {mx - region->winrct.xmin, my - region->winrct.ymin}; float ray_start[3], ray_end[3], ray_normal[3]; float depth = SCULPT_raycast_init(vc, mouse, ray_start, ray_end, ray_normal, false); @@ -316,7 +316,7 @@ static int sculpt_sample_detail_size_modal(bContext *C, wmOperator *op, const wm switch (event->type) { case LEFTMOUSE: if (event->val == KM_PRESS) { - int ss_co[2] = {event->x, event->y}; + const int ss_co[2] = {event->x, event->y}; int mode = RNA_enum_get(op->ptr, "mode"); sample_detail(C, ss_co[0], ss_co[1], mode); diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c index 1940b007cb0..5cc32be331e 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.c +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c @@ -192,7 +192,7 @@ void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); - BKE_curvemapping_initialize(brush->curve); + BKE_curvemapping_init(brush->curve); /* Threaded loop over nodes. */ SculptThreadedTaskData data = { diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c index e9a98a17f8a..e39cdc2db23 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c @@ -82,7 +82,7 @@ void SCULPT_filter_cache_init(Object *ob, Sculpt *sd, const int undo_type) ss->filter_cache->random_seed = rand(); - float center[3] = {0.0f}; + const float center[3] = {0.0f}; SculptSearchSphereData search_data = { .original = true, .center = center, @@ -132,6 +132,7 @@ void SCULPT_filter_cache_free(SculptSession *ss) MEM_SAFE_FREE(ss->filter_cache->automask); MEM_SAFE_FREE(ss->filter_cache->surface_smooth_laplacian_disp); MEM_SAFE_FREE(ss->filter_cache->sharpen_factor); + MEM_SAFE_FREE(ss->filter_cache->sharpen_detail_directions); MEM_SAFE_FREE(ss->filter_cache); } @@ -356,6 +357,17 @@ static void mesh_filter_task_cb(void *__restrict userdata, mul_v3_v3fl( disp_avg, disp_avg, smooth_ratio * pow2f(ss->filter_cache->sharpen_factor[vd.index])); add_v3_v3v3(disp, disp_avg, disp_sharpen); + + /* Intensify details. */ + if (ss->filter_cache->sharpen_intensify_detail_strength > 0.0f) { + float detail_strength[3]; + normal_short_to_float_v3(detail_strength, orig_data.no); + copy_v3_v3(detail_strength, ss->filter_cache->sharpen_detail_directions[vd.index]); + madd_v3_v3fl(disp, + detail_strength, + -ss->filter_cache->sharpen_intensify_detail_strength * + ss->filter_cache->sharpen_factor[vd.index]); + } break; } } @@ -388,8 +400,10 @@ static void mesh_filter_sharpen_init_factors(SculptSession *ss) for (int i = 0; i < totvert; i++) { float avg[3]; SCULPT_neighbor_coords_average(ss, avg, i); - ss->filter_cache->sharpen_factor[i] = len_v3v3(avg, SCULPT_vertex_co_get(ss, i)); + sub_v3_v3v3(ss->filter_cache->sharpen_detail_directions[i], avg, SCULPT_vertex_co_get(ss, i)); + ss->filter_cache->sharpen_factor[i] = len_v3(ss->filter_cache->sharpen_detail_directions[i]); } + float max_factor = 0.0f; for (int i = 0; i < totvert; i++) { if (ss->filter_cache->sharpen_factor[i] > max_factor) { @@ -402,6 +416,31 @@ static void mesh_filter_sharpen_init_factors(SculptSession *ss) ss->filter_cache->sharpen_factor[i] *= max_factor; ss->filter_cache->sharpen_factor[i] = 1.0f - pow2f(1.0f - ss->filter_cache->sharpen_factor[i]); } + + /* Smooth the calculated factors and directions to remove high frecuency detail. */ + for (int smooth_iterations = 0; + smooth_iterations < ss->filter_cache->sharpen_curvature_smooth_iterations; + smooth_iterations++) { + for (int i = 0; i < totvert; i++) { + float direction_avg[3] = {0.0f, 0.0f, 0.0f}; + float sharpen_avg = 0; + int total = 0; + + SculptVertexNeighborIter ni; + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) { + add_v3_v3(direction_avg, ss->filter_cache->sharpen_detail_directions[ni.index]); + sharpen_avg += ss->filter_cache->sharpen_factor[ni.index]; + total++; + } + SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); + + if (total > 0) { + mul_v3_v3fl( + ss->filter_cache->sharpen_detail_directions[i], direction_avg, 1.0f / (float)total); + ss->filter_cache->sharpen_factor[i] = sharpen_avg / (float)total; + } + } + } } static void mesh_filter_surface_smooth_displace_task_cb( @@ -566,7 +605,14 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_SHARPEN) { ss->filter_cache->sharpen_smooth_ratio = RNA_float_get(op->ptr, "sharpen_smooth_ratio"); + ss->filter_cache->sharpen_intensify_detail_strength = RNA_float_get( + op->ptr, "sharpen_intensify_detail_strength"); + ss->filter_cache->sharpen_curvature_smooth_iterations = RNA_int_get( + op->ptr, "sharpen_curvature_smooth_iterations"); + ss->filter_cache->sharpen_factor = MEM_mallocN(sizeof(float) * totvert, "sharpen factor"); + ss->filter_cache->sharpen_detail_directions = MEM_malloc_arrayN( + totvert, 3 * sizeof(float), "sharpen detail direction"); mesh_filter_sharpen_init_factors(ss); } @@ -642,4 +688,24 @@ void SCULPT_OT_mesh_filter(struct wmOperatorType *ot) "How much smoothing is applied to polished surfaces", 0.0f, 1.0f); + + RNA_def_float(ot->srna, + "sharpen_intensify_detail_strength", + 0.0f, + 0.0f, + 10.0f, + "Intensify Details", + "How much creases and valleys are intensified", + 0.0f, + 1.0f); + + RNA_def_int(ot->srna, + "sharpen_curvature_smooth_iterations", + 0, + 0, + 10, + "Curvature Smooth Iterations", + "How much smooth the resulting shape is, ignoring high frequency details", + 0, + 10); } diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 6a989ffea7e..74feaa8ca00 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -97,6 +97,9 @@ void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3]); float SCULPT_vertex_mask_get(struct SculptSession *ss, int index); const float *SCULPT_vertex_color_get(SculptSession *ss, int index); +const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, int index); +void SCULPT_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3]); + #define SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY 256 typedef struct SculptVertexNeighborIter { /* Storage */ @@ -347,7 +350,6 @@ void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim); void SCULPT_cloth_simulation_limits_draw(const uint gpuattr, const struct Brush *brush, - const float obmat[4][4], const float location[3], const float normal[3], const float rds, @@ -393,6 +395,7 @@ void SCULPT_pose_ik_chain_free(struct SculptPoseIKChain *ik_chain); /* Multiplane Scrape Brush. */ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); void SCULPT_multiplane_scrape_preview_draw(const uint gpuattr, + Brush *brush, SculptSession *ss, const float outline_col[3], const float outline_alpha); @@ -905,7 +908,10 @@ typedef struct FilterCache { /* Sharpen mesh filter. */ float sharpen_smooth_ratio; + float sharpen_intensify_detail_strength; + int sharpen_curvature_smooth_iterations; float *sharpen_factor; + float (*sharpen_detail_directions)[3]; /* unmasked nodes */ PBVHNode **nodes; diff --git a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c b/source/blender/editors/sculpt_paint/sculpt_mask_expand.c index 60483cc168d..bc493a036f0 100644 --- a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_mask_expand.c @@ -174,7 +174,7 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent * ARegion *region = CTX_wm_region(C); float prevclick_f[2]; copy_v2_v2(prevclick_f, op->customdata); - int prevclick[2] = {(int)prevclick_f[0], (int)prevclick_f[1]}; + const int prevclick[2] = {(int)prevclick_f[0], (int)prevclick_f[1]}; int len = (int)len_v2v2_int(prevclick, event->mval); len = abs(len); int mask_speed = RNA_int_get(op->ptr, "mask_speed"); diff --git a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c index b52036d753c..e47a94dff90 100644 --- a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c +++ b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c @@ -47,7 +47,6 @@ #include "paint_intern.h" #include "sculpt_intern.h" -#include "GPU_draw.h" #include "GPU_immediate.h" #include "GPU_immediate_util.h" #include "GPU_matrix.h" @@ -376,7 +375,7 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, /* Calculate the final left and right scrape planes. */ float plane_no[3]; float plane_no_rot[3]; - float y_axis[3] = {0.0f, 1.0f, 0.0f}; + const float y_axis[3] = {0.0f, 1.0f, 0.0f}; float mat_inv[4][4]; invert_m4_m4(mat_inv, mat); @@ -400,10 +399,15 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, } void SCULPT_multiplane_scrape_preview_draw(const uint gpuattr, + Brush *brush, SculptSession *ss, const float outline_col[3], const float outline_alpha) { + if (!(brush->flag2 & BRUSH_MULTIPLANE_SCRAPE_PLANES_PREVIEW)) { + return; + } + float local_mat_inv[4][4]; invert_m4_m4(local_mat_inv, ss->cache->stroke_local_mat); GPU_matrix_mul(local_mat_inv); @@ -414,11 +418,11 @@ void SCULPT_multiplane_scrape_preview_draw(const uint gpuattr, float offset = ss->cache->radius * 0.25f; - float p[3] = {0.0f, 0.0f, ss->cache->radius}; - float y_axis[3] = {0.0f, 1.0f, 0.0f}; + const float p[3] = {0.0f, 0.0f, ss->cache->radius}; + const float y_axis[3] = {0.0f, 1.0f, 0.0f}; float p_l[3]; float p_r[3]; - float area_center[3] = {0.0f, 0.0f, 0.0f}; + const float area_center[3] = {0.0f, 0.0f, 0.0f}; rotate_v3_v3v3fl(p_r, p, y_axis, DEG2RADF((angle + 180) * 0.5f)); rotate_v3_v3v3fl(p_l, p, y_axis, DEG2RADF(-(angle + 180) * 0.5f)); diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c index f01a914fdd3..00a59949130 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c +++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c @@ -255,7 +255,7 @@ void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode return; } - BKE_curvemapping_initialize(brush->curve); + BKE_curvemapping_init(brush->curve); float area_no[3]; float mat[4][4]; @@ -468,7 +468,7 @@ void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode } } - BKE_curvemapping_initialize(brush->curve); + BKE_curvemapping_init(brush->curve); SculptThreadedTaskData data = { .sd = sd, diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c index dc556fa1945..8a288877d43 100644 --- a/source/blender/editors/sculpt_paint/sculpt_pose.c +++ b/source/blender/editors/sculpt_paint/sculpt_pose.c @@ -1006,7 +1006,7 @@ void SCULPT_pose_brush_init(Sculpt *sd, Object *ob, SculptSession *ss, Brush *br static void sculpt_pose_do_translate_deform(SculptSession *ss, Brush *brush) { SculptPoseIKChain *ik_chain = ss->cache->pose_ik_chain; - BKE_curvemapping_initialize(brush->curve); + BKE_curvemapping_init(brush->curve); pose_solve_translate_chain(ik_chain, ss->cache->grab_delta); } @@ -1031,8 +1031,10 @@ static void sculpt_pose_do_scale_deform(SculptSession *ss, Brush *brush) copy_v3_v3(ik_target, ss->cache->true_location); add_v3_v3(ik_target, ss->cache->grab_delta); - /* Solve the IK for the first segment to include rotation as part of scale. */ - pose_solve_ik_chain(ik_chain, ik_target, brush->flag2 & BRUSH_POSE_IK_ANCHORED); + /* Solve the IK for the first segment to include rotation as part of scale if enabled. */ + if (!(brush->flag2 & BRUSH_POSE_USE_LOCK_ROTATION)) { + pose_solve_ik_chain(ik_chain, ik_target, brush->flag2 & BRUSH_POSE_IK_ANCHORED); + } float scale[3]; copy_v3_fl(scale, sculpt_pose_get_scale_from_grab_delta(ss, ik_target)); @@ -1047,7 +1049,7 @@ static void sculpt_pose_do_twist_deform(SculptSession *ss, Brush *brush) /* Calculate the maximum roll. 0.02 radians per pixel works fine. */ float roll = (ss->cache->initial_mouse[0] - ss->cache->mouse[0]) * ss->cache->bstrength * 0.02f; - BKE_curvemapping_initialize(brush->curve); + BKE_curvemapping_init(brush->curve); pose_solve_roll_chain(ik_chain, brush, roll); } diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c index 4b3df2dfea2..be509f4aed6 100644 --- a/source/blender/editors/sculpt_paint/sculpt_uv.c +++ b/source/blender/editors/sculpt_paint/sculpt_uv.c @@ -488,7 +488,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm op->customdata = data; - BKE_curvemapping_initialize(ts->uvsculpt->paint.brush->curve); + BKE_curvemapping_init(ts->uvsculpt->paint.brush->curve); if (data) { int counter = 0, i; diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index 079cee290ae..db55eff8284 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -60,7 +60,7 @@ /* ******************** default callbacks for action space ***************** */ -static SpaceLink *action_new(const ScrArea *area, const Scene *scene) +static SpaceLink *action_create(const ScrArea *area, const Scene *scene) { SpaceAction *saction; ARegion *region; @@ -863,7 +863,7 @@ void ED_spacetype_action(void) st->spaceid = SPACE_ACTION; strncpy(st->name, "Action", BKE_ST_MAXNAME); - st->new = action_new; + st->create = action_create; st->free = action_free; st->init = action_init; st->duplicate = action_duplicate; diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 3ae203b563b..1656a76e2d4 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -280,7 +280,7 @@ void ED_region_draw_cb_draw(const bContext *C, ARegion *region, int type) void ED_spacetype_xxx(void); /* allocate and init some vars */ -static SpaceLink *xxx_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) +static SpaceLink *xxx_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) { return NULL; } @@ -324,7 +324,7 @@ void ED_spacetype_xxx(void) st.spaceid = SPACE_VIEW3D; - st.new = xxx_new; + st.create = xxx_create; st.free = xxx_free; st.init = xxx_init; st.duplicate = xxx_duplicate; diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 16256f6c97e..5885d3dcbb0 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -101,7 +101,7 @@ static PointerRNA *get_pointer_type(ButsContextPath *path, StructRNA *type) /************************* Creating the Path ************************/ -static int buttons_context_path_scene(ButsContextPath *path) +static bool buttons_context_path_scene(ButsContextPath *path) { PointerRNA *ptr = &path->ptr[path->len - 1]; @@ -162,14 +162,14 @@ static int buttons_context_path_world(ButsContextPath *path) return 0; } -static int buttons_context_path_linestyle(ButsContextPath *path, wmWindow *window) +static bool buttons_context_path_linestyle(ButsContextPath *path, wmWindow *window) { FreestyleLineStyle *linestyle; PointerRNA *ptr = &path->ptr[path->len - 1]; /* if we already have a (pinned) linestyle, we're done */ if (RNA_struct_is_a(ptr->type, &RNA_FreestyleLineStyle)) { - return 1; + return true; } /* if we have a view layer, use the lineset's linestyle */ if (buttons_context_path_view_layer(path, window)) { @@ -178,24 +178,24 @@ static int buttons_context_path_linestyle(ButsContextPath *path, wmWindow *windo if (linestyle) { RNA_id_pointer_create(&linestyle->id, &path->ptr[path->len]); path->len++; - return 1; + return true; } } /* no path to a linestyle possible */ - return 0; + return false; } -static int buttons_context_path_object(ButsContextPath *path) +static bool buttons_context_path_object(ButsContextPath *path) { PointerRNA *ptr = &path->ptr[path->len - 1]; /* if we already have a (pinned) object, we're done */ if (RNA_struct_is_a(ptr->type, &RNA_Object)) { - return 1; + return true; } if (!RNA_struct_is_a(ptr->type, &RNA_ViewLayer)) { - return 0; + return false; } ViewLayer *view_layer = ptr->data; @@ -205,58 +205,58 @@ static int buttons_context_path_object(ButsContextPath *path) RNA_id_pointer_create(&ob->id, &path->ptr[path->len]); path->len++; - return 1; + return true; } /* no path to a object possible */ - return 0; + return false; } -static int buttons_context_path_data(ButsContextPath *path, int type) +static bool buttons_context_path_data(ButsContextPath *path, int type) { Object *ob; PointerRNA *ptr = &path->ptr[path->len - 1]; /* if we already have a data, we're done */ if (RNA_struct_is_a(ptr->type, &RNA_Mesh) && (type == -1 || type == OB_MESH)) { - return 1; + return true; } if (RNA_struct_is_a(ptr->type, &RNA_Curve) && (type == -1 || ELEM(type, OB_CURVE, OB_SURF, OB_FONT))) { - return 1; + return true; } if (RNA_struct_is_a(ptr->type, &RNA_Armature) && (type == -1 || type == OB_ARMATURE)) { - return 1; + return true; } if (RNA_struct_is_a(ptr->type, &RNA_MetaBall) && (type == -1 || type == OB_MBALL)) { - return 1; + return true; } if (RNA_struct_is_a(ptr->type, &RNA_Lattice) && (type == -1 || type == OB_LATTICE)) { - return 1; + return true; } if (RNA_struct_is_a(ptr->type, &RNA_Camera) && (type == -1 || type == OB_CAMERA)) { - return 1; + return true; } if (RNA_struct_is_a(ptr->type, &RNA_Light) && (type == -1 || type == OB_LAMP)) { - return 1; + return true; } if (RNA_struct_is_a(ptr->type, &RNA_Speaker) && (type == -1 || type == OB_SPEAKER)) { - return 1; + return true; } if (RNA_struct_is_a(ptr->type, &RNA_LightProbe) && (type == -1 || type == OB_LIGHTPROBE)) { - return 1; + return true; } if (RNA_struct_is_a(ptr->type, &RNA_GreasePencil) && (type == -1 || type == OB_GPENCIL)) { - return 1; + return true; } if (RNA_struct_is_a(ptr->type, &RNA_Hair) && (type == -1 || type == OB_HAIR)) { - return 1; + return true; } if (RNA_struct_is_a(ptr->type, &RNA_PointCloud) && (type == -1 || type == OB_POINTCLOUD)) { - return 1; + return true; } if (RNA_struct_is_a(ptr->type, &RNA_Volume) && (type == -1 || type == OB_VOLUME)) { - return 1; + return true; } /* try to get an object in the path, no pinning supported here */ if (buttons_context_path_object(path)) { @@ -266,15 +266,15 @@ static int buttons_context_path_data(ButsContextPath *path, int type) RNA_id_pointer_create(ob->data, &path->ptr[path->len]); path->len++; - return 1; + return true; } } /* no path to data possible */ - return 0; + return false; } -static int buttons_context_path_modifier(ButsContextPath *path) +static bool buttons_context_path_modifier(ButsContextPath *path) { Object *ob; @@ -291,14 +291,14 @@ static int buttons_context_path_modifier(ButsContextPath *path) OB_HAIR, OB_POINTCLOUD, OB_VOLUME)) { - return 1; + return true; } } - return 0; + return false; } -static int buttons_context_path_shaderfx(ButsContextPath *path) +static bool buttons_context_path_shaderfx(ButsContextPath *path) { Object *ob; @@ -306,14 +306,14 @@ static int buttons_context_path_shaderfx(ButsContextPath *path) ob = path->ptr[path->len - 1].data; if (ob && ELEM(ob->type, OB_GPENCIL)) { - return 1; + return true; } } - return 0; + return false; } -static int buttons_context_path_material(ButsContextPath *path) +static bool buttons_context_path_material(ButsContextPath *path) { Object *ob; PointerRNA *ptr = &path->ptr[path->len - 1]; @@ -321,7 +321,7 @@ static int buttons_context_path_material(ButsContextPath *path) /* if we already have a (pinned) material, we're done */ if (RNA_struct_is_a(ptr->type, &RNA_Material)) { - return 1; + return true; } /* if we have an object, use the object material slot */ if (buttons_context_path_object(path)) { @@ -331,15 +331,15 @@ static int buttons_context_path_material(ButsContextPath *path) ma = BKE_object_material_get(ob, ob->actcol); RNA_id_pointer_create(&ma->id, &path->ptr[path->len]); path->len++; - return 1; + return true; } } /* no path to a material possible */ - return 0; + return false; } -static int buttons_context_path_bone(ButsContextPath *path) +static bool buttons_context_path_bone(ButsContextPath *path) { bArmature *arm; EditBone *edbo; @@ -353,29 +353,29 @@ static int buttons_context_path_bone(ButsContextPath *path) edbo = arm->act_edbone; RNA_pointer_create(&arm->id, &RNA_EditBone, edbo, &path->ptr[path->len]); path->len++; - return 1; + return true; } } else { if (arm->act_bone) { RNA_pointer_create(&arm->id, &RNA_Bone, arm->act_bone, &path->ptr[path->len]); path->len++; - return 1; + return true; } } } /* no path to a bone possible */ - return 0; + return false; } -static int buttons_context_path_pose_bone(ButsContextPath *path) +static bool buttons_context_path_pose_bone(ButsContextPath *path) { PointerRNA *ptr = &path->ptr[path->len - 1]; /* if we already have a (pinned) PoseBone, we're done */ if (RNA_struct_is_a(ptr->type, &RNA_PoseBone)) { - return 1; + return true; } /* if we have an armature, get the active bone */ @@ -384,7 +384,7 @@ static int buttons_context_path_pose_bone(ButsContextPath *path) bArmature *arm = ob->data; /* path->ptr[path->len-1].data - works too */ if (ob->type != OB_ARMATURE || arm->edbo) { - return 0; + return false; } if (arm->act_bone) { @@ -392,16 +392,16 @@ static int buttons_context_path_pose_bone(ButsContextPath *path) if (pchan) { RNA_pointer_create(&ob->id, &RNA_PoseBone, pchan, &path->ptr[path->len]); path->len++; - return 1; + return true; } } } /* no path to a bone possible */ - return 0; + return false; } -static int buttons_context_path_particle(ButsContextPath *path) +static bool buttons_context_path_particle(ButsContextPath *path) { Object *ob; ParticleSystem *psys; @@ -409,7 +409,7 @@ static int buttons_context_path_particle(ButsContextPath *path) /* if we already have (pinned) particle settings, we're done */ if (RNA_struct_is_a(ptr->type, &RNA_ParticleSettings)) { - return 1; + return true; } /* if we have an object, get the active particle system */ if (buttons_context_path_object(path)) { @@ -420,15 +420,15 @@ static int buttons_context_path_particle(ButsContextPath *path) RNA_pointer_create(&ob->id, &RNA_ParticleSystem, psys, &path->ptr[path->len]); path->len++; - return 1; + return true; } } /* no path to a particle system possible */ - return 0; + return false; } -static int buttons_context_path_brush(const bContext *C, ButsContextPath *path) +static bool buttons_context_path_brush(const bContext *C, ButsContextPath *path) { Scene *scene; Brush *br = NULL; @@ -436,7 +436,7 @@ static int buttons_context_path_brush(const bContext *C, ButsContextPath *path) /* if we already have a (pinned) brush, we're done */ if (RNA_struct_is_a(ptr->type, &RNA_Brush)) { - return 1; + return true; } /* if we have a scene, use the toolsettings brushes */ if (buttons_context_path_scene(path)) { @@ -452,32 +452,32 @@ static int buttons_context_path_brush(const bContext *C, ButsContextPath *path) RNA_id_pointer_create((ID *)br, &path->ptr[path->len]); path->len++; - return 1; + return true; } } /* no path to a brush possible */ - return 0; + return false; } -static int buttons_context_path_texture(const bContext *C, - ButsContextPath *path, - ButsContextTexture *ct) +static bool buttons_context_path_texture(const bContext *C, + ButsContextPath *path, + ButsContextTexture *ct) { PointerRNA *ptr = &path->ptr[path->len - 1]; ID *id; if (!ct) { - return 0; + return false; } /* if we already have a (pinned) texture, we're done */ if (RNA_struct_is_a(ptr->type, &RNA_Texture)) { - return 1; + return true; } if (!ct->user) { - return 0; + return false; } id = ct->user->id; @@ -502,7 +502,7 @@ static int buttons_context_path_texture(const bContext *C, path->len++; } - return 1; + return true; } #ifdef WITH_FREESTYLE @@ -531,7 +531,7 @@ static bool buttons_context_linestyle_pinnable(const bContext *C, ViewLayer *vie } #endif -static int buttons_context_path(const bContext *C, ButsContextPath *path, int mainb, int flag) +static bool buttons_context_path(const bContext *C, ButsContextPath *path, int mainb, int flag) { /* Note we don't use CTX_data here, instead we get it from the window. * Otherwise there is a loop reading the context that we are setting. */ @@ -626,27 +626,27 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma found = buttons_context_path_pose_bone(path); break; default: - found = 0; + found = false; break; } return found; } -static int buttons_shading_context(const bContext *C, int mainb) +static bool buttons_shading_context(const bContext *C, int mainb) { wmWindow *window = CTX_wm_window(C); ViewLayer *view_layer = WM_window_get_active_view_layer(window); Object *ob = OBACT(view_layer); if (ELEM(mainb, BCONTEXT_MATERIAL, BCONTEXT_WORLD, BCONTEXT_TEXTURE)) { - return 1; + return true; } if (mainb == BCONTEXT_DATA && ob && ELEM(ob->type, OB_LAMP, OB_CAMERA)) { - return 1; + return true; } - return 0; + return false; } static int buttons_shading_new_context(const bContext *C, int flag) diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index 733f344fbc6..a062b178fc8 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -52,7 +52,9 @@ #include "buttons_intern.h" /* own include */ -/********************** context_menu operator *********************/ +/* -------------------------------------------------------------------- */ +/** \name Context Menu Operator + * \{ */ static int context_menu_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event)) { @@ -67,17 +69,21 @@ static int context_menu_invoke(bContext *C, wmOperator *UNUSED(op), const wmEven void BUTTONS_OT_context_menu(wmOperatorType *ot) { - /* identifiers */ + /* Identifiers. */ ot->name = "Context Menu"; ot->description = "Display properties editor context_menu"; ot->idname = "BUTTONS_OT_context_menu"; - /* api callbacks */ + /* Callbacks. */ ot->invoke = context_menu_invoke; ot->poll = ED_operator_buttons_active; } -/********************** filebrowse operator *********************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name File Browse Operator + * \{ */ typedef struct FileBrowseOp { PointerRNA ptr; @@ -101,7 +107,7 @@ static int file_browse_exec(bContext *C, wmOperator *op) str = RNA_string_get_alloc(op->ptr, path_prop, NULL, 0); - /* add slash for directories, important for some properties */ + /* Add slash for directories, important for some properties. */ if (RNA_property_subtype(fbo->prop) == PROP_DIRPATH) { const bool is_relative = RNA_boolean_get(op->ptr, "relative_path"); id = fbo->ptr.owner_id; @@ -110,7 +116,7 @@ static int file_browse_exec(bContext *C, wmOperator *op) BLI_path_abs(path, id ? ID_BLEND_PATH(bmain, id) : BKE_main_blendfile_path(bmain)); if (BLI_is_dir(path)) { - /* do this first so '//' isnt converted to '//\' on windows */ + /* Do this first so '//' isnt converted to '//\' on windows. */ BLI_path_slash_ensure(path); if (is_relative) { BLI_strncpy(path, str, FILE_MAX); @@ -139,7 +145,7 @@ static int file_browse_exec(bContext *C, wmOperator *op) ED_undo_push(C, undostr); } - /* special, annoying exception, filesel on redo panel [#26618] */ + /* Special annoying exception, filesel on redo panel [#26618]. */ { wmOperator *redo_op = WM_operator_last_redo(C); if (redo_op) { @@ -187,8 +193,8 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event) str = RNA_property_string_get_alloc(&ptr, prop, NULL, 0, NULL); - /* useful yet irritating feature, Shift+Click to open the file - * Alt+Click to browse a folder in the OS's browser */ + /* Useful yet irritating feature, Shift+Click to open the file + * Alt+Click to browse a folder in the OS's browser. */ if (event->shift || event->alt) { wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true); PointerRNA props_ptr; @@ -219,13 +225,13 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event) fbo->is_userdef = is_userdef; op->customdata = fbo; - /* normally ED_fileselect_get_params would handle this but we need to because of stupid - * user-prefs exception - campbell */ + /* Normally ED_fileselect_get_params would handle this but we need to because of stupid + * user-prefs exception. - campbell */ if ((prop_relpath = RNA_struct_find_property(op->ptr, "relative_path"))) { if (!RNA_property_is_set(op->ptr, prop_relpath)) { bool is_relative = (U.flag & USER_RELPATHS) != 0; - /* while we want to follow the defaults, + /* While we want to follow the defaults, * we better not switch existing paths relative/absolute state. */ if (str[0]) { is_relative = BLI_path_is_rel(str); @@ -235,7 +241,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event) is_relative = false; } - /* annoying exception!, if we're dealing with the user prefs, default relative to be off */ + /* Annoying exception!, if we're dealing with the user prefs, default relative to be off. */ RNA_property_boolean_set(op->ptr, prop_relpath, is_relative); } } @@ -250,21 +256,21 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event) void BUTTONS_OT_file_browse(wmOperatorType *ot) { - /* identifiers */ + /* Identifiers. */ ot->name = "Accept"; ot->description = "Open a file browser, Hold Shift to open the file, Alt to browse containing directory"; ot->idname = "BUTTONS_OT_file_browse"; - /* api callbacks */ + /* Callbacks. */ ot->invoke = file_browse_invoke; ot->exec = file_browse_exec; ot->cancel = file_browse_cancel; - /* conditional undo based on button flag */ + /* Conditional undo based on button flag. */ ot->flag = 0; - /* properties */ + /* Properties. */ WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, @@ -274,7 +280,7 @@ void BUTTONS_OT_file_browse(wmOperatorType *ot) FILE_SORT_ALPHA); } -/* second operator, only difference from BUTTONS_OT_file_browse is WM_FILESEL_DIRECTORY */ +/* Second operator, only difference from BUTTONS_OT_file_browse is WM_FILESEL_DIRECTORY. */ void BUTTONS_OT_directory_browse(wmOperatorType *ot) { /* identifiers */ @@ -300,3 +306,5 @@ void BUTTONS_OT_directory_browse(wmOperatorType *ot) FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA); } + +/** \} */ diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index ac59bb245f3..dc34e56dc92 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -35,6 +35,7 @@ #include "BKE_screen.h" #include "BKE_shader_fx.h" +#include "ED_buttons.h" #include "ED_screen.h" #include "ED_space_api.h" #include "ED_view3d.h" /* To draw toolbar UI. */ @@ -49,13 +50,11 @@ #include "UI_resources.h" -#include "GPU_glew.h" - #include "buttons_intern.h" /* own include */ /* ******************** default callbacks for buttons space ***************** */ -static SpaceLink *buttons_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) +static SpaceLink *buttons_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) { ARegion *region; SpaceProperties *sbuts; @@ -139,6 +138,98 @@ static void buttons_main_region_init(wmWindowManager *wm, ARegion *region) WM_event_add_keymap_handler(®ion->handlers, keymap); } +/** + * Fills an array with the tab context values for the properties editor. -1 signals a separator. + * + * \return The total number of items in the array returned. + */ +int ED_buttons_tabs_list(SpaceProperties *sbuts, int *context_tabs_array) +{ + int length = 0; + if (sbuts->pathflag & (1 << BCONTEXT_TOOL)) { + context_tabs_array[length] = BCONTEXT_TOOL; + length++; + } + if (length != 0) { + context_tabs_array[length] = -1; + length++; + } + if (sbuts->pathflag & (1 << BCONTEXT_RENDER)) { + context_tabs_array[length] = BCONTEXT_RENDER; + length++; + } + if (sbuts->pathflag & (1 << BCONTEXT_OUTPUT)) { + context_tabs_array[length] = BCONTEXT_OUTPUT; + length++; + } + if (sbuts->pathflag & (1 << BCONTEXT_VIEW_LAYER)) { + context_tabs_array[length] = BCONTEXT_VIEW_LAYER; + length++; + } + if (sbuts->pathflag & (1 << BCONTEXT_SCENE)) { + context_tabs_array[length] = BCONTEXT_SCENE; + length++; + } + if (sbuts->pathflag & (1 << BCONTEXT_WORLD)) { + context_tabs_array[length] = BCONTEXT_WORLD; + length++; + } + if (length != 0) { + context_tabs_array[length] = -1; + length++; + } + if (sbuts->pathflag & (1 << BCONTEXT_OBJECT)) { + context_tabs_array[length] = BCONTEXT_OBJECT; + length++; + } + if (sbuts->pathflag & (1 << BCONTEXT_MODIFIER)) { + context_tabs_array[length] = BCONTEXT_MODIFIER; + length++; + } + if (sbuts->pathflag & (1 << BCONTEXT_SHADERFX)) { + context_tabs_array[length] = BCONTEXT_SHADERFX; + length++; + } + if (sbuts->pathflag & (1 << BCONTEXT_PARTICLE)) { + context_tabs_array[length] = BCONTEXT_PARTICLE; + length++; + } + if (sbuts->pathflag & (1 << BCONTEXT_PHYSICS)) { + context_tabs_array[length] = BCONTEXT_PHYSICS; + length++; + } + if (sbuts->pathflag & (1 << BCONTEXT_CONSTRAINT)) { + context_tabs_array[length] = BCONTEXT_CONSTRAINT; + length++; + } + if (sbuts->pathflag & (1 << BCONTEXT_DATA)) { + context_tabs_array[length] = BCONTEXT_DATA; + length++; + } + if (sbuts->pathflag & (1 << BCONTEXT_BONE)) { + context_tabs_array[length] = BCONTEXT_BONE; + length++; + } + if (sbuts->pathflag & (1 << BCONTEXT_BONE_CONSTRAINT)) { + context_tabs_array[length] = BCONTEXT_BONE_CONSTRAINT; + length++; + } + if (sbuts->pathflag & (1 << BCONTEXT_MATERIAL)) { + context_tabs_array[length] = BCONTEXT_MATERIAL; + length++; + } + if (length != 0) { + context_tabs_array[length] = -1; + length++; + } + if (sbuts->pathflag & (1 << BCONTEXT_TEXTURE)) { + context_tabs_array[length] = BCONTEXT_TEXTURE; + length++; + } + + return length; +} + static void buttons_main_region_layout_properties(const bContext *C, SpaceProperties *sbuts, ARegion *region) @@ -618,7 +709,7 @@ void ED_spacetype_buttons(void) st->spaceid = SPACE_PROPERTIES; strncpy(st->name, "Buttons", BKE_ST_MAXNAME); - st->new = buttons_new; + st->create = buttons_create; st->free = buttons_free; st->init = buttons_init; st->duplicate = buttons_duplicate; diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c index 71f75d96cb1..80ce07d39ef 100644 --- a/source/blender/editors/space_clip/clip_buttons.c +++ b/source/blender/editors/space_clip/clip_buttons.c @@ -273,7 +273,7 @@ typedef struct { int marker_flag; } MarkerUpdateCb; -static void to_pixel_space(float r[2], float a[2], int width, int height) +static void to_pixel_space(float r[2], const float a[2], int width, int height) { copy_v2_v2(r, a); r[0] *= width; diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index c3aca95910b..c7328ae9f8f 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -49,7 +49,9 @@ #include "clip_intern.h" /* own include */ -static void track_channel_color(MovieTrackingTrack *track, float default_color[3], float color[3]) +static void track_channel_color(MovieTrackingTrack *track, + const float default_color[3], + float color[3]) { if (track->flag & TRACK_CUSTOMCOLOR) { float bg[3]; diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index d33f624063a..1d510d2989c 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -322,7 +322,7 @@ static void draw_movieclip_buffer(const bContext *C, float zoomy) { MovieClip *clip = ED_space_clip_get_clip(sc); - int filter = GL_LINEAR; + bool use_filter = true; int x, y; /* find window pixel coordinates of origin */ @@ -340,10 +340,10 @@ static void draw_movieclip_buffer(const bContext *C, /* non-scaled proxy shouldn't use filtering */ if ((clip->flag & MCLIP_USE_PROXY) == 0 || ELEM(sc->user.render_size, MCLIP_PROXY_RENDER_SIZE_FULL, MCLIP_PROXY_RENDER_SIZE_100)) { - filter = GL_NEAREST; + use_filter = false; } - ED_draw_imbuf_ctx(C, ibuf, x, y, filter, zoomx * width / ibuf->x, zoomy * height / ibuf->y); + ED_draw_imbuf_ctx(C, ibuf, x, y, use_filter, zoomx * width / ibuf->x, zoomy * height / ibuf->y); if (ibuf->planes == 32) { GPU_blend(false); diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c index 589831b1c45..ffd3241a30f 100644 --- a/source/blender/editors/space_clip/clip_graph_ops.c +++ b/source/blender/editors/space_clip/clip_graph_ops.c @@ -114,7 +114,7 @@ static void find_nearest_tracking_segment_cb(void *userdata, float val) { MouseSelectUserData *data = userdata; - float co[2] = {scene_framenr, val}; + const float co[2] = {scene_framenr, val}; if (!clip_graph_value_visible(data->sc, value_source)) { return; @@ -151,7 +151,7 @@ static void find_nearest_tracking_knot_cb(void *userdata, float val) { MouseSelectUserData *data = userdata; - float mdiff[2] = {scene_framenr - data->mouse_co[0], val - data->mouse_co[1]}; + const float mdiff[2] = {scene_framenr - data->mouse_co[0], val - data->mouse_co[1]}; float dist_sq = len_squared_v2(mdiff); if (!clip_graph_value_visible(data->sc, value_source)) { @@ -159,7 +159,7 @@ static void find_nearest_tracking_knot_cb(void *userdata, } if (data->marker == NULL || dist_sq < data->min_dist_sq) { - float co[2] = {scene_framenr, val}; + const float co[2] = {scene_framenr, val}; data->track = track; data->marker = marker; @@ -178,7 +178,7 @@ static void mouse_select_init_data(bContext *C, MouseSelectUserData *userdata, c copy_v2_v2(userdata->mouse_co, co); } -static bool mouse_select_knot(bContext *C, float co[2], bool extend) +static bool mouse_select_knot(bContext *C, const float co[2], bool extend) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); @@ -236,7 +236,7 @@ static bool mouse_select_knot(bContext *C, float co[2], bool extend) return false; } -static bool mouse_select_curve(bContext *C, float co[2], bool extend) +static bool mouse_select_curve(bContext *C, const float co[2], bool extend) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 9c251fb619a..d27b80efd40 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -56,7 +56,6 @@ #include "IMB_imbuf.h" #include "GPU_framebuffer.h" -#include "GPU_glew.h" #include "GPU_matrix.h" #include "WM_api.h" @@ -238,7 +237,7 @@ static void clip_area_sync_frame_from_scene(ScrArea *area, Scene *scene) /* ******************** default callbacks for clip space ***************** */ -static SpaceLink *clip_new(const ScrArea *area, const Scene *scene) +static SpaceLink *clip_create(const ScrArea *area, const Scene *scene) { ARegion *region; SpaceClip *sc; @@ -685,7 +684,7 @@ static void clip_refresh(const bContext *C, ScrArea *area) if (main_visible) { if (region_main && (region_main->flag & RGN_FLAG_HIDDEN)) { region_main->flag &= ~RGN_FLAG_HIDDEN; - region_main->v2d.flag &= ~V2D_IS_INITIALISED; + region_main->v2d.flag &= ~V2D_IS_INIT; view_changed = true; } @@ -697,7 +696,7 @@ static void clip_refresh(const bContext *C, ScrArea *area) else { if (region_main && !(region_main->flag & RGN_FLAG_HIDDEN)) { region_main->flag |= RGN_FLAG_HIDDEN; - region_main->v2d.flag &= ~V2D_IS_INITIALISED; + region_main->v2d.flag &= ~V2D_IS_INIT; WM_event_remove_handlers((bContext *)C, ®ion_main->handlers); view_changed = true; } @@ -710,7 +709,7 @@ static void clip_refresh(const bContext *C, ScrArea *area) if (properties_visible) { if (region_properties && (region_properties->flag & RGN_FLAG_HIDDEN)) { region_properties->flag &= ~RGN_FLAG_HIDDEN; - region_properties->v2d.flag &= ~V2D_IS_INITIALISED; + region_properties->v2d.flag &= ~V2D_IS_INIT; view_changed = true; } if (region_properties && region_properties->alignment != RGN_ALIGN_RIGHT) { @@ -721,7 +720,7 @@ static void clip_refresh(const bContext *C, ScrArea *area) else { if (region_properties && !(region_properties->flag & RGN_FLAG_HIDDEN)) { region_properties->flag |= RGN_FLAG_HIDDEN; - region_properties->v2d.flag &= ~V2D_IS_INITIALISED; + region_properties->v2d.flag &= ~V2D_IS_INIT; WM_event_remove_handlers((bContext *)C, ®ion_properties->handlers); view_changed = true; } @@ -734,7 +733,7 @@ static void clip_refresh(const bContext *C, ScrArea *area) if (tools_visible) { if (region_tools && (region_tools->flag & RGN_FLAG_HIDDEN)) { region_tools->flag &= ~RGN_FLAG_HIDDEN; - region_tools->v2d.flag &= ~V2D_IS_INITIALISED; + region_tools->v2d.flag &= ~V2D_IS_INIT; view_changed = true; } if (region_tools && region_tools->alignment != RGN_ALIGN_LEFT) { @@ -745,7 +744,7 @@ static void clip_refresh(const bContext *C, ScrArea *area) else { if (region_tools && !(region_tools->flag & RGN_FLAG_HIDDEN)) { region_tools->flag |= RGN_FLAG_HIDDEN; - region_tools->v2d.flag &= ~V2D_IS_INITIALISED; + region_tools->v2d.flag &= ~V2D_IS_INIT; WM_event_remove_handlers((bContext *)C, ®ion_tools->handlers); view_changed = true; } @@ -758,7 +757,7 @@ static void clip_refresh(const bContext *C, ScrArea *area) if (preview_visible) { if (region_preview && (region_preview->flag & RGN_FLAG_HIDDEN)) { region_preview->flag &= ~RGN_FLAG_HIDDEN; - region_preview->v2d.flag &= ~V2D_IS_INITIALISED; + region_preview->v2d.flag &= ~V2D_IS_INIT; region_preview->v2d.cur = region_preview->v2d.tot; view_changed = true; } @@ -770,7 +769,7 @@ static void clip_refresh(const bContext *C, ScrArea *area) else { if (region_preview && !(region_preview->flag & RGN_FLAG_HIDDEN)) { region_preview->flag |= RGN_FLAG_HIDDEN; - region_preview->v2d.flag &= ~V2D_IS_INITIALISED; + region_preview->v2d.flag &= ~V2D_IS_INIT; WM_event_remove_handlers((bContext *)C, ®ion_preview->handlers); view_changed = true; } @@ -783,7 +782,7 @@ static void clip_refresh(const bContext *C, ScrArea *area) if (channels_visible) { if (region_channels && (region_channels->flag & RGN_FLAG_HIDDEN)) { region_channels->flag &= ~RGN_FLAG_HIDDEN; - region_channels->v2d.flag &= ~V2D_IS_INITIALISED; + region_channels->v2d.flag &= ~V2D_IS_INIT; view_changed = true; } if (region_channels && region_channels->alignment != RGN_ALIGN_LEFT) { @@ -794,7 +793,7 @@ static void clip_refresh(const bContext *C, ScrArea *area) else { if (region_channels && !(region_channels->flag & RGN_FLAG_HIDDEN)) { region_channels->flag |= RGN_FLAG_HIDDEN; - region_channels->v2d.flag &= ~V2D_IS_INITIALISED; + region_channels->v2d.flag &= ~V2D_IS_INIT; WM_event_remove_handlers((bContext *)C, ®ion_channels->handlers); view_changed = true; } @@ -805,7 +804,7 @@ static void clip_refresh(const bContext *C, ScrArea *area) } if (view_changed) { - ED_area_initialize(wm, window, area); + ED_area_init(wm, window, area); ED_area_tag_redraw(area); } @@ -1352,7 +1351,7 @@ void ED_spacetype_clip(void) st->spaceid = SPACE_CLIP; strncpy(st->name, "Clip", BKE_ST_MAXNAME); - st->new = clip_new; + st->create = clip_create; st->free = clip_free; st->init = clip_init; st->duplicate = clip_duplicate; diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 739701b5595..177a0bc2bcf 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -513,7 +513,7 @@ static bool slide_check_corners(float (*corners)[2]) { int i, next, prev; float cross = 0.0f; - float p[2] = {0.0f, 0.0f}; + const float p[2] = {0.0f, 0.0f}; if (!isect_point_quad_v2(p, corners[0], corners[1], corners[2], corners[3])) { return false; @@ -861,7 +861,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event) BKE_tracking_marker_clamp(data->marker, CLAMP_PAT_DIM); } else if (data->action == SLIDE_ACTION_OFFSET) { - float d[2] = {dx, dy}; + const float d[2] = {dx, dy}; for (int a = 0; a < data->track->markersnr; a++) { add_v2_v2v2(data->track->markers[a].pos, data->old_markers[a], d); } @@ -940,7 +940,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event) BKE_tracking_marker_clamp(data->marker, CLAMP_SEARCH_DIM); } else if (data->area == TRACK_AREA_SEARCH) { - float d[2] = {dx, dy}; + const float d[2] = {dx, dy}; add_v2_v2v2(data->min, data->old_search_min, d); add_v2_v2v2(data->max, data->old_search_max, d); } diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c index b6f9ca9589f..80d0dd773b2 100644 --- a/source/blender/editors/space_clip/tracking_select.c +++ b/source/blender/editors/space_clip/tracking_select.c @@ -153,9 +153,9 @@ static float dist_to_rect(const float co[2], const float max[2]) { float d1, d2, d3, d4; - float p[2] = {co[0] - pos[0], co[1] - pos[1]}; - float v1[2] = {min[0], min[1]}, v2[2] = {max[0], min[1]}; - float v3[2] = {max[0], max[1]}, v4[2] = {min[0], max[1]}; + const float p[2] = {co[0] - pos[0], co[1] - pos[1]}; + const float v1[2] = {min[0], min[1]}, v2[2] = {max[0], min[1]}; + const float v3[2] = {max[0], max[1]}, v4[2] = {min[0], max[1]}; d1 = dist_squared_to_line_segment_v2(p, v1, v2); d2 = dist_squared_to_line_segment_v2(p, v2, v3); @@ -169,7 +169,7 @@ static float dist_to_rect(const float co[2], static float dist_to_crns(const float co[2], const float pos[2], const float crns[4][2]) { float d1, d2, d3, d4; - float p[2] = {co[0] - pos[0], co[1] - pos[1]}; + const float p[2] = {co[0] - pos[0], co[1] - pos[1]}; const float *v1 = crns[0], *v2 = crns[1]; const float *v3 = crns[2], *v4 = crns[3]; @@ -744,7 +744,9 @@ static int point_inside_ellipse(const float point[2], return x * x + y * y < 1.0f; } -static int marker_inside_ellipse(MovieTrackingMarker *marker, float offset[2], float ellipse[2]) +static int marker_inside_ellipse(MovieTrackingMarker *marker, + const float offset[2], + const float ellipse[2]) { return point_inside_ellipse(marker->pos, offset, ellipse); } diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index 3c62aeb1759..3a0125356f7 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -46,7 +46,7 @@ /* ******************** default callbacks for console space ***************** */ -static SpaceLink *console_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) +static SpaceLink *console_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) { ARegion *region; SpaceConsole *sconsole; @@ -312,7 +312,7 @@ void ED_spacetype_console(void) st->spaceid = SPACE_CONSOLE; strncpy(st->name, "Console", BKE_ST_MAXNAME); - st->new = console_new; + st->create = console_create; st->free = console_free; st->init = console_init; st->duplicate = console_duplicate; diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 5150f6bed69..083d41747b3 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -300,9 +300,8 @@ static void file_draw_preview(uiBlock *block, (float)yco, imb->x, imb->y, - GL_RGBA, - GL_UNSIGNED_BYTE, - GL_NEAREST, + GPU_RGBA8, + false, imb->rect, scale, scale, diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 45e45093238..e9ffd4583d7 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -518,7 +518,7 @@ static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event) rect.ymin = rect.ymax = event->mval[1]; if (!ED_fileselect_layout_is_inside_pt(sfile->layout, ®ion->v2d, rect.xmin, rect.ymin)) { - return OPERATOR_CANCELLED; + return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; } if (sfile && sfile->params) { @@ -1697,6 +1697,19 @@ static int file_exec(bContext *C, wmOperator *exec_op) return OPERATOR_FINISHED; } +static int file_exec_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + ARegion *region = CTX_wm_region(C); + SpaceFile *sfile = CTX_wm_space_file(C); + + if (!ED_fileselect_layout_is_inside_pt( + sfile->layout, ®ion->v2d, event->mval[0], event->mval[1])) { + return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; + } + + return file_exec(C, op); +} + void FILE_OT_execute(struct wmOperatorType *ot) { PropertyRNA *prop; @@ -1707,6 +1720,7 @@ void FILE_OT_execute(struct wmOperatorType *ot) ot->idname = "FILE_OT_execute"; /* api callbacks */ + ot->invoke = file_exec_invoke; ot->exec = file_exec; ot->poll = file_operator_poll; diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 43939b9ff54..f520f91b89b 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -91,7 +91,7 @@ static ARegion *file_tool_props_region_ensure(ScrArea *area, ARegion *region_pre /* ******************** default callbacks for file space ***************** */ -static SpaceLink *file_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) +static SpaceLink *file_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) { ARegion *region; SpaceFile *sfile; @@ -235,7 +235,7 @@ static void file_ensure_valid_region_state(bContext *C, ARegion *region_ui = BKE_area_find_region_type(area, RGN_TYPE_UI); ARegion *region_props = BKE_area_find_region_type(area, RGN_TYPE_TOOL_PROPS); ARegion *region_execute = BKE_area_find_region_type(area, RGN_TYPE_EXECUTE); - bool needs_init = false; /* To avoid multiple ED_area_initialize() calls. */ + bool needs_init = false; /* To avoid multiple ED_area_init() calls. */ /* If there's an file-operation, ensure we have the option and execute region */ if (sfile->op && (region_props == NULL)) { @@ -261,7 +261,7 @@ static void file_ensure_valid_region_state(bContext *C, } if (needs_init) { - ED_area_initialize(wm, win, area); + ED_area_init(wm, win, area); } } @@ -693,7 +693,7 @@ void ED_spacetype_file(void) st->spaceid = SPACE_FILE; strncpy(st->name, "File", BKE_ST_MAXNAME); - st->new = file_new; + st->create = file_create; st->free = file_free; st->init = file_init; st->exit = file_exit; diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 68fdef54a53..90fe95c6818 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1487,7 +1487,7 @@ static int graphkeys_decimate_invoke(bContext *C, wmOperator *op, const wmEvent dgo->area = CTX_wm_area(C); dgo->region = CTX_wm_region(C); - /* initialise percentage so that it will have the correct value before the first mouse move. */ + /* Initialize percentage so that it will have the correct value before the first mouse move. */ decimate_mouse_update_percentage(dgo, op, event); decimate_draw_status_header(op, dgo); diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index b1d995a7a0b..a4f76384cc6 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -64,7 +64,7 @@ /* ******************** default callbacks for ipo space ***************** */ -static SpaceLink *graph_new(const ScrArea *UNUSED(area), const Scene *scene) +static SpaceLink *graph_create(const ScrArea *UNUSED(area), const Scene *scene) { ARegion *region; SpaceGraph *sipo; @@ -838,7 +838,7 @@ void ED_spacetype_ipo(void) st->spaceid = SPACE_GRAPH; strncpy(st->name, "Graph", BKE_ST_MAXNAME); - st->new = graph_new; + st->create = graph_create; st->free = graph_free; st->init = graph_init; st->duplicate = graph_duplicate; diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index a7fa7709c51..f70589ac5f1 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -168,9 +168,9 @@ void ED_image_draw_info(Scene *scene, uchar green[3] = {0, 255, 0}; uchar blue[3] = {100, 100, 255}; #else - uchar red[3] = {255, 255, 255}; - uchar green[3] = {255, 255, 255}; - uchar blue[3] = {255, 255, 255}; + const uchar red[3] = {255, 255, 255}; + const uchar green[3] = {255, 255, 255}; + const uchar blue[3] = {255, 255, 255}; #endif float hue = 0, sat = 0, val = 0, lum = 0, u = 0, v = 0; float col[4], finalcol[4]; @@ -465,23 +465,22 @@ void ED_image_draw_info(Scene *scene, static void sima_draw_zbuf_pixels( float x1, float y1, int rectx, int recty, const int *rect, float zoomx, float zoomy) { - float red[4] = {1.0f, 0.0f, 0.0f, 0.0f}; + const float red[4] = {1.0f, 0.0f, 0.0f, 0.0f}; /* Slowwww */ - int *recti = MEM_mallocN(rectx * recty * sizeof(int), "temp"); + float *rectf = MEM_mallocN(rectx * recty * sizeof(float), "temp"); for (int a = rectx * recty - 1; a >= 0; a--) { /* zbuffer values are signed, so we need to shift color range */ - recti[a] = rect[a] * 0.5f + 0.5f; + rectf[a] = rect[a] * 0.5f + 0.5f; } IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR); GPU_shader_uniform_vector( state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red); - immDrawPixelsTex( - &state, x1, y1, rectx, recty, GL_RED, GL_INT, GL_NEAREST, recti, zoomx, zoomy, NULL); + immDrawPixelsTex(&state, x1, y1, rectx, recty, GPU_R16F, false, rectf, zoomx, zoomy, NULL); - MEM_freeN(recti); + MEM_freeN(rectf); } static void sima_draw_zbuffloat_pixels(Scene *scene, @@ -495,7 +494,7 @@ static void sima_draw_zbuffloat_pixels(Scene *scene, { float bias, scale, *rectf, clip_end; int a; - float red[4] = {1.0f, 0.0f, 0.0f, 0.0f}; + const float red[4] = {1.0f, 0.0f, 0.0f, 0.0f}; if (scene->camera && scene->camera->type == OB_CAMERA) { bias = ((Camera *)scene->camera->data)->clip_start; @@ -526,8 +525,7 @@ static void sima_draw_zbuffloat_pixels(Scene *scene, GPU_shader_uniform_vector( state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red); - immDrawPixelsTex( - &state, x1, y1, rectx, recty, GL_RED, GL_FLOAT, GL_NEAREST, rectf, zoomx, zoomy, NULL); + immDrawPixelsTex(&state, x1, y1, rectx, recty, GL_R16F, false, rectf, zoomx, zoomy, NULL); MEM_freeN(rectf); } @@ -612,8 +610,7 @@ static void draw_image_buffer(const bContext *C, /* If RGBA display with color management */ if ((sima_flag & (SI_SHOW_R | SI_SHOW_G | SI_SHOW_B | SI_SHOW_ALPHA)) == 0) { - ED_draw_imbuf_ctx_clipping( - C, ibuf, x, y, GL_NEAREST, 0, 0, clip_max_x, clip_max_y, zoomx, zoomy); + ED_draw_imbuf_ctx_clipping(C, ibuf, x, y, false, 0, 0, clip_max_x, clip_max_y, zoomx, zoomy); } else { float shuffle[4] = {0.0f, 0.0f, 0.0f, 0.0f}; @@ -649,9 +646,8 @@ static void draw_image_buffer(const bContext *C, y, ibuf->x, ibuf->y, - GL_RGBA, - GL_UNSIGNED_BYTE, - GL_NEAREST, + GPU_RGBA8, + false, display_buffer, 0, 0, @@ -780,18 +776,8 @@ static void draw_image_paint_helpers( GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_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); + immDrawPixelsTex( + &state, x, y, ibuf->x, ibuf->y, GPU_RGBA8, false, display_buffer, zoomx, zoomy, col); GPU_blend(false); @@ -812,7 +798,7 @@ static void draw_udim_tile_grid(uint pos_attr, { float x1, y1; UI_view2d_view_to_region_fl(®ion->v2d, x, y, &x1, &y1); - int gridpos[5][2] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}}; + const int gridpos[5][2] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}}; for (int i = 0; i < 4; i++) { immAttr3fv(color_attr, color); immVertex2f(pos_attr, x1 + gridpos[i][0] * stepx, y1 + gridpos[i][1] * stepy); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 4e410d35df0..1a98ec0e7c1 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -69,7 +69,6 @@ #include "DEG_depsgraph.h" -#include "GPU_draw.h" #include "GPU_immediate.h" #include "GPU_state.h" @@ -2769,7 +2768,7 @@ static int image_invert_exec(bContext *C, wmOperator *op) ED_image_undo_push_end(); /* force GPU reupload, all image is invalid */ - GPU_free_image(ima); + BKE_image_free_gputextures(ima); WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima); @@ -2860,7 +2859,7 @@ static int image_scale_exec(bContext *C, wmOperator *op) ED_image_undo_push_end(); /* force GPU reupload, all image is invalid */ - GPU_free_image(ima); + BKE_image_free_gputextures(ima); DEG_id_tag_update(&ima->id, 0); WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima); @@ -3715,7 +3714,7 @@ static void draw_fill_tile(PointerRNA *ptr, uiLayout *layout) uiItemR(col[1], ptr, "float", 0, NULL, ICON_NONE); } -static void initialize_fill_tile(PointerRNA *ptr, Image *ima, ImageTile *tile) +static void tile_fill_init(PointerRNA *ptr, Image *ima, ImageTile *tile) { ImageUser iuser; BKE_imageuser_default(&iuser); @@ -3828,7 +3827,7 @@ static int tile_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(ev } ImageTile *tile = BLI_findlink(&ima->tiles, ima->active_tile_index); - initialize_fill_tile(op->ptr, ima, tile); + tile_fill_init(op->ptr, ima, tile); RNA_int_set(op->ptr, "number", next_number); RNA_int_set(op->ptr, "count", 1); @@ -3974,7 +3973,7 @@ static int tile_fill_exec(bContext *C, wmOperator *op) static int tile_fill_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - initialize_fill_tile(op->ptr, CTX_data_edit_image(C), NULL); + tile_fill_init(op->ptr, CTX_data_edit_image(C), NULL); return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X); } diff --git a/source/blender/editors/space_image/image_undo.c b/source/blender/editors/space_image/image_undo.c index e0c44c3a0ba..27b84307f7d 100644 --- a/source/blender/editors/space_image/image_undo.c +++ b/source/blender/editors/space_image/image_undo.c @@ -60,8 +60,6 @@ #include "ED_undo.h" #include "ED_util.h" -#include "GPU_draw.h" - #include "WM_api.h" static CLG_LogRef LOG = {"ed.image.undo"}; @@ -295,7 +293,8 @@ static void ptile_restore_runtime_list(ListBase *paint_tiles) SWAP(uint *, ptile->rect.uint, tmpibuf->rect); } - GPU_free_image(image); /* force OpenGL reload (maybe partial update will operate better?) */ + BKE_image_free_gputextures( + image); /* force OpenGL reload (maybe partial update will operate better?) */ if (ibuf->rect_float) { ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */ } @@ -570,7 +569,7 @@ static void uhandle_restore_list(ListBase *undo_handles, bool use_init) if (changed) { BKE_image_mark_dirty(image, ibuf); - GPU_free_image(image); /* force OpenGL reload */ + BKE_image_free_gputextures(image); /* force OpenGL reload */ if (ibuf->rect_float) { ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */ diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index ac0dbba1606..c01bc01588e 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -116,7 +116,7 @@ static void image_user_refresh_scene(const bContext *C, SpaceImage *sima) /* ******************** default callbacks for image space ***************** */ -static SpaceLink *image_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) +static SpaceLink *image_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) { ARegion *region; SpaceImage *simage; @@ -1093,7 +1093,7 @@ void ED_spacetype_image(void) st->spaceid = SPACE_IMAGE; strncpy(st->name, "Image", BKE_ST_MAXNAME); - st->new = image_new; + st->create = image_create; st->free = image_free; st->init = image_init; st->duplicate = image_duplicate; diff --git a/source/blender/editors/space_info/info_draw.c b/source/blender/editors/space_info/info_draw.c index 6c818257ec7..72533b88406 100644 --- a/source/blender/editors/space_info/info_draw.c +++ b/source/blender/editors/space_info/info_draw.c @@ -270,12 +270,12 @@ void *info_text_pick(const SpaceInfo *sinfo, int info_textview_height(const SpaceInfo *sinfo, const ARegion *region, const ReportList *reports) { - int mval[2] = {INT_MAX, INT_MAX}; + const int mval[2] = {INT_MAX, INT_MAX}; return info_textview_main__internal(sinfo, region, reports, false, mval, NULL, NULL); } void info_textview_main(const SpaceInfo *sinfo, const ARegion *region, const ReportList *reports) { - int mval[2] = {INT_MAX, INT_MAX}; + const int mval[2] = {INT_MAX, INT_MAX}; info_textview_main__internal(sinfo, region, reports, true, mval, NULL, NULL); } diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c index 836830916ed..b9153ec0cbd 100644 --- a/source/blender/editors/space_info/space_info.c +++ b/source/blender/editors/space_info/space_info.c @@ -53,7 +53,7 @@ /* ******************** default callbacks for info space ***************** */ -static SpaceLink *info_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) +static SpaceLink *info_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) { ARegion *region; SpaceInfo *sinfo; @@ -287,7 +287,7 @@ void ED_spacetype_info(void) st->spaceid = SPACE_INFO; strncpy(st->name, "Info", BKE_ST_MAXNAME); - st->new = info_new; + st->create = info_create; st->free = info_free; st->init = info_init; st->duplicate = info_duplicate; diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c index eee8b989cc2..93a79d9a2bc 100644 --- a/source/blender/editors/space_info/textview.c +++ b/source/blender/editors/space_info/textview.c @@ -264,7 +264,7 @@ static bool textview_draw_string(TextViewDrawState *tds, if (tds->sel[0] != tds->sel[1]) { textview_step_sel(tds, -final_offset); - int pos[2] = {tds->xy[0], line_bottom}; + const int pos[2] = {tds->xy[0], line_bottom}; textview_draw_sel(s, pos, len, tds, bg_sel); } diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index 96599fd92a7..97939a93d01 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -378,7 +378,7 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uin } /* helper call to setup dashed-lines for strip outlines */ -static uint nla_draw_use_dashed_outlines(float color[4], bool muted) +static uint nla_draw_use_dashed_outlines(const float color[4], bool muted) { /* Note that we use dashed shader here, and make it draw solid lines if not muted... */ uint shdr_pos = GPU_vertformat_attr_add( diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c index b09536e0621..7bbfe451eed 100644 --- a/source/blender/editors/space_nla/space_nla.c +++ b/source/blender/editors/space_nla/space_nla.c @@ -57,7 +57,7 @@ /* ******************** default callbacks for nla space ***************** */ -static SpaceLink *nla_new(const ScrArea *area, const Scene *scene) +static SpaceLink *nla_create(const ScrArea *area, const Scene *scene) { ARegion *region; SpaceNla *snla; @@ -608,7 +608,7 @@ void ED_spacetype_nla(void) st->spaceid = SPACE_NLA; strncpy(st->name, "NLA", BKE_ST_MAXNAME); - st->new = nla_new; + st->create = nla_create; st->free = nla_free; st->init = nla_init; st->duplicate = nla_duplicate; diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 01883f1c086..207f67aed1b 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3678,9 +3678,8 @@ void draw_nodespace_back_pix(const bContext *C, y, ibuf->x, ibuf->y, - GL_RGBA, - GL_UNSIGNED_BYTE, - GL_NEAREST, + GPU_RGBA8, + false, display_buffer, snode->zoom, snode->zoom, @@ -3693,12 +3692,12 @@ void draw_nodespace_back_pix(const bContext *C, GPU_blend_set_func_separate( GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - ED_draw_imbuf_ctx(C, ibuf, x, y, GL_NEAREST, snode->zoom, snode->zoom); + ED_draw_imbuf_ctx(C, ibuf, x, y, false, snode->zoom, snode->zoom); GPU_blend(false); } else { - ED_draw_imbuf_ctx(C, ibuf, x, y, GL_NEAREST, snode->zoom, snode->zoom); + ED_draw_imbuf_ctx(C, ibuf, x, y, false, snode->zoom, snode->zoom); } if (cache_handle) { diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 22b549cbd5d..3fd0b0a5a58 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -947,9 +947,8 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv) draw_rect.ymin, preview->xsize, preview->ysize, - GL_RGBA, - GL_UNSIGNED_BYTE, - GL_LINEAR, + GPU_RGBA8, + true, preview->rect, scale, scale, @@ -987,7 +986,7 @@ void node_draw_shadow(SpaceNode *snode, bNode *node, float radius, float alpha) else { const float margin = 3.0f; - float color[4] = {0.0f, 0.0f, 0.0f, 0.33f}; + const float color[4] = {0.0f, 0.0f, 0.0f, 0.33f}; UI_draw_roundbox_aa(true, rct->xmin - margin, rct->ymin - margin, diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 7af64e75656..c88b6a1b297 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -1697,6 +1697,8 @@ static int node_mute_exec(bContext *C, wmOperator *UNUSED(op)) } } + do_tag_update |= ED_node_is_simulation(snode); + snode_notify(C, snode); if (do_tag_update) { snode_dag_update(C, snode); @@ -1739,6 +1741,8 @@ static int node_delete_exec(bContext *C, wmOperator *UNUSED(op)) } } + do_tag_update |= ED_node_is_simulation(snode); + ntreeUpdateTree(CTX_data_main(C), snode->edittree); snode_notify(C, snode); @@ -2739,7 +2743,7 @@ static int clear_viewer_border_exec(bContext *C, wmOperator *UNUSED(op)) void NODE_OT_clear_viewer_border(wmOperatorType *ot) { /* identifiers */ - ot->name = "Clear Viewer Border"; + ot->name = "Clear Viewer Region"; ot->description = "Clear the boundaries for viewer operations"; ot->idname = "NODE_OT_clear_viewer_border"; diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c index 3e898b7d400..a09c70b794a 100644 --- a/source/blender/editors/space_node/node_relationships.c +++ b/source/blender/editors/space_node/node_relationships.c @@ -670,6 +670,8 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links) } ntree->is_updating = false; + do_tag_update |= ED_node_is_simulation(snode); + ntreeUpdateTree(bmain, ntree); snode_notify(C, snode); if (do_tag_update) { @@ -1002,7 +1004,7 @@ void NODE_OT_link_make(wmOperatorType *ot) } /* ********************** Cut Link operator ***************** */ -static bool cut_links_intersect(bNodeLink *link, float mcoords[][2], int tot) +static bool cut_links_intersect(bNodeLink *link, const float mcoords[][2], int tot) { float coord_array[NODE_LINK_RESOL + 1][2]; int i, b; @@ -1070,6 +1072,8 @@ static int cut_links_exec(bContext *C, wmOperator *op) } } + do_tag_update |= ED_node_is_simulation(snode); + if (found) { ntreeUpdateTree(CTX_data_main(C), snode->edittree); snode_notify(C, snode); diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index d4adad3fc25..6d570001347 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -244,7 +244,7 @@ void snode_group_offset(SpaceNode *snode, float *x, float *y) /* ******************** default callbacks for node space ***************** */ -static SpaceLink *node_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) +static SpaceLink *node_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) { ARegion *region; SpaceNode *snode; @@ -954,7 +954,7 @@ void ED_spacetype_node(void) st->spaceid = SPACE_NODE; strncpy(st->name, "Node", BKE_ST_MAXNAME); - st->new = node_new; + st->create = node_create; st->free = node_free; st->init = node_init; st->duplicate = node_duplicate; diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index a45b415b629..4271eaded99 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -2694,7 +2694,7 @@ static void outliner_draw_iconrow_number(const uiFontStyle *fstyle, int ys, const int num_elements) { - float color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + const float color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; float ufac = 0.25f * UI_UNIT_X; float offset_x = (float)offsx + UI_UNIT_X * 0.35f; diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index aa1663dff01..8a78211f145 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -294,7 +294,7 @@ static void outliner_header_region_listener(wmWindow *UNUSED(win), /* ******************** default callbacks for outliner space ***************** */ -static SpaceLink *outliner_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) +static SpaceLink *outliner_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) { ARegion *region; SpaceOutliner *soutliner; @@ -407,7 +407,7 @@ void ED_spacetype_outliner(void) st->spaceid = SPACE_OUTLINER; strncpy(st->name, "Outliner", BKE_ST_MAXNAME); - st->new = outliner_new; + st->create = outliner_create; st->free = outliner_free; st->init = outliner_init; st->duplicate = outliner_duplicate; diff --git a/source/blender/editors/space_script/space_script.c b/source/blender/editors/space_script/space_script.c index 343f35421a4..4d0c2b658c6 100644 --- a/source/blender/editors/space_script/space_script.c +++ b/source/blender/editors/space_script/space_script.c @@ -51,7 +51,7 @@ /* ******************** default callbacks for script space ***************** */ -static SpaceLink *script_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) +static SpaceLink *script_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) { ARegion *region; SpaceScript *sscript; @@ -179,7 +179,7 @@ void ED_spacetype_script(void) st->spaceid = SPACE_SCRIPT; strncpy(st->name, "Script", BKE_ST_MAXNAME); - st->new = script_new; + st->create = script_create; st->free = script_free; st->init = script_init; st->duplicate = script_duplicate; diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 995e980aba0..0f4690c11d5 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -1599,7 +1599,7 @@ static void sequencer_draw_display_buffer(const bContext *C, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); } - /* Format needs to be created prior to any immBindProgram call. + /* Format needs to be created prior to any immBindShader call. * Do it here because OCIO binds it's own shader. */ eGPUTextureFormat format; eGPUDataFormat data; @@ -2169,7 +2169,7 @@ static void draw_cache_view(const bContext *C) if (scene->ed->cache_flag & SEQ_CACHE_VIEW_FINAL_OUT) { stripe_bot = UI_view2d_region_to_view_y(v2d, V2D_SCROLL_HANDLE_HEIGHT); stripe_top = stripe_bot + stripe_ht; - float bg_color[4] = {1.0f, 0.4f, 0.2f, 0.1f}; + const float bg_color[4] = {1.0f, 0.4f, 0.2f, 0.1f}; immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]); immRectf(pos, scene->r.sfra, stripe_bot, scene->r.efra, stripe_top); @@ -2188,7 +2188,7 @@ static void draw_cache_view(const bContext *C) stripe_top = stripe_bot + stripe_ht; if (scene->ed->cache_flag & SEQ_CACHE_VIEW_RAW) { - float bg_color[4] = {1.0f, 0.1f, 0.02f, 0.1f}; + const float bg_color[4] = {1.0f, 0.1f, 0.02f, 0.1f}; immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]); immRectf(pos, seq->startdisp, stripe_bot, seq->enddisp, stripe_top); } @@ -2197,7 +2197,7 @@ static void draw_cache_view(const bContext *C) stripe_top = stripe_bot + stripe_ht; if (scene->ed->cache_flag & SEQ_CACHE_VIEW_PREPROCESSED) { - float bg_color[4] = {0.1f, 0.1f, 0.75f, 0.1f}; + const float bg_color[4] = {0.1f, 0.1f, 0.75f, 0.1f}; immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]); immRectf(pos, seq->startdisp, stripe_bot, seq->enddisp, stripe_top); } @@ -2206,7 +2206,7 @@ static void draw_cache_view(const bContext *C) stripe_bot = stripe_top - stripe_ht; if (scene->ed->cache_flag & SEQ_CACHE_VIEW_COMPOSITE) { - float bg_color[4] = {1.0f, 0.6f, 0.0f, 0.1f}; + const float bg_color[4] = {1.0f, 0.6f, 0.0f, 0.1f}; immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]); immRectf(pos, seq->startdisp, stripe_bot, seq->enddisp, stripe_top); } diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index b2d0362602e..99d4c2d9f1a 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -666,74 +666,6 @@ int seq_effect_find_selected(Scene *scene, /** \name Delete Utilities * \{ */ -static Sequence *del_seq_find_replace_recurs(Scene *scene, Sequence *seq) -{ - Sequence *seq1, *seq2, *seq3; - - /* Try to find a replacement input sequence, and flag for later deletion if - * no replacement can be found. */ - - if (!seq) { - return NULL; - } - if (!(seq->type & SEQ_TYPE_EFFECT)) { - return ((seq->flag & SELECT) ? NULL : seq); - } - if (!(seq->flag & SELECT)) { - /* Try to find replacement for effect inputs. */ - seq1 = del_seq_find_replace_recurs(scene, seq->seq1); - seq2 = del_seq_find_replace_recurs(scene, seq->seq2); - seq3 = del_seq_find_replace_recurs(scene, seq->seq3); - - if (seq1 == seq->seq1 && seq2 == seq->seq2 && seq3 == seq->seq3) { - /* Pass. */ - } - else if (seq1 || seq2 || seq3) { - seq->seq1 = (seq1) ? seq1 : (seq2) ? seq2 : seq3; - seq->seq2 = (seq2) ? seq2 : (seq1) ? seq1 : seq3; - seq->seq3 = (seq3) ? seq3 : (seq1) ? seq1 : seq2; - - BKE_sequencer_update_changed_seq_and_deps(scene, seq, 1, 1); - } - else { - seq->flag |= SELECT; /* Mark for delete. */ - } - } - - if (seq->flag & SELECT) { - if ((seq1 = del_seq_find_replace_recurs(scene, seq->seq1))) { - return seq1; - } - if ((seq2 = del_seq_find_replace_recurs(scene, seq->seq2))) { - return seq2; - } - if ((seq3 = del_seq_find_replace_recurs(scene, seq->seq3))) { - return seq3; - } - return NULL; - } - return seq; -} - -static void del_seq_clear_modifiers_recurs(Scene *scene, Sequence *deleting_sequence) -{ - Editing *ed = BKE_sequencer_editing_get(scene, false); - Sequence *current_sequence; - - SEQP_BEGIN (ed, current_sequence) { - if (!(current_sequence->flag & SELECT) && current_sequence != deleting_sequence) { - SequenceModifierData *smd; - - for (smd = current_sequence->modifiers.first; smd; smd = smd->next) { - if (smd->mask_sequence == deleting_sequence) { - smd->mask_sequence = NULL; - } - } - } - } - SEQ_END; -} - static void recurs_del_seq_flag(Scene *scene, ListBase *lb, short flag, short deleteall) { Sequence *seq, *seqn; @@ -2586,61 +2518,20 @@ static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op)) Scene *scene = CTX_data_scene(C); Editing *ed = BKE_sequencer_editing_get(scene, false); Sequence *seq; - MetaStack *ms; - bool nothing_selected = true; BKE_sequencer_prefetch_stop(scene); - seq = BKE_sequencer_active_get(scene); - if (seq && seq->flag & SELECT) { /* Avoid a loop since this is likely to be selected. */ - nothing_selected = false; - } - else { - for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if (seq->flag & SELECT) { - nothing_selected = false; - break; - } - } - } - - if (nothing_selected) { - return OPERATOR_FINISHED; - } - - /* For effects and modifiers, try to find a replacement input. */ - for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if (!(seq->flag & SELECT)) { - if ((seq->type & SEQ_TYPE_EFFECT)) { - del_seq_find_replace_recurs(scene, seq); - } - } - else { - del_seq_clear_modifiers_recurs(scene, seq); + SEQP_BEGIN (scene->ed, seq) { + if (seq->flag & SELECT) { + BKE_sequencer_flag_for_removal(scene, ed->seqbasep, seq); } } - - /* Delete all selected strips. */ - recurs_del_seq_flag(scene, ed->seqbasep, SELECT, 0); - - /* Update lengths, etc. */ - seq = ed->seqbasep->first; - while (seq) { - BKE_sequence_calc(scene, seq); - seq = seq->next; - } - - /* Free parent metas. */ - ms = ed->metastack.last; - while (ms) { - BKE_sequence_calc(scene, ms->parseq); - ms = ms->prev; - } + SEQ_END; + BKE_sequencer_remove_flagged_sequences(scene, ed->seqbasep); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); - return OPERATOR_FINISHED; } @@ -3036,8 +2927,8 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op)) } /* This moves strips from meta to parent, sating within same edit and no new strips are - * allocated. If the UUID was unique already (as it should) it will stay unique. Nn need to - * re-generate the UUIDs.*/ + * allocated. If the UUID was unique already (as it should) it will stay unique. + * No need to re-generate the UUIDs. */ BLI_movelisttolist(ed->seqbasep, &last_seq->seqbase); BLI_listbase_clear(&last_seq->seqbase); diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 926752c6488..b8bb3e4d43b 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -86,7 +86,7 @@ static ARegion *sequencer_find_region(ScrArea *area, short type) /* ******************** default callbacks for sequencer space ***************** */ -static SpaceLink *sequencer_new(const ScrArea *UNUSED(area), const Scene *scene) +static SpaceLink *sequencer_create(const ScrArea *UNUSED(area), const Scene *scene) { ARegion *region; SpaceSeq *sseq; @@ -231,12 +231,12 @@ static void sequencer_refresh(const bContext *C, ScrArea *area) case SEQ_VIEW_SEQUENCE: if (region_main && (region_main->flag & RGN_FLAG_HIDDEN)) { region_main->flag &= ~RGN_FLAG_HIDDEN; - region_main->v2d.flag &= ~V2D_IS_INITIALISED; + region_main->v2d.flag &= ~V2D_IS_INIT; view_changed = true; } if (region_preview && !(region_preview->flag & RGN_FLAG_HIDDEN)) { region_preview->flag |= RGN_FLAG_HIDDEN; - region_preview->v2d.flag &= ~V2D_IS_INITIALISED; + region_preview->v2d.flag &= ~V2D_IS_INIT; WM_event_remove_handlers((bContext *)C, ®ion_preview->handlers); view_changed = true; } @@ -252,13 +252,13 @@ static void sequencer_refresh(const bContext *C, ScrArea *area) case SEQ_VIEW_PREVIEW: if (region_main && !(region_main->flag & RGN_FLAG_HIDDEN)) { region_main->flag |= RGN_FLAG_HIDDEN; - region_main->v2d.flag &= ~V2D_IS_INITIALISED; + region_main->v2d.flag &= ~V2D_IS_INIT; WM_event_remove_handlers((bContext *)C, ®ion_main->handlers); view_changed = true; } if (region_preview && (region_preview->flag & RGN_FLAG_HIDDEN)) { region_preview->flag &= ~RGN_FLAG_HIDDEN; - region_preview->v2d.flag &= ~V2D_IS_INITIALISED; + region_preview->v2d.flag &= ~V2D_IS_INIT; region_preview->v2d.cur = region_preview->v2d.tot; view_changed = true; } @@ -281,13 +281,13 @@ static void sequencer_refresh(const bContext *C, ScrArea *area) * 'full window' views before, though... Better than nothing. */ if (region_main->flag & RGN_FLAG_HIDDEN) { region_main->flag &= ~RGN_FLAG_HIDDEN; - region_main->v2d.flag &= ~V2D_IS_INITIALISED; + region_main->v2d.flag &= ~V2D_IS_INIT; region_preview->sizey = (int)(height - region_main->sizey); view_changed = true; } if (region_preview->flag & RGN_FLAG_HIDDEN) { region_preview->flag &= ~RGN_FLAG_HIDDEN; - region_preview->v2d.flag &= ~V2D_IS_INITIALISED; + region_preview->v2d.flag &= ~V2D_IS_INIT; region_preview->v2d.cur = region_preview->v2d.tot; region_main->sizey = (int)(height - region_preview->sizey); view_changed = true; @@ -312,7 +312,7 @@ static void sequencer_refresh(const bContext *C, ScrArea *area) } if (view_changed) { - ED_area_initialize(wm, window, area); + ED_area_init(wm, window, area); ED_area_tag_redraw(area); } } @@ -852,7 +852,7 @@ void ED_spacetype_sequencer(void) st->spaceid = SPACE_SEQ; strncpy(st->name, "Sequencer", BKE_ST_MAXNAME); - st->new = sequencer_new; + st->create = sequencer_create; st->free = sequencer_free; st->init = sequencer_init; st->duplicate = sequencer_duplicate; diff --git a/source/blender/editors/space_statusbar/space_statusbar.c b/source/blender/editors/space_statusbar/space_statusbar.c index 34d7f8b0216..ae56b111360 100644 --- a/source/blender/editors/space_statusbar/space_statusbar.c +++ b/source/blender/editors/space_statusbar/space_statusbar.c @@ -42,7 +42,7 @@ /* ******************** default callbacks for statusbar space ******************** */ -static SpaceLink *statusbar_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) +static SpaceLink *statusbar_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) { ARegion *region; SpaceStatusBar *sstatusbar; @@ -158,7 +158,7 @@ void ED_spacetype_statusbar(void) st->spaceid = SPACE_STATUSBAR; strncpy(st->name, "Status Bar", BKE_ST_MAXNAME); - st->new = statusbar_new; + st->create = statusbar_create; st->free = statusbar_free; st->init = statusbar_init; st->duplicate = statusbar_duplicate; diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index a2af99ee9f9..f6d00ec94bf 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -53,7 +53,7 @@ /* ******************** default callbacks for text space ***************** */ -static SpaceLink *text_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) +static SpaceLink *text_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) { ARegion *region; SpaceText *stext; @@ -445,7 +445,7 @@ void ED_spacetype_text(void) st->spaceid = SPACE_TEXT; strncpy(st->name, "Text", BKE_ST_MAXNAME); - st->new = text_new; + st->create = text_create; st->free = text_free; st->init = text_init; st->duplicate = text_duplicate; diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c index 24c55e60513..74cf3c866d3 100644 --- a/source/blender/editors/space_text/text_autocomplete.c +++ b/source/blender/editors/space_text/text_autocomplete.c @@ -55,7 +55,7 @@ int text_do_suggest_select(SpaceText *st, ARegion *region) TextLine *tmp; int l, x, y, w, h, i; int tgti, *top; - int mval[2] = {0, 0}; + const int mval[2] = {0, 0}; if (!st || !st->text) { return 0; diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 6be436cffb5..201f9dae5d5 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -2587,7 +2587,7 @@ static void text_scroll_apply(bContext *C, wmOperator *op, const wmEvent *event) { SpaceText *st = CTX_wm_space_text(C); TextScroll *tsc = op->customdata; - int mval[2] = {event->x, event->y}; + const int mval[2] = {event->x, event->y}; text_update_character_width(st); diff --git a/source/blender/editors/space_topbar/space_topbar.c b/source/blender/editors/space_topbar/space_topbar.c index d06c567988d..dc357cdd355 100644 --- a/source/blender/editors/space_topbar/space_topbar.c +++ b/source/blender/editors/space_topbar/space_topbar.c @@ -52,7 +52,7 @@ /* ******************** default callbacks for topbar space ***************** */ -static SpaceLink *topbar_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) +static SpaceLink *topbar_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) { ARegion *region; SpaceTopBar *stopbar; @@ -250,7 +250,7 @@ void ED_spacetype_topbar(void) st->spaceid = SPACE_TOPBAR; strncpy(st->name, "Top Bar", BKE_ST_MAXNAME); - st->new = topbar_new; + st->create = topbar_create; st->free = topbar_free; st->init = topbar_init; st->duplicate = topbar_duplicate; diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c index 9eae722d5c8..0242bb4fe24 100644 --- a/source/blender/editors/space_userpref/space_userpref.c +++ b/source/blender/editors/space_userpref/space_userpref.c @@ -45,7 +45,7 @@ /* ******************** default callbacks for userpref space ***************** */ -static SpaceLink *userpref_new(const ScrArea *area, const Scene *UNUSED(scene)) +static SpaceLink *userpref_create(const ScrArea *area, const Scene *UNUSED(scene)) { ARegion *region; SpaceUserPref *spref; @@ -115,7 +115,7 @@ static void userpref_main_region_init(wmWindowManager *wm, ARegion *region) { /* do not use here, the properties changed in userprefs do a system-wide refresh, * then scroller jumps back */ - /* region->v2d.flag &= ~V2D_IS_INITIALISED; */ + /* region->v2d.flag &= ~V2D_IS_INIT; */ region->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE; @@ -235,7 +235,7 @@ void ED_spacetype_userpref(void) st->spaceid = SPACE_USERPREF; strncpy(st->name, "Userpref", BKE_ST_MAXNAME); - st->new = userpref_new; + st->create = userpref_create; st->free = userpref_free; st->init = userpref_init; st->duplicate = userpref_duplicate; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index f17d7ccd136..1ffa653372c 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -69,7 +69,7 @@ static const float cosval[CIRCLE_RESOL] = { 0.82076344, 0.91895781, 0.97952994, 1.00000000, }; -static void circball_array_fill(float verts[CIRCLE_RESOL][3], +static void circball_array_fill(const float verts[CIRCLE_RESOL][3], const float cent[3], float rad, const float tmat[4][4]) diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index c88303daa16..e5ba27cef07 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -260,7 +260,7 @@ void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *area) /* ******************** default callbacks for view3d space ***************** */ -static SpaceLink *view3d_new(const ScrArea *UNUSED(area), const Scene *scene) +static SpaceLink *view3d_create(const ScrArea *UNUSED(area), const Scene *scene) { ARegion *region; View3D *v3d; @@ -616,11 +616,12 @@ static void view3d_lightcache_update(bContext *C) return; } - WM_operator_properties_create(&op_ptr, "SCENE_OT_light_cache_bake"); + wmOperatorType *ot = WM_operatortype_find("SCENE_OT_light_cache_bake", true); + WM_operator_properties_create_ptr(&op_ptr, ot); RNA_int_set(&op_ptr, "delay", 200); RNA_enum_set_identifier(C, &op_ptr, "subset", "DIRTY"); - WM_operator_name_call(C, "SCENE_OT_light_cache_bake", WM_OP_INVOKE_DEFAULT, &op_ptr); + WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &op_ptr); WM_operator_properties_free(&op_ptr); } @@ -1610,7 +1611,7 @@ void ED_spacetype_view3d(void) st->spaceid = SPACE_VIEW3D; strncpy(st->name, "View3D", BKE_ST_MAXNAME); - st->new = view3d_new; + st->create = view3d_create; st->free = view3d_free; st->init = view3d_init; st->listener = space_view3d_listener; diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 2e170126574..38784a5c79e 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -1071,7 +1071,7 @@ static void v3d_object_dimension_buts(bContext *C, uiLayout *layout, View3D *v3d const float lim = FLT_MAX; for (int i = 0; i < 3; i++) { uiBut *but; - char text[3] = {'X' + i, ':', '\0'}; + const char text[3] = {'X' + i, ':', '\0'}; but = uiDefButF(block, UI_BTYPE_NUM, B_TRANSFORM_PANEL_DIMS, @@ -1474,6 +1474,7 @@ static void v3d_editmetaball_buts(uiLayout *layout, Object *ob) uiLayout *col; if (!mball || !(mball->lastelem)) { + uiItemL(layout, IFACE_("Nothing selected"), ICON_NONE); return; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 1af0cc074fc..0442a0f35c9 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -36,6 +36,7 @@ #include "BKE_context.h" #include "BKE_customdata.h" #include "BKE_global.h" +#include "BKE_image.h" #include "BKE_key.h" #include "BKE_layer.h" #include "BKE_main.h" @@ -74,7 +75,6 @@ #include "GPU_batch.h" #include "GPU_batch_presets.h" -#include "GPU_draw.h" #include "GPU_framebuffer.h" #include "GPU_immediate.h" #include "GPU_immediate_util.h" @@ -1620,7 +1620,7 @@ void view3d_main_region_draw(const bContext *C, ARegion *region) view3d_draw_view(C, region); DRW_cache_free_old_batches(bmain); - GPU_free_images_old(bmain); + BKE_image_free_old_gputextures(bmain); GPU_pass_cache_garbage_collect(); /* XXX This is in order to draw UI batches with the DRW @@ -1710,7 +1710,7 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph, { /* free images which can have changed on frame-change * warning! can be slow so only free animated images - campbell */ - GPU_free_images_anim(G.main); /* XXX :((( */ + BKE_image_free_anim_gputextures(G.main); /* XXX :((( */ } GPU_matrix_push_projection(); @@ -1957,10 +1957,10 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph, NULL); if (ibuf->rect_float) { - GPU_offscreen_read_pixels(ofs, GL_FLOAT, ibuf->rect_float); + GPU_offscreen_read_pixels(ofs, GPU_DATA_FLOAT, ibuf->rect_float); } else if (ibuf->rect) { - GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect); + GPU_offscreen_read_pixels(ofs, GPU_DATA_UNSIGNED_BYTE, ibuf->rect); } /* unbind */ diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 19aa9cb203b..ac9d12cdd58 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2500,7 +2500,10 @@ static bool viewdolly_offset_lock_check(bContext *C, wmOperator *op) return false; } -static void view_dolly_to_vector_3d(ARegion *region, float orig_ofs[3], float dvec[3], float dfac) +static void view_dolly_to_vector_3d(ARegion *region, + const float orig_ofs[3], + const float dvec[3], + float dfac) { RegionView3D *rv3d = region->regiondata; madd_v3_v3v3fl(rv3d->ofs, orig_ofs, dvec, -(1.0f - dfac)); diff --git a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c index 30212fcd9e5..e17993445df 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c @@ -156,7 +156,7 @@ static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int if (eve_test) { BMVert *vert = (BMVert *)eve_test; float vert_p_co[3], vert_co[3]; - float mval_f[2] = {UNPACK2(vc.mval)}; + const float mval_f[2] = {UNPACK2(vc.mval)}; mul_v3_m4v3(vert_co, gz_ele->bases[base_index_vert]->object->obmat, vert->co); ED_view3d_project(vc.region, vert_co, vert_p_co); float len = len_v2v2(vert_p_co, mval_f); diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c index 59b2e378955..7799aba5c19 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c @@ -909,7 +909,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) static int gizmo_ruler_test_select(bContext *UNUSED(C), wmGizmo *gz, const int mval[2]) { RulerItem *ruler_item_pick = (RulerItem *)gz; - float mval_fl[2] = {UNPACK2(mval)}; + const float mval_fl[2] = {UNPACK2(mval)}; int co_index; /* select and drag */ diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c index b7219290654..a828dbc2ee0 100644 --- a/source/blender/editors/space_view3d/view3d_placement.c +++ b/source/blender/editors/space_view3d/view3d_placement.c @@ -246,7 +246,7 @@ static bool idp_poject_surface_normal(SnapObjectContext *snap_context, /** \name Primitive Drawing (Cube, Cone, Cylinder...) * \{ */ -static void draw_line_loop(float coords[][3], int coords_len, const float color[4]) +static void draw_line_loop(const float coords[][3], int coords_len, const float color[4]) { GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); @@ -279,7 +279,7 @@ static void draw_line_loop(float coords[][3], int coords_len, const float color[ GPU_blend(false); } -static void draw_line_pairs(float coords_a[][3], +static void draw_line_pairs(const float coords_a[][3], float coords_b[][3], int coords_len, const float color[4]) @@ -321,7 +321,7 @@ static void draw_line_bounds(const BoundBox *bounds, const float color[4]) GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - int edges[12][2] = { + const int edges[12][2] = { /* First side. */ {0, 1}, {1, 2}, @@ -507,7 +507,7 @@ static void draw_circle_in_quad(const float v1[2], float theta = ((2.0f * M_PI) * ((float)i / (float)resolution)) + 0.01f; float x = cosf(theta); float y = sinf(theta); - float pt[2] = {x, y}; + const float pt[2] = {x, y}; float w[4]; barycentric_weights_v2_quad(UNPACK4(quad), pt, w); diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c index c10a88af146..c790a8659ee 100644 --- a/source/blender/editors/space_view3d/view3d_project.c +++ b/source/blender/editors/space_view3d/view3d_project.c @@ -778,7 +778,7 @@ void ED_view3d_project(const struct ARegion *region, const float world[3], float { // viewport is set up to make coordinates relative to the region, not window RegionView3D *rv3d = region->regiondata; - int viewport[4] = {0, 0, region->winx, region->winy}; + const int viewport[4] = {0, 0, region->winx, region->winy}; GPU_matrix_project(world, rv3d->viewmat, rv3d->winmat, viewport, r_region_co); } @@ -787,8 +787,8 @@ bool ED_view3d_unproject( const struct ARegion *region, float regionx, float regiony, float regionz, float world[3]) { RegionView3D *rv3d = region->regiondata; - int viewport[4] = {0, 0, region->winx, region->winy}; - float region_co[3] = {regionx, regiony, regionz}; + const int viewport[4] = {0, 0, region->winx, region->winy}; + const float region_co[3] = {regionx, regiony, regionz}; return GPU_matrix_unproject(region_co, rv3d->viewmat, rv3d->winmat, viewport, world); } diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 64447015bdc..9490c807989 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -97,7 +97,6 @@ #include "UI_interface.h" -#include "GPU_glew.h" #include "GPU_matrix.h" #include "DEG_depsgraph.h" @@ -3336,12 +3335,7 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op) FOREACH_OBJECT_IN_MODE_END; } else { /* No edit-mode, unified for bones and objects. */ - if (vc.obact && vc.obact->mode & OB_MODE_SCULPT) { - /* XXX, this is not selection, could be it's own operator. */ - changed_multi = ED_sculpt_mask_box_select( - C, &vc, &rect, sel_op == SEL_OP_ADD ? true : false); - } - else if (vc.obact && BKE_paint_select_face_test(vc.obact)) { + if (vc.obact && BKE_paint_select_face_test(vc.obact)) { changed_multi = do_paintface_box_select(&vc, wm_userdata, &rect, sel_op); } else if (vc.obact && BKE_paint_select_vert_test(vc.obact)) { diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c index 4e73a2be17e..a264e1560c6 100644 --- a/source/blender/editors/space_view3d/view3d_utils.c +++ b/source/blender/editors/space_view3d/view3d_utils.c @@ -1499,7 +1499,7 @@ void ED_view3d_from_m4(const float mat[4][4], float ofs[3], float quat[4], const */ void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist) { - float iviewquat[4] = {-quat[0], quat[1], quat[2], quat[3]}; + const float iviewquat[4] = {-quat[0], quat[1], quat[2], quat[3]}; float dvec[3] = {0.0f, 0.0f, dist}; quat_to_mat4(mat, iviewquat); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 66efa5b5de3..ff9673a4262 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -50,7 +50,6 @@ #include "UI_resources.h" -#include "GPU_glew.h" #include "GPU_matrix.h" #include "GPU_select.h" #include "GPU_state.h" diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c index 64167b83655..2cc41097070 100644 --- a/source/blender/editors/space_view3d/view3d_walk.c +++ b/source/blender/editors/space_view3d/view3d_walk.c @@ -387,7 +387,7 @@ static bool walk_floor_distance_get(RegionView3D *rv3d, const float dvec[3], float *r_distance) { - float ray_normal[3] = {0, 0, -1}; /* down */ + const float ray_normal[3] = {0, 0, -1}; /* down */ float ray_start[3]; float r_location[3]; float r_normal_dummy[3]; diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index bc00dd8e221..1917d9463f4 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -80,6 +80,7 @@ typedef struct TransSnap { bool snap_self; bool peel; bool snap_spatial_grid; + bool use_backface_culling; char status; /* Snapped Element Type (currently for objects only). */ char snapElem; diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index e15239f37d4..d0e37f22236 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -388,7 +388,7 @@ void transform_constraint_snap_axis_to_face(const TransInfo *t, * Return true if the 2x axis are both aligned when projected into the view. * In this case, we can't usefully project the cursor onto the plane. */ -static bool isPlaneProjectionViewAligned(const TransInfo *t, float plane[4]) +static bool isPlaneProjectionViewAligned(const TransInfo *t, const float plane[4]) { const float eps = 0.001f; float view_to_plane[3]; diff --git a/source/blender/editors/transform/transform_convert_gpencil.c b/source/blender/editors/transform/transform_convert_gpencil.c index 0eb12aeabed..84885dd8c49 100644 --- a/source/blender/editors/transform/transform_convert_gpencil.c +++ b/source/blender/editors/transform/transform_convert_gpencil.c @@ -104,7 +104,7 @@ void createTransGPencil(bContext *C, TransInfo *t) /* initialize falloff curve */ if (is_multiedit) { - BKE_curvemapping_initialize(ts->gp_sculpt.cur_falloff); + BKE_curvemapping_init(ts->gp_sculpt.cur_falloff); } /* First Pass: Count the number of data-points required for the strokes, diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c index ad426713719..573f4550fec 100644 --- a/source/blender/editors/transform/transform_convert_mesh.c +++ b/source/blender/editors/transform/transform_convert_mesh.c @@ -754,7 +754,8 @@ void createTransEditVerts(TransInfo *t) if (tc->use_mirror_axis_any) { bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0; bool use_select = (t->flag & T_PROP_EDIT) == 0; - bool mirror_axis[3] = {tc->use_mirror_axis_x, tc->use_mirror_axis_y, tc->use_mirror_axis_z}; + const bool mirror_axis[3] = { + tc->use_mirror_axis_x, tc->use_mirror_axis_y, tc->use_mirror_axis_z}; editmesh_mirror_data_calc(em, use_select, use_topology, mirror_axis, &mirror_data); if (mirror_data.vert_map) { @@ -1033,8 +1034,10 @@ static void mesh_customdatacorrect_free_cb(struct TransInfo *UNUSED(t), # define FACE_SUBSTITUTE_INDEX INT_MIN -/* Search for a neighboring face with area and preferably without selected vertex. - * Used to replace arealess faces in customdata correction. */ +/** + * Search for a neighboring face with area and preferably without selected vertex. + * Used to replace area-less faces in custom-data correction. + */ static BMFace *mesh_customdatacorrect_find_best_face_substitute(BMFace *f) { BMFace *best_face = NULL; diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c index dacdb72806c..11cde6a9038 100644 --- a/source/blender/editors/transform/transform_gizmo_2d.c +++ b/source/blender/editors/transform/transform_gizmo_2d.c @@ -350,8 +350,8 @@ static void gizmo2d_xform_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup ptr = WM_gizmo_operator_set(ggd->cage, 0, ot_translate, NULL); RNA_boolean_set(ptr, "release_confirm", 1); - bool constraint_x[3] = {1, 0, 0}; - bool constraint_y[3] = {0, 1, 0}; + const bool constraint_x[3] = {1, 0, 0}; + const bool constraint_y[3] = {0, 1, 0}; ptr = WM_gizmo_operator_set(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X, ot_resize, NULL); PropertyRNA *prop_release_confirm = RNA_struct_find_property(ptr, "release_confirm"); @@ -484,7 +484,7 @@ static void gizmo2d_xform_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) ARegion *region = CTX_wm_region(C); GizmoGroup2D *ggd = gzgroup->customdata; float origin[3] = {UNPACK2(ggd->origin), 0.0f}; - float origin_aa[3] = {UNPACK2(ggd->origin), 0.0f}; + const float origin_aa[3] = {UNPACK2(ggd->origin), 0.0f}; gizmo2d_origin_to_region(region, origin); diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c index 3878103fa4e..6155042f555 100644 --- a/source/blender/editors/transform/transform_gizmo_3d.c +++ b/source/blender/editors/transform/transform_gizmo_3d.c @@ -2053,7 +2053,7 @@ static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmGizmoGroup for (int x = 0; x < 3; x++) { for (int y = 0; y < 3; y++) { for (int z = 0; z < 3; z++) { - bool constraint[3] = {x != 1, y != 1, z != 1}; + const bool constraint[3] = {x != 1, y != 1, z != 1}; ptr = WM_gizmo_operator_set(gz, i, ot_resize, NULL); if (prop_release_confirm == NULL) { prop_release_confirm = RNA_struct_find_property(ptr, "release_confirm"); diff --git a/source/blender/editors/transform/transform_gizmo_extrude_3d.c b/source/blender/editors/transform/transform_gizmo_extrude_3d.c index 7f6f3e53bc3..ae7cda0bd03 100644 --- a/source/blender/editors/transform/transform_gizmo_extrude_3d.c +++ b/source/blender/editors/transform/transform_gizmo_extrude_3d.c @@ -213,7 +213,7 @@ static void gizmo_mesh_extrude_setup(const bContext *C, wmGizmoGroup *gzgroup) PointerRNA macroptr = RNA_pointer_get(ptr, "TRANSFORM_OT_translate"); RNA_boolean_set(¯optr, "release_confirm", true); - bool constraint[3] = {0, 0, 0}; + const bool constraint[3] = {0, 0, 0}; RNA_boolean_set_array(¯optr, "constraint_axis", constraint); } diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c index 38d49ab5efd..495c21bc755 100644 --- a/source/blender/editors/transform/transform_mode.c +++ b/source/blender/editors/transform/transform_mode.c @@ -178,7 +178,7 @@ static void protectedRotateBits(short protectflag, float eul[3], const float old /* this function only does the delta rotation */ /* axis-angle is usually internally stored as quats... */ static void protectedAxisAngleBits( - short protectflag, float axis[3], float *angle, float oldAxis[3], float oldAngle) + short protectflag, float axis[3], float *angle, const float oldAxis[3], float oldAngle) { /* check that protection flags are set */ if ((protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) == 0) { @@ -896,7 +896,7 @@ void headerResize(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR]) * * \note this is a tricky area, before making changes see: T29633, T42444 */ -static void TransMat3ToSize(float mat[3][3], float smat[3][3], float size[3]) +static void TransMat3ToSize(const float mat[3][3], const float smat[3][3], float size[3]) { float rmat[3][3]; diff --git a/source/blender/editors/transform/transform_mode_bbone_resize.c b/source/blender/editors/transform/transform_mode_bbone_resize.c index 2c2253630c0..80a5b307a91 100644 --- a/source/blender/editors/transform/transform_mode_bbone_resize.c +++ b/source/blender/editors/transform/transform_mode_bbone_resize.c @@ -87,7 +87,10 @@ static void headerBoneSize(TransInfo *t, const float vec[3], char str[UI_MAX_DRA } } -static void ElementBoneSize(TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3]) +static void ElementBoneSize(TransInfo *t, + TransDataContainer *tc, + TransData *td, + const float mat[3][3]) { float tmat[3][3], smat[3][3], oldy; float sizemat[3][3]; diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c index 4a648a77fe1..1886f95beae 100644 --- a/source/blender/editors/transform/transform_mode_edge_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_slide.c @@ -534,7 +534,7 @@ static EdgeSlideData *createEdgeSlideVerts_double_side(TransInfo *t, TransDataCo int sv_tot; int *sv_table; /* BMVert -> sv_array index */ EdgeSlideData *sld = MEM_callocN(sizeof(*sld), "sld"); - float mval[2] = {(float)t->mval[0], (float)t->mval[1]}; + const float mval[2] = {(float)t->mval[0], (float)t->mval[1]}; int numsel, i, loop_nr; bool use_occlude_geometry = false; View3D *v3d = NULL; @@ -894,7 +894,7 @@ static EdgeSlideData *createEdgeSlideVerts_single_side(TransInfo *t, TransDataCo int sv_tot; int *sv_table; /* BMVert -> sv_array index */ EdgeSlideData *sld = MEM_callocN(sizeof(*sld), "sld"); - float mval[2] = {(float)t->mval[0], (float)t->mval[1]}; + const float mval[2] = {(float)t->mval[0], (float)t->mval[1]}; int loop_nr; bool use_occlude_geometry = false; View3D *v3d = NULL; diff --git a/source/blender/editors/transform/transform_mode_shear.c b/source/blender/editors/transform/transform_mode_shear.c index fa33c1550e7..e508a1fa4c2 100644 --- a/source/blender/editors/transform/transform_mode_shear.c +++ b/source/blender/editors/transform/transform_mode_shear.c @@ -164,7 +164,7 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2])) FOREACH_TRANS_DATA_CONTAINER (t, tc) { TransData *td = tc->data; for (i = 0; i < tc->data_len; i++, td++) { - const float *center, *co; + const float *center; if (td->flag & TD_SKIP) { continue; } @@ -178,19 +178,15 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2])) if (is_local_center) { center = td->center; - co = td->loc; } else { center = tc->center_local; - co = td->center; } - sub_v3_v3v3(vec, co, center); - + sub_v3_v3v3(vec, td->iloc, center); mul_m3_v3(tmat, vec); - add_v3_v3(vec, center); - sub_v3_v3(vec, co); + sub_v3_v3(vec, td->iloc); if (t->options & CTX_GPENCIL_STROKES) { /* grease pencil multiframe falloff */ diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c index b396317ba7c..38537194af3 100644 --- a/source/blender/editors/transform/transform_mode_vert_slide.c +++ b/source/blender/editors/transform/transform_mode_vert_slide.c @@ -126,7 +126,7 @@ static void calcVertSlideMouseActiveVert(struct TransInfo *t, const int mval[2]) { /* Active object may have no selected vertices. */ VertSlideData *sld = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data; - float mval_fl[2] = {UNPACK2(mval)}; + const float mval_fl[2] = {UNPACK2(mval)}; TransDataVertSlideVert *sv; /* set the vertex to use as a reference for the mouse direction 'curr_sv_index' */ @@ -153,8 +153,8 @@ static void calcVertSlideMouseActiveVert(struct TransInfo *t, const int mval[2]) static void calcVertSlideMouseActiveEdges(struct TransInfo *t, const int mval[2]) { VertSlideData *sld = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data; - float imval_fl[2] = {UNPACK2(t->mouse.imval)}; - float mval_fl[2] = {UNPACK2(mval)}; + const float imval_fl[2] = {UNPACK2(t->mouse.imval)}; + const float mval_fl[2] = {UNPACK2(mval)}; float dir[3]; TransDataVertSlideVert *sv; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 2943c3cb8ea..a700dd320b7 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -37,6 +37,7 @@ #include "BKE_editmesh.h" #include "BKE_layer.h" #include "BKE_object.h" +#include "BKE_scene.h" #include "BKE_sequencer.h" #include "RNA_access.h" @@ -100,6 +101,24 @@ int BIF_snappingSupported(Object *obedit) } #endif +static bool snap_use_backface_culling(const TransInfo *t) +{ + BLI_assert(t->spacetype == SPACE_VIEW3D); + View3D *v3d = t->view; + if ((v3d->shading.type == OB_SOLID) && (v3d->shading.flag & V3D_SHADING_BACKFACE_CULLING)) { + return true; + } + if (v3d->shading.type == OB_RENDER && + (t->scene->display.shading.flag & V3D_SHADING_BACKFACE_CULLING) && + BKE_scene_uses_blender_workbench(t->scene)) { + return true; + } + if (t->settings->snap_flag & SCE_SNAP_BACKFACE_CULLING) { + return true; + } + return false; +} + bool validSnap(const TransInfo *t) { return (t->tsnap.status & (POINT_INIT | TARGET_INIT)) == (POINT_INIT | TARGET_INIT) || @@ -315,8 +334,7 @@ void applyProject(TransInfo *t) .snap_select = t->tsnap.modeSelect, .use_object_edit_cage = (t->flag & T_EDIT) != 0, .use_occlusion_test = false, - .use_backface_culling = (t->scene->toolsettings->snap_flag & - SCE_SNAP_BACKFACE_CULLING) != 0, + .use_backface_culling = t->tsnap.use_backface_culling, }, mval_fl, NULL, @@ -601,6 +619,7 @@ static void initSnappingMode(TransInfo *t) if (t->spacetype == SPACE_VIEW3D) { if (t->tsnap.object_context == NULL) { + t->tsnap.use_backface_culling = snap_use_backface_culling(t); t->tsnap.object_context = ED_transform_snap_object_context_create_view3d( t->scene, 0, t->region, t->view); @@ -1120,13 +1139,12 @@ short snapObjectsTransform( return ED_transform_snap_object_project_view3d_ex( t->tsnap.object_context, t->depsgraph, - t->scene->toolsettings->snap_mode, + t->settings->snap_mode, &(const struct SnapObjectParams){ .snap_select = t->tsnap.modeSelect, .use_object_edit_cage = (t->flag & T_EDIT) != 0, - .use_occlusion_test = t->scene->toolsettings->snap_mode != SCE_SNAP_MODE_FACE, - .use_backface_culling = (t->scene->toolsettings->snap_flag & - SCE_SNAP_BACKFACE_CULLING) != 0, + .use_occlusion_test = t->settings->snap_mode != SCE_SNAP_MODE_FACE, + .use_backface_culling = t->tsnap.use_backface_culling, }, mval, target, diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index eb14c5bec28..50b7c6d147b 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -1214,7 +1214,7 @@ static void cb_mlooptri_edges_get(const int index, int v_index[3], const BVHTree const MLoopTri *lt = &data->looptri[index]; for (int j = 2, j_next = 0; j_next < 3; j = j_next++) { const MEdge *ed = &medge[mloop[lt->tri[j]].e]; - uint tri_edge[2] = {mloop[lt->tri[j]].v, mloop[lt->tri[j_next]].v}; + const uint tri_edge[2] = {mloop[lt->tri[j]].v, mloop[lt->tri[j_next]].v}; if (ELEM(ed->v1, tri_edge[0], tri_edge[1]) && ELEM(ed->v2, tri_edge[0], tri_edge[1])) { // printf("real edge found\n"); v_index[j] = mloop[lt->tri[j]].e; @@ -1302,11 +1302,11 @@ static bool test_projected_edge_dist(const struct DistProjectedAABBPrecalc *prec * \{ */ typedef void (*Nearest2DGetVertCoCallback)(const int index, const float **co, void *data); -typedef void (*Nearest2DGetEdgeVertsCallback)(const int index, int v_index[2], void *data); -typedef void (*Nearest2DGetTriVertsCallback)(const int index, int v_index[3], void *data); +typedef void (*Nearest2DGetEdgeVertsCallback)(const int index, const int v_index[2], void *data); +typedef void (*Nearest2DGetTriVertsCallback)(const int index, const int v_index[3], void *data); /* Equal the previous one */ -typedef void (*Nearest2DGetTriEdgesCallback)(const int index, int e_index[3], void *data); -typedef void (*Nearest2DCopyVertNoCallback)(const int index, float r_no[3], void *data); +typedef void (*Nearest2DGetTriEdgesCallback)(const int index, const int e_index[3], void *data); +typedef void (*Nearest2DCopyVertNoCallback)(const int index, const float r_no[3], void *data); typedef struct Nearest2dUserData { void *userdata; diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c index 3c747a29361..384da6fb931 100644 --- a/source/blender/editors/util/numinput.c +++ b/source/blender/editors/util/numinput.c @@ -26,6 +26,8 @@ #include "BLI_string_utf8.h" #include "BLI_utildefines.h" +#include "BLT_translation.h" + #include "BKE_context.h" #include "BKE_scene.h" #include "BKE_unit.h" @@ -277,8 +279,12 @@ static bool editstr_insert_at_cursor(NumInput *n, const char *buf, const int buf return true; } -bool user_string_to_number( - bContext *C, const char *str, const UnitSettings *unit, int type, double *r_value) +bool user_string_to_number(bContext *C, + const char *str, + const UnitSettings *unit, + int type, + const char *error_prefix, + double *r_value) { #ifdef WITH_PYTHON double unit_scale = BKE_scene_unit_scale(unit, type, 1.0); @@ -288,10 +294,10 @@ bool user_string_to_number( bUnit_ReplaceString( str_unit_convert, sizeof(str_unit_convert), str, unit_scale, unit->system, type); - return BPY_execute_string_as_number(C, NULL, str_unit_convert, true, r_value); + return BPY_execute_string_as_number(C, NULL, str_unit_convert, error_prefix, r_value); } - int success = BPY_execute_string_as_number(C, NULL, str, true, r_value); + int success = BPY_execute_string_as_number(C, NULL, str, error_prefix, r_value); *r_value *= bUnit_PreferredInputUnitScalar(unit, type); *r_value /= unit_scale; return success; @@ -573,7 +579,8 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event) Scene *sce = CTX_data_scene(C); double val; - int success = user_string_to_number(C, n->str, &sce->unit, n->unit_type[idx], &val); + int success = user_string_to_number( + C, n->str, &sce->unit, n->unit_type[idx], IFACE_("Numeric input evaluation"), &val); if (success) { n->val[idx] = (float)val; diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index daa31869a11..7455004ccb8 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -116,6 +116,7 @@ void UV_OT_sphere_project(struct wmOperatorType *ot); void UV_OT_unwrap(struct wmOperatorType *ot); void UV_OT_rip(struct wmOperatorType *ot); void UV_OT_stitch(struct wmOperatorType *ot); +void UV_OT_smart_project(struct wmOperatorType *ot); /* uvedit_path.c */ void UV_OT_shortest_path_pick(struct wmOperatorType *ot); diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 532061e3dc1..956c094c19b 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -2094,6 +2094,7 @@ void ED_operatortypes_uvedit(void) WM_operatortype_append(UV_OT_reset); WM_operatortype_append(UV_OT_sphere_project); WM_operatortype_append(UV_OT_unwrap); + WM_operatortype_append(UV_OT_smart_project); WM_operatortype_append(UV_OT_reveal); WM_operatortype_append(UV_OT_hide); diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index a4ee9a294fe..8e079dcac94 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -497,7 +497,7 @@ static void p_chart_uv_translate(PChart *chart, const float trans[2]) } } -static void p_chart_uv_transform(PChart *chart, float mat[2][2]) +static void p_chart_uv_transform(PChart *chart, const float mat[2][2]) { PVert *v; diff --git a/source/blender/editors/uvedit/uvedit_rip.c b/source/blender/editors/uvedit/uvedit_rip.c index 07bec2da1ae..421e58b1cb5 100644 --- a/source/blender/editors/uvedit/uvedit_rip.c +++ b/source/blender/editors/uvedit/uvedit_rip.c @@ -538,23 +538,22 @@ static bool uv_rip_pairs_loop_change_sides_test(BMLoop *l_switch, if (count_a + count_b == 4) { return count_a > count_b; } - else { - const float angle_a_before = uv_rip_pairs_calc_uv_angle( - l_switch, side_a, aspect_y, cd_loop_uv_offset); - const float angle_b_before = uv_rip_pairs_calc_uv_angle( - l_target, side_b, aspect_y, cd_loop_uv_offset); - UL(l_switch)->side = side_b; + const float angle_a_before = uv_rip_pairs_calc_uv_angle( + l_switch, side_a, aspect_y, cd_loop_uv_offset); + const float angle_b_before = uv_rip_pairs_calc_uv_angle( + l_target, side_b, aspect_y, cd_loop_uv_offset); - const float angle_a_after = uv_rip_pairs_calc_uv_angle( - l_switch, side_a, aspect_y, cd_loop_uv_offset); - const float angle_b_after = uv_rip_pairs_calc_uv_angle( - l_target, side_b, aspect_y, cd_loop_uv_offset); + UL(l_switch)->side = side_b; - UL(l_switch)->side = side_a; + const float angle_a_after = uv_rip_pairs_calc_uv_angle( + l_switch, side_a, aspect_y, cd_loop_uv_offset); + const float angle_b_after = uv_rip_pairs_calc_uv_angle( + l_target, side_b, aspect_y, cd_loop_uv_offset); - return fabsf(angle_a_before - angle_b_before) > fabsf(angle_a_after - angle_b_after); - } + UL(l_switch)->side = side_a; + + return fabsf(angle_a_before - angle_b_before) > fabsf(angle_a_after - angle_b_after); } /** diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index f649ee528d4..f3ea7456c38 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -323,7 +323,10 @@ static int getNumOfIslandUvs(UvElementMap *elementMap, int island) return elementMap->islandIndices[island + 1] - elementMap->islandIndices[island]; } -static void stitch_uv_rotate(float mat[2][2], float medianPoint[2], float uv[2], float aspect) +static void stitch_uv_rotate(const float mat[2][2], + const float medianPoint[2], + float uv[2], + float aspect) { float uv_rotation_result[2]; diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 6fcfb0e0bfc..49f11cd6a74 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -35,7 +35,10 @@ #include "DNA_scene_types.h" #include "BLI_alloca.h" +#include "BLI_array.h" +#include "BLI_linklist.h" #include "BLI_math.h" +#include "BLI_memarena.h" #include "BLI_string.h" #include "BLI_utildefines.h" #include "BLI_uvproject.h" @@ -147,7 +150,13 @@ typedef struct UnwrapOptions { /** Connectivity based on UV coordinates instead of seams. */ bool topology_from_uvs; /** Only affect selected faces. */ - bool only_selected; + bool only_selected_faces; + /** + * Only affect selected UV's. + * \note Disable this for operations that don't run in the image-window. + * Unwrapping from the 3D view for example, where only 'only_selected_faces' should be used. + */ + bool only_selected_uvs; /** Fill holes to better preserve shape. */ bool fill_holes; /** Correct for mapped image texture aspect ratio. */ @@ -299,7 +308,7 @@ static ParamHandle *construct_param_handle(const Scene *scene, BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || - (options->only_selected && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) { + (options->only_selected_faces && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) { continue; } @@ -307,10 +316,12 @@ static ParamHandle *construct_param_handle(const Scene *scene, bool is_loopsel = false; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - is_loopsel = true; - break; + if (options->only_selected_uvs && + (uvedit_uv_select_test(scene, l, cd_loop_uv_offset) == false)) { + continue; } + is_loopsel = true; + break; } if (is_loopsel == false) { continue; @@ -382,7 +393,7 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene, BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || - (options->only_selected && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) { + (options->only_selected_faces && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) { continue; } @@ -390,10 +401,12 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene, bool is_loopsel = false; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - is_loopsel = true; - break; + if (options->only_selected_uvs && + (uvedit_uv_select_test(scene, l, cd_loop_uv_offset) == false)) { + continue; } + is_loopsel = true; + break; } if (is_loopsel == false) { continue; @@ -571,7 +584,7 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, } else { if (BM_elem_flag_test(origFace, BM_ELEM_HIDDEN) || - (options->only_selected && !BM_elem_flag_test(origFace, BM_ELEM_SELECT))) { + (options->only_selected_faces && !BM_elem_flag_test(origFace, BM_ELEM_SELECT))) { continue; } } @@ -671,7 +684,8 @@ static bool minimize_stretch_init(bContext *C, wmOperator *op) const UnwrapOptions options = { .topology_from_uvs = true, .fill_holes = RNA_boolean_get(op->ptr, "fill_holes"), - .only_selected = true, + .only_selected_faces = true, + .only_selected_uvs = true, .correct_aspect = true, }; @@ -933,7 +947,8 @@ static void uvedit_pack_islands(const Scene *scene, Object *ob, BMesh *bm) { const UnwrapOptions options = { .topology_from_uvs = true, - .only_selected = false, + .only_selected_faces = false, + .only_selected_uvs = true, .fill_holes = false, .correct_aspect = false, }; @@ -975,7 +990,8 @@ static int pack_islands_exec(bContext *C, wmOperator *op) const UnwrapOptions options = { .topology_from_uvs = true, - .only_selected = true, + .only_selected_faces = true, + .only_selected_uvs = true, .fill_holes = false, .correct_aspect = true, }; @@ -1040,7 +1056,8 @@ static int average_islands_scale_exec(bContext *C, wmOperator *UNUSED(op)) const UnwrapOptions options = { .topology_from_uvs = true, - .only_selected = true, + .only_selected_faces = true, + .only_selected_uvs = true, .fill_holes = false, .correct_aspect = true, }; @@ -1114,7 +1131,8 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit) const UnwrapOptions options = { .topology_from_uvs = false, - .only_selected = false, + .only_selected_faces = false, + .only_selected_uvs = true, .fill_holes = (scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES) != 0, .correct_aspect = (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) == 0, }; @@ -1330,7 +1348,7 @@ static void uv_map_rotation_matrix(float result[4][4], float sideangledeg, float radius) { - float offset[4] = {0}; + const float offset[4] = {0}; uv_map_rotation_matrix_ex(result, rv3d, ob, upangledeg, sideangledeg, radius, offset); } @@ -1471,18 +1489,21 @@ static void correct_uv_aspect(Object *ob, BMEditMesh *em) /** \name UV Map Clip & Correct * \{ */ -static void uv_map_clip_correct_properties(wmOperatorType *ot) +static void uv_map_clip_correct_properties_ex(wmOperatorType *ot, bool clip_to_bounds) { RNA_def_boolean(ot->srna, "correct_aspect", 1, "Correct Aspect", "Map UVs taking image aspect ratio into account"); - RNA_def_boolean(ot->srna, - "clip_to_bounds", - 0, - "Clip to Bounds", - "Clip UV coordinates to bounds after unwrapping"); + /* Optional, since not all unwrapping types need to be clipped. */ + if (clip_to_bounds) { + RNA_def_boolean(ot->srna, + "clip_to_bounds", + 0, + "Clip to Bounds", + "Clip UV coordinates to bounds after unwrapping"); + } RNA_def_boolean(ot->srna, "scale_to_bounds", 0, @@ -1490,6 +1511,11 @@ static void uv_map_clip_correct_properties(wmOperatorType *ot) "Scale UV coordinates to bounds after unwrapping"); } +static void uv_map_clip_correct_properties(wmOperatorType *ot) +{ + uv_map_clip_correct_properties_ex(ot, true); +} + static void uv_map_clip_correct_multi(Object **objects, uint objects_len, wmOperator *op) { BMFace *efa; @@ -1498,7 +1524,8 @@ static void uv_map_clip_correct_multi(Object **objects, uint objects_len, wmOper MLoopUV *luv; float dx, dy, min[2], max[2]; const bool correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect"); - const bool clip_to_bounds = RNA_boolean_get(op->ptr, "clip_to_bounds"); + const bool clip_to_bounds = (RNA_struct_find_property(op->ptr, "clip_to_bounds") && + RNA_boolean_get(op->ptr, "clip_to_bounds")); const bool scale_to_bounds = RNA_boolean_get(op->ptr, "scale_to_bounds"); INIT_MINMAX2(min, max); @@ -1635,7 +1662,8 @@ void ED_uvedit_live_unwrap(const Scene *scene, Object **objects, int objects_len if (scene->toolsettings->edge_mode_live_unwrap) { const UnwrapOptions options = { .topology_from_uvs = false, - .only_selected = false, + .only_selected_faces = false, + .only_selected_uvs = true, .fill_holes = (scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES) != 0, .correct_aspect = (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) == 0, }; @@ -1670,7 +1698,8 @@ static int unwrap_exec(bContext *C, wmOperator *op) const UnwrapOptions options = { .topology_from_uvs = false, - .only_selected = true, + .only_selected_faces = true, + .only_selected_uvs = true, .fill_holes = RNA_boolean_get(op->ptr, "fill_holes"), .correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect"), }; @@ -1829,6 +1858,363 @@ void UV_OT_unwrap(wmOperatorType *ot) /** \} */ /* -------------------------------------------------------------------- */ +/** \name Smart UV Project Operator + * \{ */ + +/* Ignore all areas below this, as the UV's get zeroed. */ +static const float smart_uv_project_area_ignore = 1e-12f; + +typedef struct ThickFace { + float area; + BMFace *efa; +} ThickFace; + +static int smart_uv_project_thickface_area_cmp_fn(const void *tf_a_p, const void *tf_b_p) +{ + + const ThickFace *tf_a = (ThickFace *)tf_a_p; + const ThickFace *tf_b = (ThickFace *)tf_b_p; + + /* Ignore the area of small faces. + * Also, order checks so `!isfinite(...)` values are counted as zero area. */ + if (!((tf_a->area > smart_uv_project_area_ignore) || + (tf_b->area > smart_uv_project_area_ignore))) { + return 0; + } + + if (tf_a->area < tf_b->area) { + return 1; + } + if (tf_a->area > tf_b->area) { + return -1; + } + return 0; +} + +static uint smart_uv_project_calculate_project_normals(const ThickFace *thick_faces, + const uint thick_faces_len, + BMesh *bm, + const float project_angle_limit_half_cos, + const float project_angle_limit_cos, + const float area_weight, + float (**r_project_normal_array)[3]) +{ + if (UNLIKELY(thick_faces_len == 0)) { + *r_project_normal_array = NULL; + return 0; + } + + const float *project_normal = thick_faces[0].efa->no; + + const ThickFace **project_thick_faces = NULL; + BLI_array_declare(project_thick_faces); + + float(*project_normal_array)[3] = NULL; + BLI_array_declare(project_normal_array); + + BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false); + + while (true) { + for (int f_index = thick_faces_len - 1; f_index >= 0; f_index--) { + if (BM_elem_flag_test(thick_faces[f_index].efa, BM_ELEM_TAG)) { + continue; + } + + if (dot_v3v3(thick_faces[f_index].efa->no, project_normal) > project_angle_limit_half_cos) { + BLI_array_append(project_thick_faces, &thick_faces[f_index]); + BM_elem_flag_set(thick_faces[f_index].efa, BM_ELEM_TAG, true); + } + } + + float average_normal[3] = {0.0f, 0.0f, 0.0f}; + + if (area_weight <= 0.0f) { + for (int f_proj_index = 0; f_proj_index < BLI_array_len(project_thick_faces); + f_proj_index++) { + const ThickFace *tf = project_thick_faces[f_proj_index]; + add_v3_v3(average_normal, tf->efa->no); + } + } + else if (area_weight >= 1.0f) { + for (int f_proj_index = 0; f_proj_index < BLI_array_len(project_thick_faces); + f_proj_index++) { + const ThickFace *tf = project_thick_faces[f_proj_index]; + madd_v3_v3fl(average_normal, tf->efa->no, tf->area); + } + } + else { + for (int f_proj_index = 0; f_proj_index < BLI_array_len(project_thick_faces); + f_proj_index++) { + const ThickFace *tf = project_thick_faces[f_proj_index]; + const float area_blend = (tf->area * area_weight) + (1.0f - area_weight); + madd_v3_v3fl(average_normal, tf->efa->no, area_blend); + } + } + + /* Avoid NAN. */ + if (normalize_v3(average_normal) != 0.0f) { + float(*normal)[3] = BLI_array_append_ret(project_normal_array); + copy_v3_v3(*normal, average_normal); + } + + /* Find the most unique angle that points away from other normals. */ + float anble_best = 1.0f; + uint angle_best_index = 0; + + for (int f_index = thick_faces_len - 1; f_index >= 0; f_index--) { + if (BM_elem_flag_test(thick_faces[f_index].efa, BM_ELEM_TAG)) { + continue; + } + + float angle_test = -1.0f; + for (int p_index = 0; p_index < BLI_array_len(project_normal_array); p_index++) { + angle_test = max_ff(angle_test, + dot_v3v3(project_normal_array[p_index], thick_faces[f_index].efa->no)); + } + + if (angle_test < anble_best) { + anble_best = angle_test; + angle_best_index = f_index; + } + } + + if (anble_best < project_angle_limit_cos) { + project_normal = thick_faces[angle_best_index].efa->no; + BLI_array_clear(project_thick_faces); + BLI_array_append(project_thick_faces, &thick_faces[angle_best_index]); + BM_elem_flag_enable(thick_faces[angle_best_index].efa, BM_ELEM_TAG); + } + else { + if (BLI_array_len(project_normal_array) >= 1) { + break; + } + } + } + + BLI_array_free(project_thick_faces); + BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false); + + *r_project_normal_array = project_normal_array; + return BLI_array_len(project_normal_array); +} + +static int smart_project_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + + /* May be NULL. */ + View3D *v3d = CTX_wm_view3d(C); + + const float project_angle_limit = RNA_float_get(op->ptr, "angle_limit"); + const float island_margin = RNA_float_get(op->ptr, "island_margin"); + const float area_weight = RNA_float_get(op->ptr, "area_weight"); + + const float project_angle_limit_cos = cosf(project_angle_limit); + const float project_angle_limit_half_cos = cosf(project_angle_limit / 2); + + /* Memory arena for list links (cleared for each object). */ + MemArena *arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); + + uint objects_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs( + view_layer, v3d, &objects_len); + + Object **objects_changed = MEM_mallocN(sizeof(*objects_changed) * objects_len, __func__); + uint object_changed_len = 0; + + BMFace *efa; + BMIter iter; + uint ob_index; + + for (ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + BMEditMesh *em = BKE_editmesh_from_object(obedit); + bool changed = false; + + const uint cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + ThickFace *thick_faces = MEM_mallocN(sizeof(*thick_faces) * em->bm->totface, __func__); + + uint thick_faces_len = 0; + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) { + continue; + } + thick_faces[thick_faces_len].area = BM_face_calc_area(efa); + thick_faces[thick_faces_len].efa = efa; + thick_faces_len++; + } + + qsort(thick_faces, thick_faces_len, sizeof(ThickFace), smart_uv_project_thickface_area_cmp_fn); + + /* Remove all zero area faces. */ + while ((thick_faces_len > 0) && + !(thick_faces[thick_faces_len - 1].area > smart_uv_project_area_ignore)) { + + /* Zero UV's so they don't overlap with other faces being unwrapped. */ + BMIter liter; + BMLoop *l; + BM_ITER_ELEM (l, &liter, thick_faces[thick_faces_len - 1].efa, BM_LOOPS_OF_FACE) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + zero_v2(luv->uv); + changed = true; + } + + thick_faces_len -= 1; + } + + float(*project_normal_array)[3] = NULL; + int project_normals_len = smart_uv_project_calculate_project_normals( + thick_faces, + thick_faces_len, + em->bm, + project_angle_limit_half_cos, + project_angle_limit_cos, + area_weight, + &project_normal_array); + + if (project_normals_len == 0) { + MEM_freeN(thick_faces); + BLI_assert(project_normal_array == NULL); + continue; + } + + /* After finding projection vectors, we find the uv positions. */ + LinkNode **thickface_project_groups = MEM_callocN( + sizeof(*thickface_project_groups) * project_normals_len, __func__); + + BLI_memarena_clear(arena); + + for (int f_index = thick_faces_len - 1; f_index >= 0; f_index--) { + const float *f_normal = thick_faces[f_index].efa->no; + + float angle_best = dot_v3v3(f_normal, project_normal_array[0]); + uint angle_best_index = 0; + + for (int p_index = 1; p_index < project_normals_len; p_index++) { + const float angle_test = dot_v3v3(f_normal, project_normal_array[p_index]); + if (angle_test > angle_best) { + angle_best = angle_test; + angle_best_index = p_index; + } + } + + BLI_linklist_prepend_arena( + &thickface_project_groups[angle_best_index], &thick_faces[f_index], arena); + } + + for (int p_index = 0; p_index < project_normals_len; p_index++) { + if (thickface_project_groups[p_index] == NULL) { + continue; + } + + float axis_mat[3][3]; + axis_dominant_v3_to_m3_negate(axis_mat, project_normal_array[p_index]); + + for (LinkNode *list = thickface_project_groups[p_index]; list; list = list->next) { + ThickFace *tf = list->link; + BMIter liter; + BMLoop *l; + BM_ITER_ELEM (l, &liter, tf->efa, BM_LOOPS_OF_FACE) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + mul_v2_m3v3(luv->uv, axis_mat, l->v->co); + } + changed = true; + } + } + + MEM_freeN(thick_faces); + MEM_freeN(project_normal_array); + + /* No need to free the lists in 'thickface_project_groups' values as the 'arena' is used. */ + MEM_freeN(thickface_project_groups); + + if (changed) { + objects_changed[object_changed_len] = objects[ob_index]; + object_changed_len += 1; + } + } + + BLI_memarena_free(arena); + + MEM_freeN(objects); + + /* Pack islands & Stretch to UV bounds */ + if (object_changed_len > 0) { + + scene->toolsettings->uvcalc_margin = island_margin; + const UnwrapOptions options = { + .topology_from_uvs = true, + .only_selected_faces = true, + .only_selected_uvs = false, + .fill_holes = true, + .correct_aspect = false, + }; + + /* Depsgraph refresh functions are called here. */ + uvedit_pack_islands_multi(scene, objects_changed, object_changed_len, &options, true, false); + uv_map_clip_correct_multi(objects_changed, object_changed_len, op); + } + + MEM_freeN(objects_changed); + + return OPERATOR_FINISHED; +} + +void UV_OT_smart_project(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Smart UV Project"; + ot->idname = "UV_OT_smart_project"; + ot->description = "Projection unwraps the selected faces of mesh objects"; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* api callbacks */ + ot->exec = smart_project_exec; + ot->poll = ED_operator_uvmap; + ot->invoke = WM_operator_props_popup_confirm; + + /* properties */ + prop = RNA_def_float_rotation(ot->srna, + "angle_limit", + 0, + NULL, + DEG2RADF(0.0f), + DEG2RADF(90.0f), + "Angle Limit", + "Lower for more projection groups, higher for less distortion", + DEG2RADF(0.0f), + DEG2RADF(89.0f)); + RNA_def_property_float_default(prop, DEG2RADF(66.0f)); + + RNA_def_float(ot->srna, + "island_margin", + 0.0f, + 0.0f, + 1.0f, + "Island Margin", + "Margin to reduce bleed from adjacent islands", + 0.0f, + 1.0f); + RNA_def_float(ot->srna, + "area_weight", + 0.0f, + 0.0f, + 1.0f, + "Area Weight", + "Weight projections vector by faces with larger areas", + 0.0f, + 1.0f); + + uv_map_clip_correct_properties_ex(ot, false); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Project UV From View Operator * \{ */ diff --git a/source/blender/freestyle/FRS_freestyle.h b/source/blender/freestyle/FRS_freestyle.h index 57b6dc815a3..bc5e9d49bee 100644 --- a/source/blender/freestyle/FRS_freestyle.h +++ b/source/blender/freestyle/FRS_freestyle.h @@ -42,7 +42,7 @@ struct FreestyleGlobals { extern struct FreestyleGlobals g_freestyle; /* Rendering */ -void FRS_initialize(void); +void FRS_init(void); void FRS_set_context(struct bContext *C); int FRS_is_freestyle_enabled(struct ViewLayer *view_layer); void FRS_init_stroke_renderer(struct Render *re); diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp index f9edadb2d4a..dea09b7620f 100644 --- a/source/blender/freestyle/intern/application/Controller.cpp +++ b/source/blender/freestyle/intern/application/Controller.cpp @@ -316,10 +316,9 @@ int Controller::LoadMesh(Render *re, ViewLayer *view_layer, Depsgraph *depsgraph ClearRootNode(); return 0; } - else { - delete _ViewMap; - _ViewMap = NULL; - } + + delete _ViewMap; + _ViewMap = NULL; } _Chrono.start(); diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp index e1763514e08..a06218620ac 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -684,7 +684,7 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) if (v0 == v1 || v0 == v2 || v1 == v2) { continue; // do nothing for now } - else if (GeomUtils::distPointSegment<Vec3r>(v0, v1, v2) < 1.0e-6) { + if (GeomUtils::distPointSegment<Vec3r>(v0, v1, v2) < 1.0e-6) { detri.viP = vi0; detri.viA = vi1; detri.viB = vi2; diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp index 51ac281e330..2b43e913b3d 100644 --- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp +++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp @@ -100,7 +100,7 @@ static bCallbackFuncStore load_post_callback_funcstore = { // Initialization //======================================================= -void FRS_initialize() +void FRS_init() { if (freestyle_is_initialized) { return; diff --git a/source/blender/freestyle/intern/geometry/GeomUtils.cpp b/source/blender/freestyle/intern/geometry/GeomUtils.cpp index 4c4f12faaba..dbd792852ad 100644 --- a/source/blender/freestyle/intern/geometry/GeomUtils.cpp +++ b/source/blender/freestyle/intern/geometry/GeomUtils.cpp @@ -514,9 +514,8 @@ intersection_test intersectRayPlane(const Vec3r &orig, if (fabs((norm * orig) + d) <= epsilon) { return COINCIDENT; // plane and ray are coincident } - else { - return COLINEAR; - } + + return COLINEAR; } t = -(d + (norm * orig)) / denom; @@ -766,9 +765,8 @@ inline bool intersect2dSegPoly(Vec2r *seg, Vec2r *poly, unsigned n) if (N < 0) { return false; } - else { - continue; - } + + continue; } t = N / D; diff --git a/source/blender/freestyle/intern/python/BPy_Convert.cpp b/source/blender/freestyle/intern/python/BPy_Convert.cpp index 427e4198e5c..03f9760344b 100644 --- a/source/blender/freestyle/intern/python/BPy_Convert.cpp +++ b/source/blender/freestyle/intern/python/BPy_Convert.cpp @@ -110,22 +110,22 @@ PyObject *Any_BPy_Interface0D_from_Interface0D(Interface0D &if0D) if (typeid(if0D) == typeid(CurvePoint)) { return BPy_CurvePoint_from_CurvePoint(dynamic_cast<CurvePoint &>(if0D)); } - else if (typeid(if0D) == typeid(StrokeVertex)) { + if (typeid(if0D) == typeid(StrokeVertex)) { return BPy_StrokeVertex_from_StrokeVertex(dynamic_cast<StrokeVertex &>(if0D)); } - else if (typeid(if0D) == typeid(SVertex)) { + if (typeid(if0D) == typeid(SVertex)) { return BPy_SVertex_from_SVertex(dynamic_cast<SVertex &>(if0D)); } - else if (typeid(if0D) == typeid(ViewVertex)) { + if (typeid(if0D) == typeid(ViewVertex)) { return BPy_ViewVertex_from_ViewVertex(dynamic_cast<ViewVertex &>(if0D)); } - else if (typeid(if0D) == typeid(NonTVertex)) { + if (typeid(if0D) == typeid(NonTVertex)) { return BPy_NonTVertex_from_NonTVertex(dynamic_cast<NonTVertex &>(if0D)); } - else if (typeid(if0D) == typeid(TVertex)) { + if (typeid(if0D) == typeid(TVertex)) { return BPy_TVertex_from_TVertex(dynamic_cast<TVertex &>(if0D)); } - else if (typeid(if0D) == typeid(Interface0D)) { + if (typeid(if0D) == typeid(Interface0D)) { return BPy_Interface0D_from_Interface0D(if0D); } string msg("unexpected type: " + if0D.getExactTypeName()); @@ -138,22 +138,22 @@ PyObject *Any_BPy_Interface1D_from_Interface1D(Interface1D &if1D) if (typeid(if1D) == typeid(ViewEdge)) { return BPy_ViewEdge_from_ViewEdge(dynamic_cast<ViewEdge &>(if1D)); } - else if (typeid(if1D) == typeid(Chain)) { + if (typeid(if1D) == typeid(Chain)) { return BPy_Chain_from_Chain(dynamic_cast<Chain &>(if1D)); } - else if (typeid(if1D) == typeid(Stroke)) { + if (typeid(if1D) == typeid(Stroke)) { return BPy_Stroke_from_Stroke(dynamic_cast<Stroke &>(if1D)); } - else if (typeid(if1D) == typeid(FEdgeSharp)) { + if (typeid(if1D) == typeid(FEdgeSharp)) { return BPy_FEdgeSharp_from_FEdgeSharp(dynamic_cast<FEdgeSharp &>(if1D)); } - else if (typeid(if1D) == typeid(FEdgeSmooth)) { + if (typeid(if1D) == typeid(FEdgeSmooth)) { return BPy_FEdgeSmooth_from_FEdgeSmooth(dynamic_cast<FEdgeSmooth &>(if1D)); } - else if (typeid(if1D) == typeid(FEdge)) { + if (typeid(if1D) == typeid(FEdge)) { return BPy_FEdge_from_FEdge(dynamic_cast<FEdge &>(if1D)); } - else if (typeid(if1D) == typeid(Interface1D)) { + if (typeid(if1D) == typeid(Interface1D)) { return BPy_Interface1D_from_Interface1D(if1D); } string msg("unexpected type: " + if1D.getExactTypeName()); @@ -166,10 +166,10 @@ PyObject *Any_BPy_FEdge_from_FEdge(FEdge &fe) if (typeid(fe) == typeid(FEdgeSharp)) { return BPy_FEdgeSharp_from_FEdgeSharp(dynamic_cast<FEdgeSharp &>(fe)); } - else if (typeid(fe) == typeid(FEdgeSmooth)) { + if (typeid(fe) == typeid(FEdgeSmooth)) { return BPy_FEdgeSmooth_from_FEdgeSmooth(dynamic_cast<FEdgeSmooth &>(fe)); } - else if (typeid(fe) == typeid(FEdge)) { + if (typeid(fe) == typeid(FEdge)) { return BPy_FEdge_from_FEdge(fe); } string msg("unexpected type: " + fe.getExactTypeName()); @@ -182,10 +182,10 @@ PyObject *Any_BPy_ViewVertex_from_ViewVertex(ViewVertex &vv) if (typeid(vv) == typeid(NonTVertex)) { return BPy_NonTVertex_from_NonTVertex(dynamic_cast<NonTVertex &>(vv)); } - else if (typeid(vv) == typeid(TVertex)) { + if (typeid(vv) == typeid(TVertex)) { return BPy_TVertex_from_TVertex(dynamic_cast<TVertex &>(vv)); } - else if (typeid(vv) == typeid(ViewVertex)) { + if (typeid(vv) == typeid(ViewVertex)) { return BPy_ViewVertex_from_ViewVertex(vv); } string msg("unexpected type: " + vv.getExactTypeName()); @@ -773,7 +773,7 @@ bool float_array_from_PyObject(PyObject *obj, float *v, int n) } return 1; } - else if (ColorObject_Check(obj) && n == 3) { + if (ColorObject_Check(obj) && n == 3) { if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) { return 0; } @@ -782,10 +782,10 @@ bool float_array_from_PyObject(PyObject *obj, float *v, int n) } return 1; } - else if (PyList_Check(obj) && PyList_GET_SIZE(obj) == n) { + if (PyList_Check(obj) && PyList_GET_SIZE(obj) == n) { return float_array_from_PyList(obj, v, n); } - else if (PyTuple_Check(obj) && PyTuple_GET_SIZE(obj) == n) { + if (PyTuple_Check(obj) && PyTuple_GET_SIZE(obj) == n) { return float_array_from_PyTuple(obj, v, n); } return 0; diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp index 33078e6ba6a..9796dcda964 100644 --- a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp +++ b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp @@ -264,7 +264,7 @@ static PyObject *Freestyle_evaluateCurveMappingF(PyObject * /*self*/, PyObject * return NULL; } cumap = (CurveMapping *)py_srna->ptr.data; - BKE_curvemapping_initialize(cumap); + BKE_curvemapping_init(cumap); /* disable extrapolation if enabled */ if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE)) { cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE; diff --git a/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp b/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp index 2c226e330d7..dbf1c12fb01 100644 --- a/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp +++ b/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp @@ -108,7 +108,7 @@ static int FrsMaterial_init(BPy_FrsMaterial *self, PyObject *args, PyObject *kwd self->m = new FrsMaterial(*m); } } - else if (PyErr_Clear(), + else if ((void)PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "O&O&O&O&O&fi", @@ -508,9 +508,8 @@ static PyObject *BPy_FrsMaterial_richcmpr(PyObject *objectA, if (comparison_type == Py_NE) { Py_RETURN_TRUE; } - else { - Py_RETURN_FALSE; - } + + Py_RETURN_FALSE; } matA = (BPy_FrsMaterial *)objectA; @@ -531,9 +530,8 @@ static PyObject *BPy_FrsMaterial_richcmpr(PyObject *objectA, if (result == true) { Py_RETURN_TRUE; } - else { - Py_RETURN_FALSE; - } + + Py_RETURN_FALSE; } static Py_hash_t FrsMaterial_hash(PyObject *self) diff --git a/source/blender/freestyle/intern/python/BPy_Id.cpp b/source/blender/freestyle/intern/python/BPy_Id.cpp index 4f61ba847f6..eb0eb661e3d 100644 --- a/source/blender/freestyle/intern/python/BPy_Id.cpp +++ b/source/blender/freestyle/intern/python/BPy_Id.cpp @@ -75,7 +75,7 @@ static int Id_init(BPy_Id *self, PyObject *args, PyObject *kwds) if (PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_1, &Id_Type, &brother)) { self->id = new Id(*(((BPy_Id *)brother)->id)); } - else if (PyErr_Clear(), + else if ((void)PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "|ii", (char **)kwlist_2, &first, &second)) { self->id = new Id(first, second); } diff --git a/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp b/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp index 98b0099bcad..9c155db913c 100644 --- a/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp +++ b/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp @@ -88,21 +88,20 @@ static PyObject *Integrator_integrate(PyObject * /*self*/, PyObject *args, PyObj double res = integrate(*fun, it, it_end, t); return PyFloat_FromDouble(res); } - else if (BPy_UnaryFunction0DFloat_Check(obj1)) { + if (BPy_UnaryFunction0DFloat_Check(obj1)) { UnaryFunction0D<float> *fun = ((BPy_UnaryFunction0DFloat *)obj1)->uf0D_float; float res = integrate(*fun, it, it_end, t); return PyFloat_FromDouble(res); } - else if (BPy_UnaryFunction0DUnsigned_Check(obj1)) { + if (BPy_UnaryFunction0DUnsigned_Check(obj1)) { UnaryFunction0D<unsigned int> *fun = ((BPy_UnaryFunction0DUnsigned *)obj1)->uf0D_unsigned; unsigned int res = integrate(*fun, it, it_end, t); return PyLong_FromLong(res); } - else { - string class_name(Py_TYPE(obj1)->tp_name); - PyErr_SetString(PyExc_TypeError, ("unsupported function type: " + class_name).c_str()); - return NULL; - } + + string class_name(Py_TYPE(obj1)->tp_name); + PyErr_SetString(PyExc_TypeError, ("unsupported function type: " + class_name).c_str()); + return NULL; } /*-----------------------Integrator module docstring---------------------------------------*/ diff --git a/source/blender/freestyle/intern/python/BPy_Operators.cpp b/source/blender/freestyle/intern/python/BPy_Operators.cpp index 510e823ba55..56f95b8ecbb 100644 --- a/source/blender/freestyle/intern/python/BPy_Operators.cpp +++ b/source/blender/freestyle/intern/python/BPy_Operators.cpp @@ -365,8 +365,8 @@ static PyObject *Operators_sequential_split(BPy_Operators * /*self*/, return NULL; } } - else if (PyErr_Clear(), - (f = 0.0f), + else if ((void)PyErr_Clear(), + (void)(f = 0.0f), PyArg_ParseTupleAndKeywords( args, kwds, "O!|f", (char **)kwlist_2, &UnaryPredicate0D_Type, &obj1, &f)) { if (!((BPy_UnaryPredicate0D *)obj1)->up0D) { @@ -484,8 +484,8 @@ static PyObject *Operators_recursive_split(BPy_Operators * /*self*/, return NULL; } } - else if (PyErr_Clear(), - (f = 0.0f), + else if ((void)PyErr_Clear(), + (void)(f = 0.0f), PyArg_ParseTupleAndKeywords(args, kwds, "O!O!O!|f", diff --git a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp index 5f5407e82e3..214385f74ad 100644 --- a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp +++ b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp @@ -110,7 +110,7 @@ static int StrokeAttribute_init(BPy_StrokeAttribute *self, PyObject *args, PyObj self->sa = new StrokeAttribute(*(((BPy_StrokeAttribute *)obj1)->sa)); } } - else if (PyErr_Clear(), + else if ((void)PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "O!O!f", @@ -123,7 +123,7 @@ static int StrokeAttribute_init(BPy_StrokeAttribute *self, PyObject *args, PyObj self->sa = new StrokeAttribute( *(((BPy_StrokeAttribute *)obj1)->sa), *(((BPy_StrokeAttribute *)obj2)->sa), t); } - else if (PyErr_Clear(), + else if ((void)PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "ffffff", diff --git a/source/blender/freestyle/intern/python/BPy_ViewShape.cpp b/source/blender/freestyle/intern/python/BPy_ViewShape.cpp index f59ae15ae01..2adcae13e6d 100644 --- a/source/blender/freestyle/intern/python/BPy_ViewShape.cpp +++ b/source/blender/freestyle/intern/python/BPy_ViewShape.cpp @@ -88,7 +88,7 @@ static int ViewShape_init(BPy_ViewShape *self, PyObject *args, PyObject *kwds) self->py_ss = ((BPy_ViewShape *)obj)->py_ss; } } - else if (PyErr_Clear(), + else if ((void)PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_2, &SShape_Type, &obj)) { BPy_SShape *py_ss = (BPy_SShape *)obj; self->vs = new ViewShape(py_ss->ss); diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp index 6af80c4bfd9..81dd79ff270 100644 --- a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp +++ b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp @@ -95,7 +95,7 @@ static int CurvePoint_init(BPy_CurvePoint *self, PyObject *args, PyObject *kwds) self->cp = new CurvePoint(*(((BPy_CurvePoint *)obj1)->cp)); } } - else if (PyErr_Clear(), + else if ((void)PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "O!O!f", @@ -107,7 +107,7 @@ static int CurvePoint_init(BPy_CurvePoint *self, PyObject *args, PyObject *kwds) &t2d)) { self->cp = new CurvePoint(((BPy_SVertex *)obj1)->sv, ((BPy_SVertex *)obj2)->sv, t2d); } - else if (PyErr_Clear(), + else if ((void)PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "O!O!f", diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp index 71a87c2c01e..c01f1f17000 100644 --- a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp +++ b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp @@ -72,7 +72,7 @@ static int SVertex_init(BPy_SVertex *self, PyObject *args, PyObject *kwds) self->sv = new SVertex(*(((BPy_SVertex *)obj)->sv)); } } - else if (PyErr_Clear(), + else if ((void)PyErr_Clear(), PyArg_ParseTupleAndKeywords( args, kwds, "O&O!", (char **)kwlist_2, convert_v3, v, &Id_Type, &obj)) { Vec3r point_3d(v[0], v[1], v[2]); diff --git a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp index b4c08714af0..519bd72db3b 100644 --- a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp +++ b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp @@ -107,7 +107,7 @@ static int StrokeVertex_init(BPy_StrokeVertex *self, PyObject *args, PyObject *k self->sv = new StrokeVertex(*(((BPy_StrokeVertex *)obj1)->sv)); } } - else if (PyErr_Clear(), + else if ((void)PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "O!O!f", @@ -129,7 +129,7 @@ static int StrokeVertex_init(BPy_StrokeVertex *self, PyObject *args, PyObject *k } self->sv = new StrokeVertex(sv1, sv2, t3d); } - else if (PyErr_Clear(), + else if ((void)PyErr_Clear(), PyArg_ParseTupleAndKeywords( args, kwds, "O!", (char **)kwlist_3, &CurvePoint_Type, &obj1)) { CurvePoint *cp = ((BPy_CurvePoint *)obj1)->cp; @@ -139,8 +139,8 @@ static int StrokeVertex_init(BPy_StrokeVertex *self, PyObject *args, PyObject *k } self->sv = new StrokeVertex(cp); } - else if (PyErr_Clear(), - (obj2 = 0), + else if ((void)PyErr_Clear(), + (void)(obj2 = 0), PyArg_ParseTupleAndKeywords(args, kwds, "O!|O!", diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp index 8a09e7722ea..187ab94360a 100644 --- a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp +++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp @@ -81,7 +81,7 @@ static int FEdge_init(BPy_FEdge *self, PyObject *args, PyObject *kwds) self->fe = new FEdge(*(((BPy_FEdge *)obj1)->fe)); } } - else if (PyErr_Clear(), + else if ((void)PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "O!O!", diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp index fd434f9c4ef..788dfa78992 100644 --- a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp +++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp @@ -72,7 +72,7 @@ static int FrsCurve_init(BPy_FrsCurve *self, PyObject *args, PyObject *kwds) self->c = new Curve(*(((BPy_FrsCurve *)obj)->c)); } } - else if (PyErr_Clear(), + else if ((void)PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_2, &Id_Type, &obj)) { self->c = new Curve(*(((BPy_Id *)obj)->id)); } diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp index 3a25ddb0252..b31efe1f923 100644 --- a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp +++ b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp @@ -157,7 +157,8 @@ static PyObject *Stroke_resample(BPy_Stroke *self, PyObject *args, PyObject *kwd return NULL; } } - else if (PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "f", (char **)kwlist_2, &f)) { + else if ((void)PyErr_Clear(), + PyArg_ParseTupleAndKeywords(args, kwds, "f", (char **)kwlist_2, &f)) { if (self->s->Resample(f) < 0) { PyErr_SetString(PyExc_RuntimeError, "Stroke resampling (by vertex interval) failed"); return NULL; diff --git a/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp index 285100193d3..9cdc344081e 100644 --- a/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp +++ b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp @@ -71,7 +71,7 @@ static int Chain_init(BPy_Chain *self, PyObject *args, PyObject *kwds) self->c = new Chain(*(((BPy_Chain *)obj)->c)); } } - else if (PyErr_Clear(), + else if ((void)PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_2, &Id_Type, &obj)) { self->c = new Chain(*(((BPy_Id *)obj)->id)); } diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp index 725daa80b5e..5db75c84608 100644 --- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp +++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp @@ -75,7 +75,7 @@ static int FEdgeSharp_init(BPy_FEdgeSharp *self, PyObject *args, PyObject *kwds) self->fes = new FEdgeSharp(*(((BPy_FEdgeSharp *)obj1)->fes)); } } - else if (PyErr_Clear(), + else if ((void)PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "O!O!", diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp index 65d9dcbe01f..3fb739b18db 100644 --- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp +++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp @@ -73,7 +73,7 @@ static int FEdgeSmooth_init(BPy_FEdgeSmooth *self, PyObject *args, PyObject *kwd self->fes = new FEdgeSmooth(*(((BPy_FEdgeSmooth *)obj1)->fes)); } } - else if (PyErr_Clear(), + else if ((void)PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "O!O!", diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp index 74ae7809284..90e751333b9 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp @@ -82,8 +82,8 @@ static int AdjacencyIterator_init(BPy_AdjacencyIterator *self, PyObject *args, P self->at_start = ((BPy_AdjacencyIterator *)obj1)->at_start; } } - else if (PyErr_Clear(), - (obj2 = obj3 = 0), + else if ((void)PyErr_Clear(), + (void)(obj2 = obj3 = 0), PyArg_ParseTupleAndKeywords(args, kwds, "O!|O!O!", diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp index 164e1646934..1703fc2bddb 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp @@ -114,8 +114,8 @@ static int ChainPredicateIterator_init(BPy_ChainPredicateIterator *self, Py_INCREF(self->upred); Py_INCREF(self->bpred); } - else if (PyErr_Clear(), - (obj3 = obj4 = obj5 = obj6 = 0), + else if ((void)PyErr_Clear(), + (void)(obj3 = obj4 = obj5 = obj6 = 0), PyArg_ParseTupleAndKeywords(args, kwds, "O!O!|O!O!O&O!", diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp index 401959be0c0..d8ad82d667c 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp @@ -91,8 +91,8 @@ static int ChainSilhouetteIterator_init(BPy_ChainSilhouetteIterator *self, args, kwds, "O!", (char **)kwlist_1, &ChainSilhouetteIterator_Type, &obj1)) { self->cs_it = new ChainSilhouetteIterator(*(((BPy_ChainSilhouetteIterator *)obj1)->cs_it)); } - else if (PyErr_Clear(), - (obj1 = obj2 = obj3 = 0), + else if ((void)PyErr_Clear(), + (void)(obj1 = obj2 = obj3 = 0), PyArg_ParseTupleAndKeywords(args, kwds, "|O!O&O!", diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp index b6d841c5b64..dbd6e8dd09d 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp @@ -91,8 +91,8 @@ static int ChainingIterator___init__(BPy_ChainingIterator *self, PyObject *args, args, kwds, "O!", (char **)kwlist_1, &ChainingIterator_Type, &obj1)) { self->c_it = new ChainingIterator(*(((BPy_ChainingIterator *)obj1)->c_it)); } - else if (PyErr_Clear(), - (obj1 = obj2 = obj3 = obj4 = 0), + else if ((void)PyErr_Clear(), + (void)(obj1 = obj2 = obj3 = obj4 = 0), PyArg_ParseTupleAndKeywords(args, kwds, "|O!O!O&O!", diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp index 6ea61a060cb..6c496b0308b 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp @@ -75,7 +75,8 @@ static int CurvePointIterator_init(BPy_CurvePointIterator *self, PyObject *args, *(((BPy_CurvePointIterator *)brother)->cp_it)); } } - else if (PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "f", (char **)kwlist_2, &step)) { + else if ((void)PyErr_Clear(), + PyArg_ParseTupleAndKeywords(args, kwds, "f", (char **)kwlist_2, &step)) { self->cp_it = new CurveInternal::CurvePointIterator(step); } else { diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp index 0dbef9f325c..734ed0117f4 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp @@ -81,14 +81,14 @@ static int Interface0DIterator_init(BPy_Interface0DIterator *self, PyObject *arg self->at_start = true; self->reversed = false; } - else if (PyErr_Clear(), + else if ((void)PyErr_Clear(), PyArg_ParseTupleAndKeywords( args, kwds, "O!", (char **)kwlist_2, &Interface1D_Type, &inter)) { self->if0D_it = new Interface0DIterator(((BPy_Interface1D *)inter)->if1D->verticesBegin()); self->at_start = true; self->reversed = false; } - else if (PyErr_Clear(), + else if ((void)PyErr_Clear(), PyArg_ParseTupleAndKeywords( args, kwds, "O!", (char **)kwlist_3, &Interface0DIterator_Type, &brother)) { self->if0D_it = new Interface0DIterator(*(((BPy_Interface0DIterator *)brother)->if0D_it)); @@ -124,7 +124,7 @@ static PyObject *Interface0DIterator_iternext(BPy_Interface0DIterator *self) PyErr_SetNone(PyExc_StopIteration); return NULL; } - else if (self->at_start) { + if (self->at_start) { self->at_start = false; } else if (self->if0D_it->atLast()) { diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp index dd738b97473..4a5927ff6eb 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp @@ -82,7 +82,7 @@ static int SVertexIterator_init(BPy_SVertexIterator *self, PyObject *args, PyObj self->sv_it = new ViewEdgeInternal::SVertexIterator(*(((BPy_SVertexIterator *)obj1)->sv_it)); } } - else if (PyErr_Clear(), + else if ((void)PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "O!O!O!O!f", diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp index 84f57f1fe31..cda4031240b 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp @@ -74,7 +74,7 @@ static int StrokeVertexIterator_init(BPy_StrokeVertexIterator *self, self->at_start = ((BPy_StrokeVertexIterator *)brother)->at_start; } - else if (PyErr_Clear(), + else if ((void)PyErr_Clear(), PyArg_ParseTupleAndKeywords( args, kwds, "|O!", (char **)kwlist_2, &Stroke_Type, &stroke)) { if (!stroke) { @@ -125,7 +125,7 @@ static PyObject *StrokeVertexIterator_iternext(BPy_StrokeVertexIterator *self) } /* If at the start of the iterator, only return the object * and don't increment, to keep for-loops in sync */ - else if (self->at_start) { + if (self->at_start) { self->at_start = false; } /* If sv_it.atLast() is true, the iterator is currently pointing to the final valid element. diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp index c8a978784a4..3d0ed5d5a4d 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp @@ -78,8 +78,8 @@ static int ViewEdgeIterator_init(BPy_ViewEdgeIterator *self, PyObject *args, PyO args, kwds, "O!", (char **)kwlist_1, &ViewEdgeIterator_Type, &obj1)) { self->ve_it = new ViewEdgeInternal::ViewEdgeIterator(*(((BPy_ViewEdgeIterator *)obj1)->ve_it)); } - else if (PyErr_Clear(), - (obj1 = obj2 = 0), + else if ((void)PyErr_Clear(), + (void)(obj1 = obj2 = 0), PyArg_ParseTupleAndKeywords( args, kwds, "|O&O!", (char **)kwlist_2, check_begin, &obj1, &PyBool_Type, &obj2)) { ViewEdge *begin = (!obj1 || obj1 == Py_None) ? NULL : ((BPy_ViewEdge *)obj1)->ve; diff --git a/source/blender/freestyle/intern/stroke/Curve.cpp b/source/blender/freestyle/intern/stroke/Curve.cpp index 02a1d32953d..51c40c890a3 100644 --- a/source/blender/freestyle/intern/stroke/Curve.cpp +++ b/source/blender/freestyle/intern/stroke/Curve.cpp @@ -216,10 +216,10 @@ FEdge *CurvePoint::getFEdge(Interface0D &inter) if (iVertexB->__B == 0) { return __A->getFEdge(*(iVertexB->__A)); } - else if (iVertexB->__A == __A) { + if (iVertexB->__A == __A) { return __A->getFEdge(*(iVertexB->__B)); } - else if (iVertexB->__B == __A) { + if (iVertexB->__B == __A) { return __A->getFEdge(*(iVertexB->__A)); } } @@ -227,7 +227,7 @@ FEdge *CurvePoint::getFEdge(Interface0D &inter) if (iVertexB->__A == __A) { return __B->getFEdge(*(iVertexB->__A)); } - else if (iVertexB->__A == __B) { + if (iVertexB->__A == __B) { return __A->getFEdge(*(iVertexB->__A)); } } diff --git a/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp b/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp index a76579c7c96..a29d015b4c9 100644 --- a/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp +++ b/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp @@ -101,9 +101,8 @@ unsigned TextureManager::getBrushTextureIndex(string name, Stroke::MediumType lo cerr << "brush file " << name << " not found" << endl; return 0; } - else { - return _brushesMap[bt]; - } + + return _brushesMap[bt]; } void TextureManager::Options::setPatternsPath(const string &path) diff --git a/source/blender/freestyle/intern/system/PseudoNoise.cpp b/source/blender/freestyle/intern/system/PseudoNoise.cpp index 048be5d018c..c05c269c404 100644 --- a/source/blender/freestyle/intern/system/PseudoNoise.cpp +++ b/source/blender/freestyle/intern/system/PseudoNoise.cpp @@ -33,9 +33,8 @@ static int modf_to_index(Freestyle::real x, unsigned int range) BLI_assert(i >= 0 && i < range); return i; } - else { - return 0; - } + + return 0; } namespace Freestyle { diff --git a/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp b/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp index 55bc02b8358..26a40ee587c 100644 --- a/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp +++ b/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp @@ -43,9 +43,8 @@ AutoPtr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensity if (avg->cellSize() > p23->cellSize()) { return (AutoPtr<GridDensityProvider>)p23; } - else { - return (AutoPtr<GridDensityProvider>)avg; - } + + return (AutoPtr<GridDensityProvider>)avg; } AutoPtr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider( @@ -58,9 +57,8 @@ AutoPtr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensity if (avg->cellSize() > p23->cellSize()) { return (AutoPtr<GridDensityProvider>)p23; } - else { - return (AutoPtr<GridDensityProvider>)avg; - } + + return (AutoPtr<GridDensityProvider>)avg; } AutoPtr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider( @@ -75,9 +73,8 @@ AutoPtr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensity if (avg->cellSize() > p23->cellSize()) { return (AutoPtr<GridDensityProvider>)p23; } - else { - return (AutoPtr<GridDensityProvider>)avg; - } + + return (AutoPtr<GridDensityProvider>)avg; } } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/view_map/OccluderSource.cpp b/source/blender/freestyle/intern/view_map/OccluderSource.cpp index 7132e0172ae..e75856edc35 100644 --- a/source/blender/freestyle/intern/view_map/OccluderSource.cpp +++ b/source/blender/freestyle/intern/view_map/OccluderSource.cpp @@ -77,11 +77,10 @@ bool OccluderSource::next() valid = false; return false; } - else { - vector<WFace *> &wFaces = (*currentShape)->GetFaceList(); - currentFace = wFaces.begin(); - facesEnd = wFaces.end(); - } + + vector<WFace *> &wFaces = (*currentShape)->GetFaceList(); + currentFace = wFaces.begin(); + facesEnd = wFaces.end(); } buildCachedPolygon(); return true; diff --git a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp index d024c360e3f..aecd37fa0de 100644 --- a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp +++ b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp @@ -344,9 +344,8 @@ OWXFaceLayer ViewEdgeXBuilder::FindNextFaceLayer(const OWXFaceLayer &iFaceLayer) if (woeend == winner->getSmoothEdge()->woea()->twin()) { return OWXFaceLayer(winner, true); } - else { - return OWXFaceLayer(winner, false); - } + + return OWXFaceLayer(winner, false); } } ++f; @@ -368,19 +367,17 @@ OWXFaceLayer ViewEdgeXBuilder::FindNextFaceLayer(const OWXFaceLayer &iFaceLayer) if ((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) { return OWXFaceLayer(NULL, true); } - else { - WXFaceLayer *winner = sameNatureLayers[0]; - // check face mark continuity - if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark()) { - return OWXFaceLayer(NULL, true); - } - if (woeend == winner->getSmoothEdge()->woea()->twin()) { - return OWXFaceLayer(winner, true); - } - else { - return OWXFaceLayer(winner, false); - } + + WXFaceLayer *winner = sameNatureLayers[0]; + // check face mark continuity + if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark()) { + return OWXFaceLayer(NULL, true); + } + if (woeend == winner->getSmoothEdge()->woea()->twin()) { + return OWXFaceLayer(winner, true); } + + return OWXFaceLayer(winner, false); } return OWXFaceLayer(NULL, true); } @@ -429,9 +426,8 @@ OWXFaceLayer ViewEdgeXBuilder::FindPreviousFaceLayer(const OWXFaceLayer &iFaceLa if (woebegin == winner->getSmoothEdge()->woeb()->twin()) { return OWXFaceLayer(winner, true); } - else { - return OWXFaceLayer(winner, false); - } + + return OWXFaceLayer(winner, false); } } } @@ -452,19 +448,17 @@ OWXFaceLayer ViewEdgeXBuilder::FindPreviousFaceLayer(const OWXFaceLayer &iFaceLa if ((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) { return OWXFaceLayer(NULL, true); } - else { - WXFaceLayer *winner = sameNatureLayers[0]; - // check face mark continuity - if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark()) { - return OWXFaceLayer(NULL, true); - } - if (woebegin == winner->getSmoothEdge()->woeb()->twin()) { - return OWXFaceLayer(winner, true); - } - else { - return OWXFaceLayer(winner, false); - } + + WXFaceLayer *winner = sameNatureLayers[0]; + // check face mark continuity + if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark()) { + return OWXFaceLayer(NULL, true); + } + if (woebegin == winner->getSmoothEdge()->woeb()->twin()) { + return OWXFaceLayer(winner, true); } + + return OWXFaceLayer(winner, false); } return OWXFaceLayer(NULL, true); } @@ -631,11 +625,10 @@ OWXEdge ViewEdgeXBuilder::FindNextWEdge(const OWXEdge &iEdge) // So the vertex order is OK. return OWXEdge(wxe, true); } - else { - // That means that the face necessarily lies on the edge left. - // So the vertex order is OK. - return OWXEdge(wxe, false); - } + + // That means that the face necessarily lies on the edge left. + // So the vertex order is OK. + return OWXEdge(wxe, false); } // we did not find: return OWXEdge(NULL, true); @@ -679,9 +672,8 @@ OWXEdge ViewEdgeXBuilder::FindPreviousWEdge(const OWXEdge &iEdge) if (wxe->GetbVertex() == v) { return OWXEdge(wxe, true); } - else { - return OWXEdge(wxe, false); - } + + return OWXEdge(wxe, false); } // we did not find: return OWXEdge(NULL, true); diff --git a/source/blender/freestyle/intern/view_map/ViewMap.cpp b/source/blender/freestyle/intern/view_map/ViewMap.cpp index 47c6c3a1f6a..fa2f95dac72 100644 --- a/source/blender/freestyle/intern/view_map/ViewMap.cpp +++ b/source/blender/freestyle/intern/view_map/ViewMap.cpp @@ -323,18 +323,16 @@ static bool ViewEdgeComp(ViewVertex::directedViewEdge &dve1, ViewVertex::directe if (v2.y() < 0) { return true; } - else { - return (v1.x() > v2.x()); - } + + return (v1.x() > v2.x()); } - else { - if (v2.y() > 0) { - return false; - } - else { - return (v1.x() < v2.x()); - } + + if (v2.y() > 0) { + return false; } + + return (v1.x() < v2.x()); + return false; } diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp index 8ac272e92b5..a0989c52e4e 100644 --- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp +++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp @@ -504,10 +504,10 @@ static void computeCumulativeVisibility(ViewMap *ioViewMap, (*ve)->setaShape(0); continue; } - else { - ++qiMajority; - qiMajority >>= 1; - } + + ++qiMajority; + qiMajority >>= 1; + #if LOGGING if (_global.debug & G_DEBUG_FREESTYLE) { cout << "\tqiMajority: " << qiMajority << endl; @@ -702,10 +702,10 @@ static void computeDetailedVisibility(ViewMap *ioViewMap, (*ve)->setaShape(0); continue; } - else { - ++qiMajority; - qiMajority >>= 1; - } + + ++qiMajority; + qiMajority >>= 1; + #if LOGGING if (_global.debug & G_DEBUG_FREESTYLE) { cout << "\tqiMajority: " << qiMajority << endl; @@ -873,10 +873,9 @@ static void computeFastVisibility(ViewMap *ioViewMap, G &grid, real epsilon) (*ve)->setaShape(0); continue; } - else { - ++qiMajority; - qiMajority >>= 1; - } + + ++qiMajority; + qiMajority >>= 1; even_test = true; maxIndex = 0; diff --git a/source/blender/freestyle/intern/winged_edge/WEdge.cpp b/source/blender/freestyle/intern/winged_edge/WEdge.cpp index d624728250a..c8805c144e3 100644 --- a/source/blender/freestyle/intern/winged_edge/WEdge.cpp +++ b/source/blender/freestyle/intern/winged_edge/WEdge.cpp @@ -114,7 +114,7 @@ bool WVertex::isBoundary() if (_Border == 1) { return true; } - else if (_Border == 0) { + if (_Border == 0) { return false; } @@ -412,9 +412,8 @@ bool WFace::getOppositeEdge(const WVertex *v, WOEdge *&e) if (!e) { return false; } - else { - return true; - } + + return true; } float WFace::getArea() diff --git a/source/blender/functions/CMakeLists.txt b/source/blender/functions/CMakeLists.txt index 2686275e898..ad29dbe6668 100644 --- a/source/blender/functions/CMakeLists.txt +++ b/source/blender/functions/CMakeLists.txt @@ -57,3 +57,20 @@ set(LIB ) blender_add_lib(bf_functions "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") + +if(WITH_GTESTS) + set(TEST_SRC + tests/FN_array_spans_test.cc + tests/FN_attributes_ref_test.cc + tests/FN_cpp_type_test.cc + tests/FN_generic_vector_array_test.cc + tests/FN_multi_function_network_test.cc + tests/FN_multi_function_test.cc + tests/FN_spans_test.cc + ) + set (TEST_LIB + bf_functions + ) + include(GTestTesting) + blender_add_test_lib(bf_functions_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}") +endif() diff --git a/source/blender/functions/FN_array_spans.hh b/source/blender/functions/FN_array_spans.hh index 52325c19c1b..976b9a44d3e 100644 --- a/source/blender/functions/FN_array_spans.hh +++ b/source/blender/functions/FN_array_spans.hh @@ -157,7 +157,7 @@ class GVArraySpan : public VArraySpanBase<void> { this->type_ = &array.type(); this->virtual_size_ = virtual_size; this->category_ = VArraySpanCategory::SingleArray; - this->data_.single_array.start = array.buffer(); + this->data_.single_array.start = array.data(); this->data_.single_array.size = array.size(); } diff --git a/source/blender/functions/FN_attributes_ref.hh b/source/blender/functions/FN_attributes_ref.hh index fe7e59b5e00..0cac8d82d26 100644 --- a/source/blender/functions/FN_attributes_ref.hh +++ b/source/blender/functions/FN_attributes_ref.hh @@ -49,12 +49,12 @@ class AttributesInfoBuilder : NonCopyable, NonMovable { AttributesInfoBuilder() = default; ~AttributesInfoBuilder(); - template<typename T> void add(StringRef name, const T &default_value) + template<typename T> bool add(StringRef name, const T &default_value) { - this->add(name, CPPType::get<T>(), (const void *)&default_value); + return this->add(name, CPPType::get<T>(), (const void *)&default_value); } - void add(StringRef name, const CPPType &type, const void *default_value = nullptr); + bool add(StringRef name, const CPPType &type, const void *default_value = nullptr); }; /** diff --git a/source/blender/functions/FN_cpp_type.hh b/source/blender/functions/FN_cpp_type.hh index 1176a705e66..2f1d3f83c63 100644 --- a/source/blender/functions/FN_cpp_type.hh +++ b/source/blender/functions/FN_cpp_type.hh @@ -370,7 +370,7 @@ class CPPType : NonCopyable, NonMovable { void copy_to_initialized_n(const void *src, void *dst, int64_t n) const { - BLI_assert(src != dst); + BLI_assert(n == 0 || src != dst); BLI_assert(n == 0 || this->pointer_can_point_to_instance(src)); BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst)); @@ -379,7 +379,7 @@ class CPPType : NonCopyable, NonMovable { void copy_to_initialized_indices(const void *src, void *dst, IndexMask mask) const { - BLI_assert(src != dst); + BLI_assert(mask.size() == 0 || src != dst); BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src)); BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst)); @@ -405,7 +405,7 @@ class CPPType : NonCopyable, NonMovable { void copy_to_uninitialized_n(const void *src, void *dst, int64_t n) const { - BLI_assert(src != dst); + BLI_assert(n == 0 || src != dst); BLI_assert(n == 0 || this->pointer_can_point_to_instance(src)); BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst)); @@ -414,7 +414,7 @@ class CPPType : NonCopyable, NonMovable { void copy_to_uninitialized_indices(const void *src, void *dst, IndexMask mask) const { - BLI_assert(src != dst); + BLI_assert(mask.size() == 0 || src != dst); BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src)); BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst)); @@ -440,7 +440,7 @@ class CPPType : NonCopyable, NonMovable { void relocate_to_initialized_n(void *src, void *dst, int64_t n) const { - BLI_assert(src != dst); + BLI_assert(n == 0 || src != dst); BLI_assert(n == 0 || this->pointer_can_point_to_instance(src)); BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst)); @@ -449,7 +449,7 @@ class CPPType : NonCopyable, NonMovable { void relocate_to_initialized_indices(void *src, void *dst, IndexMask mask) const { - BLI_assert(src != dst); + BLI_assert(mask.size() == 0 || src != dst); BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src)); BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst)); @@ -475,7 +475,7 @@ class CPPType : NonCopyable, NonMovable { void relocate_to_uninitialized_n(void *src, void *dst, int64_t n) const { - BLI_assert(src != dst); + BLI_assert(n == 0 || src != dst); BLI_assert(n == 0 || this->pointer_can_point_to_instance(src)); BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst)); @@ -484,7 +484,7 @@ class CPPType : NonCopyable, NonMovable { void relocate_to_uninitialized_indices(void *src, void *dst, IndexMask mask) const { - BLI_assert(src != dst); + BLI_assert(mask.size() == 0 || src != dst); BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src)); BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst)); diff --git a/source/blender/functions/FN_multi_function_params.hh b/source/blender/functions/FN_multi_function_params.hh index 71b05754717..ba2d1d0edd3 100644 --- a/source/blender/functions/FN_multi_function_params.hh +++ b/source/blender/functions/FN_multi_function_params.hh @@ -49,52 +49,56 @@ class MFParamsBuilder { MFParamsBuilder(const class MultiFunction &fn, int64_t min_array_size); - template<typename T> void add_readonly_single_input(const T *value) + template<typename T> void add_readonly_single_input(const T *value, StringRef expected_name = "") { - this->add_readonly_single_input(GVSpan::FromSingle(CPPType::get<T>(), value, min_array_size_)); + this->add_readonly_single_input(GVSpan::FromSingle(CPPType::get<T>(), value, min_array_size_), + expected_name); } - void add_readonly_single_input(GVSpan ref) + void add_readonly_single_input(GVSpan ref, StringRef expected_name = "") { - this->assert_current_param_type(MFParamType::ForSingleInput(ref.type())); + this->assert_current_param_type(MFParamType::ForSingleInput(ref.type()), expected_name); BLI_assert(ref.size() >= min_array_size_); virtual_spans_.append(ref); } - void add_readonly_vector_input(GVArraySpan ref) + void add_readonly_vector_input(GVArraySpan ref, StringRef expected_name = "") { - this->assert_current_param_type(MFParamType::ForVectorInput(ref.type())); + this->assert_current_param_type(MFParamType::ForVectorInput(ref.type()), expected_name); BLI_assert(ref.size() >= min_array_size_); virtual_array_spans_.append(ref); } - template<typename T> void add_uninitialized_single_output(T *value) + template<typename T> void add_uninitialized_single_output(T *value, StringRef expected_name = "") { - this->add_uninitialized_single_output(GMutableSpan(CPPType::get<T>(), value, 1)); + this->add_uninitialized_single_output(GMutableSpan(CPPType::get<T>(), value, 1), + expected_name); } - void add_uninitialized_single_output(GMutableSpan ref) + void add_uninitialized_single_output(GMutableSpan ref, StringRef expected_name = "") { - this->assert_current_param_type(MFParamType::ForSingleOutput(ref.type())); + this->assert_current_param_type(MFParamType::ForSingleOutput(ref.type()), expected_name); BLI_assert(ref.size() >= min_array_size_); mutable_spans_.append(ref); } - void add_vector_output(GVectorArray &vector_array) + void add_vector_output(GVectorArray &vector_array, StringRef expected_name = "") { - this->assert_current_param_type(MFParamType::ForVectorOutput(vector_array.type())); + this->assert_current_param_type(MFParamType::ForVectorOutput(vector_array.type()), + expected_name); BLI_assert(vector_array.size() >= min_array_size_); vector_arrays_.append(&vector_array); } - void add_single_mutable(GMutableSpan ref) + void add_single_mutable(GMutableSpan ref, StringRef expected_name = "") { - this->assert_current_param_type(MFParamType::ForMutableSingle(ref.type())); + this->assert_current_param_type(MFParamType::ForMutableSingle(ref.type()), expected_name); BLI_assert(ref.size() >= min_array_size_); mutable_spans_.append(ref); } - void add_vector_mutable(GVectorArray &vector_array) + void add_vector_mutable(GVectorArray &vector_array, StringRef expected_name = "") { - this->assert_current_param_type(MFParamType::ForMutableVector(vector_array.type())); + this->assert_current_param_type(MFParamType::ForMutableVector(vector_array.type()), + expected_name); BLI_assert(vector_array.size() >= min_array_size_); vector_arrays_.append(&vector_array); } @@ -118,11 +122,17 @@ class MFParamsBuilder { } private: - void assert_current_param_type(MFParamType param_type) + void assert_current_param_type(MFParamType param_type, StringRef expected_name = "") { - UNUSED_VARS_NDEBUG(param_type); + UNUSED_VARS_NDEBUG(param_type, expected_name); #ifdef DEBUG int param_index = this->current_param_index(); + + if (expected_name != "") { + StringRef actual_name = signature_->param_names[param_index]; + BLI_assert(actual_name == expected_name); + } + MFParamType expected_type = signature_->param_types[param_index]; BLI_assert(expected_type == param_type); #endif diff --git a/source/blender/functions/FN_multi_function_signature.hh b/source/blender/functions/FN_multi_function_signature.hh index fd92bb2ff55..ef51ddbaf24 100644 --- a/source/blender/functions/FN_multi_function_signature.hh +++ b/source/blender/functions/FN_multi_function_signature.hh @@ -31,10 +31,9 @@ namespace blender::fn { struct MFSignature { std::string function_name; - /* Use RawAllocator so that a MultiFunction can have static storage duration. */ - RawVector<std::string> param_names; - RawVector<MFParamType> param_types; - RawVector<int> param_data_indices; + Vector<std::string> param_names; + Vector<MFParamType> param_types; + Vector<int> param_data_indices; bool depends_on_context = false; int data_index(int param_index) const diff --git a/source/blender/functions/FN_spans.hh b/source/blender/functions/FN_spans.hh index 3ceb78ea6bd..76380f46e91 100644 --- a/source/blender/functions/FN_spans.hh +++ b/source/blender/functions/FN_spans.hh @@ -50,12 +50,12 @@ namespace blender::fn { class GSpan { private: const CPPType *type_; - const void *buffer_; + const void *data_; int64_t size_; public: GSpan(const CPPType &type, const void *buffer, int64_t size) - : type_(&type), buffer_(buffer), size_(size) + : type_(&type), data_(buffer), size_(size) { BLI_assert(size >= 0); BLI_assert(buffer != nullptr || size == 0); @@ -86,21 +86,21 @@ class GSpan { return size_; } - const void *buffer() const + const void *data() const { - return buffer_; + return data_; } const void *operator[](int64_t index) const { BLI_assert(index < size_); - return POINTER_OFFSET(buffer_, type_->size() * index); + return POINTER_OFFSET(data_, type_->size() * index); } template<typename T> Span<T> typed() const { BLI_assert(type_->is<T>()); - return Span<T>((const T *)buffer_, size_); + return Span<T>((const T *)data_, size_); } }; @@ -111,12 +111,12 @@ class GSpan { class GMutableSpan { private: const CPPType *type_; - void *buffer_; + void *data_; int64_t size_; public: GMutableSpan(const CPPType &type, void *buffer, int64_t size) - : type_(&type), buffer_(buffer), size_(size) + : type_(&type), data_(buffer), size_(size) { BLI_assert(size >= 0); BLI_assert(buffer != nullptr || size == 0); @@ -135,7 +135,7 @@ class GMutableSpan { operator GSpan() const { - return GSpan(*type_, buffer_, size_); + return GSpan(*type_, data_, size_); } const CPPType &type() const @@ -153,21 +153,21 @@ class GMutableSpan { return size_; } - void *buffer() + void *data() { - return buffer_; + return data_; } void *operator[](int64_t index) { BLI_assert(index < size_); - return POINTER_OFFSET(buffer_, type_->size() * index); + return POINTER_OFFSET(data_, type_->size() * index); } template<typename T> MutableSpan<T> typed() { BLI_assert(type_->is<T>()); - return MutableSpan<T>((T *)buffer_, size_); + return MutableSpan<T>((T *)data_, size_); } }; @@ -208,6 +208,20 @@ template<typename T> struct VSpanBase { return false; } + bool is_full_array() const + { + switch (category_) { + case VSpanCategory::Single: + return virtual_size_ == 1; + case VSpanCategory::FullArray: + return true; + case VSpanCategory::FullPointerArray: + return virtual_size_ <= 1; + } + BLI_assert(false); + return false; + } + bool is_empty() const { return this->virtual_size_ == 0; @@ -284,6 +298,22 @@ template<typename T> class VSpan : public VSpanBase<T> { BLI_assert(false); return *this->data_.single.data; } + + const T &as_single_element() const + { + BLI_assert(this->is_single_element()); + return (*this)[0]; + } + + Span<T> as_full_array() const + { + BLI_assert(this->is_full_array()); + if (this->virtual_size_ == 0) { + return Span<T>(); + } + const T *data = &(*this)[0]; + return Span<T>(data, this->virtual_size_); + } }; /** @@ -310,7 +340,7 @@ class GVSpan : public VSpanBase<void> { this->type_ = &values.type(); this->virtual_size_ = values.size(); this->category_ = VSpanCategory::FullArray; - this->data_.full_array.data = values.buffer(); + this->data_.full_array.data = values.data(); } GVSpan(GMutableSpan values) : GVSpan(GSpan(values)) @@ -394,6 +424,16 @@ class GVSpan : public VSpanBase<void> { return (*this)[0]; } + GSpan as_full_array() const + { + BLI_assert(this->is_full_array()); + if (this->virtual_size_ == 0) { + return GSpan(*this->type_); + } + const void *data = (*this)[0]; + return GSpan(*this->type_, data, this->virtual_size_); + } + void materialize_to_uninitialized(void *dst) const { this->materialize_to_uninitialized(IndexRange(virtual_size_), dst); diff --git a/source/blender/functions/intern/attributes_ref.cc b/source/blender/functions/intern/attributes_ref.cc index 7bfcc69671a..9f1e7fa65e5 100644 --- a/source/blender/functions/intern/attributes_ref.cc +++ b/source/blender/functions/intern/attributes_ref.cc @@ -25,8 +25,12 @@ AttributesInfoBuilder::~AttributesInfoBuilder() } } -void AttributesInfoBuilder::add(StringRef name, const CPPType &type, const void *default_value) +bool AttributesInfoBuilder::add(StringRef name, const CPPType &type, const void *default_value) { + if (name.size() == 0) { + std::cout << "Warning: Tried to add an attribute with empty name.\n"; + return false; + } if (names_.add_as(name)) { types_.append(&type); @@ -36,11 +40,15 @@ void AttributesInfoBuilder::add(StringRef name, const CPPType &type, const void void *dst = allocator_.allocate(type.size(), type.alignment()); type.copy_to_uninitialized(default_value, dst); defaults_.append(dst); + return true; } - else { - /* The same name can be added more than once as long as the type is always the same. */ - BLI_assert(types_[names_.index_of_as(name)] == &type); + + const CPPType &stored_type = *types_[names_.index_of_as(name)]; + if (stored_type != type) { + std::cout << "Warning: Tried to add an attribute twice with different types (" << name << ": " + << stored_type.name() << ", " << type.name() << ").\n"; } + return false; } AttributesInfo::AttributesInfo(const AttributesInfoBuilder &builder) diff --git a/source/blender/functions/intern/multi_function_builder.cc b/source/blender/functions/intern/multi_function_builder.cc index 06084247e66..c9e8b88ba03 100644 --- a/source/blender/functions/intern/multi_function_builder.cc +++ b/source/blender/functions/intern/multi_function_builder.cc @@ -34,7 +34,7 @@ void CustomMF_GenericConstant::call(IndexMask mask, MFContext UNUSED(context)) const { GMutableSpan output = params.uninitialized_single_output(0); - type_.fill_uninitialized_indices(value_, output.buffer(), mask); + type_.fill_uninitialized_indices(value_, output.data(), mask); } uint64_t CustomMF_GenericConstant::hash() const @@ -111,7 +111,7 @@ void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, MFContext UNU if (param_type.data_type().is_single()) { GMutableSpan span = params.uninitialized_single_output(param_index); const CPPType &type = span.type(); - type.fill_uninitialized_indices(type.default_value(), span.buffer(), mask); + type.fill_uninitialized_indices(type.default_value(), span.data(), mask); } } } diff --git a/source/blender/functions/intern/multi_function_network_evaluation.cc b/source/blender/functions/intern/multi_function_network_evaluation.cc index 58577e31c42..480a048b510 100644 --- a/source/blender/functions/intern/multi_function_network_evaluation.cc +++ b/source/blender/functions/intern/multi_function_network_evaluation.cc @@ -390,7 +390,7 @@ BLI_NOINLINE void MFNetworkEvaluator::initialize_remaining_outputs( case MFDataType::Single: { GVSpan values = storage.get_single_input__full(*socket); GMutableSpan output_values = params.uninitialized_single_output(param_index); - values.materialize_to_uninitialized(storage.mask(), output_values.buffer()); + values.materialize_to_uninitialized(storage.mask(), output_values.data()); break; } case MFDataType::Vector: { @@ -519,16 +519,16 @@ MFNetworkEvaluationStorage::~MFNetworkEvaluationStorage() if (any_value == nullptr) { continue; } - else if (any_value->type == ValueType::OwnSingle) { + if (any_value->type == ValueType::OwnSingle) { OwnSingleValue *value = (OwnSingleValue *)any_value; GMutableSpan span = value->span; const CPPType &type = span.type(); if (value->is_single_allocated) { - type.destruct(span.buffer()); + type.destruct(span.data()); } else { - type.destruct_indices(span.buffer(), mask_); - MEM_freeN(span.buffer()); + type.destruct_indices(span.data(), mask_); + MEM_freeN(span.data()); } } else if (any_value->type == ValueType::OwnVector) { @@ -634,11 +634,11 @@ void MFNetworkEvaluationStorage::finish_input_socket(const MFInputSocket &socket GMutableSpan span = value->span; const CPPType &type = span.type(); if (value->is_single_allocated) { - type.destruct(span.buffer()); + type.destruct(span.data()); } else { - type.destruct_indices(span.buffer(), mask_); - MEM_freeN(span.buffer()); + type.destruct_indices(span.data(), mask_); + MEM_freeN(span.data()); } value_per_output_id_[origin.id()] = nullptr; } @@ -710,10 +710,9 @@ GMutableSpan MFNetworkEvaluationStorage::get_single_output__full(const MFOutputS return span; } - else { - BLI_assert(any_value->type == ValueType::OutputSingle); - return ((OutputSingleValue *)any_value)->span; - } + + BLI_assert(any_value->type == ValueType::OutputSingle); + return ((OutputSingleValue *)any_value)->span; } GMutableSpan MFNetworkEvaluationStorage::get_single_output__single(const MFOutputSocket &socket) @@ -729,12 +728,11 @@ GMutableSpan MFNetworkEvaluationStorage::get_single_output__single(const MFOutpu return value->span; } - else { - BLI_assert(any_value->type == ValueType::OutputSingle); - GMutableSpan span = ((OutputSingleValue *)any_value)->span; - BLI_assert(span.size() == 1); - return span; - } + + BLI_assert(any_value->type == ValueType::OutputSingle); + GMutableSpan span = ((OutputSingleValue *)any_value)->span; + BLI_assert(span.size() == 1); + return span; } GVectorArray &MFNetworkEvaluationStorage::get_vector_output__full(const MFOutputSocket &socket) @@ -749,10 +747,9 @@ GVectorArray &MFNetworkEvaluationStorage::get_vector_output__full(const MFOutput return *value->vector_array; } - else { - BLI_assert(any_value->type == ValueType::OutputVector); - return *((OutputVectorValue *)any_value)->vector_array; - } + + BLI_assert(any_value->type == ValueType::OutputVector); + return *((OutputVectorValue *)any_value)->vector_array; } GVectorArray &MFNetworkEvaluationStorage::get_vector_output__single(const MFOutputSocket &socket) @@ -767,12 +764,11 @@ GVectorArray &MFNetworkEvaluationStorage::get_vector_output__single(const MFOutp return *value->vector_array; } - else { - BLI_assert(any_value->type == ValueType::OutputVector); - GVectorArray &vector_array = *((OutputVectorValue *)any_value)->vector_array; - BLI_assert(vector_array.size() == 1); - return vector_array; - } + + BLI_assert(any_value->type == ValueType::OutputVector); + GVectorArray &vector_array = *((OutputVectorValue *)any_value)->vector_array; + BLI_assert(vector_array.size() == 1); + return vector_array; } GMutableSpan MFNetworkEvaluationStorage::get_mutable_single__full(const MFInputSocket &input, @@ -791,7 +787,7 @@ GMutableSpan MFNetworkEvaluationStorage::get_mutable_single__full(const MFInputS BLI_assert(to_any_value->type == ValueType::OutputSingle); GMutableSpan span = ((OutputSingleValue *)to_any_value)->span; GVSpan virtual_span = this->get_single_input__full(input); - virtual_span.materialize_to_uninitialized(mask_, span.buffer()); + virtual_span.materialize_to_uninitialized(mask_, span.data()); return span; } @@ -808,7 +804,7 @@ GMutableSpan MFNetworkEvaluationStorage::get_mutable_single__full(const MFInputS GVSpan virtual_span = this->get_single_input__full(input); void *new_buffer = MEM_mallocN_aligned(min_array_size_ * type.size(), type.alignment(), AT); GMutableSpan new_array_ref(type, new_buffer, min_array_size_); - virtual_span.materialize_to_uninitialized(mask_, new_array_ref.buffer()); + virtual_span.materialize_to_uninitialized(mask_, new_array_ref.data()); OwnSingleValue *new_value = allocator_.construct<OwnSingleValue>( new_array_ref, to.targets().size(), false); @@ -953,17 +949,16 @@ GVSpan MFNetworkEvaluationStorage::get_single_input__full(const MFInputSocket &s if (any_value->type == ValueType::OwnSingle) { OwnSingleValue *value = (OwnSingleValue *)any_value; if (value->is_single_allocated) { - return GVSpan::FromSingle(value->span.type(), value->span.buffer(), min_array_size_); - } - else { - return value->span; + return GVSpan::FromSingle(value->span.type(), value->span.data(), min_array_size_); } + + return value->span; } - else if (any_value->type == ValueType::InputSingle) { + if (any_value->type == ValueType::InputSingle) { InputSingleValue *value = (InputSingleValue *)any_value; return value->virtual_span; } - else if (any_value->type == ValueType::OutputSingle) { + if (any_value->type == ValueType::OutputSingle) { OutputSingleValue *value = (OutputSingleValue *)any_value; BLI_assert(value->is_computed); return value->span; @@ -984,12 +979,12 @@ GVSpan MFNetworkEvaluationStorage::get_single_input__single(const MFInputSocket BLI_assert(value->span.size() == 1); return value->span; } - else if (any_value->type == ValueType::InputSingle) { + if (any_value->type == ValueType::InputSingle) { InputSingleValue *value = (InputSingleValue *)any_value; BLI_assert(value->virtual_span.is_single_element()); return value->virtual_span; } - else if (any_value->type == ValueType::OutputSingle) { + if (any_value->type == ValueType::OutputSingle) { OutputSingleValue *value = (OutputSingleValue *)any_value; BLI_assert(value->is_computed); BLI_assert(value->span.size() == 1); @@ -1012,15 +1007,14 @@ GVArraySpan MFNetworkEvaluationStorage::get_vector_input__full(const MFInputSock GSpan span = (*value->vector_array)[0]; return GVArraySpan(span, min_array_size_); } - else { - return *value->vector_array; - } + + return *value->vector_array; } - else if (any_value->type == ValueType::InputVector) { + if (any_value->type == ValueType::InputVector) { InputVectorValue *value = (InputVectorValue *)any_value; return value->virtual_array_span; } - else if (any_value->type == ValueType::OutputVector) { + if (any_value->type == ValueType::OutputVector) { OutputVectorValue *value = (OutputVectorValue *)any_value; return *value->vector_array; } @@ -1040,12 +1034,12 @@ GVArraySpan MFNetworkEvaluationStorage::get_vector_input__single(const MFInputSo BLI_assert(value->vector_array->size() == 1); return *value->vector_array; } - else if (any_value->type == ValueType::InputVector) { + if (any_value->type == ValueType::InputVector) { InputVectorValue *value = (InputVectorValue *)any_value; BLI_assert(value->virtual_array_span.is_single_array()); return value->virtual_array_span; } - else if (any_value->type == ValueType::OutputVector) { + if (any_value->type == ValueType::OutputVector) { OutputVectorValue *value = (OutputVectorValue *)any_value; BLI_assert(value->vector_array->size() == 1); return *value->vector_array; diff --git a/source/blender/functions/intern/multi_function_network_optimization.cc b/source/blender/functions/intern/multi_function_network_optimization.cc index f1e047f01a1..e53b9a2c648 100644 --- a/source/blender/functions/intern/multi_function_network_optimization.cc +++ b/source/blender/functions/intern/multi_function_network_optimization.cc @@ -28,6 +28,7 @@ #include "BLI_disjoint_set.hh" #include "BLI_ghash.h" #include "BLI_map.hh" +#include "BLI_multi_value_map.hh" #include "BLI_rand.h" #include "BLI_stack.hh" @@ -44,9 +45,8 @@ static bool set_tag_and_check_if_modified(bool &tag, bool new_value) tag = new_value; return true; } - else { - return false; - } + + return false; } static Array<bool> mask_nodes_to_the_left(MFNetwork &network, Span<MFNode *> nodes) @@ -265,7 +265,7 @@ static Array<MFOutputSocket *> add_constant_folded_sockets(const MultiFunction & case MFDataType::Single: { const CPPType &cpp_type = data_type.single_type(); GMutableSpan array = params.computed_array(param_index); - void *buffer = array.buffer(); + void *buffer = array.data(); resources.add(buffer, array.type().destruct_cb(), AT); constant_fn = &resources.construct<CustomMF_GenericConstant>(AT, cpp_type, buffer); @@ -403,15 +403,15 @@ static Array<uint64_t> compute_node_hashes(MFNetwork &network) return node_hashes; } -static Map<uint64_t, Vector<MFNode *, 1>> group_nodes_by_hash(MFNetwork &network, - Span<uint64_t> node_hashes) +static MultiValueMap<uint64_t, MFNode *> group_nodes_by_hash(MFNetwork &network, + Span<uint64_t> node_hashes) { - Map<uint64_t, Vector<MFNode *, 1>> nodes_by_hash; + MultiValueMap<uint64_t, MFNode *> nodes_by_hash; for (int id : IndexRange(network.node_id_amount())) { MFNode *node = network.node_or_null_by_id(id); if (node != nullptr) { uint64_t node_hash = node_hashes[id]; - nodes_by_hash.lookup_or_add_default(node_hash).append(node); + nodes_by_hash.add(node_hash, node); } } return nodes_by_hash; @@ -456,7 +456,7 @@ static bool nodes_output_same_values(DisjointSet &cache, const MFNode &a, const } static void relink_duplicate_nodes(MFNetwork &network, - Map<uint64_t, Vector<MFNode *, 1>> &nodes_by_hash) + MultiValueMap<uint64_t, MFNode *> &nodes_by_hash) { DisjointSet same_node_cache{network.node_id_amount()}; @@ -494,7 +494,7 @@ static void relink_duplicate_nodes(MFNetwork &network, void common_subnetwork_elimination(MFNetwork &network) { Array<uint64_t> node_hashes = compute_node_hashes(network); - Map<uint64_t, Vector<MFNode *, 1>> nodes_by_hash = group_nodes_by_hash(network, node_hashes); + MultiValueMap<uint64_t, MFNode *> nodes_by_hash = group_nodes_by_hash(network, node_hashes); relink_duplicate_nodes(network, nodes_by_hash); } diff --git a/source/blender/functions/tests/FN_array_spans_test.cc b/source/blender/functions/tests/FN_array_spans_test.cc new file mode 100644 index 00000000000..9a632b58be8 --- /dev/null +++ b/source/blender/functions/tests/FN_array_spans_test.cc @@ -0,0 +1,132 @@ +/* Apache License, Version 2.0 */ + +#include "testing/testing.h" + +#include "FN_array_spans.hh" +#include "FN_generic_vector_array.hh" + +#include "BLI_array.hh" + +namespace blender::fn::tests { + +TEST(virtual_array_span, EmptyConstructor) +{ + VArraySpan<int> span; + EXPECT_EQ(span.size(), 0); + EXPECT_TRUE(span.is_empty()); + + GVArraySpan converted(span); + EXPECT_EQ(converted.type(), CPPType::get<int>()); + EXPECT_EQ(converted.size(), 0); +} + +TEST(virtual_array_span, SingleArrayConstructor) +{ + std::array<int, 4> values = {3, 4, 5, 6}; + VArraySpan<int> span{Span<int>(values), 3}; + EXPECT_EQ(span.size(), 3); + EXPECT_FALSE(span.is_empty()); + EXPECT_EQ(span[0].size(), 4); + EXPECT_EQ(span[1].size(), 4); + EXPECT_EQ(span[2].size(), 4); + EXPECT_EQ(span[0][0], 3); + EXPECT_EQ(span[0][1], 4); + EXPECT_EQ(span[0][2], 5); + EXPECT_EQ(span[0][3], 6); + EXPECT_EQ(span[1][3], 6); + EXPECT_EQ(span[2][1], 4); + + GVArraySpan converted(span); + EXPECT_EQ(converted.type(), CPPType::get<int>()); + EXPECT_EQ(converted.size(), 3); + EXPECT_EQ(converted[0].size(), 4); + EXPECT_EQ(converted[1].size(), 4); + EXPECT_EQ(converted[1][2], &values[2]); +} + +TEST(virtual_array_span, MultipleArrayConstructor) +{ + std::array<int, 4> values0 = {1, 2, 3, 4}; + std::array<int, 2> values1 = {6, 7}; + std::array<int, 1> values2 = {8}; + std::array<const int *, 3> starts = {values0.data(), values1.data(), values2.data()}; + std::array<int64_t, 3> sizes{values0.size(), values1.size(), values2.size()}; + + VArraySpan<int> span{starts, sizes}; + EXPECT_EQ(span.size(), 3); + EXPECT_FALSE(span.is_empty()); + EXPECT_EQ(span[0].size(), 4); + EXPECT_EQ(span[1].size(), 2); + EXPECT_EQ(span[2].size(), 1); + EXPECT_EQ(&span[0][0], values0.data()); + EXPECT_EQ(&span[1][0], values1.data()); + EXPECT_EQ(&span[2][0], values2.data()); + EXPECT_EQ(span[2][0], 8); + EXPECT_EQ(span[1][1], 7); + + GVArraySpan converted(span); + EXPECT_EQ(converted.type(), CPPType::get<int>()); + EXPECT_EQ(converted.size(), 3); + EXPECT_EQ(converted[0].size(), 4); + EXPECT_EQ(converted[1].size(), 2); + EXPECT_EQ(converted[2].size(), 1); + EXPECT_EQ(converted[0][0], values0.data()); + EXPECT_EQ(converted[1][1], values1.data() + 1); +} + +TEST(generic_virtual_array_span, TypeConstructor) +{ + GVArraySpan span{CPPType::get<int32_t>()}; + EXPECT_EQ(span.size(), 0); + EXPECT_TRUE(span.is_empty()); + + VArraySpan converted = span.typed<int>(); + EXPECT_EQ(converted.size(), 0); +} + +TEST(generic_virtual_array_span, GSpanConstructor) +{ + std::array<std::string, 3> values = {"hello", "world", "test"}; + GVArraySpan span{GSpan(CPPType::get<std::string>(), values.data(), 3), 5}; + EXPECT_EQ(span.size(), 5); + EXPECT_FALSE(span.is_empty()); + EXPECT_EQ(span[0][0], values.data()); + EXPECT_EQ(span[1][0], values.data()); + EXPECT_EQ(span[4][0], values.data()); + EXPECT_EQ(span[0].size(), 3); + EXPECT_EQ(span[2].size(), 3); + EXPECT_EQ(*(std::string *)span[3][1], "world"); + + VArraySpan converted = span.typed<std::string>(); + EXPECT_EQ(converted.size(), 5); + EXPECT_EQ(converted[0][0], "hello"); + EXPECT_EQ(converted[1][0], "hello"); + EXPECT_EQ(converted[4][0], "hello"); + EXPECT_EQ(converted[0].size(), 3); + EXPECT_EQ(converted[2].size(), 3); +} + +TEST(generic_virtual_array_span, IsSingleArray1) +{ + Array<int> values = {5, 6, 7}; + GVArraySpan span{GSpan(values.as_span()), 4}; + EXPECT_TRUE(span.is_single_array()); + + VArraySpan converted = span.typed<int>(); + EXPECT_TRUE(converted.is_single_array()); +} + +TEST(generic_virtual_array_span, IsSingleArray2) +{ + GVectorArray vectors{CPPType::get<int32_t>(), 3}; + GVectorArrayRef<int> vectors_ref = vectors; + vectors_ref.append(1, 4); + + GVArraySpan span = vectors; + EXPECT_FALSE(span.is_single_array()); + + VArraySpan converted = span.typed<int>(); + EXPECT_FALSE(converted.is_single_array()); +} + +} // namespace blender::fn::tests diff --git a/source/blender/functions/tests/FN_attributes_ref_test.cc b/source/blender/functions/tests/FN_attributes_ref_test.cc new file mode 100644 index 00000000000..3a5e4743c1e --- /dev/null +++ b/source/blender/functions/tests/FN_attributes_ref_test.cc @@ -0,0 +1,97 @@ +/* Apache License, Version 2.0 */ + +#include "BLI_float3.hh" +#include "FN_attributes_ref.hh" + +#include "testing/testing.h" + +namespace blender::fn::tests { + +TEST(attributes_info, BuildEmpty) +{ + AttributesInfoBuilder info_builder; + AttributesInfo info{info_builder}; + + EXPECT_EQ(info.size(), 0); +} + +TEST(attributes_info, AddSameNameTwice) +{ + AttributesInfoBuilder info_builder; + info_builder.add<int>("A", 4); + info_builder.add<int>("A", 5); + AttributesInfo info{info_builder}; + EXPECT_EQ(info.size(), 1); + EXPECT_TRUE(info.has_attribute("A", CPPType::get<int>())); + EXPECT_FALSE(info.has_attribute("B", CPPType::get<int>())); + EXPECT_FALSE(info.has_attribute("A", CPPType::get<float>())); + EXPECT_EQ(info.default_of<int>("A"), 4); + EXPECT_EQ(info.name_of(0), "A"); + EXPECT_EQ(info.index_range().start(), 0); + EXPECT_EQ(info.index_range().one_after_last(), 1); +} + +TEST(attributes_info, BuildWithDefaultString) +{ + AttributesInfoBuilder info_builder; + info_builder.add("A", CPPType::get<std::string>()); + AttributesInfo info{info_builder}; + EXPECT_EQ(info.default_of<std::string>("A"), ""); +} + +TEST(attributes_info, BuildWithGivenDefault) +{ + AttributesInfoBuilder info_builder; + info_builder.add<std::string>("A", "hello world"); + AttributesInfo info{info_builder}; + const void *default_value = info.default_of("A"); + EXPECT_EQ(*(const std::string *)default_value, "hello world"); + EXPECT_EQ(info.type_of("A"), CPPType::get<std::string>()); +} + +TEST(mutable_attributes_ref, ComplexTest) +{ + AttributesInfoBuilder info_builder; + info_builder.add<float3>("Position", {0, 0, 10}); + info_builder.add<uint>("ID", 0); + info_builder.add<float>("Size", 0.5f); + info_builder.add<std::string>("Name", "<no name>"); + AttributesInfo info{info_builder}; + + int amount = 5; + Array<float3> positions(amount); + Array<uint> ids(amount, 0); + Array<float> sizes(amount); + Array<std::string> names(amount); + + Array<void *> buffers = {positions.data(), ids.data(), sizes.data(), names.data()}; + MutableAttributesRef attributes{info, buffers, IndexRange(1, 3)}; + EXPECT_EQ(attributes.size(), 3); + EXPECT_EQ(attributes.info().size(), 4); + EXPECT_EQ(attributes.get("Position").data(), positions.data() + 1); + EXPECT_EQ(attributes.get("ID").data(), ids.data() + 1); + EXPECT_EQ(attributes.get("Size").data(), sizes.data() + 1); + EXPECT_EQ(attributes.get("Name").data(), names.data() + 1); + + EXPECT_EQ(attributes.get("ID").size(), 3); + EXPECT_EQ(attributes.get<uint>("ID").size(), 3); + + EXPECT_EQ(ids[2], 0); + MutableSpan<uint> ids_span = attributes.get<uint>("ID"); + ids_span[1] = 42; + EXPECT_EQ(ids[2], 42); + + EXPECT_FALSE(attributes.try_get<int>("not existant").has_value()); + EXPECT_FALSE(attributes.try_get<int>("Position").has_value()); + EXPECT_TRUE(attributes.try_get<float3>("Position").has_value()); + EXPECT_FALSE(attributes.try_get("not existant", CPPType::get<int>()).has_value()); + EXPECT_FALSE(attributes.try_get("Position", CPPType::get<int>()).has_value()); + EXPECT_TRUE(attributes.try_get("Position", CPPType::get<float3>()).has_value()); + + MutableAttributesRef sliced = attributes.slice(IndexRange(1, 2)); + EXPECT_EQ(sliced.size(), 2); + sliced.get<uint>("ID")[0] = 100; + EXPECT_EQ(ids[2], 100); +} + +} // namespace blender::fn::tests diff --git a/source/blender/functions/tests/FN_cpp_type_test.cc b/source/blender/functions/tests/FN_cpp_type_test.cc new file mode 100644 index 00000000000..29368b251cc --- /dev/null +++ b/source/blender/functions/tests/FN_cpp_type_test.cc @@ -0,0 +1,325 @@ +/* Apache License, Version 2.0 */ + +#include "testing/testing.h" + +#include "FN_cpp_type.hh" + +namespace blender::fn::tests { + +static const int default_constructed_value = 1; +static const int copy_constructed_value = 2; +static const int move_constructed_value = 3; +static const int copy_constructed_from_value = 4; +static const int move_constructed_from_value = 5; +static const int copy_assigned_value = 6; +static const int copy_assigned_from_value = 7; +static const int move_assigned_value = 8; +static const int move_assigned_from_value = 9; +static const int destructed_value = 10; + +struct TestType { + mutable volatile int value; + + TestType() + { + value = default_constructed_value; + } + + ~TestType() + { + value = destructed_value; + } + + TestType(const TestType &other) + { + value = copy_constructed_value; + other.value = copy_constructed_from_value; + } + + TestType(TestType &&other) noexcept + { + value = move_constructed_value; + other.value = move_constructed_from_value; + } + + TestType &operator=(const TestType &other) + { + value = copy_assigned_value; + other.value = copy_assigned_from_value; + return *this; + } + + TestType &operator=(TestType &&other) noexcept + { + value = move_assigned_value; + other.value = move_assigned_from_value; + return *this; + } + + friend std::ostream &operator<<(std::ostream &stream, const TestType &value) + { + stream << value.value; + return stream; + } + + friend bool operator==(const TestType &UNUSED(a), const TestType &UNUSED(b)) + { + return false; + } + + uint64_t hash() const + { + return 0; + } +}; + +} // namespace blender::fn::tests + +MAKE_CPP_TYPE(TestType, blender::fn::tests::TestType) + +namespace blender::fn::tests { + +const CPPType &CPPType_TestType = CPPType::get<TestType>(); + +TEST(cpp_type, Size) +{ + EXPECT_EQ(CPPType_TestType.size(), sizeof(TestType)); +} + +TEST(cpp_type, Alignment) +{ + EXPECT_EQ(CPPType_TestType.alignment(), alignof(TestType)); +} + +TEST(cpp_type, Is) +{ + EXPECT_TRUE(CPPType_TestType.is<TestType>()); + EXPECT_FALSE(CPPType_TestType.is<int>()); +} + +TEST(cpp_type, DefaultConstruction) +{ + int buffer[10] = {0}; + CPPType_TestType.construct_default((void *)buffer); + EXPECT_EQ(buffer[0], default_constructed_value); + EXPECT_EQ(buffer[1], 0); + CPPType_TestType.construct_default_n((void *)buffer, 3); + EXPECT_EQ(buffer[0], default_constructed_value); + EXPECT_EQ(buffer[1], default_constructed_value); + EXPECT_EQ(buffer[2], default_constructed_value); + EXPECT_EQ(buffer[3], 0); + CPPType_TestType.construct_default_indices((void *)buffer, {2, 5, 7}); + EXPECT_EQ(buffer[2], default_constructed_value); + EXPECT_EQ(buffer[4], 0); + EXPECT_EQ(buffer[5], default_constructed_value); + EXPECT_EQ(buffer[6], 0); + EXPECT_EQ(buffer[7], default_constructed_value); + EXPECT_EQ(buffer[8], 0); +} + +TEST(cpp_type, Destruct) +{ + int buffer[10] = {0}; + CPPType_TestType.destruct((void *)buffer); + EXPECT_EQ(buffer[0], destructed_value); + EXPECT_EQ(buffer[1], 0); + CPPType_TestType.destruct_n((void *)buffer, 3); + EXPECT_EQ(buffer[0], destructed_value); + EXPECT_EQ(buffer[1], destructed_value); + EXPECT_EQ(buffer[2], destructed_value); + EXPECT_EQ(buffer[3], 0); + CPPType_TestType.destruct_indices((void *)buffer, {2, 5, 7}); + EXPECT_EQ(buffer[2], destructed_value); + EXPECT_EQ(buffer[4], 0); + EXPECT_EQ(buffer[5], destructed_value); + EXPECT_EQ(buffer[6], 0); + EXPECT_EQ(buffer[7], destructed_value); + EXPECT_EQ(buffer[8], 0); +} + +TEST(cpp_type, CopyToUninitialized) +{ + int buffer1[10] = {0}; + int buffer2[10] = {0}; + CPPType_TestType.copy_to_uninitialized((void *)buffer1, (void *)buffer2); + EXPECT_EQ(buffer1[0], copy_constructed_from_value); + EXPECT_EQ(buffer2[0], copy_constructed_value); + CPPType_TestType.copy_to_uninitialized_n((void *)buffer1, (void *)buffer2, 3); + EXPECT_EQ(buffer1[0], copy_constructed_from_value); + EXPECT_EQ(buffer2[0], copy_constructed_value); + EXPECT_EQ(buffer1[1], copy_constructed_from_value); + EXPECT_EQ(buffer2[1], copy_constructed_value); + EXPECT_EQ(buffer1[2], copy_constructed_from_value); + EXPECT_EQ(buffer2[2], copy_constructed_value); + EXPECT_EQ(buffer1[3], 0); + EXPECT_EQ(buffer2[3], 0); + CPPType_TestType.copy_to_uninitialized_indices((void *)buffer1, (void *)buffer2, {2, 5, 7}); + EXPECT_EQ(buffer1[2], copy_constructed_from_value); + EXPECT_EQ(buffer2[2], copy_constructed_value); + EXPECT_EQ(buffer1[4], 0); + EXPECT_EQ(buffer2[4], 0); + EXPECT_EQ(buffer1[5], copy_constructed_from_value); + EXPECT_EQ(buffer2[5], copy_constructed_value); + EXPECT_EQ(buffer1[6], 0); + EXPECT_EQ(buffer2[6], 0); + EXPECT_EQ(buffer1[7], copy_constructed_from_value); + EXPECT_EQ(buffer2[7], copy_constructed_value); + EXPECT_EQ(buffer1[8], 0); + EXPECT_EQ(buffer2[8], 0); +} + +TEST(cpp_type, CopyToInitialized) +{ + int buffer1[10] = {0}; + int buffer2[10] = {0}; + CPPType_TestType.copy_to_initialized((void *)buffer1, (void *)buffer2); + EXPECT_EQ(buffer1[0], copy_assigned_from_value); + EXPECT_EQ(buffer2[0], copy_assigned_value); + CPPType_TestType.copy_to_initialized_n((void *)buffer1, (void *)buffer2, 3); + EXPECT_EQ(buffer1[0], copy_assigned_from_value); + EXPECT_EQ(buffer2[0], copy_assigned_value); + EXPECT_EQ(buffer1[1], copy_assigned_from_value); + EXPECT_EQ(buffer2[1], copy_assigned_value); + EXPECT_EQ(buffer1[2], copy_assigned_from_value); + EXPECT_EQ(buffer2[2], copy_assigned_value); + EXPECT_EQ(buffer1[3], 0); + EXPECT_EQ(buffer2[3], 0); + CPPType_TestType.copy_to_initialized_indices((void *)buffer1, (void *)buffer2, {2, 5, 7}); + EXPECT_EQ(buffer1[2], copy_assigned_from_value); + EXPECT_EQ(buffer2[2], copy_assigned_value); + EXPECT_EQ(buffer1[4], 0); + EXPECT_EQ(buffer2[4], 0); + EXPECT_EQ(buffer1[5], copy_assigned_from_value); + EXPECT_EQ(buffer2[5], copy_assigned_value); + EXPECT_EQ(buffer1[6], 0); + EXPECT_EQ(buffer2[6], 0); + EXPECT_EQ(buffer1[7], copy_assigned_from_value); + EXPECT_EQ(buffer2[7], copy_assigned_value); + EXPECT_EQ(buffer1[8], 0); + EXPECT_EQ(buffer2[8], 0); +} + +TEST(cpp_type, RelocateToUninitialized) +{ + int buffer1[10] = {0}; + int buffer2[10] = {0}; + CPPType_TestType.relocate_to_uninitialized((void *)buffer1, (void *)buffer2); + EXPECT_EQ(buffer1[0], destructed_value); + EXPECT_EQ(buffer2[0], move_constructed_value); + CPPType_TestType.relocate_to_uninitialized_n((void *)buffer1, (void *)buffer2, 3); + EXPECT_EQ(buffer1[0], destructed_value); + EXPECT_EQ(buffer2[0], move_constructed_value); + EXPECT_EQ(buffer1[1], destructed_value); + EXPECT_EQ(buffer2[1], move_constructed_value); + EXPECT_EQ(buffer1[2], destructed_value); + EXPECT_EQ(buffer2[2], move_constructed_value); + EXPECT_EQ(buffer1[3], 0); + EXPECT_EQ(buffer2[3], 0); + CPPType_TestType.relocate_to_uninitialized_indices((void *)buffer1, (void *)buffer2, {2, 5, 7}); + EXPECT_EQ(buffer1[2], destructed_value); + EXPECT_EQ(buffer2[2], move_constructed_value); + EXPECT_EQ(buffer1[4], 0); + EXPECT_EQ(buffer2[4], 0); + EXPECT_EQ(buffer1[5], destructed_value); + EXPECT_EQ(buffer2[5], move_constructed_value); + EXPECT_EQ(buffer1[6], 0); + EXPECT_EQ(buffer2[6], 0); + EXPECT_EQ(buffer1[7], destructed_value); + EXPECT_EQ(buffer2[7], move_constructed_value); + EXPECT_EQ(buffer1[8], 0); + EXPECT_EQ(buffer2[8], 0); +} + +TEST(cpp_type, RelocateToInitialized) +{ + int buffer1[10] = {0}; + int buffer2[10] = {0}; + CPPType_TestType.relocate_to_initialized((void *)buffer1, (void *)buffer2); + EXPECT_EQ(buffer1[0], destructed_value); + EXPECT_EQ(buffer2[0], move_assigned_value); + CPPType_TestType.relocate_to_initialized_n((void *)buffer1, (void *)buffer2, 3); + EXPECT_EQ(buffer1[0], destructed_value); + EXPECT_EQ(buffer2[0], move_assigned_value); + EXPECT_EQ(buffer1[1], destructed_value); + EXPECT_EQ(buffer2[1], move_assigned_value); + EXPECT_EQ(buffer1[2], destructed_value); + EXPECT_EQ(buffer2[2], move_assigned_value); + EXPECT_EQ(buffer1[3], 0); + EXPECT_EQ(buffer2[3], 0); + CPPType_TestType.relocate_to_initialized_indices((void *)buffer1, (void *)buffer2, {2, 5, 7}); + EXPECT_EQ(buffer1[2], destructed_value); + EXPECT_EQ(buffer2[2], move_assigned_value); + EXPECT_EQ(buffer1[4], 0); + EXPECT_EQ(buffer2[4], 0); + EXPECT_EQ(buffer1[5], destructed_value); + EXPECT_EQ(buffer2[5], move_assigned_value); + EXPECT_EQ(buffer1[6], 0); + EXPECT_EQ(buffer2[6], 0); + EXPECT_EQ(buffer1[7], destructed_value); + EXPECT_EQ(buffer2[7], move_assigned_value); + EXPECT_EQ(buffer1[8], 0); + EXPECT_EQ(buffer2[8], 0); +} + +TEST(cpp_type, FillInitialized) +{ + int buffer1 = 0; + int buffer2[10] = {0}; + CPPType_TestType.fill_initialized((void *)&buffer1, (void *)buffer2, 3); + EXPECT_EQ(buffer1, copy_assigned_from_value); + EXPECT_EQ(buffer2[0], copy_assigned_value); + EXPECT_EQ(buffer2[1], copy_assigned_value); + EXPECT_EQ(buffer2[2], copy_assigned_value); + EXPECT_EQ(buffer2[3], 0); + + buffer1 = 0; + CPPType_TestType.fill_initialized_indices((void *)&buffer1, (void *)buffer2, {1, 6, 8}); + EXPECT_EQ(buffer1, copy_assigned_from_value); + EXPECT_EQ(buffer2[0], copy_assigned_value); + EXPECT_EQ(buffer2[1], copy_assigned_value); + EXPECT_EQ(buffer2[2], copy_assigned_value); + EXPECT_EQ(buffer2[3], 0); + EXPECT_EQ(buffer2[4], 0); + EXPECT_EQ(buffer2[5], 0); + EXPECT_EQ(buffer2[6], copy_assigned_value); + EXPECT_EQ(buffer2[7], 0); + EXPECT_EQ(buffer2[8], copy_assigned_value); + EXPECT_EQ(buffer2[9], 0); +} + +TEST(cpp_type, FillUninitialized) +{ + int buffer1 = 0; + int buffer2[10] = {0}; + CPPType_TestType.fill_uninitialized((void *)&buffer1, (void *)buffer2, 3); + EXPECT_EQ(buffer1, copy_constructed_from_value); + EXPECT_EQ(buffer2[0], copy_constructed_value); + EXPECT_EQ(buffer2[1], copy_constructed_value); + EXPECT_EQ(buffer2[2], copy_constructed_value); + EXPECT_EQ(buffer2[3], 0); + + buffer1 = 0; + CPPType_TestType.fill_uninitialized_indices((void *)&buffer1, (void *)buffer2, {1, 6, 8}); + EXPECT_EQ(buffer1, copy_constructed_from_value); + EXPECT_EQ(buffer2[0], copy_constructed_value); + EXPECT_EQ(buffer2[1], copy_constructed_value); + EXPECT_EQ(buffer2[2], copy_constructed_value); + EXPECT_EQ(buffer2[3], 0); + EXPECT_EQ(buffer2[4], 0); + EXPECT_EQ(buffer2[5], 0); + EXPECT_EQ(buffer2[6], copy_constructed_value); + EXPECT_EQ(buffer2[7], 0); + EXPECT_EQ(buffer2[8], copy_constructed_value); + EXPECT_EQ(buffer2[9], 0); +} + +TEST(cpp_type, DebugPrint) +{ + int value = 42; + std::stringstream ss; + CPPType::get<int32_t>().debug_print((void *)&value, ss); + std::string text = ss.str(); + EXPECT_EQ(text, "42"); +} + +} // namespace blender::fn::tests diff --git a/source/blender/functions/tests/FN_generic_vector_array_test.cc b/source/blender/functions/tests/FN_generic_vector_array_test.cc new file mode 100644 index 00000000000..77ec05f12dc --- /dev/null +++ b/source/blender/functions/tests/FN_generic_vector_array_test.cc @@ -0,0 +1,101 @@ +/* Apache License, Version 2.0 */ + +#include "FN_generic_vector_array.hh" + +#include "testing/testing.h" + +namespace blender::fn::tests { + +TEST(generic_vector_array, Constructor) +{ + GVectorArray vectors{CPPType::get<int32_t>(), 3}; + EXPECT_EQ(vectors.size(), 3); + EXPECT_EQ(vectors.lengths().size(), 3); + EXPECT_EQ(vectors.starts().size(), 3); + EXPECT_EQ(vectors.lengths()[0], 0); + EXPECT_EQ(vectors.lengths()[1], 0); + EXPECT_EQ(vectors.lengths()[2], 0); + EXPECT_EQ(vectors.type(), CPPType::get<int32_t>()); +} + +TEST(generic_vector_array, Append) +{ + GVectorArray vectors{CPPType::get<std::string>(), 3}; + std::string value = "hello"; + vectors.append(0, &value); + value = "world"; + vectors.append(0, &value); + vectors.append(2, &value); + + EXPECT_EQ(vectors.lengths()[0], 2); + EXPECT_EQ(vectors.lengths()[1], 0); + EXPECT_EQ(vectors.lengths()[2], 1); + EXPECT_EQ(vectors[0].size(), 2); + EXPECT_EQ(vectors[0].typed<std::string>()[0], "hello"); + EXPECT_EQ(vectors[0].typed<std::string>()[1], "world"); + EXPECT_EQ(vectors[2].typed<std::string>()[0], "world"); +} + +TEST(generic_vector_array, AsArraySpan) +{ + GVectorArray vectors{CPPType::get<int32_t>(), 3}; + int value = 3; + vectors.append(0, &value); + vectors.append(0, &value); + value = 5; + vectors.append(2, &value); + vectors.append(2, &value); + vectors.append(2, &value); + + GVArraySpan span = vectors; + EXPECT_EQ(span.type(), CPPType::get<int32_t>()); + EXPECT_EQ(span.size(), 3); + EXPECT_EQ(span[0].size(), 2); + EXPECT_EQ(span[1].size(), 0); + EXPECT_EQ(span[2].size(), 3); + EXPECT_EQ(span[0].typed<int>()[1], 3); + EXPECT_EQ(span[2].typed<int>()[0], 5); +} + +TEST(generic_vector_array, TypedRef) +{ + GVectorArray vectors{CPPType::get<int32_t>(), 4}; + GVectorArrayRef<int> ref = vectors.typed<int>(); + ref.append(0, 2); + ref.append(0, 6); + ref.append(0, 7); + ref.append(2, 1); + ref.append(2, 1); + ref.append(3, 5); + ref.append(3, 6); + + EXPECT_EQ(ref[0].size(), 3); + EXPECT_EQ(vectors[0].size(), 3); + EXPECT_EQ(ref[0][0], 2); + EXPECT_EQ(ref[0][1], 6); + EXPECT_EQ(ref[0][2], 7); + EXPECT_EQ(ref[1].size(), 0); + EXPECT_EQ(ref[2][0], 1); + EXPECT_EQ(ref[2][1], 1); + EXPECT_EQ(ref[3][0], 5); + EXPECT_EQ(ref[3][1], 6); +} + +TEST(generic_vector_array, Extend) +{ + GVectorArray vectors{CPPType::get<int32_t>(), 3}; + GVectorArrayRef<int> ref = vectors; + + ref.extend(1, {5, 6, 7}); + ref.extend(0, {3}); + + EXPECT_EQ(vectors[0].size(), 1); + EXPECT_EQ(vectors[1].size(), 3); + EXPECT_EQ(vectors[2].size(), 0); + EXPECT_EQ(ref[1][0], 5); + EXPECT_EQ(ref[1][1], 6); + EXPECT_EQ(ref[1][2], 7); + EXPECT_EQ(ref[0][0], 3); +} + +} // namespace blender::fn::tests diff --git a/source/blender/functions/tests/FN_multi_function_network_test.cc b/source/blender/functions/tests/FN_multi_function_network_test.cc new file mode 100644 index 00000000000..f226e0eac2e --- /dev/null +++ b/source/blender/functions/tests/FN_multi_function_network_test.cc @@ -0,0 +1,255 @@ +/* Apache License, Version 2.0 */ + +#include "testing/testing.h" + +#include "FN_multi_function_builder.hh" +#include "FN_multi_function_network.hh" +#include "FN_multi_function_network_evaluation.hh" + +namespace blender::fn::tests { +namespace { + +TEST(multi_function_network, Test1) +{ + CustomMF_SI_SO<int, int> add_10_fn("add 10", [](int value) { return value + 10; }); + CustomMF_SI_SI_SO<int, int, int> multiply_fn("multiply", [](int a, int b) { return a * b; }); + + MFNetwork network; + + MFNode &node1 = network.add_function(add_10_fn); + MFNode &node2 = network.add_function(multiply_fn); + MFOutputSocket &input_socket = network.add_input("Input", MFDataType::ForSingle<int>()); + MFInputSocket &output_socket = network.add_output("Output", MFDataType::ForSingle<int>()); + network.add_link(node1.output(0), node2.input(0)); + network.add_link(node1.output(0), node2.input(1)); + network.add_link(node2.output(0), output_socket); + network.add_link(input_socket, node1.input(0)); + + MFNetworkEvaluator network_fn{{&input_socket}, {&output_socket}}; + + { + Array<int> values = {4, 6, 1, 2, 0}; + Array<int> results(values.size(), 0); + + MFParamsBuilder params(network_fn, values.size()); + params.add_readonly_single_input(values.as_span()); + params.add_uninitialized_single_output(results.as_mutable_span()); + + MFContextBuilder context; + + network_fn.call({0, 2, 3, 4}, params, context); + + EXPECT_EQ(results[0], 14 * 14); + EXPECT_EQ(results[1], 0); + EXPECT_EQ(results[2], 11 * 11); + EXPECT_EQ(results[3], 12 * 12); + EXPECT_EQ(results[4], 10 * 10); + } + { + int value = 3; + Array<int> results(5, 0); + + MFParamsBuilder params(network_fn, results.size()); + params.add_readonly_single_input(&value); + params.add_uninitialized_single_output(results.as_mutable_span()); + + MFContextBuilder context; + + network_fn.call({1, 2, 4}, params, context); + + EXPECT_EQ(results[0], 0); + EXPECT_EQ(results[1], 13 * 13); + EXPECT_EQ(results[2], 13 * 13); + EXPECT_EQ(results[3], 0); + EXPECT_EQ(results[4], 13 * 13); + } +} + +class ConcatVectorsFunction : public MultiFunction { + public: + ConcatVectorsFunction() + { + MFSignatureBuilder signature = this->get_builder("Concat Vectors"); + signature.vector_mutable<int>("A"); + signature.vector_input<int>("B"); + } + + void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override + { + GVectorArrayRef<int> a = params.vector_mutable<int>(0); + VArraySpan<int> b = params.readonly_vector_input<int>(1); + + for (int64_t i : mask) { + a.extend(i, b[i]); + } + } +}; + +class AppendFunction : public MultiFunction { + public: + AppendFunction() + { + MFSignatureBuilder signature = this->get_builder("Append"); + signature.vector_mutable<int>("Vector"); + signature.single_input<int>("Value"); + } + + void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override + { + GVectorArrayRef<int> vectors = params.vector_mutable<int>(0); + VSpan<int> values = params.readonly_single_input<int>(1); + + for (int64_t i : mask) { + vectors.append(i, values[i]); + } + } +}; + +class SumVectorFunction : public MultiFunction { + public: + SumVectorFunction() + { + MFSignatureBuilder signature = this->get_builder("Sum Vector"); + signature.vector_input<int>("Vector"); + signature.single_output<int>("Sum"); + } + + void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override + { + VArraySpan<int> vectors = params.readonly_vector_input<int>(0); + MutableSpan<int> sums = params.uninitialized_single_output<int>(1); + + for (int64_t i : mask) { + int sum = 0; + VSpan<int> vector = vectors[i]; + for (int j = 0; j < vector.size(); j++) { + sum += vector[j]; + } + sums[i] = sum; + } + } +}; + +class CreateRangeFunction : public MultiFunction { + public: + CreateRangeFunction() + { + MFSignatureBuilder builder = this->get_builder("Create Range"); + builder.single_input<int>("Size"); + builder.vector_output<int>("Range"); + } + + void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override + { + VSpan<int> sizes = params.readonly_single_input<int>(0, "Size"); + GVectorArrayRef<int> ranges = params.vector_output<int>(1, "Range"); + + for (int64_t i : mask) { + int size = sizes[i]; + for (int j : IndexRange(size)) { + ranges.append(i, j); + } + } + } +}; + +TEST(multi_function_network, Test2) +{ + CustomMF_SI_SO<int, int> add_3_fn("add 3", [](int value) { return value + 3; }); + + ConcatVectorsFunction concat_vectors_fn; + AppendFunction append_fn; + SumVectorFunction sum_fn; + CreateRangeFunction create_range_fn; + + MFNetwork network; + + MFOutputSocket &input1 = network.add_input("Input 1", MFDataType::ForVector<int>()); + MFOutputSocket &input2 = network.add_input("Input 2", MFDataType::ForSingle<int>()); + MFInputSocket &output1 = network.add_output("Output 1", MFDataType::ForVector<int>()); + MFInputSocket &output2 = network.add_output("Output 2", MFDataType::ForSingle<int>()); + + MFNode &node1 = network.add_function(add_3_fn); + MFNode &node2 = network.add_function(create_range_fn); + MFNode &node3 = network.add_function(concat_vectors_fn); + MFNode &node4 = network.add_function(sum_fn); + MFNode &node5 = network.add_function(append_fn); + MFNode &node6 = network.add_function(sum_fn); + + network.add_link(input2, node1.input(0)); + network.add_link(node1.output(0), node2.input(0)); + network.add_link(node2.output(0), node3.input(1)); + network.add_link(input1, node3.input(0)); + network.add_link(input1, node4.input(0)); + network.add_link(node4.output(0), node5.input(1)); + network.add_link(node3.output(0), node5.input(0)); + network.add_link(node5.output(0), node6.input(0)); + network.add_link(node3.output(0), output1); + network.add_link(node6.output(0), output2); + + // std::cout << network.to_dot() << "\n\n"; + + MFNetworkEvaluator network_fn{{&input1, &input2}, {&output1, &output2}}; + + { + Array<int> input_value_1 = {3, 6}; + int input_value_2 = 4; + + GVectorArray output_value_1(CPPType::get<int32_t>(), 5); + Array<int> output_value_2(5, -1); + + MFParamsBuilder params(network_fn, 5); + params.add_readonly_vector_input(GVArraySpan(input_value_1.as_span(), 5)); + params.add_readonly_single_input(&input_value_2); + params.add_vector_output(output_value_1); + params.add_uninitialized_single_output(output_value_2.as_mutable_span()); + + MFContextBuilder context; + + network_fn.call({1, 2, 4}, params, context); + + EXPECT_EQ(output_value_1[0].size(), 0); + EXPECT_EQ(output_value_1[1].size(), 9); + EXPECT_EQ(output_value_1[2].size(), 9); + EXPECT_EQ(output_value_1[3].size(), 0); + EXPECT_EQ(output_value_1[4].size(), 9); + + EXPECT_EQ(output_value_2[0], -1); + EXPECT_EQ(output_value_2[1], 39); + EXPECT_EQ(output_value_2[2], 39); + EXPECT_EQ(output_value_2[3], -1); + EXPECT_EQ(output_value_2[4], 39); + } + { + GVectorArray input_value_1(CPPType::get<int32_t>(), 3); + GVectorArrayRef<int> input_value_ref_1 = input_value_1; + input_value_ref_1.extend(0, {3, 4, 5}); + input_value_ref_1.extend(1, {1, 2}); + + Array<int> input_value_2 = {4, 2, 3}; + + GVectorArray output_value_1(CPPType::get<int32_t>(), 3); + Array<int> output_value_2(3, -1); + + MFParamsBuilder params(network_fn, 3); + params.add_readonly_vector_input(input_value_1); + params.add_readonly_single_input(input_value_2.as_span()); + params.add_vector_output(output_value_1); + params.add_uninitialized_single_output(output_value_2.as_mutable_span()); + + MFContextBuilder context; + + network_fn.call({0, 1, 2}, params, context); + + EXPECT_EQ(output_value_1[0].size(), 10); + EXPECT_EQ(output_value_1[1].size(), 7); + EXPECT_EQ(output_value_1[2].size(), 6); + + EXPECT_EQ(output_value_2[0], 45); + EXPECT_EQ(output_value_2[1], 16); + EXPECT_EQ(output_value_2[2], 15); + } +} + +} // namespace +} // namespace blender::fn::tests diff --git a/source/blender/functions/tests/FN_multi_function_test.cc b/source/blender/functions/tests/FN_multi_function_test.cc new file mode 100644 index 00000000000..cc023bce597 --- /dev/null +++ b/source/blender/functions/tests/FN_multi_function_test.cc @@ -0,0 +1,387 @@ +/* Apache License, Version 2.0 */ + +#include "testing/testing.h" + +#include "FN_multi_function.hh" +#include "FN_multi_function_builder.hh" + +namespace blender::fn::tests { +namespace { + +class AddFunction : public MultiFunction { + public: + AddFunction() + { + MFSignatureBuilder builder = this->get_builder("Add"); + builder.single_input<int>("A"); + builder.single_input<int>("B"); + builder.single_output<int>("Result"); + } + + void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override + { + VSpan<int> a = params.readonly_single_input<int>(0, "A"); + VSpan<int> b = params.readonly_single_input<int>(1, "B"); + MutableSpan<int> result = params.uninitialized_single_output<int>(2, "Result"); + + for (int64_t i : mask) { + result[i] = a[i] + b[i]; + } + } +}; + +TEST(multi_function, AddFunction) +{ + AddFunction fn; + + Array<int> input1 = {4, 5, 6}; + Array<int> input2 = {10, 20, 30}; + Array<int> output(3, -1); + + MFParamsBuilder params(fn, 3); + params.add_readonly_single_input(input1.as_span()); + params.add_readonly_single_input(input2.as_span()); + params.add_uninitialized_single_output(output.as_mutable_span()); + + MFContextBuilder context; + + fn.call({0, 2}, params, context); + + EXPECT_EQ(output[0], 14); + EXPECT_EQ(output[1], -1); + EXPECT_EQ(output[2], 36); +} + +class AddPrefixFunction : public MultiFunction { + public: + AddPrefixFunction() + { + MFSignatureBuilder builder = this->get_builder("Add Prefix"); + builder.single_input<std::string>("Prefix"); + builder.single_mutable<std::string>("Strings"); + } + + void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override + { + VSpan<std::string> prefixes = params.readonly_single_input<std::string>(0, "Prefix"); + MutableSpan<std::string> strings = params.single_mutable<std::string>(1, "Strings"); + + for (int64_t i : mask) { + strings[i] = prefixes[i] + strings[i]; + } + } +}; + +TEST(multi_function, AddPrefixFunction) +{ + AddPrefixFunction fn; + + Array<std::string> strings = { + "Hello", + "World", + "This is a test", + "Another much longer string to trigger an allocation", + }; + + std::string prefix = "AB"; + + MFParamsBuilder params(fn, strings.size()); + params.add_readonly_single_input(&prefix); + params.add_single_mutable(strings.as_mutable_span()); + + MFContextBuilder context; + + fn.call({0, 2, 3}, params, context); + + EXPECT_EQ(strings[0], "ABHello"); + EXPECT_EQ(strings[1], "World"); + EXPECT_EQ(strings[2], "ABThis is a test"); + EXPECT_EQ(strings[3], "ABAnother much longer string to trigger an allocation"); +} + +class CreateRangeFunction : public MultiFunction { + public: + CreateRangeFunction() + { + MFSignatureBuilder builder = this->get_builder("Create Range"); + builder.single_input<uint>("Size"); + builder.vector_output<uint>("Range"); + } + + void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override + { + VSpan<uint> sizes = params.readonly_single_input<uint>(0, "Size"); + GVectorArrayRef<uint> ranges = params.vector_output<uint>(1, "Range"); + + for (int64_t i : mask) { + uint size = sizes[i]; + for (uint j : IndexRange(size)) { + ranges.append(i, j); + } + } + } +}; + +TEST(multi_function, CreateRangeFunction) +{ + CreateRangeFunction fn; + + GVectorArray ranges(CPPType::get<uint>(), 5); + GVectorArrayRef<uint> ranges_ref(ranges); + Array<uint> sizes = {3, 0, 6, 1, 4}; + + MFParamsBuilder params(fn, ranges.size()); + params.add_readonly_single_input(sizes.as_span()); + params.add_vector_output(ranges); + + MFContextBuilder context; + + fn.call({0, 1, 2, 3}, params, context); + + EXPECT_EQ(ranges_ref[0].size(), 3); + EXPECT_EQ(ranges_ref[1].size(), 0); + EXPECT_EQ(ranges_ref[2].size(), 6); + EXPECT_EQ(ranges_ref[3].size(), 1); + EXPECT_EQ(ranges_ref[4].size(), 0); + + EXPECT_EQ(ranges_ref[0][0], 0); + EXPECT_EQ(ranges_ref[0][1], 1); + EXPECT_EQ(ranges_ref[0][2], 2); + EXPECT_EQ(ranges_ref[2][0], 0); + EXPECT_EQ(ranges_ref[2][1], 1); +} + +class GenericAppendFunction : public MultiFunction { + public: + GenericAppendFunction(const CPPType &type) + { + MFSignatureBuilder builder = this->get_builder("Append"); + builder.vector_mutable("Vector", type); + builder.single_input("Value", type); + } + + void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override + { + GVectorArray &vectors = params.vector_mutable(0, "Vector"); + GVSpan values = params.readonly_single_input(1, "Value"); + + for (int64_t i : mask) { + vectors.append(i, values[i]); + } + } +}; + +TEST(multi_function, GenericAppendFunction) +{ + GenericAppendFunction fn(CPPType::get<int32_t>()); + + GVectorArray vectors(CPPType::get<int32_t>(), 4); + GVectorArrayRef<int> vectors_ref(vectors); + vectors_ref.append(0, 1); + vectors_ref.append(0, 2); + vectors_ref.append(2, 6); + Array<int> values = {5, 7, 3, 1}; + + MFParamsBuilder params(fn, vectors.size()); + params.add_vector_mutable(vectors); + params.add_readonly_single_input(values.as_span()); + + MFContextBuilder context; + + fn.call(IndexRange(vectors.size()), params, context); + + EXPECT_EQ(vectors_ref[0].size(), 3); + EXPECT_EQ(vectors_ref[1].size(), 1); + EXPECT_EQ(vectors_ref[2].size(), 2); + EXPECT_EQ(vectors_ref[3].size(), 1); + + EXPECT_EQ(vectors_ref[0][0], 1); + EXPECT_EQ(vectors_ref[0][1], 2); + EXPECT_EQ(vectors_ref[0][2], 5); + EXPECT_EQ(vectors_ref[1][0], 7); + EXPECT_EQ(vectors_ref[2][0], 6); + EXPECT_EQ(vectors_ref[2][1], 3); + EXPECT_EQ(vectors_ref[3][0], 1); +} + +TEST(multi_function, CustomMF_SI_SO) +{ + CustomMF_SI_SO<std::string, uint> fn("strlen", + [](const std::string &str) { return str.size(); }); + + Array<std::string> strings = {"hello", "world", "test", "another test"}; + Array<uint> sizes(strings.size(), 0); + + MFParamsBuilder params(fn, strings.size()); + params.add_readonly_single_input(strings.as_span()); + params.add_uninitialized_single_output(sizes.as_mutable_span()); + + MFContextBuilder context; + + fn.call(IndexRange(strings.size()), params, context); + + EXPECT_EQ(sizes[0], 5); + EXPECT_EQ(sizes[1], 5); + EXPECT_EQ(sizes[2], 4); + EXPECT_EQ(sizes[3], 12); +} + +TEST(multi_function, CustomMF_SI_SI_SO) +{ + CustomMF_SI_SI_SO<int, int, int> fn("mul", [](int a, int b) { return a * b; }); + + Array<int> values_a = {4, 6, 8, 9}; + int value_b = 10; + Array<int> outputs(values_a.size(), -1); + + MFParamsBuilder params(fn, values_a.size()); + params.add_readonly_single_input(values_a.as_span()); + params.add_readonly_single_input(&value_b); + params.add_uninitialized_single_output(outputs.as_mutable_span()); + + MFContextBuilder context; + + fn.call({0, 1, 3}, params, context); + + EXPECT_EQ(outputs[0], 40); + EXPECT_EQ(outputs[1], 60); + EXPECT_EQ(outputs[2], -1); + EXPECT_EQ(outputs[3], 90); +} + +TEST(multi_function, CustomMF_SI_SI_SI_SO) +{ + CustomMF_SI_SI_SI_SO<int, std::string, bool, uint> fn{ + "custom", + [](int a, const std::string &b, bool c) { return (uint)((uint)a + b.size() + (uint)c); }}; + + Array<int> values_a = {5, 7, 3, 8}; + Array<std::string> values_b = {"hello", "world", "another", "test"}; + Array<bool> values_c = {true, false, false, true}; + Array<uint> outputs(values_a.size(), 0); + + MFParamsBuilder params(fn, values_a.size()); + params.add_readonly_single_input(values_a.as_span()); + params.add_readonly_single_input(values_b.as_span()); + params.add_readonly_single_input(values_c.as_span()); + params.add_uninitialized_single_output(outputs.as_mutable_span()); + + MFContextBuilder context; + + fn.call({1, 2, 3}, params, context); + + EXPECT_EQ(outputs[0], 0); + EXPECT_EQ(outputs[1], 12); + EXPECT_EQ(outputs[2], 10); + EXPECT_EQ(outputs[3], 13); +} + +TEST(multi_function, CustomMF_SM) +{ + CustomMF_SM<std::string> fn("AddSuffix", [](std::string &value) { value += " test"; }); + + Array<std::string> values = {"a", "b", "c", "d", "e"}; + + MFParamsBuilder params(fn, values.size()); + params.add_single_mutable(values.as_mutable_span()); + + MFContextBuilder context; + + fn.call({1, 2, 3}, params, context); + + EXPECT_EQ(values[0], "a"); + EXPECT_EQ(values[1], "b test"); + EXPECT_EQ(values[2], "c test"); + EXPECT_EQ(values[3], "d test"); + EXPECT_EQ(values[4], "e"); +} + +TEST(multi_function, CustomMF_Constant) +{ + CustomMF_Constant<int> fn{42}; + + Array<int> outputs(4, 0); + + MFParamsBuilder params(fn, outputs.size()); + params.add_uninitialized_single_output(outputs.as_mutable_span()); + + MFContextBuilder context; + + fn.call({0, 2, 3}, params, context); + + EXPECT_EQ(outputs[0], 42); + EXPECT_EQ(outputs[1], 0); + EXPECT_EQ(outputs[2], 42); + EXPECT_EQ(outputs[3], 42); +} + +TEST(multi_function, CustomMF_GenericConstant) +{ + int value = 42; + CustomMF_GenericConstant fn{CPPType::get<int32_t>(), (const void *)&value}; + EXPECT_EQ(fn.param_name(0), "42"); + + Array<int> outputs(4, 0); + + MFParamsBuilder params(fn, outputs.size()); + params.add_uninitialized_single_output(outputs.as_mutable_span()); + + MFContextBuilder context; + + fn.call({0, 1, 2}, params, context); + + EXPECT_EQ(outputs[0], 42); + EXPECT_EQ(outputs[1], 42); + EXPECT_EQ(outputs[2], 42); + EXPECT_EQ(outputs[3], 0); +} + +TEST(multi_function, CustomMF_GenericConstantArray) +{ + std::array<int, 4> values = {3, 4, 5, 6}; + CustomMF_GenericConstantArray fn{GSpan(Span(values))}; + EXPECT_EQ(fn.param_name(0), "[3, 4, 5, 6, ]"); + + GVectorArray g_vector_array{CPPType::get<int32_t>(), 4}; + GVectorArrayRef<int> vector_array = g_vector_array; + + MFParamsBuilder params(fn, g_vector_array.size()); + params.add_vector_output(g_vector_array); + + MFContextBuilder context; + + fn.call({1, 2, 3}, params, context); + + EXPECT_EQ(vector_array[0].size(), 0); + EXPECT_EQ(vector_array[1].size(), 4); + EXPECT_EQ(vector_array[2].size(), 4); + EXPECT_EQ(vector_array[3].size(), 4); + for (int i = 1; i < 4; i++) { + EXPECT_EQ(vector_array[i][0], 3); + EXPECT_EQ(vector_array[i][1], 4); + EXPECT_EQ(vector_array[i][2], 5); + EXPECT_EQ(vector_array[i][3], 6); + } +} + +TEST(multi_function, CustomMF_Convert) +{ + CustomMF_Convert<float, int> fn; + + Array<float> inputs = {5.4f, 7.1f, 9.0f}; + Array<int> outputs(inputs.size(), 0); + + MFParamsBuilder params(fn, inputs.size()); + params.add_readonly_single_input(inputs.as_span()); + params.add_uninitialized_single_output(outputs.as_mutable_span()); + + MFContextBuilder context; + fn.call({0, 2}, params, context); + + EXPECT_EQ(outputs[0], 5); + EXPECT_EQ(outputs[1], 0); + EXPECT_EQ(outputs[2], 9); +} + +} // namespace +} // namespace blender::fn::tests diff --git a/source/blender/functions/tests/FN_spans_test.cc b/source/blender/functions/tests/FN_spans_test.cc new file mode 100644 index 00000000000..fbcf1fda71e --- /dev/null +++ b/source/blender/functions/tests/FN_spans_test.cc @@ -0,0 +1,222 @@ +/* Apache License, Version 2.0 */ + +#include "testing/testing.h" + +#include "FN_spans.hh" + +namespace blender::fn::tests { + +TEST(generic_span, TypeConstructor) +{ + GSpan span(CPPType::get<float>()); + EXPECT_EQ(span.size(), 0); + EXPECT_EQ(span.typed<float>().size(), 0); + EXPECT_TRUE(span.is_empty()); +} + +TEST(generic_span, BufferAndSizeConstructor) +{ + int values[4] = {6, 7, 3, 2}; + void *buffer = (void *)values; + GSpan span(CPPType::get<int32_t>(), buffer, 4); + EXPECT_EQ(span.size(), 4); + EXPECT_FALSE(span.is_empty()); + EXPECT_EQ(span.typed<int>().size(), 4); + EXPECT_EQ(span[0], &values[0]); + EXPECT_EQ(span[1], &values[1]); + EXPECT_EQ(span[2], &values[2]); + EXPECT_EQ(span[3], &values[3]); +} + +TEST(generic_mutable_span, TypeConstructor) +{ + GMutableSpan span(CPPType::get<int32_t>()); + EXPECT_EQ(span.size(), 0); + EXPECT_TRUE(span.is_empty()); +} + +TEST(generic_mutable_span, BufferAndSizeConstructor) +{ + int values[4] = {4, 7, 3, 5}; + void *buffer = (void *)values; + GMutableSpan span(CPPType::get<int32_t>(), buffer, 4); + EXPECT_EQ(span.size(), 4); + EXPECT_FALSE(span.is_empty()); + EXPECT_EQ(span.typed<int>().size(), 4); + EXPECT_EQ(values[2], 3); + *(int *)span[2] = 10; + EXPECT_EQ(values[2], 10); + span.typed<int>()[2] = 20; + EXPECT_EQ(values[2], 20); +} + +TEST(virtual_span, EmptyConstructor) +{ + VSpan<int> span; + EXPECT_EQ(span.size(), 0); + EXPECT_TRUE(span.is_empty()); + EXPECT_FALSE(span.is_single_element()); + EXPECT_TRUE(span.is_full_array()); + + GVSpan converted(span); + EXPECT_EQ(converted.type(), CPPType::get<int>()); + EXPECT_EQ(converted.size(), 0); +} + +TEST(virtual_span, SpanConstructor) +{ + std::array<int, 5> values = {7, 3, 8, 6, 4}; + Span<int> span = values; + VSpan<int> virtual_span = span; + EXPECT_EQ(virtual_span.size(), 5); + EXPECT_FALSE(virtual_span.is_empty()); + EXPECT_EQ(virtual_span[0], 7); + EXPECT_EQ(virtual_span[2], 8); + EXPECT_EQ(virtual_span[3], 6); + EXPECT_FALSE(virtual_span.is_single_element()); + EXPECT_TRUE(virtual_span.is_full_array()); + + GVSpan converted(span); + EXPECT_EQ(converted.type(), CPPType::get<int>()); + EXPECT_EQ(converted.size(), 5); +} + +TEST(virtual_span, PointerSpanConstructor) +{ + int x0 = 3; + int x1 = 6; + int x2 = 7; + std::array<const int *, 3> pointers = {&x0, &x2, &x1}; + VSpan<int> span = Span<const int *>(pointers); + EXPECT_EQ(span.size(), 3); + EXPECT_FALSE(span.is_empty()); + EXPECT_EQ(span[0], 3); + EXPECT_EQ(span[1], 7); + EXPECT_EQ(span[2], 6); + EXPECT_EQ(&span[1], &x2); + EXPECT_FALSE(span.is_single_element()); + EXPECT_FALSE(span.is_full_array()); + + GVSpan converted(span); + EXPECT_EQ(converted.type(), CPPType::get<int>()); + EXPECT_EQ(converted.size(), 3); + EXPECT_EQ(converted[0], &x0); + EXPECT_EQ(converted[1], &x2); + EXPECT_EQ(converted[2], &x1); +} + +TEST(virtual_span, SingleConstructor) +{ + int value = 5; + VSpan<int> span = VSpan<int>::FromSingle(&value, 3); + EXPECT_EQ(span.size(), 3); + EXPECT_FALSE(span.is_empty()); + EXPECT_EQ(span[0], 5); + EXPECT_EQ(span[1], 5); + EXPECT_EQ(span[2], 5); + EXPECT_EQ(&span[0], &value); + EXPECT_EQ(&span[1], &value); + EXPECT_EQ(&span[2], &value); + EXPECT_TRUE(span.is_single_element()); + EXPECT_FALSE(span.is_full_array()); + + GVSpan converted(span); + EXPECT_EQ(converted.type(), CPPType::get<int>()); + EXPECT_EQ(converted.size(), 3); + EXPECT_EQ(converted[0], &value); + EXPECT_EQ(converted[1], &value); + EXPECT_EQ(converted[2], &value); +} + +TEST(generic_virtual_span, TypeConstructor) +{ + GVSpan span(CPPType::get<int32_t>()); + EXPECT_EQ(span.size(), 0); + EXPECT_TRUE(span.is_empty()); + EXPECT_FALSE(span.is_single_element()); + EXPECT_TRUE(span.is_full_array()); + + VSpan<int> converted = span.typed<int>(); + EXPECT_EQ(converted.size(), 0); +} + +TEST(generic_virtual_span, GenericSpanConstructor) +{ + int values[4] = {3, 4, 5, 6}; + GVSpan span{GSpan(CPPType::get<int32_t>(), values, 4)}; + EXPECT_EQ(span.size(), 4); + EXPECT_FALSE(span.is_empty()); + EXPECT_EQ(span[0], &values[0]); + EXPECT_EQ(span[1], &values[1]); + EXPECT_EQ(span[2], &values[2]); + EXPECT_EQ(span[3], &values[3]); + EXPECT_FALSE(span.is_single_element()); + EXPECT_TRUE(span.is_full_array()); + + int materialized[4] = {0}; + span.materialize_to_uninitialized(materialized); + EXPECT_EQ(materialized[0], 3); + EXPECT_EQ(materialized[1], 4); + EXPECT_EQ(materialized[2], 5); + EXPECT_EQ(materialized[3], 6); + + VSpan<int> converted = span.typed<int>(); + EXPECT_EQ(converted.size(), 4); + EXPECT_EQ(converted[0], 3); + EXPECT_EQ(converted[1], 4); + EXPECT_EQ(converted[2], 5); + EXPECT_EQ(converted[3], 6); +} + +TEST(generic_virtual_span, SpanConstructor) +{ + std::array<int, 3> values = {6, 7, 8}; + GVSpan span{Span<int>(values)}; + EXPECT_EQ(span.type(), CPPType::get<int32_t>()); + EXPECT_EQ(span.size(), 3); + EXPECT_EQ(span[0], &values[0]); + EXPECT_EQ(span[1], &values[1]); + EXPECT_EQ(span[2], &values[2]); + EXPECT_FALSE(span.is_single_element()); + EXPECT_TRUE(span.is_full_array()); + + int materialized[3] = {0}; + span.materialize_to_uninitialized(materialized); + EXPECT_EQ(materialized[0], 6); + EXPECT_EQ(materialized[1], 7); + EXPECT_EQ(materialized[2], 8); + + VSpan<int> converted = span.typed<int>(); + EXPECT_EQ(converted.size(), 3); + EXPECT_EQ(converted[0], 6); + EXPECT_EQ(converted[1], 7); + EXPECT_EQ(converted[2], 8); +} + +TEST(generic_virtual_span, SingleConstructor) +{ + int value = 5; + GVSpan span = GVSpan::FromSingle(CPPType::get<int32_t>(), &value, 3); + EXPECT_EQ(span.size(), 3); + EXPECT_FALSE(span.is_empty()); + EXPECT_EQ(span[0], &value); + EXPECT_EQ(span[1], &value); + EXPECT_EQ(span[2], &value); + EXPECT_TRUE(span.is_single_element()); + EXPECT_EQ(span.as_single_element(), &value); + EXPECT_FALSE(span.is_full_array()); + + int materialized[3] = {0}; + span.materialize_to_uninitialized({1, 2}, materialized); + EXPECT_EQ(materialized[0], 0); + EXPECT_EQ(materialized[1], 5); + EXPECT_EQ(materialized[2], 5); + + VSpan<int> converted = span.typed<int>(); + EXPECT_EQ(converted.size(), 3); + EXPECT_EQ(converted[0], 5); + EXPECT_EQ(converted[1], 5); + EXPECT_EQ(converted[2], 5); +} + +} // namespace blender::fn::tests diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c index f7929b58650..077a454db73 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c @@ -180,9 +180,8 @@ float get_modifier_point_weight(MDeformVert *dvert, bool inverse, int def_nr) if (inverse == 1) { return 1.0f; } - else { - return -1.0f; - } + + return -1.0f; } return weight; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c index d92721f887f..d645064475b 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c @@ -236,7 +236,7 @@ static void generate_geometry(GpencilModifierData *md, float rand[3][3]; for (int j = 0; j < 3; j++) { - uint primes[3] = {2, 3, 7}; + const uint primes[3] = {2, 3, 7}; double offset[3] = {0.0, 0.0, 0.0}; double r[3]; /* To ensure a nice distribution, we use halton sequence and offset using the seed. */ diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c index 56d94611b5d..bf6c47b2df5 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c @@ -484,7 +484,7 @@ static void generate_geometry(GpencilModifierData *md, /* Early exit */ return; } - else if (ctime >= end_frame) { + if (ctime >= end_frame) { /* Past End - Animation finished. Display final result. */ if (reverse) { /* 1) Reverse = Start with all, end with nothing. diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c index 03137a5cf23..21a8962b131 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c @@ -69,7 +69,7 @@ static void initData(GpencilModifierData *md) gpmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); if (gpmd->curve_intensity) { CurveMapping *curve = gpmd->curve_intensity; - BKE_curvemapping_initialize(curve); + BKE_curvemapping_init(curve); } } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c index 4761dc878c0..30ac18c64ae 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c @@ -94,7 +94,7 @@ static void initData(GpencilModifierData *md) gpmd->falloff_type = eGPHook_Falloff_Smooth; gpmd->curfalloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); if (gpmd->curfalloff) { - BKE_curvemapping_initialize(gpmd->curfalloff); + BKE_curvemapping_init(gpmd->curfalloff); } } @@ -120,7 +120,7 @@ static float gpencil_hook_falloff(const struct GPHookData_cb *tData, const float if (len_sq > tData->falloff_sq) { return 0.0f; } - else if (len_sq > 0.0f) { + if (len_sq > 0.0f) { float fac; if (tData->falloff_type == eGPHook_Falloff_Const) { diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c index 0d8a5f7914e..67c26bf2584 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c @@ -79,7 +79,7 @@ static void initData(GpencilModifierData *md) if (gpmd->curve_intensity) { CurveMapping *curve = gpmd->curve_intensity; BKE_curvemap_reset(curve->cm, &curve->clipr, CURVE_PRESET_BELL, CURVEMAP_SLOPE_POSITIVE); - BKE_curvemapping_initialize(curve); + BKE_curvemapping_init(curve); } } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c index 9cc3712e8f4..75f929e979e 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c @@ -105,19 +105,23 @@ static void deformStroke(GpencilModifierData *md, bGPDspoint *pt = &gps->points[i]; MDeformVert *dvert = gps->dvert != NULL ? &gps->dvert[i] : NULL; - /* verify vertex group */ + /* Verify vertex group. */ const float weight = get_modifier_point_weight( dvert, (mmd->flag & GP_OFFSET_INVERT_VGROUP) != 0, def_nr); if (weight < 0.0f) { continue; } - /* calculate matrix */ + /* Calculate matrix. */ mul_v3_v3fl(loc, mmd->loc, weight); mul_v3_v3fl(rot, mmd->rot, weight); mul_v3_v3fl(scale, mmd->scale, weight); add_v3_fl(scale, 1.0); loc_eul_size_to_mat4(mat, loc, rot, scale); + /* Apply scale to thickness. */ + float unit_scale = (scale[0] + scale[1] + scale[2]) / 3.0f; + pt->pressure *= unit_scale; + mul_m4_v3(mat, &pt->x); } /* Calc geometry data. */ diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c index 34142709c18..efa58cc4ae0 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c @@ -70,7 +70,7 @@ static void initData(GpencilModifierData *md) gpmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); if (gpmd->curve_intensity) { CurveMapping *curve = gpmd->curve_intensity; - BKE_curvemapping_initialize(curve); + BKE_curvemapping_init(curve); } } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c index 557a305d731..e3511d9645e 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c @@ -66,7 +66,7 @@ static void initData(GpencilModifierData *md) gpmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); if (gpmd->curve_intensity) { CurveMapping *curve = gpmd->curve_intensity; - BKE_curvemapping_initialize(curve); + BKE_curvemapping_init(curve); } } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c index 4fa47a592ba..68547614776 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c @@ -65,7 +65,7 @@ static void initData(GpencilModifierData *md) gpmd->material = NULL; gpmd->curve_thickness = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); if (gpmd->curve_thickness) { - BKE_curvemapping_initialize(gpmd->curve_thickness); + BKE_curvemapping_init(gpmd->curve_thickness); } } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c index 315f1b9e19b..389f3ca1bd2 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c @@ -169,7 +169,7 @@ static int remapTime(struct GpencilModifierData *md, const int delta = abs(sfra - nfra); return efra - delta + 1; } - else if (cfra + offset > efra) { + if (cfra + offset > efra) { return nfra - efra + sfra - 1; } } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c index da7d33839f1..9d10fcbe49b 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c @@ -96,7 +96,7 @@ static void initData(GpencilModifierData *md) gpmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); if (gpmd->curve_intensity) { CurveMapping *curve = gpmd->curve_intensity; - BKE_curvemapping_initialize(curve); + BKE_curvemapping_init(curve); } } diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 4f90482d16e..3ea18f72166 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -52,38 +52,37 @@ set(INC_SYS ) set(SRC - intern/gpu_attr_binding.c - intern/gpu_batch.c + intern/gpu_attr_binding.cc + intern/gpu_batch.cc intern/gpu_batch_presets.c intern/gpu_batch_utils.c intern/gpu_buffers.c intern/gpu_codegen.c - intern/gpu_context.cpp - intern/gpu_debug.c - intern/gpu_draw.c - intern/gpu_draw_smoke.c - intern/gpu_element.c - intern/gpu_extensions.c - intern/gpu_framebuffer.c - intern/gpu_immediate.c + intern/gpu_context.cc + intern/gpu_debug.cc + intern/gpu_element.cc + intern/gpu_extensions.cc + intern/gpu_framebuffer.cc + intern/gpu_immediate.cc intern/gpu_immediate_util.c intern/gpu_init_exit.c intern/gpu_material.c intern/gpu_material_library.c - intern/gpu_matrix.c + intern/gpu_matrix.cc intern/gpu_node_graph.c - intern/gpu_platform.c + intern/gpu_platform.cc intern/gpu_primitive.c intern/gpu_select.c intern/gpu_select_pick.c intern/gpu_select_sample_query.c - intern/gpu_shader.c - intern/gpu_shader_interface.c - intern/gpu_state.c - intern/gpu_texture.c - intern/gpu_uniformbuffer.c - intern/gpu_vertex_buffer.c - intern/gpu_vertex_format.c + intern/gpu_shader.cc + intern/gpu_shader_builtin.c + intern/gpu_shader_interface.cc + intern/gpu_state.cc + intern/gpu_texture.cc + intern/gpu_uniformbuffer.cc + intern/gpu_vertex_buffer.cc + intern/gpu_vertex_format.cc intern/gpu_viewport.c GPU_attr_binding.h @@ -94,7 +93,6 @@ set(SRC GPU_common.h GPU_context.h GPU_debug.h - GPU_draw.h GPU_element.h GPU_extensions.h GPU_framebuffer.h @@ -216,6 +214,8 @@ data_to_c_simple(shaders/gpu_shader_text_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_keyframe_diamond_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_keyframe_diamond_frag.glsl SRC) +data_to_c_simple(shaders/gpu_shader_codegen_lib.glsl SRC) + data_to_c_simple(shaders/gpu_shader_geometry.glsl SRC) data_to_c_simple(shaders/material/gpu_shader_material_add_shader.glsl SRC) diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h index ca6aaa90ddc..71a29d0b178 100644 --- a/source/blender/gpu/GPU_batch.h +++ b/source/blender/gpu/GPU_batch.h @@ -126,9 +126,8 @@ int GPU_batch_vertbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo); #define GPU_batch_vertbuf_add(batch, verts) GPU_batch_vertbuf_add_ex(batch, verts, false) -void GPU_batch_program_set_no_use(GPUBatch *, uint32_t program, const GPUShaderInterface *); -void GPU_batch_program_set(GPUBatch *, uint32_t program, const GPUShaderInterface *); -void GPU_batch_program_set_shader(GPUBatch *, GPUShader *shader); +void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader); +void GPU_batch_set_shader_no_bind(GPUBatch *batch, GPUShader *shader); void GPU_batch_program_set_imm_shader(GPUBatch *batch); void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id); void GPU_batch_program_set_builtin_with_config(GPUBatch *batch, diff --git a/source/blender/gpu/GPU_debug.h b/source/blender/gpu/GPU_debug.h index 282c2437640..be822056678 100644 --- a/source/blender/gpu/GPU_debug.h +++ b/source/blender/gpu/GPU_debug.h @@ -23,8 +23,6 @@ #pragma once -#include "GPU_glew.h" - #ifdef __cplusplus extern "C" { #endif diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h deleted file mode 100644 index c0458fec7c3..00000000000 --- a/source/blender/gpu/GPU_draw.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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. - */ - -/** \file - * \ingroup gpu - */ - -#pragma once - -#include "BLI_utildefines.h" -#include "DNA_object_enums.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct FluidModifierData; -struct ImBuf; -struct Image; -struct ImageUser; -struct Main; - -/* OpenGL drawing functions related to shading. */ - -/* Mipmap settings - * - these will free textures on changes */ - -void GPU_set_mipmap(struct Main *bmain, bool mipmap); -bool GPU_get_mipmap(void); -void GPU_set_linear_mipmap(bool linear); -bool GPU_get_linear_mipmap(void); -void GPU_paint_set_mipmap(struct Main *bmain, bool mipmap); - -/* Anisotropic filtering settings - * - these will free textures on changes */ -void GPU_set_anisotropic(float value); -float GPU_get_anisotropic(void); - -/* Image updates and free - * - these deal with images bound as opengl textures */ - -void GPU_paint_update_image( - struct Image *ima, struct ImageUser *iuser, int x, int y, int w, int h); -void GPU_create_gl_tex(unsigned int *bind, - unsigned int *rect, - float *frect, - int rectw, - int recth, - int textarget, - bool mipmap, - bool half_float, - bool use_srgb, - struct Image *ima); -void GPU_create_gl_tex_compressed(unsigned int *bind, - int textarget, - struct Image *ima, - struct ImBuf *ibuf); -bool GPU_upload_dxt_texture(struct ImBuf *ibuf, bool use_srgb); -void GPU_free_image(struct Image *ima); -void GPU_free_images(struct Main *bmain); -void GPU_free_images_anim(struct Main *bmain); -void GPU_free_images_old(struct Main *bmain); - -/* gpu_draw_smoke.c */ -void GPU_free_smoke(struct FluidModifierData *fmd); -void GPU_free_smoke_velocity(struct FluidModifierData *fmd); -void GPU_create_smoke(struct FluidModifierData *fmd, int highres); -void GPU_create_smoke_coba_field(struct FluidModifierData *fmd); -void GPU_create_smoke_velocity(struct FluidModifierData *fmd); - -/* Delayed free of OpenGL buffers by main thread */ -void GPU_free_unused_buffers(void); - -#ifdef __cplusplus -} -#endif diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h index 6cb7a297d09..2ce6e458378 100644 --- a/source/blender/gpu/GPU_extensions.h +++ b/source/blender/gpu/GPU_extensions.h @@ -51,6 +51,8 @@ bool GPU_use_main_context_workaround(void); bool GPU_texture_copy_workaround(void); bool GPU_crappy_amd_driver(void); +int GPU_texture_size_with_limit(int res); + bool GPU_mem_stats_supported(void); void GPU_mem_stats_get(int *totalmem, int *freemem); diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h index 4958d1eaac8..9dc07fefd4e 100644 --- a/source/blender/gpu/GPU_framebuffer.h +++ b/source/blender/gpu/GPU_framebuffer.h @@ -31,7 +31,7 @@ extern "C" { typedef struct GPUAttachment { struct GPUTexture *tex; - int mip, layer; + int layer, mip; } GPUAttachment; typedef enum eGPUFrameBufferBits { @@ -119,35 +119,35 @@ void GPU_framebuffer_config_array(GPUFrameBuffer *fb, const GPUAttachment *confi #define GPU_ATTACHMENT_NONE \ { \ - .tex = NULL, .layer = -1, .mip = 0, \ + NULL, -1, 0, \ } #define GPU_ATTACHMENT_LEAVE \ { \ - .tex = NULL, .layer = -1, .mip = -1, \ + NULL, -1, -1, \ } #define GPU_ATTACHMENT_TEXTURE(_tex) \ { \ - .tex = _tex, .layer = -1, .mip = 0, \ + _tex, -1, 0, \ } #define GPU_ATTACHMENT_TEXTURE_MIP(_tex, _mip) \ { \ - .tex = _tex, .layer = -1, .mip = _mip, \ + _tex, -1, _mip, \ } #define GPU_ATTACHMENT_TEXTURE_LAYER(_tex, _layer) \ { \ - .tex = _tex, .layer = _layer, .mip = 0, \ + _tex, _layer, 0, \ } #define GPU_ATTACHMENT_TEXTURE_LAYER_MIP(_tex, _layer, _mip) \ { \ - .tex = _tex, .layer = _layer, .mip = _mip, \ + _tex, _layer, _mip, \ } #define GPU_ATTACHMENT_TEXTURE_CUBEFACE(_tex, _face) \ { \ - .tex = _tex, .layer = _face, .mip = 0, \ + _tex, _face, 0, \ } #define GPU_ATTACHMENT_TEXTURE_CUBEFACE_MIP(_tex, _face, _mip) \ { \ - .tex = _tex, .layer = _face, .mip = _mip, \ + _tex, _face, _mip, \ } /* Framebuffer operations */ @@ -211,7 +211,7 @@ GPUOffScreen *GPU_offscreen_create( 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_read_pixels(GPUOffScreen *ofs, eGPUDataFormat type, void *pixels); void GPU_offscreen_draw_to_screen(GPUOffScreen *ofs, int x, int y); int GPU_offscreen_width(const GPUOffScreen *ofs); int GPU_offscreen_height(const GPUOffScreen *ofs); diff --git a/source/blender/gpu/GPU_immediate.h b/source/blender/gpu/GPU_immediate.h index 08bfcb95942..41d4f5d28d3 100644 --- a/source/blender/gpu/GPU_immediate.h +++ b/source/blender/gpu/GPU_immediate.h @@ -41,7 +41,7 @@ extern "C" { GPUVertFormat *immVertexFormat(void); /** Every immBegin must have a program bound first. */ -void immBindProgram(uint32_t program, const GPUShaderInterface *); +void immBindShader(GPUShader *shader); /** Call after your last immEnd, or before binding another program. */ void immUnbindProgram(void); @@ -133,7 +133,7 @@ void immUniformColor3ubvAlpha(const unsigned char rgb[3], unsigned char a); void immUniformColor4ubv(const unsigned char rgba[4]); /** - * Extend #immBindProgram to use Blender’s library of built-in shader programs. + * Extend #immBindShader to use Blender’s library of built-in shader programs. * Use #immUnbindProgram() when done. */ void immBindBuiltinProgram(eGPUBuiltinShader shader_id); diff --git a/source/blender/gpu/GPU_init_exit.h b/source/blender/gpu/GPU_init_exit.h index bd4771e2357..42c56940c4c 100644 --- a/source/blender/gpu/GPU_init_exit.h +++ b/source/blender/gpu/GPU_init_exit.h @@ -31,7 +31,7 @@ extern "C" { void GPU_init(void); void GPU_exit(void); -bool GPU_is_initialized(void); +bool GPU_is_init(void); #ifdef __cplusplus } diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index b2352b3f3b0..b8957ff1819 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -109,6 +109,7 @@ typedef enum eGPUMatFlag { GPU_MATFLAG_GLOSSY = (1 << 1), GPU_MATFLAG_REFRACT = (1 << 2), GPU_MATFLAG_SSS = (1 << 3), + GPU_MATFLAG_BARYCENTRIC = (1 << 4), } eGPUMatFlag; typedef enum eGPUBlendMode { @@ -136,6 +137,13 @@ typedef enum eGPUMaterialStatus { GPU_MAT_SUCCESS, } eGPUMaterialStatus; +typedef void (*GPUMaterialEvalCallbackFn)(GPUMaterial *mat, + int options, + const char **vert_code, + const char **geom_code, + const char **frag_lib, + const char **defines); + GPUNodeLink *GPU_constant(const float *num); GPUNodeLink *GPU_uniform(const float *num); GPUNodeLink *GPU_attribute(GPUMaterial *mat, CustomDataType type, const char *name); @@ -189,7 +197,8 @@ GPUMaterial *GPU_material_from_nodetree(struct Scene *scene, const char *geom_code, const char *frag_lib, const char *defines, - const char *name); + const char *name, + GPUMaterialEvalCallbackFn callback); void GPU_material_compile(GPUMaterial *mat); void GPU_material_free(struct ListBase *gpumaterial); diff --git a/source/blender/gpu/GPU_platform.h b/source/blender/gpu/GPU_platform.h index 0848252c788..a89298c0d01 100644 --- a/source/blender/gpu/GPU_platform.h +++ b/source/blender/gpu/GPU_platform.h @@ -24,10 +24,7 @@ #pragma once #include "BLI_sys_types.h" - -#ifdef __cplusplus -extern "C" { -#endif +#include "BLI_utildefines.h" /* GPU platform support */ @@ -42,6 +39,8 @@ typedef enum eGPUDeviceType { GPU_DEVICE_ANY = (0xff), } eGPUDeviceType; +ENUM_OPERATORS(eGPUDeviceType) + typedef enum eGPUOSType { GPU_OS_WIN = (1 << 8), GPU_OS_MAC = (1 << 9), @@ -62,6 +61,10 @@ typedef enum eGPUSupportLevel { GPU_SUPPORT_LEVEL_UNSUPPORTED, } eGPUSupportLevel; +#ifdef __cplusplus +extern "C" { +#endif + bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver); eGPUSupportLevel GPU_platform_support_level(void); const char *GPU_platform_support_level_key(void); diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 1ec70c1106b..f782742ae53 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -86,8 +86,6 @@ void GPU_shader_transform_feedback_disable(GPUShader *shader); int GPU_shader_get_program(GPUShader *shader); -void *GPU_shader_get_interface(GPUShader *shader); - void GPU_shader_set_srgb_uniform(const struct GPUShaderInterface *interface); int GPU_shader_get_uniform(GPUShader *shader, const char *name); diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h index 4cf1d9844ae..4a2c90e241b 100644 --- a/source/blender/gpu/GPU_state.h +++ b/source/blender/gpu/GPU_state.h @@ -86,6 +86,7 @@ bool GPU_depth_mask_get(void); void GPU_stencil_mask(uint stencil); void GPU_unpack_row_length_set(uint len); void GPU_clip_distances(int enabled_len); +bool GPU_mipmap_enabled(void); void GPU_flush(void); void GPU_finish(void); diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index 7cbd4b1eee3..7ee7f8fcdec 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -24,6 +24,7 @@ #pragma once #include "BLI_utildefines.h" + #include "GPU_state.h" struct GPUVertBuf; @@ -42,7 +43,6 @@ typedef struct GPUTexture GPUTexture; * - Internally used by textures. * - All states are created at startup to avoid runtime costs. */ - typedef enum eGPUSamplerState { GPU_SAMPLER_FILTER = (1 << 0), GPU_SAMPLER_MIPMAP = (1 << 1), @@ -56,6 +56,8 @@ typedef enum eGPUSamplerState { GPU_SAMPLER_MAX = (1 << 8), } eGPUSamplerState; +ENUM_OPERATORS(eGPUSamplerState) + #ifdef __cplusplus extern "C" { #endif @@ -120,7 +122,6 @@ typedef enum eGPUTextureFormat { #if 0 GPU_RGB10_A2, GPU_RGB10_A2UI, - GPU_SRGB8_A8, #endif GPU_R11F_G11F_B10F, GPU_DEPTH32F_STENCIL8, @@ -149,7 +150,13 @@ typedef enum eGPUTextureFormat { GPU_R8_SNORM, #endif -/* Special formats texture only */ + /* Special formats texture only */ + GPU_SRGB8_A8_DXT1, + GPU_SRGB8_A8_DXT3, + GPU_SRGB8_A8_DXT5, + GPU_RGBA8_DXT1, + GPU_RGBA8_DXT3, + GPU_RGBA8_DXT5, #if 0 GPU_SRGB8, GPU_RGB9_E5, @@ -222,17 +229,10 @@ GPUTexture *GPU_texture_create_cube_array( GPUTexture *GPU_texture_create_from_vertbuf(struct GPUVertBuf *vert); GPUTexture *GPU_texture_create_buffer(eGPUTextureFormat data_type, const uint buffer); -GPUTexture *GPU_texture_from_bindcode(int textarget, int bindcode); -GPUTexture *GPU_texture_from_blender(struct Image *ima, - struct ImageUser *iuser, - struct ImBuf *ibuf, - int textarget); +GPUTexture *GPU_texture_create_compressed( + int w, int h, int miplen, eGPUTextureFormat format, const void *data); -/* movie clip drawing */ -GPUTexture *GPU_texture_from_movieclip(struct MovieClip *clip, - struct MovieClipUser *cuser, - int textarget); -void GPU_free_texture_movieclip(struct MovieClip *clip); +GPUTexture *GPU_texture_create_error(int dimension, bool array); void GPU_texture_add_mipmap(GPUTexture *tex, eGPUDataFormat gpu_data_format, @@ -268,6 +268,7 @@ void GPU_texture_unbind_all(void); void GPU_texture_copy(GPUTexture *dst, GPUTexture *src); void GPU_texture_generate_mipmap(GPUTexture *tex); +void GPU_texture_anisotropic_filter(GPUTexture *tex, bool use_aniso); void GPU_texture_compare_mode(GPUTexture *tex, bool use_compare); void GPU_texture_filter_mode(GPUTexture *tex, bool use_filter); void GPU_texture_mipmap_mode(GPUTexture *tex, bool use_mipmap, bool use_filter); diff --git a/source/blender/gpu/GPU_uniformbuffer.h b/source/blender/gpu/GPU_uniformbuffer.h index 56e258d8a48..e2b2a757fb9 100644 --- a/source/blender/gpu/GPU_uniformbuffer.h +++ b/source/blender/gpu/GPU_uniformbuffer.h @@ -41,8 +41,7 @@ void GPU_uniformbuffer_dynamic_update(GPUUniformBuffer *ubo_); void GPU_uniformbuffer_bind(GPUUniformBuffer *ubo, int number); void GPU_uniformbuffer_unbind(GPUUniformBuffer *ubo); - -int GPU_uniformbuffer_bindpoint(GPUUniformBuffer *ubo); +void GPU_uniformbuffer_unbind_all(void); bool GPU_uniformbuffer_is_empty(GPUUniformBuffer *ubo); bool GPU_uniformbuffer_is_dirty(GPUUniformBuffer *ubo); diff --git a/source/blender/gpu/GPU_vertex_buffer.h b/source/blender/gpu/GPU_vertex_buffer.h index 8f194ed2c36..757255496e0 100644 --- a/source/blender/gpu/GPU_vertex_buffer.h +++ b/source/blender/gpu/GPU_vertex_buffer.h @@ -58,10 +58,10 @@ typedef struct GPUVertBuf { /** 0 indicates not yet allocated. */ uint32_t vbo_id; /** Usage hint for GL optimisation. */ - uint usage : 2; + GPUUsageType usage; /** Data has been touched and need to be reuploaded to GPU. */ - uint dirty : 1; - unsigned char *data; /* NULL indicates data in VRAM (unmapped) */ + bool dirty; + uchar *data; /* NULL indicates data in VRAM (unmapped) */ } GPUVertBuf; GPUVertBuf *GPU_vertbuf_create(GPUUsageType); diff --git a/source/blender/gpu/GPU_vertex_format.h b/source/blender/gpu/GPU_vertex_format.h index 391eaf61876..59af912ed3d 100644 --- a/source/blender/gpu/GPU_vertex_format.h +++ b/source/blender/gpu/GPU_vertex_format.h @@ -41,7 +41,7 @@ extern "C" { #define GPU_MAX_SAFE_ATTR_NAME 12 typedef enum { - GPU_COMP_I8, + GPU_COMP_I8 = 0, GPU_COMP_U8, GPU_COMP_I16, GPU_COMP_U16, @@ -51,17 +51,21 @@ typedef enum { GPU_COMP_F32, GPU_COMP_I10, + /* Warning! adjust GPUVertAttr if changing. */ } GPUVertCompType; typedef enum { - GPU_FETCH_FLOAT, + GPU_FETCH_FLOAT = 0, GPU_FETCH_INT, GPU_FETCH_INT_TO_FLOAT_UNIT, /* 127 (ubyte) -> 0.5 (and so on for other int types) */ GPU_FETCH_INT_TO_FLOAT, /* 127 (any int type) -> 127.0 */ + /* Warning! adjust GPUVertAttr if changing. */ } GPUVertFetchMode; typedef struct GPUVertAttr { + /* GPUVertFetchMode */ uint fetch_mode : 2; + /* GPUVertCompType */ uint comp_type : 3; /* 1 to 4 or 8 or 12 or 16 */ uint comp_len : 5; @@ -71,8 +75,6 @@ typedef struct GPUVertAttr { uint offset : 11; /* up to GPU_VERT_ATTR_MAX_NAMES */ uint name_len : 3; - uint gl_comp_type; - /* -- 8 Bytes -- */ uchar names[GPU_VERT_ATTR_MAX_NAMES]; } GPUVertAttr; diff --git a/source/blender/gpu/intern/gpu_attr_binding.c b/source/blender/gpu/intern/gpu_attr_binding.cc index 6cb60884620..6cb60884620 100644 --- a/source/blender/gpu/intern/gpu_attr_binding.c +++ b/source/blender/gpu/intern/gpu_attr_binding.cc diff --git a/source/blender/gpu/intern/gpu_attr_binding_private.h b/source/blender/gpu/intern/gpu_attr_binding_private.h index 4f18655ec62..4d359343c38 100644 --- a/source/blender/gpu/intern/gpu_attr_binding_private.h +++ b/source/blender/gpu/intern/gpu_attr_binding_private.h @@ -28,9 +28,18 @@ #include "GPU_shader_interface.h" #include "GPU_vertex_format.h" +#ifdef __cplusplus +extern "C" { +#endif + +/* TODO(fclem) remove, use shaderface directly. */ void AttrBinding_clear(GPUAttrBinding *binding); void get_attr_locations(const GPUVertFormat *format, GPUAttrBinding *binding, const GPUShaderInterface *shaderface); uint read_attr_location(const GPUAttrBinding *binding, uint a_idx); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.cc index 5f77f13c135..9f9adcacfa6 100644 --- a/source/blender/gpu/intern/gpu_batch.c +++ b/source/blender/gpu/intern/gpu_batch.cc @@ -37,6 +37,7 @@ #include "gpu_context_private.h" #include "gpu_primitive_private.h" #include "gpu_shader_private.h" +#include "gpu_vertex_format_private.h" #include <limits.h> #include <stdlib.h> @@ -89,7 +90,7 @@ GPUBatch *GPU_batch_create_ex(GPUPrimType prim_type, GPUIndexBuf *elem, uint owns_flag) { - GPUBatch *batch = MEM_callocN(sizeof(GPUBatch), "GPUBatch"); + GPUBatch *batch = (GPUBatch *)MEM_callocN(sizeof(GPUBatch), "GPUBatch"); GPU_batch_init_ex(batch, prim_type, verts, elem, owns_flag); return batch; } @@ -327,10 +328,10 @@ static GLuint batch_vao_get(GPUBatch *batch) } /* Init dynamic arrays and let the branch below set the values. */ batch->dynamic_vaos.count = GPU_BATCH_VAO_DYN_ALLOC_COUNT; - batch->dynamic_vaos.interfaces = MEM_callocN( + batch->dynamic_vaos.interfaces = (const GPUShaderInterface **)MEM_callocN( batch->dynamic_vaos.count * sizeof(GPUShaderInterface *), "dyn vaos interfaces"); - batch->dynamic_vaos.vao_ids = MEM_callocN(batch->dynamic_vaos.count * sizeof(GLuint), - "dyn vaos ids"); + batch->dynamic_vaos.vao_ids = (GLuint *)MEM_callocN( + batch->dynamic_vaos.count * sizeof(GLuint), "dyn vaos ids"); } } @@ -346,11 +347,11 @@ static GLuint batch_vao_get(GPUBatch *batch) /* Not enough place, realloc the array. */ i = batch->dynamic_vaos.count; batch->dynamic_vaos.count += GPU_BATCH_VAO_DYN_ALLOC_COUNT; - batch->dynamic_vaos.interfaces = MEM_recallocN((void *)batch->dynamic_vaos.interfaces, - sizeof(GPUShaderInterface *) * - batch->dynamic_vaos.count); - batch->dynamic_vaos.vao_ids = MEM_recallocN(batch->dynamic_vaos.vao_ids, - sizeof(GLuint) * batch->dynamic_vaos.count); + batch->dynamic_vaos.interfaces = (const GPUShaderInterface **)MEM_recallocN( + (void *)batch->dynamic_vaos.interfaces, + sizeof(GPUShaderInterface *) * batch->dynamic_vaos.count); + batch->dynamic_vaos.vao_ids = (GLuint *)MEM_recallocN( + batch->dynamic_vaos.vao_ids, sizeof(GLuint) * batch->dynamic_vaos.count); } batch->dynamic_vaos.interfaces[i] = batch->interface; batch->dynamic_vaos.vao_ids[i] = new_vao = GPU_vao_alloc(); @@ -370,22 +371,20 @@ static GLuint batch_vao_get(GPUBatch *batch) return new_vao; } -void GPU_batch_program_set_no_use(GPUBatch *batch, - uint32_t program, - const GPUShaderInterface *shaderface) +void GPU_batch_set_shader_no_bind(GPUBatch *batch, GPUShader *shader) { #if TRUST_NO_ONE - assert(glIsProgram(program)); + assert(glIsProgram(shader->program)); assert(batch->program_in_use == 0); #endif - batch->interface = shaderface; - batch->program = program; + batch->interface = shader->interface; + batch->program = shader->program; batch->vao_id = batch_vao_get(batch); } -void GPU_batch_program_set(GPUBatch *batch, uint32_t program, const GPUShaderInterface *shaderface) +void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader) { - GPU_batch_program_set_no_use(batch, program, shaderface); + GPU_batch_set_shader_no_bind(batch, shader); GPU_batch_program_use_begin(batch); /* hack! to make Batch_Uniform* simpler */ } @@ -440,6 +439,7 @@ static void create_bindings(GPUVertBuf *verts, } const GLvoid *pointer = (const GLubyte *)0 + offset + v_first * stride; + const GLenum type = convert_comp_type_to_gl(static_cast<GPUVertCompType>(a->comp_type)); for (uint n_idx = 0; n_idx < a->name_len; n_idx++) { const char *name = GPU_vertformat_attr_name_get(format, a, n_idx); @@ -452,19 +452,13 @@ static void create_bindings(GPUVertBuf *verts, *attr_mask &= ~(1 << input->location); if (a->comp_len == 16 || a->comp_len == 12 || a->comp_len == 8) { -#if TRUST_NO_ONE - assert(a->fetch_mode == GPU_FETCH_FLOAT); - assert(a->gl_comp_type == GL_FLOAT); -#endif + BLI_assert(a->fetch_mode == GPU_FETCH_FLOAT); + BLI_assert(a->comp_type == GPU_COMP_F32); for (int i = 0; i < a->comp_len / 4; i++) { glEnableVertexAttribArray(input->location + i); glVertexAttribDivisor(input->location + i, (use_instancing) ? 1 : 0); - glVertexAttribPointer(input->location + i, - 4, - a->gl_comp_type, - GL_FALSE, - stride, - (const GLubyte *)pointer + i * 16); + glVertexAttribPointer( + input->location + i, 4, type, GL_FALSE, stride, (const GLubyte *)pointer + i * 16); } } else { @@ -474,15 +468,13 @@ static void create_bindings(GPUVertBuf *verts, switch (a->fetch_mode) { case GPU_FETCH_FLOAT: case GPU_FETCH_INT_TO_FLOAT: - glVertexAttribPointer( - input->location, a->comp_len, a->gl_comp_type, GL_FALSE, stride, pointer); + glVertexAttribPointer(input->location, a->comp_len, type, GL_FALSE, stride, pointer); break; case GPU_FETCH_INT_TO_FLOAT_UNIT: - glVertexAttribPointer( - input->location, a->comp_len, a->gl_comp_type, GL_TRUE, stride, pointer); + glVertexAttribPointer(input->location, a->comp_len, type, GL_TRUE, stride, pointer); break; case GPU_FETCH_INT: - glVertexAttribIPointer(input->location, a->comp_len, a->gl_comp_type, stride, pointer); + glVertexAttribIPointer(input->location, a->comp_len, type, stride, pointer); break; } } @@ -839,7 +831,7 @@ struct GPUDrawList { GPUDrawList *GPU_draw_list_create(int length) { - GPUDrawList *list = MEM_callocN(sizeof(GPUDrawList), "GPUDrawList"); + GPUDrawList *list = (GPUDrawList *)MEM_callocN(sizeof(GPUDrawList), "GPUDrawList"); /* Alloc the biggest possible command list which is indexed. */ list->buffer_size = sizeof(GPUDrawCommandIndexed) * length; if (USE_MULTI_DRAW_INDIRECT) { @@ -848,7 +840,7 @@ GPUDrawList *GPU_draw_list_create(int length) glBufferData(GL_DRAW_INDIRECT_BUFFER, list->buffer_size, NULL, GL_DYNAMIC_DRAW); } else { - list->commands = MEM_mallocN(list->buffer_size, "GPUDrawList data"); + list->commands = (GPUDrawCommand *)MEM_mallocN(list->buffer_size, "GPUDrawList data"); } return list; } @@ -880,7 +872,7 @@ void GPU_draw_list_init(GPUDrawList *list, GPUBatch *batch) list->cmd_offset = 0; } GLenum flags = GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_FLUSH_EXPLICIT_BIT; - list->commands = glMapBufferRange( + list->commands = (GPUDrawCommand *)glMapBufferRange( GL_DRAW_INDIRECT_BUFFER, list->cmd_offset, list->buffer_size - list->cmd_offset, flags); } } @@ -989,17 +981,12 @@ void GPU_draw_list_submit(GPUDrawList *list) /** \name Utilities * \{ */ -void GPU_batch_program_set_shader(GPUBatch *batch, GPUShader *shader) -{ - GPU_batch_program_set(batch, shader->program, shader->interface); -} - void GPU_batch_program_set_builtin_with_config(GPUBatch *batch, eGPUBuiltinShader shader_id, eGPUShaderConfig sh_cfg) { GPUShader *shader = GPU_shader_get_builtin_shader_with_config(shader_id, sh_cfg); - GPU_batch_program_set(batch, shader->program, shader->interface); + GPU_batch_set_shader(batch, shader); } void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id) @@ -1012,10 +999,7 @@ void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id) * DO NOT DRAW WITH THE BATCH BEFORE CALLING immUnbindProgram. */ void GPU_batch_program_set_imm_shader(GPUBatch *batch) { - GLuint program; - GPUShaderInterface *interface; - immGetProgram(&program, &interface); - GPU_batch_program_set(batch, program, interface); + GPU_batch_set_shader(batch, immGetShader()); } /** \} */ diff --git a/source/blender/gpu/intern/gpu_batch_presets.c b/source/blender/gpu/intern/gpu_batch_presets.c index 7f842d4d508..3d9b4326c7e 100644 --- a/source/blender/gpu/intern/gpu_batch_presets.c +++ b/source/blender/gpu/intern/gpu_batch_presets.c @@ -129,12 +129,11 @@ GPUBatch *GPU_batch_preset_sphere(int lod) if (lod == 0) { return g_presets_3d.batch.sphere_low; } - else if (lod == 1) { + if (lod == 1) { return g_presets_3d.batch.sphere_med; } - else { - return g_presets_3d.batch.sphere_high; - } + + return g_presets_3d.batch.sphere_high; } GPUBatch *GPU_batch_preset_sphere_wire(int lod) @@ -145,9 +144,8 @@ GPUBatch *GPU_batch_preset_sphere_wire(int lod) if (lod == 0) { return g_presets_3d.batch.sphere_wire_low; } - else { - return g_presets_3d.batch.sphere_wire_med; - } + + return g_presets_3d.batch.sphere_wire_med; } /** \} */ diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 10d5a860f6a..d32b45e0b5f 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -695,7 +695,7 @@ void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers *buffers, } if (show_vcol) { - ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX}; + const ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX}; GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index, &vcol); } @@ -749,7 +749,7 @@ void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers *buffers, empty_mask = empty_mask && (cmask == 0); } - ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX}; + const ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX}; GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 0, &vcol); GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 1, &vcol); GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 2, &vcol); @@ -832,12 +832,12 @@ static void gpu_bmesh_vert_to_buffer_copy(BMVert *v, } if (show_vcol) { - ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX}; + const ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX}; GPU_vertbuf_attr_set(vert_buf, g_vbo_id.col, v_index, &vcol); } /* Add default face sets color to avoid artifacts. */ - uchar face_set[3] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX}; + const uchar face_set[3] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX}; GPU_vertbuf_attr_set(vert_buf, g_vbo_id.fset, v_index, &face_set); } @@ -1083,9 +1083,8 @@ GPUBatch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast, bool if (wires) { return (fast && buffers->lines_fast) ? buffers->lines_fast : buffers->lines; } - else { - return (fast && buffers->triangles_fast) ? buffers->triangles_fast : buffers->triangles; - } + + return (fast && buffers->triangles_fast) ? buffers->triangles_fast : buffers->triangles; } bool GPU_pbvh_buffers_has_overlays(GPU_PBVH_Buffers *buffers) diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 155179205c5..08d2779043e 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -41,7 +41,6 @@ #include "BKE_material.h" #include "GPU_extensions.h" -#include "GPU_glew.h" #include "GPU_material.h" #include "GPU_shader.h" #include "GPU_uniformbuffer.h" @@ -56,8 +55,8 @@ #include <stdarg.h> #include <string.h> +extern char datatoc_gpu_shader_codegen_lib_glsl[]; extern char datatoc_gpu_shader_common_obinfos_lib_glsl[]; -extern char datatoc_common_view_lib_glsl[]; /* -------------------- GPUPass Cache ------------------ */ /** @@ -221,79 +220,74 @@ static const char *gpu_builtin_name(eGPUBuiltin builtin) if (builtin == GPU_VIEW_MATRIX) { return "unfviewmat"; } - else if (builtin == GPU_OBJECT_MATRIX) { + if (builtin == GPU_OBJECT_MATRIX) { return "unfobmat"; } - else if (builtin == GPU_INVERSE_VIEW_MATRIX) { + if (builtin == GPU_INVERSE_VIEW_MATRIX) { return "unfinvviewmat"; } - else if (builtin == GPU_INVERSE_OBJECT_MATRIX) { + if (builtin == GPU_INVERSE_OBJECT_MATRIX) { return "unfinvobmat"; } - else if (builtin == GPU_LOC_TO_VIEW_MATRIX) { + if (builtin == GPU_LOC_TO_VIEW_MATRIX) { return "unflocaltoviewmat"; } - else if (builtin == GPU_INVERSE_LOC_TO_VIEW_MATRIX) { + if (builtin == GPU_INVERSE_LOC_TO_VIEW_MATRIX) { return "unfinvlocaltoviewmat"; } - else if (builtin == GPU_VIEW_POSITION) { + if (builtin == GPU_VIEW_POSITION) { return "varposition"; } - else if (builtin == GPU_WORLD_NORMAL) { + if (builtin == GPU_WORLD_NORMAL) { return "varwnormal"; } - else if (builtin == GPU_VIEW_NORMAL) { + if (builtin == GPU_VIEW_NORMAL) { return "varnormal"; } - else if (builtin == GPU_OBJECT_COLOR) { + if (builtin == GPU_OBJECT_COLOR) { return "unfobjectcolor"; } - else if (builtin == GPU_AUTO_BUMPSCALE) { + if (builtin == GPU_AUTO_BUMPSCALE) { return "unfobautobumpscale"; } - else if (builtin == GPU_CAMERA_TEXCO_FACTORS) { + if (builtin == GPU_CAMERA_TEXCO_FACTORS) { return "unfcameratexfactors"; } - else if (builtin == GPU_PARTICLE_SCALAR_PROPS) { + if (builtin == GPU_PARTICLE_SCALAR_PROPS) { return "unfparticlescalarprops"; } - else if (builtin == GPU_PARTICLE_LOCATION) { + if (builtin == GPU_PARTICLE_LOCATION) { return "unfparticleco"; } - else if (builtin == GPU_PARTICLE_VELOCITY) { + if (builtin == GPU_PARTICLE_VELOCITY) { return "unfparticlevel"; } - else if (builtin == GPU_PARTICLE_ANG_VELOCITY) { + if (builtin == GPU_PARTICLE_ANG_VELOCITY) { return "unfparticleangvel"; } - else if (builtin == GPU_OBJECT_INFO) { + if (builtin == GPU_OBJECT_INFO) { return "unfobjectinfo"; } - else if (builtin == GPU_BARYCENTRIC_TEXCO) { + if (builtin == GPU_BARYCENTRIC_TEXCO) { return "unfbarycentrictex"; } - else if (builtin == GPU_BARYCENTRIC_DIST) { + if (builtin == GPU_BARYCENTRIC_DIST) { return "unfbarycentricdist"; } - else { - return ""; - } + return ""; } static void codegen_set_unique_ids(GPUNodeGraph *graph) { - GPUNode *node; - GPUInput *input; - GPUOutput *output; int id = 1; - for (node = graph->nodes.first; node; node = node->next) { - for (input = node->inputs.first; input; input = input->next) { + LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) { + LISTBASE_FOREACH (GPUInput *, input, &node->inputs) { /* set id for unique names of uniform variables */ input->id = id++; } - for (output = node->outputs.first; output; output = output->next) { + LISTBASE_FOREACH (GPUOutput *, output, &node->outputs) { /* set id for unique names of tmp variables storing output */ output->id = id++; } @@ -307,17 +301,10 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds, GPUNodeGraph *graph) { - GPUNode *node; - GPUInput *input; const char *name; int builtins = 0; ListBase ubo_inputs = {NULL, NULL}; - /* Attributes */ - LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) { - BLI_dynstr_appendf(ds, "in %s var%d;\n", gpu_data_type_to_string(attr->gputype), attr->id); - } - /* Textures */ LISTBASE_FOREACH (GPUMaterialTexture *, tex, &graph->textures) { if (tex->colorband) { @@ -339,8 +326,9 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, } /* Print other uniforms */ - for (node = graph->nodes.first; node; node = node->next) { - for (input = node->inputs.first; input; input = input->next) { + + LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) { + LISTBASE_FOREACH (GPUInput *, input, &node->inputs) { if (input->source == GPU_SOURCE_BUILTIN) { /* only define each builtin uniform/varying once */ if (!(builtins & input->builtin)) { @@ -382,8 +370,8 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, BLI_dynstr_appendf(ds, "\nlayout (std140) uniform %s {\n", GPU_UBO_BLOCK_NAME); LISTBASE_FOREACH (LinkData *, link, &ubo_inputs) { - input = link->data; - BLI_dynstr_appendf(ds, "\t%s unf%d;\n", gpu_data_type_to_string(input->type), input->id); + GPUInput *input = (GPUInput *)(link->data); + BLI_dynstr_appendf(ds, " %s unf%d;\n", gpu_data_type_to_string(input->type), input->id); } BLI_dynstr_append(ds, "};\n"); BLI_freelistN(&ubo_inputs); @@ -396,34 +384,26 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, static void codegen_declare_tmps(DynStr *ds, GPUNodeGraph *graph) { - GPUNode *node; - GPUOutput *output; - - for (node = graph->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) { /* declare temporary variables for node output storage */ - for (output = node->outputs.first; output; output = output->next) { + LISTBASE_FOREACH (GPUOutput *, output, &node->outputs) { if (output->type == GPU_CLOSURE) { - BLI_dynstr_appendf(ds, "\tClosure tmp%d;\n", output->id); + BLI_dynstr_appendf(ds, " Closure tmp%d;\n", output->id); } else { - BLI_dynstr_appendf(ds, "\t%s tmp%d;\n", gpu_data_type_to_string(output->type), output->id); + BLI_dynstr_appendf(ds, " %s tmp%d;\n", gpu_data_type_to_string(output->type), output->id); } } } - BLI_dynstr_append(ds, "\n"); } static void codegen_call_functions(DynStr *ds, GPUNodeGraph *graph, GPUOutput *finaloutput) { - GPUNode *node; - GPUInput *input; - GPUOutput *output; + LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) { + BLI_dynstr_appendf(ds, " %s(", node->name); - for (node = graph->nodes.first; node; node = node->next) { - BLI_dynstr_appendf(ds, "\t%s(", node->name); - - for (input = node->inputs.first; input; input = input->next) { + LISTBASE_FOREACH (GPUInput *, input, &node->inputs) { if (input->source == GPU_SOURCE_TEX) { BLI_dynstr_append(ds, input->texture->sampler_name); } @@ -504,7 +484,7 @@ static void codegen_call_functions(DynStr *ds, GPUNodeGraph *graph, GPUOutput *f BLI_dynstr_append(ds, ", "); } - for (output = node->outputs.first; output; output = output->next) { + LISTBASE_FOREACH (GPUOutput *, output, &node->outputs) { BLI_dynstr_appendf(ds, "tmp%d", output->id); if (output->next) { BLI_dynstr_append(ds, ", "); @@ -514,21 +494,24 @@ static void codegen_call_functions(DynStr *ds, GPUNodeGraph *graph, GPUOutput *f BLI_dynstr_append(ds, ");\n"); } - BLI_dynstr_appendf(ds, "\n\treturn tmp%d", finaloutput->id); - BLI_dynstr_append(ds, ";\n"); + BLI_dynstr_appendf(ds, "\n return tmp%d;\n", finaloutput->id); } -static char *code_generate_fragment(GPUMaterial *material, GPUNodeGraph *graph) +static char *code_generate_fragment(GPUMaterial *material, + GPUNodeGraph *graph, + const char *interface_str) { DynStr *ds = BLI_dynstr_new(); char *code; int builtins; -#if 0 - BLI_dynstr_append(ds, FUNCTION_PROTOTYPES); -#endif - codegen_set_unique_ids(graph); + + /* Attributes, Shader stage interface. */ + if (interface_str) { + BLI_dynstr_appendf(ds, "in codegenInterface {%s};\n\n", interface_str); + } + builtins = codegen_process_uniforms_functions(material, ds, graph); if (builtins & (GPU_OBJECT_INFO | GPU_OBJECT_COLOR)) { @@ -536,73 +519,61 @@ static char *code_generate_fragment(GPUMaterial *material, GPUNodeGraph *graph) } if (builtins & GPU_BARYCENTRIC_TEXCO) { - BLI_dynstr_append(ds, "in vec2 barycentricTexCo;\n"); - } - - if (builtins & GPU_BARYCENTRIC_DIST) { - BLI_dynstr_append(ds, "flat in vec3 barycentricDist;\n"); + BLI_dynstr_append(ds, datatoc_gpu_shader_codegen_lib_glsl); } BLI_dynstr_append(ds, "Closure nodetree_exec(void)\n{\n"); if (builtins & GPU_BARYCENTRIC_TEXCO) { - BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n"); - BLI_dynstr_append(ds, - "\tvec2 barytexco = vec2((fract(barycentricTexCo.y) != 0.0)\n" - "\t ? barycentricTexCo.x\n" - "\t : 1.0 - barycentricTexCo.x,\n" - "\t 0.0);\n"); - BLI_dynstr_append(ds, "#else\n"); - BLI_dynstr_append(ds, "\tvec2 barytexco = barycentricTexCo;\n"); - BLI_dynstr_append(ds, "#endif\n"); + BLI_dynstr_append(ds, " vec2 barytexco = barycentric_resolve(barycentricTexCo);\n"); } /* TODO(fclem) get rid of that. */ if (builtins & GPU_VIEW_MATRIX) { - BLI_dynstr_append(ds, "\t#define viewmat ViewMatrix\n"); + BLI_dynstr_append(ds, " #define viewmat ViewMatrix\n"); } if (builtins & GPU_CAMERA_TEXCO_FACTORS) { - BLI_dynstr_append(ds, "\t#define camtexfac CameraTexCoFactors\n"); + BLI_dynstr_append(ds, " #define camtexfac CameraTexCoFactors\n"); } if (builtins & GPU_OBJECT_MATRIX) { - BLI_dynstr_append(ds, "\t#define objmat ModelMatrix\n"); + BLI_dynstr_append(ds, " #define objmat ModelMatrix\n"); } if (builtins & GPU_INVERSE_OBJECT_MATRIX) { - BLI_dynstr_append(ds, "\t#define objinv ModelMatrixInverse\n"); + BLI_dynstr_append(ds, " #define objinv ModelMatrixInverse\n"); } if (builtins & GPU_INVERSE_VIEW_MATRIX) { - BLI_dynstr_append(ds, "\t#define viewinv ViewMatrixInverse\n"); + BLI_dynstr_append(ds, " #define viewinv ViewMatrixInverse\n"); } if (builtins & GPU_LOC_TO_VIEW_MATRIX) { - BLI_dynstr_append(ds, "\t#define localtoviewmat (ViewMatrix * ModelMatrix)\n"); + BLI_dynstr_append(ds, " #define localtoviewmat (ViewMatrix * ModelMatrix)\n"); } if (builtins & GPU_INVERSE_LOC_TO_VIEW_MATRIX) { BLI_dynstr_append(ds, - "\t#define invlocaltoviewmat (ModelMatrixInverse * ViewMatrixInverse)\n"); + " #define invlocaltoviewmat (ModelMatrixInverse * ViewMatrixInverse)\n"); } if (builtins & GPU_VIEW_NORMAL) { BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n"); - BLI_dynstr_append(ds, "\tvec3 n;\n"); - BLI_dynstr_append(ds, "\tworld_normals_get(n);\n"); - BLI_dynstr_append(ds, "\tvec3 facingnormal = transform_direction(ViewMatrix, n);\n"); + BLI_dynstr_append(ds, " vec3 n;\n"); + BLI_dynstr_append(ds, " world_normals_get(n);\n"); + BLI_dynstr_append(ds, " vec3 facingnormal = transform_direction(ViewMatrix, n);\n"); BLI_dynstr_append(ds, "#else\n"); - BLI_dynstr_append(ds, "\tvec3 facingnormal = gl_FrontFacing ? viewNormal: -viewNormal;\n"); + BLI_dynstr_append(ds, " vec3 facingnormal = gl_FrontFacing ? viewNormal: -viewNormal;\n"); BLI_dynstr_append(ds, "#endif\n"); } if (builtins & GPU_WORLD_NORMAL) { - BLI_dynstr_append(ds, "\tvec3 facingwnormal;\n"); + BLI_dynstr_append(ds, " vec3 facingwnormal;\n"); if (builtins & GPU_VIEW_NORMAL) { BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n"); - BLI_dynstr_append(ds, "\tfacingwnormal = n;\n"); + BLI_dynstr_append(ds, " facingwnormal = n;\n"); BLI_dynstr_append(ds, "#else\n"); - BLI_dynstr_append(ds, "\tworld_normals_get(facingwnormal);\n"); + BLI_dynstr_append(ds, " world_normals_get(facingwnormal);\n"); BLI_dynstr_append(ds, "#endif\n"); } else { - BLI_dynstr_append(ds, "\tworld_normals_get(facingwnormal);\n"); + BLI_dynstr_append(ds, " world_normals_get(facingwnormal);\n"); } } if (builtins & GPU_VIEW_POSITION) { - BLI_dynstr_append(ds, "\t#define viewposition viewPosition\n"); + BLI_dynstr_append(ds, " #define viewposition viewPosition\n"); } codegen_declare_tmps(ds, graph); @@ -610,21 +581,6 @@ static char *code_generate_fragment(GPUMaterial *material, GPUNodeGraph *graph) BLI_dynstr_append(ds, "}\n"); - /* XXX This cannot go into gpu_shader_material.glsl because main() - * would be parsed and generate error */ - /* Old glsl mode compat. */ - /* TODO(fclem) This is only used by world shader now. get rid of it? */ - BLI_dynstr_append(ds, "#ifndef NODETREE_EXEC\n"); - BLI_dynstr_append(ds, "out vec4 fragColor;\n"); - BLI_dynstr_append(ds, "void main()\n"); - BLI_dynstr_append(ds, "{\n"); - BLI_dynstr_append(ds, "\tClosure cl = nodetree_exec();\n"); - BLI_dynstr_append(ds, - "\tfragColor = vec4(cl.radiance, " - "saturate(1.0 - avg(cl.transmittance)));\n"); - BLI_dynstr_append(ds, "}\n"); - BLI_dynstr_append(ds, "#endif\n\n"); - /* create shader */ code = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); @@ -659,23 +615,48 @@ static const char *attr_prefix_get(CustomDataType type) } } -static char *code_generate_vertex(GPUNodeGraph *graph, const char *vert_code, bool use_geom) +/* We talk about shader stage interface, not to be mistaken with GPUShaderInterface. */ +static char *code_generate_interface(GPUNodeGraph *graph, int builtins) { + if (BLI_listbase_is_empty(&graph->attributes) && + (builtins & (GPU_BARYCENTRIC_DIST | GPU_BARYCENTRIC_TEXCO)) == 0) { + return NULL; + } + DynStr *ds = BLI_dynstr_new(); - GPUNode *node; - GPUInput *input; - char *code; - int builtins = 0; - /* Hairs uv and col attributes are passed by bufferTextures. */ - BLI_dynstr_append(ds, - "#ifdef HAIR_SHADER\n" - "#define DEFINE_ATTR(type, attr) uniform samplerBuffer attr\n" - "#else\n" - "#define DEFINE_ATTR(type, attr) in type attr\n" - "#endif\n"); + BLI_dynstr_append(ds, "\n"); LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) { + BLI_dynstr_appendf(ds, "%s var%d;\n", gpu_data_type_to_string(attr->gputype), attr->id); + } + if (builtins & GPU_BARYCENTRIC_TEXCO) { + BLI_dynstr_append(ds, "vec2 barycentricTexCo;\n"); + } + if (builtins & GPU_BARYCENTRIC_DIST) { + BLI_dynstr_append(ds, "vec3 barycentricDist;\n"); + } + + char *code = BLI_dynstr_get_cstring(ds); + + BLI_dynstr_free(ds); + + return code; +} + +static char *code_generate_vertex(GPUNodeGraph *graph, + const char *interface_str, + const char *vert_code, + int builtins) +{ + DynStr *ds = BLI_dynstr_new(); + + BLI_dynstr_append(ds, datatoc_gpu_shader_codegen_lib_glsl); + + /* Inputs */ + LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) { + const char *type_str = gpu_data_type_to_string(attr->gputype); + const char *prefix = attr_prefix_get(attr->type); /* XXX FIXME : see notes in mesh_render_data_create() */ /* NOTE : Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */ if (attr->type == CD_ORCO) { @@ -684,188 +665,58 @@ static char *code_generate_vertex(GPUNodeGraph *graph, const char *vert_code, bo BLI_dynstr_append(ds, "DEFINE_ATTR(vec4, orco);\n"); } else if (attr->name[0] == '\0') { - BLI_dynstr_appendf(ds, - "DEFINE_ATTR(%s, %s);\n", - gpu_data_type_to_string(attr->gputype), - attr_prefix_get(attr->type)); - BLI_dynstr_appendf(ds, "#define att%d %s\n", attr->id, attr_prefix_get(attr->type)); + BLI_dynstr_appendf(ds, "DEFINE_ATTR(%s, %s);\n", type_str, prefix); + BLI_dynstr_appendf(ds, "#define att%d %s\n", attr->id, prefix); } else { char attr_safe_name[GPU_MAX_SAFE_ATTR_NAME]; GPU_vertformat_safe_attr_name(attr->name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME); - BLI_dynstr_appendf(ds, - "DEFINE_ATTR(%s, %s%s);\n", - gpu_data_type_to_string(attr->gputype), - attr_prefix_get(attr->type), - attr_safe_name); - BLI_dynstr_appendf( - ds, "#define att%d %s%s\n", attr->id, attr_prefix_get(attr->type), attr_safe_name); + BLI_dynstr_appendf(ds, "DEFINE_ATTR(%s, %s%s);\n", type_str, prefix, attr_safe_name); + BLI_dynstr_appendf(ds, "#define att%d %s%s\n", attr->id, prefix, attr_safe_name); } - BLI_dynstr_appendf(ds, - "out %s var%d%s;\n", - gpu_data_type_to_string(attr->gputype), - attr->id, - use_geom ? "g" : ""); - } - - for (node = graph->nodes.first; node; node = node->next) { - for (input = node->inputs.first; input; input = input->next) { - if (input->source == GPU_SOURCE_BUILTIN) { - builtins |= input->builtin; - } - } - } - - if (builtins & GPU_BARYCENTRIC_TEXCO) { - BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n"); - BLI_dynstr_appendf(ds, "out vec2 barycentricTexCo%s;\n", use_geom ? "g" : ""); - BLI_dynstr_append(ds, "#endif\n"); } - if (builtins & GPU_BARYCENTRIC_DIST) { - BLI_dynstr_append(ds, "out vec3 barycentricPosg;\n"); + /* Outputs interface */ + if (interface_str) { + BLI_dynstr_appendf(ds, "out codegenInterface {%s};\n\n", interface_str); } - BLI_dynstr_append(ds, "\n#define USE_ATTR\n"); - - /* Prototype, defined later (this is because of matrices definition). */ - BLI_dynstr_append(ds, "void pass_attr(in vec3 position);\n"); - - BLI_dynstr_append(ds, "\n"); - - if (use_geom) { - /* XXX HACK: Eevee specific. */ - char *vert_new, *vert_new2; - vert_new = BLI_str_replaceN(vert_code, "worldPosition", "worldPositiong"); - vert_new2 = vert_new; - vert_new = BLI_str_replaceN(vert_new2, "viewPosition", "viewPositiong"); - MEM_freeN(vert_new2); - vert_new2 = vert_new; - vert_new = BLI_str_replaceN(vert_new2, "worldNormal", "worldNormalg"); - MEM_freeN(vert_new2); - vert_new2 = vert_new; - vert_new = BLI_str_replaceN(vert_new2, "viewNormal", "viewNormalg"); - MEM_freeN(vert_new2); - - BLI_dynstr_append(ds, vert_new); - - MEM_freeN(vert_new); - } - else { - BLI_dynstr_append(ds, vert_code); - } + /* Prototype. Needed for hair functions. */ + BLI_dynstr_append(ds, "void pass_attr(vec3 position, mat3 normalmat, mat4 modelmatinv);\n"); + BLI_dynstr_append(ds, "#define USE_ATTR\n\n"); + BLI_dynstr_append(ds, vert_code); BLI_dynstr_append(ds, "\n"); - BLI_dynstr_append(ds, use_geom ? "RESOURCE_ID_VARYING_GEOM\n" : "RESOURCE_ID_VARYING\n"); - - /* Prototype because defined later. */ - BLI_dynstr_append(ds, - "vec2 hair_get_customdata_vec2(const samplerBuffer);\n" - "vec3 hair_get_customdata_vec3(const samplerBuffer);\n" - "vec4 hair_get_customdata_vec4(const samplerBuffer);\n" - "vec3 hair_get_strand_pos(void);\n" - "int hair_get_base_id(void);\n" - "\n"); - - BLI_dynstr_append(ds, "void pass_attr(in vec3 position) {\n"); - - BLI_dynstr_append(ds, use_geom ? "\tPASS_RESOURCE_ID_GEOM\n" : "\tPASS_RESOURCE_ID\n"); - - BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n"); - - if (builtins & GPU_BARYCENTRIC_TEXCO) { - /* To match cycles without breaking into individual segment we encode if we need to invert - * the first component into the second component. We invert if the barycentricTexCo.y - * is NOT 0.0 or 1.0. */ - BLI_dynstr_append(ds, "\tint _base_id = hair_get_base_id();\n"); - BLI_dynstr_appendf( - ds, "\tbarycentricTexCo%s.x = float((_base_id %% 2) == 1);\n", use_geom ? "g" : ""); - BLI_dynstr_appendf( - ds, "\tbarycentricTexCo%s.y = float(((_base_id %% 4) %% 3) > 0);\n", use_geom ? "g" : ""); - } - - if (builtins & GPU_BARYCENTRIC_DIST) { - BLI_dynstr_append(ds, "\tbarycentricPosg = position;\n"); - } - - LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) { - if (attr->type == CD_TANGENT) { - /* Not supported by hairs */ - BLI_dynstr_appendf(ds, "\tvar%d%s = vec4(0.0);\n", attr->id, use_geom ? "g" : ""); - } - else if (attr->type == CD_ORCO) { - BLI_dynstr_appendf(ds, - "\tvar%d%s = OrcoTexCoFactors[0].xyz + (ModelMatrixInverse * " - "vec4(hair_get_strand_pos(), 1.0)).xyz * OrcoTexCoFactors[1].xyz;\n", - attr->id, - use_geom ? "g" : ""); - /* TODO: fix ORCO with modifiers. */ - } - else { - BLI_dynstr_appendf(ds, - "\tvar%d%s = hair_get_customdata_%s(att%d);\n", - attr->id, - use_geom ? "g" : "", - gpu_data_type_to_string(attr->gputype), - attr->id); - } - } - - BLI_dynstr_append(ds, "#else /* MESH_SHADER */\n"); + BLI_dynstr_append(ds, "void pass_attr(vec3 position, mat3 normalmat, mat4 modelmatinv) {\n"); /* GPU_BARYCENTRIC_TEXCO cannot be computed based on gl_VertexID * for MESH_SHADER because of indexed drawing. In this case a * geometry shader is needed. */ - + if (builtins & GPU_BARYCENTRIC_TEXCO) { + BLI_dynstr_appendf(ds, " barycentricTexCo = barycentric_get();\n"); + } if (builtins & GPU_BARYCENTRIC_DIST) { - BLI_dynstr_append(ds, "\tbarycentricPosg = (ModelMatrix * vec4(position, 1.0)).xyz;\n"); + BLI_dynstr_appendf(ds, " barycentricDist = vec3(0);\n"); } LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) { if (attr->type == CD_TANGENT) { /* silly exception */ - BLI_dynstr_appendf(ds, - "\tvar%d%s.xyz = transpose(mat3(ModelMatrixInverse)) * att%d.xyz;\n", - attr->id, - use_geom ? "g" : "", - attr->id); - BLI_dynstr_appendf(ds, "\tvar%d%s.w = att%d.w;\n", attr->id, use_geom ? "g" : "", attr->id); - /* Normalize only if vector is not null. */ - BLI_dynstr_appendf(ds, - "\tfloat lvar%d = dot(var%d%s.xyz, var%d%s.xyz);\n", - attr->id, - attr->id, - use_geom ? "g" : "", - attr->id, - use_geom ? "g" : ""); - BLI_dynstr_appendf(ds, - "\tvar%d%s.xyz *= (lvar%d > 0.0) ? inversesqrt(lvar%d) : 1.0;\n", - attr->id, - use_geom ? "g" : "", - attr->id, - attr->id); + BLI_dynstr_appendf(ds, " var%d = tangent_get(att%d, normalmat);\n", attr->id, attr->id); } else if (attr->type == CD_ORCO) { - BLI_dynstr_appendf(ds, - "\tvar%d%s = OrcoTexCoFactors[0].xyz + position *" - " OrcoTexCoFactors[1].xyz;\n", - attr->id, - use_geom ? "g" : ""); - /* See mesh_create_loop_orco() for explanation. */ - BLI_dynstr_appendf(ds, - "\tif (orco.w == 0.0) { var%d%s = orco.xyz * 0.5 + 0.5; }\n", - attr->id, - use_geom ? "g" : ""); + BLI_dynstr_appendf( + ds, " var%d = orco_get(position, modelmatinv, OrcoTexCoFactors, orco);\n", attr->id); } else { - BLI_dynstr_appendf(ds, "\tvar%d%s = att%d;\n", attr->id, use_geom ? "g" : "", attr->id); + const char *type_str = gpu_data_type_to_string(attr->gputype); + BLI_dynstr_appendf(ds, " var%d = GET_ATTR(%s, att%d);\n", attr->id, type_str, attr->id); } } - BLI_dynstr_append(ds, "#endif /* HAIR_SHADER */\n"); BLI_dynstr_append(ds, "}\n"); - code = BLI_dynstr_get_cstring(ds); + char *code = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); @@ -879,146 +730,46 @@ static char *code_generate_vertex(GPUNodeGraph *graph, const char *vert_code, bo } static char *code_generate_geometry(GPUNodeGraph *graph, + const char *interface_str, const char *geom_code, - const char *defines) + int builtins) { - DynStr *ds = BLI_dynstr_new(); - GPUNode *node; - GPUInput *input; - char *code; - int builtins = 0; - - /* XXX we should not make specific eevee cases here. */ - bool is_hair_shader = (strstr(defines, "HAIR_SHADER") != NULL); - - /* Create prototype because attributes cannot be declared before layout. */ - BLI_dynstr_append(ds, "void pass_attr(in int vert);\n"); - BLI_dynstr_append(ds, "void calc_barycentric_distances(vec3 pos0, vec3 pos1, vec3 pos2);\n"); - BLI_dynstr_append(ds, "#define USE_ATTR\n"); - - /* Generate varying declarations. */ - for (node = graph->nodes.first; node; node = node->next) { - for (input = node->inputs.first; input; input = input->next) { - if (input->source == GPU_SOURCE_BUILTIN) { - builtins |= input->builtin; - } - } - } - - LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) { - BLI_dynstr_appendf(ds, "in %s var%dg[];\n", gpu_data_type_to_string(attr->gputype), attr->id); - BLI_dynstr_appendf(ds, "out %s var%d;\n", gpu_data_type_to_string(attr->gputype), attr->id); + if (!geom_code) { + return NULL; } - if (builtins & GPU_BARYCENTRIC_TEXCO) { - BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n"); - BLI_dynstr_append(ds, "in vec2 barycentricTexCog[];\n"); - BLI_dynstr_append(ds, "#endif\n"); - - BLI_dynstr_append(ds, "out vec2 barycentricTexCo;\n"); - } + DynStr *ds = BLI_dynstr_new(); - if (builtins & GPU_BARYCENTRIC_DIST) { - BLI_dynstr_append(ds, "in vec3 barycentricPosg[];\n"); - BLI_dynstr_append(ds, "flat out vec3 barycentricDist;\n"); + /* Attributes, Shader interface; */ + if (interface_str) { + BLI_dynstr_appendf(ds, "in codegenInterface {%s} dataAttrIn[];\n\n", interface_str); + BLI_dynstr_appendf(ds, "out codegenInterface {%s} dataAttrOut;\n\n", interface_str); } - if (geom_code == NULL) { - /* Force geometry usage if GPU_BARYCENTRIC_DIST or GPU_BARYCENTRIC_TEXCO are used. - * Note: GPU_BARYCENTRIC_TEXCO only requires it if the shader is not drawing hairs. */ - if ((builtins & (GPU_BARYCENTRIC_DIST | GPU_BARYCENTRIC_TEXCO)) == 0 || is_hair_shader) { - /* Early out */ - BLI_dynstr_free(ds); - return NULL; - } - else { - /* Force geom shader usage */ - /* TODO put in external file. */ - BLI_dynstr_append(ds, "layout(triangles) in;\n"); - BLI_dynstr_append(ds, "layout(triangle_strip, max_vertices=3) out;\n"); - - BLI_dynstr_append(ds, "in vec3 worldPositiong[];\n"); - BLI_dynstr_append(ds, "in vec3 viewPositiong[];\n"); - BLI_dynstr_append(ds, "in vec3 worldNormalg[];\n"); - BLI_dynstr_append(ds, "in vec3 viewNormalg[];\n"); - - BLI_dynstr_append(ds, "out vec3 worldPosition;\n"); - BLI_dynstr_append(ds, "out vec3 viewPosition;\n"); - BLI_dynstr_append(ds, "out vec3 worldNormal;\n"); - BLI_dynstr_append(ds, "out vec3 viewNormal;\n"); - - BLI_dynstr_append(ds, datatoc_common_view_lib_glsl); - - BLI_dynstr_append(ds, "void main(){\n"); - - if (builtins & GPU_BARYCENTRIC_DIST) { - BLI_dynstr_append(ds, - "\tcalc_barycentric_distances(barycentricPosg[0], barycentricPosg[1], " - "barycentricPosg[2]);\n"); - } - - for (int i = 0; i < 3; i++) { - BLI_dynstr_appendf(ds, "\tgl_Position = gl_in[%d].gl_Position;\n", i); - BLI_dynstr_appendf(ds, "\tgl_ClipDistance[0] = gl_in[%d].gl_ClipDistance[0];\n", i); - BLI_dynstr_appendf(ds, "\tpass_attr(%d);\n", i); - BLI_dynstr_append(ds, "\tEmitVertex();\n"); - } - BLI_dynstr_append(ds, "}\n"); - } - } - else { - BLI_dynstr_append(ds, geom_code); - } + BLI_dynstr_append(ds, datatoc_gpu_shader_codegen_lib_glsl); if (builtins & GPU_BARYCENTRIC_DIST) { - BLI_dynstr_append(ds, "void calc_barycentric_distances(vec3 pos0, vec3 pos1, vec3 pos2) {\n"); - BLI_dynstr_append(ds, "\tvec3 edge21 = pos2 - pos1;\n"); - BLI_dynstr_append(ds, "\tvec3 edge10 = pos1 - pos0;\n"); - BLI_dynstr_append(ds, "\tvec3 edge02 = pos0 - pos2;\n"); - BLI_dynstr_append(ds, "\tvec3 d21 = normalize(edge21);\n"); - BLI_dynstr_append(ds, "\tvec3 d10 = normalize(edge10);\n"); - BLI_dynstr_append(ds, "\tvec3 d02 = normalize(edge02);\n"); - - BLI_dynstr_append(ds, "\tfloat d = dot(d21, edge02);\n"); - BLI_dynstr_append(ds, "\tbarycentricDist.x = sqrt(dot(edge02, edge02) - d * d);\n"); - BLI_dynstr_append(ds, "\td = dot(d02, edge10);\n"); - BLI_dynstr_append(ds, "\tbarycentricDist.y = sqrt(dot(edge10, edge10) - d * d);\n"); - BLI_dynstr_append(ds, "\td = dot(d10, edge21);\n"); - BLI_dynstr_append(ds, "\tbarycentricDist.z = sqrt(dot(edge21, edge21) - d * d);\n"); - BLI_dynstr_append(ds, "}\n"); + /* geom_code should do something with this, but may not. */ + BLI_dynstr_append(ds, "#define DO_BARYCENTRIC_DISTANCES\n"); } - BLI_dynstr_append(ds, "RESOURCE_ID_VARYING\n"); - /* Generate varying assignments. */ - BLI_dynstr_append(ds, "void pass_attr(in int vert) {\n"); - - BLI_dynstr_append(ds, "\tPASS_RESOURCE_ID(vert)\n"); - - /* XXX HACK: Eevee specific. */ - if (geom_code == NULL) { - BLI_dynstr_append(ds, "\tworldPosition = worldPositiong[vert];\n"); - BLI_dynstr_append(ds, "\tviewPosition = viewPositiong[vert];\n"); - BLI_dynstr_append(ds, "\tworldNormal = worldNormalg[vert];\n"); - BLI_dynstr_append(ds, "\tviewNormal = viewNormalg[vert];\n"); - } + BLI_dynstr_append(ds, "#define USE_ATTR\n"); + BLI_dynstr_append(ds, "void pass_attr(const int vert) {\n"); if (builtins & GPU_BARYCENTRIC_TEXCO) { - BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n"); - BLI_dynstr_append(ds, "\tbarycentricTexCo = barycentricTexCog[vert];\n"); - BLI_dynstr_append(ds, "#else\n"); - BLI_dynstr_append(ds, "\tbarycentricTexCo.x = float((vert % 3) == 0);\n"); - BLI_dynstr_append(ds, "\tbarycentricTexCo.y = float((vert % 3) == 1);\n"); - BLI_dynstr_append(ds, "#endif\n"); + BLI_dynstr_append(ds, " dataAttrOut.barycentricTexCo = calc_barycentric_co(vert);\n"); } LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) { /* TODO let shader choose what to do depending on what the attribute is. */ - BLI_dynstr_appendf(ds, "\tvar%d = var%dg[vert];\n", attr->id, attr->id); + BLI_dynstr_appendf(ds, " dataAttrOut.var%d = dataAttrIn[vert].var%d;\n", attr->id, attr->id); } - BLI_dynstr_append(ds, "}\n"); + BLI_dynstr_append(ds, "}\n\n"); - code = BLI_dynstr_get_cstring(ds); + BLI_dynstr_append(ds, geom_code); + + char *code = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); return code; @@ -1048,8 +799,17 @@ GPUPass *GPU_generate_pass(GPUMaterial *material, * generated VBOs are ready to accept the future shader. */ gpu_node_graph_prune_unused(graph); + int builtins = 0; + LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) { + LISTBASE_FOREACH (GPUInput *, input, &node->inputs) { + if (input->source == GPU_SOURCE_BUILTIN) { + builtins |= input->builtin; + } + } + } /* generate code */ - char *fragmentgen = code_generate_fragment(material, graph); + char *interface_str = code_generate_interface(graph, builtins); + char *fragmentgen = code_generate_fragment(material, graph, interface_str); /* Cache lookup: Reuse shaders already compiled */ uint32_t hash = gpu_pass_hash(fragmentgen, defines, &graph->attributes); @@ -1057,6 +817,7 @@ GPUPass *GPU_generate_pass(GPUMaterial *material, if (pass_hash && (pass_hash->next == NULL || pass_hash->next->hash != hash)) { /* No collision, just return the pass. */ + MEM_SAFE_FREE(interface_str); MEM_freeN(fragmentgen); if (!gpu_pass_is_valid(pass_hash)) { /* Shader has already been created but failed to compile. */ @@ -1071,10 +832,11 @@ GPUPass *GPU_generate_pass(GPUMaterial *material, GSet *used_libraries = gpu_material_used_libraries(material); char *tmp = gpu_material_library_generate_code(used_libraries, frag_lib); - char *geometrycode = code_generate_geometry(graph, geom_code, defines); - char *vertexcode = code_generate_vertex(graph, vert_code, (geometrycode != NULL)); + char *geometrycode = code_generate_geometry(graph, interface_str, geom_code, builtins); + char *vertexcode = code_generate_vertex(graph, interface_str, vert_code, builtins); char *fragmentcode = BLI_strdupcat(tmp, fragmentgen); + MEM_SAFE_FREE(interface_str); MEM_freeN(fragmentgen); MEM_freeN(tmp); diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h index 1454edeb1e0..5d130d75d2c 100644 --- a/source/blender/gpu/intern/gpu_codegen.h +++ b/source/blender/gpu/intern/gpu_codegen.h @@ -25,6 +25,10 @@ #pragma once +#ifdef __cplusplus +extern "C" { +#endif + struct GPUMaterial; struct GPUNodeGraph; struct GPUOutput; @@ -61,3 +65,7 @@ void GPU_pass_release(GPUPass *pass); void gpu_codegen_init(void); void gpu_codegen_exit(void); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/gpu/intern/gpu_context.cpp b/source/blender/gpu/intern/gpu_context.cc index e6356580ea3..e6356580ea3 100644 --- a/source/blender/gpu/intern/gpu_context.cpp +++ b/source/blender/gpu/intern/gpu_context.cc diff --git a/source/blender/gpu/intern/gpu_debug.c b/source/blender/gpu/intern/gpu_debug.cc index f7d6236071d..f7d6236071d 100644 --- a/source/blender/gpu/intern/gpu_debug.c +++ b/source/blender/gpu/intern/gpu_debug.cc diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c deleted file mode 100644 index e5f49555265..00000000000 --- a/source/blender/gpu/intern/gpu_draw.c +++ /dev/null @@ -1,1469 +0,0 @@ -/* - * 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. - */ - -/** \file - * \ingroup gpu - * - * Utility functions for dealing with OpenGL texture & material context, - * mipmap generation and light objects. - * - * These are some obscure rendering functions shared between the game engine (not anymore) - * and the blender, in this module to avoid duplication - * and abstract them away from the rest a bit. - */ - -#include <string.h> - -#include "BLI_blenlib.h" -#include "BLI_boxpack_2d.h" -#include "BLI_linklist.h" -#include "BLI_math.h" -#include "BLI_threads.h" -#include "BLI_utildefines.h" - -#include "DNA_image_types.h" -#include "DNA_movieclip_types.h" -#include "DNA_userdef_types.h" - -#include "MEM_guardedalloc.h" - -#include "IMB_colormanagement.h" -#include "IMB_imbuf.h" -#include "IMB_imbuf_types.h" - -#include "BKE_global.h" -#include "BKE_image.h" -#include "BKE_main.h" -#include "BKE_movieclip.h" - -#include "GPU_draw.h" -#include "GPU_extensions.h" -#include "GPU_glew.h" -#include "GPU_matrix.h" -#include "GPU_platform.h" -#include "GPU_texture.h" - -#include "PIL_time.h" - -static void gpu_free_image(Image *ima, const bool immediate); -static void gpu_free_unused_buffers(void); - -//* Checking powers of two for images since OpenGL ES requires it */ -#ifdef WITH_DDS -static bool is_power_of_2_resolution(int w, int h) -{ - return is_power_of_2_i(w) && is_power_of_2_i(h); -} -#endif - -static bool is_over_resolution_limit(GLenum textarget, int w, int h) -{ - int size = (textarget == GL_TEXTURE_CUBE_MAP) ? GPU_max_cube_map_size() : GPU_max_texture_size(); - int reslimit = (U.glreslimit != 0) ? min_ii(U.glreslimit, size) : size; - - return (w > reslimit || h > reslimit); -} - -static int smaller_power_of_2_limit(int num) -{ - int reslimit = (U.glreslimit != 0) ? min_ii(U.glreslimit, GPU_max_texture_size()) : - GPU_max_texture_size(); - /* take texture clamping into account */ - if (num > reslimit) { - return reslimit; - } - - return power_of_2_min_i(num); -} - -/* Current OpenGL state caching for GPU_set_tpage */ - -static struct GPUTextureState { - /* also controls min/mag filtering */ - bool domipmap; - /* only use when 'domipmap' is set */ - bool linearmipmap; - /* store this so that new images created while texture painting won't be set to mipmapped */ - bool texpaint; - - float anisotropic; -} GTS = {1, 0, 0, 1.0f}; - -/* Mipmap settings */ - -void GPU_set_mipmap(Main *bmain, bool mipmap) -{ - if (GTS.domipmap != mipmap) { - GPU_free_images(bmain); - GTS.domipmap = mipmap; - } -} - -void GPU_set_linear_mipmap(bool linear) -{ - if (GTS.linearmipmap != linear) { - GTS.linearmipmap = linear; - } -} - -bool GPU_get_mipmap(void) -{ - return GTS.domipmap && !GTS.texpaint; -} - -bool GPU_get_linear_mipmap(void) -{ - return GTS.linearmipmap; -} - -static GLenum gpu_get_mipmap_filter(bool mag) -{ - /* linearmipmap is off by default *when mipmapping is off, - * use unfiltered display */ - if (mag) { - if (GTS.domipmap) { - return GL_LINEAR; - } - else { - return GL_NEAREST; - } - } - else { - if (GTS.domipmap) { - if (GTS.linearmipmap) { - return GL_LINEAR_MIPMAP_LINEAR; - } - else { - return GL_LINEAR_MIPMAP_NEAREST; - } - } - else { - return GL_NEAREST; - } - } -} - -/* Anisotropic filtering settings */ -void GPU_set_anisotropic(float value) -{ - if (GTS.anisotropic != value) { - GPU_samplers_free(); - - /* Clamp value to the maximum value the graphics card supports */ - const float max = GPU_max_texture_anisotropy(); - if (value > max) { - value = max; - } - - GTS.anisotropic = value; - - GPU_samplers_init(); - } -} - -float GPU_get_anisotropic(void) -{ - return GTS.anisotropic; -} - -/* Set OpenGL state for an MTFace */ - -static GPUTexture **gpu_get_image_gputexture(Image *ima, GLenum textarget, const int multiview_eye) -{ - if (textarget == GL_TEXTURE_2D) { - return &(ima->gputexture[TEXTARGET_TEXTURE_2D][multiview_eye]); - } - else if (textarget == GL_TEXTURE_CUBE_MAP) { - return &(ima->gputexture[TEXTARGET_TEXTURE_CUBE_MAP][multiview_eye]); - } - else if (textarget == GL_TEXTURE_2D_ARRAY) { - return &(ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][multiview_eye]); - } - else if (textarget == GL_TEXTURE_1D_ARRAY) { - return &(ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING][multiview_eye]); - } - - return NULL; -} - -static uint gpu_texture_create_tile_mapping(Image *ima, const int multiview_eye) -{ - GPUTexture *tilearray = ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][multiview_eye]; - - if (tilearray == NULL) { - return 0; - } - - float array_w = GPU_texture_width(tilearray); - float array_h = GPU_texture_height(tilearray); - - ImageTile *last_tile = ima->tiles.last; - /* Tiles are sorted by number. */ - int max_tile = last_tile->tile_number - 1001; - - /* create image */ - int bindcode; - glGenTextures(1, (GLuint *)&bindcode); - glBindTexture(GL_TEXTURE_1D_ARRAY, bindcode); - - int width = max_tile + 1; - float *data = MEM_callocN(width * 8 * sizeof(float), __func__); - for (int i = 0; i < width; i++) { - data[4 * i] = -1.0f; - } - LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { - int i = tile->tile_number - 1001; - data[4 * i] = tile->runtime.tilearray_layer; - - float *tile_info = &data[4 * width + 4 * i]; - tile_info[0] = tile->runtime.tilearray_offset[0] / array_w; - tile_info[1] = tile->runtime.tilearray_offset[1] / array_h; - tile_info[2] = tile->runtime.tilearray_size[0] / array_w; - tile_info[3] = tile->runtime.tilearray_size[1] / array_h; - } - - glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, GL_RGBA32F, width, 2, 0, GL_RGBA, GL_FLOAT, data); - MEM_freeN(data); - - glTexParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - glBindTexture(GL_TEXTURE_1D_ARRAY, 0); - - return bindcode; -} - -typedef struct PackTile { - FixedSizeBoxPack boxpack; - ImageTile *tile; - float pack_score; -} PackTile; - -static int compare_packtile(const void *a, const void *b) -{ - const PackTile *tile_a = a; - const PackTile *tile_b = b; - - return tile_a->pack_score < tile_b->pack_score; -} - -static uint gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf) -{ - int arraywidth = 0, arrayheight = 0; - - ListBase boxes = {NULL}; - - LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { - ImageUser iuser; - BKE_imageuser_default(&iuser); - iuser.tile = tile->tile_number; - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); - - if (ibuf) { - PackTile *packtile = MEM_callocN(sizeof(PackTile), __func__); - packtile->tile = tile; - packtile->boxpack.w = ibuf->x; - packtile->boxpack.h = ibuf->y; - - if (is_over_resolution_limit( - GL_TEXTURE_2D_ARRAY, packtile->boxpack.w, packtile->boxpack.h)) { - packtile->boxpack.w = smaller_power_of_2_limit(packtile->boxpack.w); - packtile->boxpack.h = smaller_power_of_2_limit(packtile->boxpack.h); - } - arraywidth = max_ii(arraywidth, packtile->boxpack.w); - arrayheight = max_ii(arrayheight, packtile->boxpack.h); - - /* We sort the tiles by decreasing size, with an additional penalty term - * for high aspect ratios. This improves packing efficiency. */ - float w = packtile->boxpack.w, h = packtile->boxpack.h; - packtile->pack_score = max_ff(w, h) / min_ff(w, h) * w * h; - - BKE_image_release_ibuf(ima, ibuf, NULL); - BLI_addtail(&boxes, packtile); - } - } - - BLI_assert(arraywidth > 0 && arrayheight > 0); - - BLI_listbase_sort(&boxes, compare_packtile); - int arraylayers = 0; - /* Keep adding layers until all tiles are packed. */ - while (boxes.first != NULL) { - ListBase packed = {NULL}; - BLI_box_pack_2d_fixedarea(&boxes, arraywidth, arrayheight, &packed); - BLI_assert(packed.first != NULL); - - LISTBASE_FOREACH (PackTile *, packtile, &packed) { - ImageTile *tile = packtile->tile; - int *tileoffset = tile->runtime.tilearray_offset; - int *tilesize = tile->runtime.tilearray_size; - - tileoffset[0] = packtile->boxpack.x; - tileoffset[1] = packtile->boxpack.y; - tilesize[0] = packtile->boxpack.w; - tilesize[1] = packtile->boxpack.h; - tile->runtime.tilearray_layer = arraylayers; - } - - BLI_freelistN(&packed); - arraylayers++; - } - - /* create image */ - int bindcode; - glGenTextures(1, (GLuint *)&bindcode); - glBindTexture(GL_TEXTURE_2D_ARRAY, bindcode); - - GLenum data_type, internal_format; - if (main_ibuf->rect_float) { - data_type = GL_FLOAT; - internal_format = (!(main_ibuf->flags & IB_halffloat) && (ima->flag & IMA_HIGH_BITDEPTH)) ? - GL_RGBA32F : - GL_RGBA16F; - } - else { - data_type = GL_UNSIGNED_BYTE; - internal_format = GL_RGBA8; - if (!IMB_colormanagement_space_is_data(main_ibuf->rect_colorspace) && - !IMB_colormanagement_space_is_scene_linear(main_ibuf->rect_colorspace)) { - internal_format = GL_SRGB8_ALPHA8; - } - } - - glTexImage3D(GL_TEXTURE_2D_ARRAY, - 0, - internal_format, - arraywidth, - arrayheight, - arraylayers, - 0, - GL_RGBA, - data_type, - NULL); - - LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { - int tilelayer = tile->runtime.tilearray_layer; - int *tileoffset = tile->runtime.tilearray_offset; - int *tilesize = tile->runtime.tilearray_size; - - if (tilesize[0] == 0 || tilesize[1] == 0) { - continue; - } - - ImageUser iuser; - BKE_imageuser_default(&iuser); - iuser.tile = tile->tile_number; - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); - - if (ibuf) { - bool needs_scale = (ibuf->x != tilesize[0] || ibuf->y != tilesize[1]); - - ImBuf *scale_ibuf = NULL; - if (ibuf->rect_float) { - float *rect_float = ibuf->rect_float; - - const bool store_premultiplied = ima->alpha_mode != IMA_ALPHA_STRAIGHT; - if (ibuf->channels != 4 || !store_premultiplied) { - rect_float = MEM_mallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, __func__); - IMB_colormanagement_imbuf_to_float_texture( - rect_float, 0, 0, ibuf->x, ibuf->y, ibuf, store_premultiplied); - } - - float *pixeldata = rect_float; - if (needs_scale) { - scale_ibuf = IMB_allocFromBuffer(NULL, rect_float, ibuf->x, ibuf->y, 4); - IMB_scaleImBuf(scale_ibuf, tilesize[0], tilesize[1]); - pixeldata = scale_ibuf->rect_float; - } - - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, - 0, - tileoffset[0], - tileoffset[1], - tilelayer, - tilesize[0], - tilesize[1], - 1, - GL_RGBA, - GL_FLOAT, - pixeldata); - - if (rect_float != ibuf->rect_float) { - MEM_freeN(rect_float); - } - } - else { - unsigned int *rect = ibuf->rect; - - if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) { - rect = MEM_mallocN(sizeof(uchar) * 4 * ibuf->x * ibuf->y, __func__); - IMB_colormanagement_imbuf_to_byte_texture((uchar *)rect, - 0, - 0, - ibuf->x, - ibuf->y, - ibuf, - internal_format == GL_SRGB8_ALPHA8, - ima->alpha_mode == IMA_ALPHA_PREMUL); - } - - unsigned int *pixeldata = rect; - if (needs_scale) { - scale_ibuf = IMB_allocFromBuffer(rect, NULL, ibuf->x, ibuf->y, 4); - IMB_scaleImBuf(scale_ibuf, tilesize[0], tilesize[1]); - pixeldata = scale_ibuf->rect; - } - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, - 0, - tileoffset[0], - tileoffset[1], - tilelayer, - tilesize[0], - tilesize[1], - 1, - GL_RGBA, - GL_UNSIGNED_BYTE, - pixeldata); - - if (rect != ibuf->rect) { - MEM_freeN(rect); - } - } - if (scale_ibuf != NULL) { - IMB_freeImBuf(scale_ibuf); - } - } - - BKE_image_release_ibuf(ima, ibuf, NULL); - } - - if (GPU_get_mipmap()) { - glGenerateMipmap(GL_TEXTURE_2D_ARRAY); - if (ima) { - ima->gpuflag |= IMA_GPU_MIPMAP_COMPLETE; - } - } - - glBindTexture(GL_TEXTURE_2D_ARRAY, 0); - - return bindcode; -} - -static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget) -{ - uint bindcode = 0; - const bool mipmap = GPU_get_mipmap(); - const bool half_float = (ibuf->flags & IB_halffloat) != 0; - -#ifdef WITH_DDS - if (ibuf->ftype == IMB_FTYPE_DDS) { - /* DDS is loaded directly in compressed form. */ - GPU_create_gl_tex_compressed(&bindcode, textarget, ima, ibuf); - return bindcode; - } -#endif - - /* Regular uncompressed texture. */ - float *rect_float = ibuf->rect_float; - uchar *rect = (uchar *)ibuf->rect; - bool compress_as_srgb = false; - - if (rect_float == NULL) { - /* Byte image is in original colorspace from the file. If the file is sRGB - * scene linear, or non-color data no conversion is needed. Otherwise we - * compress as scene linear + sRGB transfer function to avoid precision loss - * in common cases. - * - * We must also convert to premultiplied for correct texture interpolation - * and consistency with float images. */ - if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) { - compress_as_srgb = !IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace); - - rect = MEM_mallocN(sizeof(uchar) * 4 * ibuf->x * ibuf->y, __func__); - if (rect == NULL) { - return bindcode; - } - - /* Texture storage of images is defined by the alpha mode of the image. The - * downside of this is that there can be artifacts near alpha edges. However, - * this allows us to use sRGB texture formats and preserves color values in - * zero alpha areas, and appears generally closer to what game engines that we - * want to be compatible with do. */ - const bool store_premultiplied = ima ? (ima->alpha_mode == IMA_ALPHA_PREMUL) : true; - IMB_colormanagement_imbuf_to_byte_texture( - rect, 0, 0, ibuf->x, ibuf->y, ibuf, compress_as_srgb, store_premultiplied); - } - } - else { - /* Float image is already in scene linear colorspace or non-color data by - * convention, no colorspace conversion needed. But we do require 4 channels - * currently. */ - const bool store_premultiplied = ima ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) : false; - - if (ibuf->channels != 4 || !store_premultiplied) { - rect_float = MEM_mallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, __func__); - if (rect_float == NULL) { - return bindcode; - } - IMB_colormanagement_imbuf_to_float_texture( - rect_float, 0, 0, ibuf->x, ibuf->y, ibuf, store_premultiplied); - } - } - - /* Create OpenGL texture. */ - GPU_create_gl_tex(&bindcode, - (uint *)rect, - rect_float, - ibuf->x, - ibuf->y, - textarget, - mipmap, - half_float, - compress_as_srgb, - ima); - - /* Free buffers if needed. */ - if (rect && rect != (uchar *)ibuf->rect) { - MEM_freeN(rect); - } - if (rect_float && rect_float != ibuf->rect_float) { - MEM_freeN(rect_float); - } - - return bindcode; -} - -static GPUTexture **gpu_get_movieclip_gputexture(MovieClip *clip, - MovieClipUser *cuser, - GLenum textarget) -{ - MovieClip_RuntimeGPUTexture *tex; - for (tex = clip->runtime.gputextures.first; tex; tex = tex->next) { - if (memcmp(&tex->user, cuser, sizeof(MovieClipUser)) == 0) { - break; - } - } - - if (tex == NULL) { - tex = MEM_mallocN(sizeof(MovieClip_RuntimeGPUTexture), __func__); - - for (int i = 0; i < TEXTARGET_COUNT; i++) { - tex->gputexture[i] = NULL; - } - - memcpy(&tex->user, cuser, sizeof(MovieClipUser)); - BLI_addtail(&clip->runtime.gputextures, tex); - } - - if (textarget == GL_TEXTURE_2D) { - return &tex->gputexture[TEXTARGET_TEXTURE_2D]; - } - else if (textarget == GL_TEXTURE_CUBE_MAP) { - return &tex->gputexture[TEXTARGET_TEXTURE_CUBE_MAP]; - } - - return NULL; -} - -static ImBuf *update_do_scale(uchar *rect, - float *rect_float, - int *x, - int *y, - int *w, - int *h, - int limit_w, - int limit_h, - int full_w, - int full_h) -{ - /* Partial update with scaling. */ - float xratio = limit_w / (float)full_w; - float yratio = limit_h / (float)full_h; - - int part_w = *w, part_h = *h; - - /* Find sub coordinates in scaled image. Take ceiling because we will be - * losing 1 pixel due to rounding errors in x,y. */ - *x *= xratio; - *y *= yratio; - *w = (int)ceil(xratio * (*w)); - *h = (int)ceil(yratio * (*h)); - - /* ...but take back if we are over the limit! */ - if (*x + *w > limit_w) { - (*w)--; - } - if (*y + *h > limit_h) { - (*h)--; - } - - /* Scale pixels. */ - ImBuf *ibuf = IMB_allocFromBuffer((uint *)rect, rect_float, part_w, part_h, 4); - IMB_scaleImBuf(ibuf, *w, *h); - - return ibuf; -} - -static void gpu_texture_update_scaled_array(uchar *rect, - float *rect_float, - int full_w, - int full_h, - int x, - int y, - int layer, - const int *tile_offset, - const int *tile_size, - int w, - int h) -{ - ImBuf *ibuf = update_do_scale( - rect, rect_float, &x, &y, &w, &h, tile_size[0], tile_size[1], full_w, full_h); - - /* Shift to account for tile packing. */ - x += tile_offset[0]; - y += tile_offset[1]; - - if (ibuf->rect_float) { - glTexSubImage3D( - GL_TEXTURE_2D_ARRAY, 0, x, y, layer, w, h, 1, GL_RGBA, GL_FLOAT, ibuf->rect_float); - } - else { - glTexSubImage3D( - GL_TEXTURE_2D_ARRAY, 0, x, y, layer, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); - } - - IMB_freeImBuf(ibuf); -} - -static void gpu_texture_update_scaled( - uchar *rect, float *rect_float, int full_w, int full_h, int x, int y, int w, int h) -{ - /* Partial update with scaling. */ - int limit_w = smaller_power_of_2_limit(full_w); - int limit_h = smaller_power_of_2_limit(full_h); - - ImBuf *ibuf = update_do_scale( - rect, rect_float, &x, &y, &w, &h, limit_w, limit_h, full_w, full_h); - - if (ibuf->rect_float) { - glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_FLOAT, ibuf->rect_float); - } - else { - glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); - } - - IMB_freeImBuf(ibuf); -} - -static void gpu_texture_update_unscaled(uchar *rect, - float *rect_float, - int x, - int y, - int layer, - int w, - int h, - GLint tex_stride, - GLint tex_offset) -{ - /* Partial update without scaling. Stride and offset are used to copy only a - * subset of a possible larger buffer than what we are updating. */ - GPU_unpack_row_length_set(tex_stride); - - if (layer >= 0) { - if (rect_float == NULL) { - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, - 0, - x, - y, - layer, - w, - h, - 1, - GL_RGBA, - GL_UNSIGNED_BYTE, - rect + tex_offset); - } - else { - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, - 0, - x, - y, - layer, - w, - h, - 1, - GL_RGBA, - GL_FLOAT, - rect_float + tex_offset); - } - } - else { - if (rect_float == NULL) { - glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rect + tex_offset); - } - else { - glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_FLOAT, rect_float + tex_offset); - } - } - - /* Restore default. */ - GPU_unpack_row_length_set(0); -} - -static void gpu_texture_update_from_ibuf( - GPUTexture *tex, Image *ima, ImBuf *ibuf, ImageTile *tile, int x, int y, int w, int h) -{ - /* Partial update of texture for texture painting. This is often much - * quicker than fully updating the texture for high resolution images. */ - GPU_texture_bind(tex, 0); - - bool scaled; - if (tile != NULL) { - int *tilesize = tile->runtime.tilearray_size; - scaled = (ibuf->x != tilesize[0]) || (ibuf->y != tilesize[1]); - } - else { - scaled = is_over_resolution_limit(GL_TEXTURE_2D, ibuf->x, ibuf->y); - } - - if (scaled) { - /* Extra padding to account for bleed from neighboring pixels. */ - const int padding = 4; - const int xmax = min_ii(x + w + padding, ibuf->x); - const int ymax = min_ii(y + h + padding, ibuf->y); - x = max_ii(x - padding, 0); - y = max_ii(y - padding, 0); - w = xmax - x; - h = ymax - y; - } - - /* Get texture data pointers. */ - float *rect_float = ibuf->rect_float; - uchar *rect = (uchar *)ibuf->rect; - GLint tex_stride = ibuf->x; - GLint tex_offset = ibuf->channels * (y * ibuf->x + x); - - if (rect_float == NULL) { - /* Byte pixels. */ - if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) { - const bool compress_as_srgb = !IMB_colormanagement_space_is_scene_linear( - ibuf->rect_colorspace); - - rect = MEM_mallocN(sizeof(uchar) * 4 * w * h, __func__); - if (rect == NULL) { - return; - } - - tex_stride = w; - tex_offset = 0; - - /* Convert to scene linear with sRGB compression, and premultiplied for - * correct texture interpolation. */ - const bool store_premultiplied = (ima->alpha_mode == IMA_ALPHA_PREMUL); - IMB_colormanagement_imbuf_to_byte_texture( - rect, x, y, w, h, ibuf, compress_as_srgb, store_premultiplied); - } - } - else { - /* Float pixels. */ - const bool store_premultiplied = (ima->alpha_mode != IMA_ALPHA_STRAIGHT); - - if (ibuf->channels != 4 || scaled || !store_premultiplied) { - rect_float = MEM_mallocN(sizeof(float) * 4 * w * h, __func__); - if (rect_float == NULL) { - return; - } - - tex_stride = w; - tex_offset = 0; - - IMB_colormanagement_imbuf_to_float_texture( - rect_float, x, y, w, h, ibuf, store_premultiplied); - } - } - - if (scaled) { - /* Slower update where we first have to scale the input pixels. */ - if (tile != NULL) { - int *tileoffset = tile->runtime.tilearray_offset; - int *tilesize = tile->runtime.tilearray_size; - int tilelayer = tile->runtime.tilearray_layer; - gpu_texture_update_scaled_array( - rect, rect_float, ibuf->x, ibuf->y, x, y, tilelayer, tileoffset, tilesize, w, h); - } - else { - gpu_texture_update_scaled(rect, rect_float, ibuf->x, ibuf->y, x, y, w, h); - } - } - else { - /* Fast update at same resolution. */ - if (tile != NULL) { - int *tileoffset = tile->runtime.tilearray_offset; - int tilelayer = tile->runtime.tilearray_layer; - gpu_texture_update_unscaled(rect, - rect_float, - x + tileoffset[0], - y + tileoffset[1], - tilelayer, - w, - h, - tex_stride, - tex_offset); - } - else { - gpu_texture_update_unscaled(rect, rect_float, x, y, -1, w, h, tex_stride, tex_offset); - } - } - - /* Free buffers if needed. */ - if (rect && rect != (uchar *)ibuf->rect) { - MEM_freeN(rect); - } - if (rect_float && rect_float != ibuf->rect_float) { - MEM_freeN(rect_float); - } - - if (GPU_get_mipmap()) { - glGenerateMipmap((tile != NULL) ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D); - } - else { - ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE; - } - - GPU_texture_unbind(tex); -} - -/* Get the GPUTexture for a given `Image`. - * - * `iuser` and `ibuf` are mutual exclusive parameters. The caller can pass the `ibuf` when already - * available. It is also required when requesting the GPUTexture for a render result. */ -GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, ImBuf *ibuf, int textarget) -{ -#ifndef GPU_STANDALONE - if (ima == NULL) { - return NULL; - } - - /* Free any unused GPU textures, since we know we are in a thread with OpenGL - * context and might as well ensure we have as much space free as possible. */ - gpu_free_unused_buffers(); - - /* currently, gpu refresh tagging is used by ima sequences */ - if (ima->gpuflag & IMA_GPU_REFRESH) { - gpu_free_image(ima, true); - ima->gpuflag &= ~IMA_GPU_REFRESH; - } - - /* Tag as in active use for garbage collector. */ - BKE_image_tag_time(ima); - - /* Test if we already have a texture. */ - GPUTexture **tex = gpu_get_image_gputexture(ima, textarget, iuser ? iuser->multiview_eye : 0); - if (*tex) { - return *tex; - } - - /* Check if we have a valid image. If not, we return a dummy - * texture with zero bindcode so we don't keep trying. */ - uint bindcode = 0; - ImageTile *tile = BKE_image_get_tile(ima, 0); - if (tile == NULL || tile->ok == 0) { - *tex = GPU_texture_from_bindcode(textarget, bindcode); - return *tex; - } - - /* check if we have a valid image buffer */ - ImBuf *ibuf_intern = ibuf; - if (ibuf_intern == NULL) { - ibuf_intern = BKE_image_acquire_ibuf(ima, iuser, NULL); - if (ibuf_intern == NULL) { - *tex = GPU_texture_from_bindcode(textarget, bindcode); - return *tex; - } - } - - if (textarget == GL_TEXTURE_2D_ARRAY) { - bindcode = gpu_texture_create_tile_array(ima, ibuf_intern); - } - else if (textarget == GL_TEXTURE_1D_ARRAY) { - bindcode = gpu_texture_create_tile_mapping(ima, iuser ? iuser->multiview_eye : 0); - } - else { - bindcode = gpu_texture_create_from_ibuf(ima, ibuf_intern, textarget); - } - - /* if `ibuf` was given, we don't own the `ibuf_intern` */ - if (ibuf == NULL) { - BKE_image_release_ibuf(ima, ibuf_intern, NULL); - } - - *tex = GPU_texture_from_bindcode(textarget, bindcode); - - GPU_texture_orig_size_set(*tex, ibuf_intern->x, ibuf_intern->y); - - if (textarget == GL_TEXTURE_1D_ARRAY) { - /* Special for tile mapping. */ - GPU_texture_mipmap_mode(*tex, false, false); - } - - return *tex; -#endif - return NULL; -} - -GPUTexture *GPU_texture_from_movieclip(MovieClip *clip, MovieClipUser *cuser, int textarget) -{ -#ifndef GPU_STANDALONE - if (clip == NULL) { - return NULL; - } - - GPUTexture **tex = gpu_get_movieclip_gputexture(clip, cuser, textarget); - if (*tex) { - return *tex; - } - - /* check if we have a valid image buffer */ - uint bindcode = 0; - ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, cuser); - if (ibuf == NULL) { - *tex = GPU_texture_from_bindcode(textarget, bindcode); - return *tex; - } - - bindcode = gpu_texture_create_from_ibuf(NULL, ibuf, textarget); - IMB_freeImBuf(ibuf); - - *tex = GPU_texture_from_bindcode(textarget, bindcode); - return *tex; -#else - return NULL; -#endif -} - -void GPU_free_texture_movieclip(struct MovieClip *clip) -{ - /* number of gpu textures to keep around as cache - * We don't want to keep too many GPU textures for - * movie clips around, as they can be large.*/ - const int MOVIECLIP_NUM_GPUTEXTURES = 1; - - while (BLI_listbase_count(&clip->runtime.gputextures) > MOVIECLIP_NUM_GPUTEXTURES) { - MovieClip_RuntimeGPUTexture *tex = BLI_pophead(&clip->runtime.gputextures); - for (int i = 0; i < TEXTARGET_COUNT; i++) { - /* free glsl image binding */ - if (tex->gputexture[i]) { - GPU_texture_free(tex->gputexture[i]); - tex->gputexture[i] = NULL; - } - } - MEM_freeN(tex); - } -} - -static void **gpu_gen_cube_map(uint *rect, float *frect, int rectw, int recth) -{ - size_t block_size = frect ? sizeof(float[4]) : sizeof(uchar[4]); - void **sides = NULL; - int h = recth / 2; - int w = rectw / 3; - - if (w != h) { - return sides; - } - - /* PosX, NegX, PosY, NegY, PosZ, NegZ */ - sides = MEM_mallocN(sizeof(void *) * 6, ""); - for (int i = 0; i < 6; i++) { - sides[i] = MEM_mallocN(block_size * w * h, ""); - } - - /* divide image into six parts */ - /* ______________________ - * | | | | - * | NegX | NegY | PosX | - * |______|______|______| - * | | | | - * | NegZ | PosZ | PosY | - * |______|______|______| - */ - if (frect) { - float(*frectb)[4] = (float(*)[4])frect; - float(**fsides)[4] = (float(**)[4])sides; - - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - memcpy(&fsides[0][x * h + y], &frectb[(recth - y - 1) * rectw + 2 * w + x], block_size); - memcpy(&fsides[1][x * h + y], &frectb[(y + h) * rectw + w - 1 - x], block_size); - memcpy( - &fsides[3][y * w + x], &frectb[(recth - y - 1) * rectw + 2 * w - 1 - x], block_size); - memcpy(&fsides[5][y * w + x], &frectb[(h - y - 1) * rectw + w - 1 - x], block_size); - } - memcpy(&fsides[2][y * w], frectb[y * rectw + 2 * w], block_size * w); - memcpy(&fsides[4][y * w], frectb[y * rectw + w], block_size * w); - } - } - else { - uint **isides = (uint **)sides; - - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - isides[0][x * h + y] = rect[(recth - y - 1) * rectw + 2 * w + x]; - isides[1][x * h + y] = rect[(y + h) * rectw + w - 1 - x]; - isides[3][y * w + x] = rect[(recth - y - 1) * rectw + 2 * w - 1 - x]; - isides[5][y * w + x] = rect[(h - y - 1) * rectw + w - 1 - x]; - } - memcpy(&isides[2][y * w], &rect[y * rectw + 2 * w], block_size * w); - memcpy(&isides[4][y * w], &rect[y * rectw + w], block_size * w); - } - } - - return sides; -} - -static void gpu_del_cube_map(void **cube_map) -{ - int i; - if (cube_map == NULL) { - return; - } - for (i = 0; i < 6; i++) { - MEM_freeN(cube_map[i]); - } - MEM_freeN(cube_map); -} - -/* Image *ima can be NULL */ -void GPU_create_gl_tex(uint *bind, - uint *rect, - float *frect, - int rectw, - int recth, - int textarget, - bool mipmap, - bool half_float, - bool use_srgb, - Image *ima) -{ - ImBuf *ibuf = NULL; - - if (textarget == GL_TEXTURE_2D && is_over_resolution_limit(textarget, rectw, recth)) { - int tpx = rectw; - int tpy = recth; - rectw = smaller_power_of_2_limit(rectw); - recth = smaller_power_of_2_limit(recth); - - if (frect) { - ibuf = IMB_allocFromBuffer(NULL, frect, tpx, tpy, 4); - IMB_scaleImBuf(ibuf, rectw, recth); - - frect = ibuf->rect_float; - } - else { - ibuf = IMB_allocFromBuffer(rect, NULL, tpx, tpy, 4); - IMB_scaleImBuf(ibuf, rectw, recth); - - rect = ibuf->rect; - } - } - - /* create image */ - glGenTextures(1, (GLuint *)bind); - glBindTexture(textarget, *bind); - - GLenum float_format = (!half_float && (ima && (ima->flag & IMA_HIGH_BITDEPTH))) ? GL_RGBA32F : - GL_RGBA16F; - GLenum internal_format = (frect) ? float_format : (use_srgb) ? GL_SRGB8_ALPHA8 : GL_RGBA8; - - if (textarget == GL_TEXTURE_2D) { - if (frect) { - glTexImage2D(GL_TEXTURE_2D, 0, internal_format, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect); - } - else { - glTexImage2D( - GL_TEXTURE_2D, 0, internal_format, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect); - } - - if (GPU_get_mipmap() && mipmap) { - glGenerateMipmap(GL_TEXTURE_2D); - if (ima) { - ima->gpuflag |= IMA_GPU_MIPMAP_COMPLETE; - } - } - } - else if (textarget == GL_TEXTURE_CUBE_MAP) { - int w = rectw / 3, h = recth / 2; - - if (h == w && is_power_of_2_i(h) && !is_over_resolution_limit(textarget, h, w)) { - void **cube_map = gpu_gen_cube_map(rect, frect, rectw, recth); - GLenum type = frect ? GL_FLOAT : GL_UNSIGNED_BYTE; - - if (cube_map) { - for (int i = 0; i < 6; i++) { - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, - 0, - internal_format, - w, - h, - 0, - GL_RGBA, - type, - cube_map[i]); - } - } - - if (GPU_get_mipmap() && mipmap) { - glGenerateMipmap(GL_TEXTURE_CUBE_MAP); - - if (ima) { - ima->gpuflag |= IMA_GPU_MIPMAP_COMPLETE; - } - } - - gpu_del_cube_map(cube_map); - } - else { - printf("Incorrect envmap size\n"); - } - } - - glBindTexture(textarget, 0); - - if (ibuf) { - IMB_freeImBuf(ibuf); - } -} - -/** - * GPU_upload_dxt_texture() assumes that the texture is already bound and ready to go. - * This is so the viewport and the BGE can share some code. - * Returns false if the provided ImBuf doesn't have a supported DXT compression format - */ -bool GPU_upload_dxt_texture(ImBuf *ibuf, bool use_srgb) -{ -#ifdef WITH_DDS - GLint format = 0; - int blocksize, height, width, i, size, offset = 0; - - width = ibuf->x; - height = ibuf->y; - - if (GLEW_EXT_texture_compression_s3tc) { - if (ibuf->dds_data.fourcc == FOURCC_DXT1) { - format = (use_srgb) ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT : - GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - } - else if (ibuf->dds_data.fourcc == FOURCC_DXT3) { - format = (use_srgb) ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT : - GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - } - else if (ibuf->dds_data.fourcc == FOURCC_DXT5) { - format = (use_srgb) ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT : - GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - } - } - - if (format == 0) { - fprintf(stderr, "Unable to find a suitable DXT compression, falling back to uncompressed\n"); - return false; - } - - if (!is_power_of_2_resolution(width, height)) { - fprintf( - stderr, - "Unable to load non-power-of-two DXT image resolution, falling back to uncompressed\n"); - return false; - } - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1)); - - /* Reset to opengl Defaults. (Untested, might not be needed) */ - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - - blocksize = (ibuf->dds_data.fourcc == FOURCC_DXT1) ? 8 : 16; - for (i = 0; i < ibuf->dds_data.nummipmaps && (width || height); i++) { - if (width == 0) { - width = 1; - } - if (height == 0) { - height = 1; - } - - size = ((width + 3) / 4) * ((height + 3) / 4) * blocksize; - - glCompressedTexImage2D( - GL_TEXTURE_2D, i, format, width, height, 0, size, ibuf->dds_data.data + offset); - - offset += size; - width >>= 1; - height >>= 1; - } - /* Restore Blender default. */ - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - /* set number of mipmap levels we have, needed in case they don't go down to 1x1 */ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, i - 1); - - return true; -#else - UNUSED_VARS(ibuf, use_srgb); - return false; -#endif -} - -void GPU_create_gl_tex_compressed(unsigned int *bind, int textarget, Image *ima, ImBuf *ibuf) -{ - /* For DDS we only support data, scene linear and sRGB. Converting to - * different colorspace would break the compression. */ - const bool use_srgb = !(IMB_colormanagement_space_is_data(ibuf->rect_colorspace) || - IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace)); - const bool mipmap = GPU_get_mipmap(); - const bool half_float = (ibuf->flags & IB_halffloat) != 0; - -#ifndef WITH_DDS - (void)ibuf; - /* Fall back to uncompressed if DDS isn't enabled */ - GPU_create_gl_tex( - bind, ibuf->rect, NULL, ibuf->x, ibuf->y, textarget, mipmap, half_float, use_srgb, ima); -#else - glGenTextures(1, (GLuint *)bind); - glBindTexture(textarget, *bind); - - if (textarget == GL_TEXTURE_2D && GPU_upload_dxt_texture(ibuf, use_srgb) == 0) { - glDeleteTextures(1, (GLuint *)bind); - GPU_create_gl_tex( - bind, ibuf->rect, NULL, ibuf->x, ibuf->y, textarget, mipmap, half_float, use_srgb, ima); - } - - glBindTexture(textarget, 0); -#endif -} - -/* these two functions are called on entering and exiting texture paint mode, - * temporary disabling/enabling mipmapping on all images for quick texture - * updates with glTexSubImage2D. images that didn't change don't have to be - * re-uploaded to OpenGL */ -void GPU_paint_set_mipmap(Main *bmain, bool mipmap) -{ -#ifndef GPU_STANDALONE - if (!GTS.domipmap) { - return; - } - - GTS.texpaint = !mipmap; - - if (mipmap) { - for (Image *ima = bmain->images.first; ima; ima = ima->id.next) { - if (BKE_image_has_opengl_texture(ima)) { - if (ima->gpuflag & IMA_GPU_MIPMAP_COMPLETE) { - for (int eye = 0; eye < 2; eye++) { - for (int a = 0; a < TEXTARGET_COUNT; a++) { - if (ELEM(a, TEXTARGET_TEXTURE_2D, TEXTARGET_TEXTURE_2D_ARRAY)) { - GPUTexture *tex = ima->gputexture[a][eye]; - if (tex != NULL) { - GPU_texture_bind(tex, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1)); - GPU_texture_unbind(tex); - } - } - } - } - } - else { - GPU_free_image(ima); - } - } - else { - ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE; - } - } - } - else { - for (Image *ima = bmain->images.first; ima; ima = ima->id.next) { - if (BKE_image_has_opengl_texture(ima)) { - for (int eye = 0; eye < 2; eye++) { - for (int a = 0; a < TEXTARGET_COUNT; a++) { - if (ELEM(a, TEXTARGET_TEXTURE_2D, TEXTARGET_TEXTURE_2D_ARRAY)) { - GPUTexture *tex = ima->gputexture[a][eye]; - if (tex != NULL) { - GPU_texture_bind(tex, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1)); - GPU_texture_unbind(tex); - } - } - } - } - } - else { - ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE; - } - } - } -#endif /* GPU_STANDALONE */ -} - -void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, int h) -{ -#ifndef GPU_STANDALONE - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL); - ImageTile *tile = BKE_image_get_tile_from_iuser(ima, iuser); - - if ((ibuf == NULL) || (w == 0) || (h == 0)) { - /* Full reload of texture. */ - GPU_free_image(ima); - } - - GPUTexture *tex = ima->gputexture[TEXTARGET_TEXTURE_2D][0]; - /* Check if we need to update the main gputexture. */ - if (tex != NULL && tile == ima->tiles.first) { - gpu_texture_update_from_ibuf(tex, ima, ibuf, NULL, x, y, w, h); - } - - /* Check if we need to update the array gputexture. */ - tex = ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][0]; - if (tex != NULL) { - gpu_texture_update_from_ibuf(tex, ima, ibuf, tile, x, y, w, h); - } - - BKE_image_release_ibuf(ima, ibuf, NULL); -#endif -} - -/* Delayed GPU texture free. Image datablocks can be deleted by any thread, - * but there may not be any active OpenGL context. In that case we push them - * into a queue and free the buffers later. */ -static LinkNode *gpu_texture_free_queue = NULL; -static ThreadMutex gpu_texture_queue_mutex = BLI_MUTEX_INITIALIZER; - -static void gpu_free_unused_buffers() -{ - if (gpu_texture_free_queue == NULL) { - return; - } - - BLI_mutex_lock(&gpu_texture_queue_mutex); - - if (gpu_texture_free_queue != NULL) { - for (LinkNode *node = gpu_texture_free_queue; node; node = node->next) { - GPUTexture *tex = node->link; - GPU_texture_free(tex); - } - - BLI_linklist_free(gpu_texture_free_queue, NULL); - gpu_texture_free_queue = NULL; - } - - BLI_mutex_unlock(&gpu_texture_queue_mutex); -} - -static void gpu_free_image(Image *ima, const bool immediate) -{ - for (int eye = 0; eye < 2; eye++) { - for (int i = 0; i < TEXTARGET_COUNT; i++) { - if (ima->gputexture[i][eye] != NULL) { - if (immediate) { - GPU_texture_free(ima->gputexture[i][eye]); - } - else { - BLI_mutex_lock(&gpu_texture_queue_mutex); - BLI_linklist_prepend(&gpu_texture_free_queue, ima->gputexture[i][eye]); - BLI_mutex_unlock(&gpu_texture_queue_mutex); - } - - ima->gputexture[i][eye] = NULL; - } - } - } - - ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE; -} - -void GPU_free_unused_buffers() -{ - if (BLI_thread_is_main()) { - gpu_free_unused_buffers(); - } -} - -void GPU_free_image(Image *ima) -{ - gpu_free_image(ima, BLI_thread_is_main()); -} - -void GPU_free_images(Main *bmain) -{ - if (bmain) { - for (Image *ima = bmain->images.first; ima; ima = ima->id.next) { - GPU_free_image(ima); - } - } -} - -/* same as above but only free animated images */ -void GPU_free_images_anim(Main *bmain) -{ - if (bmain) { - for (Image *ima = bmain->images.first; ima; ima = ima->id.next) { - if (BKE_image_is_animated(ima)) { - GPU_free_image(ima); - } - } - } -} - -void GPU_free_images_old(Main *bmain) -{ - static int lasttime = 0; - int ctime = (int)PIL_check_seconds_timer(); - - /* - * Run garbage collector once for every collecting period of time - * if textimeout is 0, that's the option to NOT run the collector - */ - if (U.textimeout == 0 || ctime % U.texcollectrate || ctime == lasttime) { - return; - } - - /* of course not! */ - if (G.is_rendering) { - return; - } - - lasttime = ctime; - - Image *ima = bmain->images.first; - while (ima) { - if ((ima->flag & IMA_NOCOLLECT) == 0 && ctime - ima->lastused > U.textimeout) { - /* If it's in GL memory, deallocate and set time tag to current time - * This gives textures a "second chance" to be used before dying. */ - if (BKE_image_has_opengl_texture(ima)) { - GPU_free_image(ima); - ima->lastused = ctime; - } - /* Otherwise, just kill the buffers */ - else { - BKE_image_free_buffers(ima); - } - } - ima = ima->id.next; - } -} diff --git a/source/blender/gpu/intern/gpu_element.c b/source/blender/gpu/intern/gpu_element.cc index 036588b4a48..449d119267d 100644 --- a/source/blender/gpu/intern/gpu_element.c +++ b/source/blender/gpu/intern/gpu_element.cc @@ -26,6 +26,7 @@ #include "MEM_guardedalloc.h" #include "GPU_element.h" +#include "GPU_glew.h" #include "gpu_context_private.h" @@ -37,21 +38,18 @@ static GLenum convert_index_type_to_gl(GPUIndexBufType type) { - static const GLenum table[] = { - [GPU_INDEX_U16] = GL_UNSIGNED_SHORT, - [GPU_INDEX_U32] = GL_UNSIGNED_INT, - }; - return table[type]; +#if GPU_TRACK_INDEX_RANGE + return (type == GPU_INDEX_U32) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT; +#else + return GL_UNSIGNED_INT; +#endif } uint GPU_indexbuf_size_get(const GPUIndexBuf *elem) { #if GPU_TRACK_INDEX_RANGE - static const uint table[] = { - [GPU_INDEX_U16] = sizeof(GLushort), - [GPU_INDEX_U32] = sizeof(GLuint), - }; - return elem->index_len * table[elem->index_type]; + return elem->index_len * + ((elem->index_type == GPU_INDEX_U32) ? sizeof(GLuint) : sizeof(GLshort)); #else return elem->index_len * sizeof(GLuint); #endif @@ -86,7 +84,7 @@ void GPU_indexbuf_init_ex(GPUIndexBufBuilder *builder, builder->max_index_len = index_len; builder->index_len = 0; // start empty builder->prim_type = prim_type; - builder->data = MEM_callocN(builder->max_index_len * sizeof(uint), "GPUIndexBuf data"); + builder->data = (uint *)MEM_callocN(builder->max_index_len * sizeof(uint), "GPUIndexBuf data"); } void GPU_indexbuf_init(GPUIndexBufBuilder *builder, @@ -241,7 +239,7 @@ void GPU_indexbuf_set_tri_restart(GPUIndexBufBuilder *builder, uint elem) GPUIndexBuf *GPU_indexbuf_create_subrange(GPUIndexBuf *elem_src, uint start, uint length) { - GPUIndexBuf *elem = MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf"); + GPUIndexBuf *elem = (GPUIndexBuf *)MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf"); GPU_indexbuf_create_subrange_in_place(elem, elem_src, start, length); return elem; } @@ -282,7 +280,7 @@ static uint index_range(const uint values[], uint value_len, uint *min_out, uint if (value == RESTART_INDEX) { continue; } - else if (value < min_value) { + if (value < min_value) { min_value = value; } else if (value > max_value) { @@ -294,11 +292,10 @@ static uint index_range(const uint values[], uint value_len, uint *min_out, uint *max_out = 0; return 0; } - else { - *min_out = min_value; - *max_out = max_value; - return max_value - min_value; - } + + *min_out = min_value; + *max_out = max_value; + return max_value - min_value; } static void squeeze_indices_short(GPUIndexBufBuilder *builder, @@ -331,7 +328,7 @@ static void squeeze_indices_short(GPUIndexBufBuilder *builder, GPUIndexBuf *GPU_indexbuf_build(GPUIndexBufBuilder *builder) { - GPUIndexBuf *elem = MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf"); + GPUIndexBuf *elem = (GPUIndexBuf *)MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf"); GPU_indexbuf_build_in_place(builder, elem); return elem; } diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.cc index 9c37cc32e1d..35b70a18363 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.cc @@ -31,6 +31,8 @@ #include "BKE_global.h" #include "MEM_guardedalloc.h" +#include "DNA_userdef_types.h" + #include "GPU_extensions.h" #include "GPU_framebuffer.h" #include "GPU_glew.h" @@ -104,7 +106,8 @@ static struct GPUGlobal { static void gpu_detect_mip_render_workaround(void) { int cube_size = 2; - float *source_pix = MEM_callocN(sizeof(float) * 4 * 6 * cube_size * cube_size, __func__); + float *source_pix = (float *)MEM_callocN(sizeof(float) * 4 * 6 * cube_size * cube_size, + __func__); float clear_color[4] = {1.0f, 0.5f, 0.0f, 0.0f}; GPUTexture *tex = GPU_texture_create_cube(cube_size, GPU_RGBA16F, source_pix, NULL); @@ -123,7 +126,7 @@ static void gpu_detect_mip_render_workaround(void) GPU_framebuffer_restore(); GPU_framebuffer_free(fb); - float *data = GPU_texture_read(tex, GPU_DATA_FLOAT, 1); + float *data = (float *)GPU_texture_read(tex, GPU_DATA_FLOAT, 1); GG.mip_render_workaround = !equals_v4v4(clear_color, data); MEM_freeN(data); @@ -238,6 +241,13 @@ bool GPU_crappy_amd_driver(void) return GG.broken_amd_driver; } +int GPU_texture_size_with_limit(int res) +{ + int size = GPU_max_texture_size(); + int reslimit = (U.glreslimit != 0) ? min_ii(U.glreslimit, size) : size; + return min_ii(reslimit, res); +} + void gpu_extensions_init(void) { /* during 2.8 development each platform has its own OpenGL minimum requirements @@ -311,7 +321,7 @@ void gpu_extensions_init(void) if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL)) { /* Limit this fix to older hardware with GL < 4.5. This means Broadwell GPUs are * covered since they only support GL 4.4 on windows. - * This fixes some issues with workbench antialiasing on Win + Intel GPU. (see T76273) */ + * This fixes some issues with workbench anti-aliasing on Win + Intel GPU. (see T76273) */ if (!GLEW_VERSION_4_5) { GG.texture_copy_workaround = true; } diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.cc index 77abb786117..13df2268221 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.c +++ b/source/blender/gpu/intern/gpu_framebuffer.cc @@ -28,7 +28,6 @@ #include "BLI_utildefines.h" #include "GPU_batch.h" -#include "GPU_draw.h" #include "GPU_extensions.h" #include "GPU_framebuffer.h" #include "GPU_shader.h" @@ -53,6 +52,10 @@ typedef enum { GPU_FB_MAX_ATTACHEMENT, } GPUAttachmentType; +#define FOREACH_ATTACHMENT_RANGE(att, _start, _end) \ + for (GPUAttachmentType att = static_cast<GPUAttachmentType>(_start); att < _end; \ + att = static_cast<GPUAttachmentType>(att + 1)) + #define GPU_FB_MAX_COLOR_ATTACHMENT (GPU_FB_MAX_ATTACHEMENT - GPU_FB_COLOR_ATTACHMENT0) #define GPU_FB_DIRTY_DRAWBUFFER (1 << 15) @@ -74,17 +77,25 @@ struct GPUFrameBuffer { static GLenum convert_attachment_type_to_gl(GPUAttachmentType type) { - static const GLenum table[] = { - [GPU_FB_DEPTH_ATTACHMENT] = GL_DEPTH_ATTACHMENT, - [GPU_FB_DEPTH_STENCIL_ATTACHMENT] = GL_DEPTH_STENCIL_ATTACHMENT, - [GPU_FB_COLOR_ATTACHMENT0] = GL_COLOR_ATTACHMENT0, - [GPU_FB_COLOR_ATTACHMENT1] = GL_COLOR_ATTACHMENT1, - [GPU_FB_COLOR_ATTACHMENT2] = GL_COLOR_ATTACHMENT2, - [GPU_FB_COLOR_ATTACHMENT3] = GL_COLOR_ATTACHMENT3, - [GPU_FB_COLOR_ATTACHMENT4] = GL_COLOR_ATTACHMENT4, - [GPU_FB_COLOR_ATTACHMENT5] = GL_COLOR_ATTACHMENT5, - }; - return table[type]; +#define ATTACHMENT(type) \ + case GPU_FB_##type: { \ + return GL_##type; \ + } \ + ((void)0) + + switch (type) { + ATTACHMENT(DEPTH_ATTACHMENT); + ATTACHMENT(DEPTH_STENCIL_ATTACHMENT); + ATTACHMENT(COLOR_ATTACHMENT0); + ATTACHMENT(COLOR_ATTACHMENT1); + ATTACHMENT(COLOR_ATTACHMENT2); + ATTACHMENT(COLOR_ATTACHMENT3); + ATTACHMENT(COLOR_ATTACHMENT4); + ATTACHMENT(COLOR_ATTACHMENT5); + default: + BLI_assert(0); + return GL_COLOR_ATTACHMENT0; + } } static GPUAttachmentType attachment_type_from_tex(GPUTexture *tex, int slot) @@ -98,7 +109,7 @@ static GPUAttachmentType attachment_type_from_tex(GPUTexture *tex, int slot) case GPU_DEPTH32F_STENCIL8: return GPU_FB_DEPTH_STENCIL_ATTACHMENT; default: - return GPU_FB_COLOR_ATTACHMENT0 + slot; + return static_cast<GPUAttachmentType>(GPU_FB_COLOR_ATTACHMENT0 + slot); } } @@ -116,9 +127,8 @@ static GPUTexture *framebuffer_get_depth_tex(GPUFrameBuffer *fb) if (fb->attachments[GPU_FB_DEPTH_ATTACHMENT].tex) { return fb->attachments[GPU_FB_DEPTH_ATTACHMENT].tex; } - else { - return fb->attachments[GPU_FB_DEPTH_STENCIL_ATTACHMENT].tex; - } + + return fb->attachments[GPU_FB_DEPTH_STENCIL_ATTACHMENT].tex; } static GPUTexture *framebuffer_get_color_tex(GPUFrameBuffer *fb, int slot) @@ -179,9 +189,8 @@ GPUFrameBuffer *GPU_framebuffer_active_get(void) if (ctx) { return gpu_context_active_framebuffer_get(ctx); } - else { - return 0; - } + + return 0; } static void gpu_framebuffer_current_set(GPUFrameBuffer *fb) @@ -198,7 +207,7 @@ GPUFrameBuffer *GPU_framebuffer_create(void) { /* We generate the FB object later at first use in order to * create the framebuffer in the right opengl context. */ - return MEM_callocN(sizeof(GPUFrameBuffer), "GPUFrameBuffer"); + return (GPUFrameBuffer *)MEM_callocN(sizeof(GPUFrameBuffer), "GPUFrameBuffer"); } static void gpu_framebuffer_init(GPUFrameBuffer *fb) @@ -210,7 +219,8 @@ static void gpu_framebuffer_init(GPUFrameBuffer *fb) void GPU_framebuffer_free(GPUFrameBuffer *fb) { - for (GPUAttachmentType type = 0; type < GPU_FB_MAX_ATTACHEMENT; type++) { + for (int i_type = 0; i_type < GPU_FB_MAX_ATTACHEMENT; i_type++) { + GPUAttachmentType type = static_cast<GPUAttachmentType>(i_type); if (fb->attachments[type].tex != NULL) { GPU_framebuffer_texture_detach(fb, fb->attachments[type].tex); } @@ -249,7 +259,7 @@ static void gpu_framebuffer_texture_attach_ex( if ((attachment->tex == tex) && (attachment->mip == mip) && (attachment->layer == layer)) { return; /* Exact same texture already bound here. */ } - else if (attachment->tex != NULL) { + if (attachment->tex != NULL) { GPU_framebuffer_texture_detach(fb, attachment->tex); } @@ -304,7 +314,7 @@ void GPU_framebuffer_texture_detach_slot(GPUFrameBuffer *fb, GPUTexture *tex, in void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex) { - GPUAttachmentType type = GPU_texture_detach_framebuffer(tex, fb); + GPUAttachmentType type = (GPUAttachmentType)GPU_texture_detach_framebuffer(tex, fb); GPU_framebuffer_texture_detach_slot(fb, tex, type); } @@ -387,8 +397,8 @@ static void gpu_framebuffer_update_attachments(GPUFrameBuffer *fb) BLI_assert(GPU_framebuffer_active_get() == fb); /* Update attachments */ - for (GPUAttachmentType type = 0; type < GPU_FB_MAX_ATTACHEMENT; type++) { - + FOREACH_ATTACHMENT_RANGE(type, 0, GPU_FB_MAX_ATTACHEMENT) + { if (type >= GPU_FB_COLOR_ATTACHMENT0) { if (fb->attachments[type].tex) { gl_attachments[numslots] = convert_attachment_type_to_gl(type); @@ -402,7 +412,7 @@ static void gpu_framebuffer_update_attachments(GPUFrameBuffer *fb) if (GPU_FB_ATTACHEMENT_IS_DIRTY(fb->dirty_flag, type) == false) { continue; } - else if (fb->attachments[type].tex != NULL) { + if (fb->attachments[type].tex != NULL) { gpu_framebuffer_attachment_attach(&fb->attachments[type], type); fb->multisample = (GPU_texture_samples(fb->attachments[type].tex) > 0); @@ -438,7 +448,8 @@ static void gpu_framebuffer_update_attachments_and_fill_empty_slots(GPUFrameBuff BLI_assert(GPU_framebuffer_active_get() == fb); /* Update attachments */ - for (GPUAttachmentType type = GPU_FB_MAX_ATTACHEMENT; type--;) { + for (int i_type = GPU_FB_MAX_ATTACHEMENT - 1; i_type >= 0; --i_type) { + GPUAttachmentType type = static_cast<GPUAttachmentType>(i_type); GPUTexture *tex = fb->attachments[type].tex; if (type >= GPU_FB_COLOR_ATTACHMENT0) { @@ -623,8 +634,9 @@ void GPU_framebuffer_multi_clear(GPUFrameBuffer *fb, const float (*clear_cols)[4 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - GPUAttachmentType type = GPU_FB_COLOR_ATTACHMENT0; - for (int i = 0; type < GPU_FB_MAX_ATTACHEMENT; i++, type++) { + int i_type = GPU_FB_COLOR_ATTACHMENT0; + for (int i = 0; i_type < GPU_FB_MAX_ATTACHEMENT; i++, i_type++) { + GPUAttachmentType type = static_cast<GPUAttachmentType>(i_type); if (fb->attachments[type].tex != NULL) { glClearBufferfv(GL_COLOR, i, clear_cols[i]); } @@ -702,7 +714,8 @@ void GPU_framebuffer_read_color(GPUFrameBuffer *fb, void *data) { CHECK_FRAMEBUFFER_IS_BOUND(fb); - gpu_framebuffer_read_color_ex(x, y, w, h, channels, GL_COLOR_ATTACHMENT0 + slot, format, data); + gpu_framebuffer_read_color_ex( + x, y, w, h, channels, GL_COLOR_ATTACHMENT0 + slot, format, (float *)data); } /* read_slot and write_slot are only used for color buffers. */ @@ -815,7 +828,8 @@ void GPU_framebuffer_recursive_downsample(GPUFrameBuffer *fb, current_dim[0] = max_ii(current_dim[0] / 2, 1); current_dim[1] = max_ii(current_dim[1] / 2, 1); - for (GPUAttachmentType type = 0; type < GPU_FB_MAX_ATTACHEMENT; type++) { + for (int i_type = 0; i_type < GPU_FB_MAX_ATTACHEMENT; i_type++) { + GPUAttachmentType type = static_cast<GPUAttachmentType>(i_type); if (fb->attachments[type].tex != NULL) { /* Some Intel HDXXX have issue with rendering to a mipmap that is below * the texture GL_TEXTURE_MAX_LEVEL. So even if it not correct, in this case @@ -844,7 +858,8 @@ void GPU_framebuffer_recursive_downsample(GPUFrameBuffer *fb, } } - for (GPUAttachmentType type = 0; type < GPU_FB_MAX_ATTACHEMENT; type++) { + for (int i_type = 0; i_type < GPU_FB_MAX_ATTACHEMENT; i_type++) { + GPUAttachmentType type = static_cast<GPUAttachmentType>(i_type); if (fb->attachments[type].tex != NULL) { /* reset mipmap level range */ GPUTexture *tex = fb->attachments[type].tex; @@ -885,9 +900,11 @@ static GPUFrameBuffer *gpu_offscreen_fb_get(GPUOffScreen *ofs) for (int i = 0; i < MAX_CTX_FB_LEN; i++) { if (ofs->framebuffers[i].fb == NULL) { ofs->framebuffers[i].ctx = ctx; - GPU_framebuffer_ensure_config( - &ofs->framebuffers[i].fb, - {GPU_ATTACHMENT_TEXTURE(ofs->depth), GPU_ATTACHMENT_TEXTURE(ofs->color)}); + GPU_framebuffer_ensure_config(&ofs->framebuffers[i].fb, + { + GPU_ATTACHMENT_TEXTURE(ofs->depth), + GPU_ATTACHMENT_TEXTURE(ofs->color), + }); } if (ofs->framebuffers[i].ctx == ctx) { @@ -916,9 +933,7 @@ static GPUFrameBuffer *gpu_offscreen_fb_get(GPUOffScreen *ofs) GPUOffScreen *GPU_offscreen_create( int width, int height, bool depth, bool high_bitdepth, char err_out[256]) { - GPUOffScreen *ofs; - - ofs = MEM_callocN(sizeof(GPUOffScreen), "GPUOffScreen"); + GPUOffScreen *ofs = (GPUOffScreen *)MEM_callocN(sizeof(GPUOffScreen), __func__); /* Sometimes areas can have 0 height or width and this will * create a 1D texture which we don't want. */ @@ -975,7 +990,7 @@ void GPU_offscreen_free(GPUOffScreen *ofs) void GPU_offscreen_bind(GPUOffScreen *ofs, bool save) { if (save) { - gpuPushAttr(GPU_SCISSOR_BIT | GPU_VIEWPORT_BIT); + gpuPushAttr((eGPUAttrMask)(GPU_SCISSOR_BIT | GPU_VIEWPORT_BIT)); GPUFrameBuffer *fb = GPU_framebuffer_active_get(); gpuPushFrameBuffer(fb); } @@ -1023,14 +1038,15 @@ void GPU_offscreen_draw_to_screen(GPUOffScreen *ofs, int x, int y) glBindFramebuffer(GL_READ_FRAMEBUFFER, GPU_framebuffer_default()); } -void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels) +void GPU_offscreen_read_pixels(GPUOffScreen *ofs, eGPUDataFormat type, void *pixels) { const int w = GPU_texture_width(ofs->color); const int h = GPU_texture_height(ofs->color); - BLI_assert(type == GL_UNSIGNED_BYTE || type == GL_FLOAT); + BLI_assert(ELEM(type, GPU_DATA_UNSIGNED_BYTE, GPU_DATA_FLOAT)); + GLenum gl_type = (type == GPU_DATA_FLOAT) ? GL_FLOAT : GL_UNSIGNED_BYTE; - glReadPixels(0, 0, w, h, GL_RGBA, type, pixels); + glReadPixels(0, 0, w, h, GL_RGBA, gl_type, pixels); } int GPU_offscreen_width(const GPUOffScreen *ofs) @@ -1077,8 +1093,7 @@ void GPU_clear(eGPUFrameBufferBits flags) void GPU_frontbuffer_read_pixels( int x, int y, int w, int h, int channels, eGPUDataFormat format, void *data) { - glReadBuffer(GL_FRONT); - gpu_framebuffer_read_color_ex(x, y, w, h, channels, GL_FRONT, format, data); + gpu_framebuffer_read_color_ex(x, y, w, h, channels, GL_FRONT, format, (float *)data); } /* For stereo rendering. */ diff --git a/source/blender/gpu/intern/gpu_immediate.c b/source/blender/gpu/intern/gpu_immediate.cc index 1e99371f9a1..7283f7c12aa 100644 --- a/source/blender/gpu/intern/gpu_immediate.c +++ b/source/blender/gpu/intern/gpu_immediate.cc @@ -29,6 +29,7 @@ #include "GPU_attr_binding.h" #include "GPU_immediate.h" +#include "GPU_matrix.h" #include "GPU_texture.h" #include "gpu_attr_binding_private.h" @@ -40,10 +41,6 @@ #include <stdlib.h> #include <string.h> -/* necessary functions from matrix API */ -extern void GPU_matrix_bind(const GPUShaderInterface *); -extern bool GPU_matrix_dirty_get(void); - typedef struct ImmediateDrawBuffer { GLuint vbo_id; GLubyte *buffer_data; @@ -75,7 +72,7 @@ typedef struct { GLuint vao_id; - GLuint bound_program; + GPUShader *bound_program; const GPUShaderInterface *shader_interface; GPUAttrBinding attr_binding; uint16_t prev_enabled_attr_bits; /* <-- only affects this VAO, so we're ok */ @@ -146,48 +143,47 @@ GPUVertFormat *immVertexFormat(void) return &imm.vertex_format; } -void immBindProgram(GLuint program, const GPUShaderInterface *shaderface) +void immBindShader(GPUShader *shader) { #if TRUST_NO_ONE - assert(imm.bound_program == 0); - assert(glIsProgram(program)); + assert(imm.bound_program == NULL); + assert(glIsProgram(shader->program)); #endif - imm.bound_program = program; - imm.shader_interface = shaderface; + imm.bound_program = shader; + imm.shader_interface = shader->interface; if (!imm.vertex_format.packed) { VertexFormat_pack(&imm.vertex_format); } - glUseProgram(program); - get_attr_locations(&imm.vertex_format, &imm.attr_binding, shaderface); - GPU_matrix_bind(shaderface); - GPU_shader_set_srgb_uniform(shaderface); + GPU_shader_bind(shader); + get_attr_locations(&imm.vertex_format, &imm.attr_binding, imm.shader_interface); + GPU_matrix_bind(imm.shader_interface); + GPU_shader_set_srgb_uniform(imm.shader_interface); } void immBindBuiltinProgram(eGPUBuiltinShader shader_id) { GPUShader *shader = GPU_shader_get_builtin_shader(shader_id); - immBindProgram(shader->program, shader->interface); + immBindShader(shader); } void immUnbindProgram(void) { #if TRUST_NO_ONE - assert(imm.bound_program != 0); + assert(imm.bound_program != NULL); #endif #if PROGRAM_NO_OPTI glUseProgram(0); #endif - imm.bound_program = 0; + imm.bound_program = NULL; } /* XXX do not use it. Special hack to use OCIO with batch API. */ -void immGetProgram(GLuint *program, GPUShaderInterface **shaderface) +GPUShader *immGetShader(void) { - *program = imm.bound_program; - *shaderface = (GPUShaderInterface *)imm.shader_interface; + return imm.bound_program; } #if TRUST_NO_ONE @@ -281,7 +277,7 @@ void immBegin(GPUPrimType prim_type, uint vertex_len) } #endif - active_buffer->buffer_data = glMapBufferRange( + active_buffer->buffer_data = (GLubyte *)glMapBufferRange( GL_ARRAY_BUFFER, active_buffer->buffer_offset, bytes_needed, @@ -367,17 +363,18 @@ static void immDrawSetup(void) const GLvoid *pointer = (const GLubyte *)0 + offset; const uint loc = read_attr_location(&imm.attr_binding, a_idx); + const GLenum type = convert_comp_type_to_gl(static_cast<GPUVertCompType>(a->comp_type)); switch (a->fetch_mode) { case GPU_FETCH_FLOAT: case GPU_FETCH_INT_TO_FLOAT: - glVertexAttribPointer(loc, a->comp_len, a->gl_comp_type, GL_FALSE, stride, pointer); + glVertexAttribPointer(loc, a->comp_len, type, GL_FALSE, stride, pointer); break; case GPU_FETCH_INT_TO_FLOAT_UNIT: - glVertexAttribPointer(loc, a->comp_len, a->gl_comp_type, GL_TRUE, stride, pointer); + glVertexAttribPointer(loc, a->comp_len, type, GL_TRUE, stride, pointer); break; case GPU_FETCH_INT: - glVertexAttribIPointer(loc, a->comp_len, a->gl_comp_type, stride, pointer); + glVertexAttribIPointer(loc, a->comp_len, type, stride, pointer); } } @@ -425,7 +422,7 @@ void immEnd(void) GPU_vertbuf_data_resize(imm.batch->verts[0], imm.vertex_len); /* TODO: resize only if vertex count is much smaller */ } - GPU_batch_program_set(imm.batch, imm.bound_program, imm.shader_interface); + GPU_batch_set_shader(imm.batch, imm.bound_program); imm.batch->phase = GPU_BATCH_READY_TO_DRAW; imm.batch = NULL; /* don't free, batch belongs to caller */ } diff --git a/source/blender/gpu/intern/gpu_immediate_util.c b/source/blender/gpu/intern/gpu_immediate_util.c index e834d6afccb..b8cd9fe356d 100644 --- a/source/blender/gpu/intern/gpu_immediate_util.c +++ b/source/blender/gpu/intern/gpu_immediate_util.c @@ -460,10 +460,10 @@ void imm_draw_cylinder_fill_normal_3d( float h1 = height * ((float)j / (float)stacks); float h2 = height * ((float)(j + 1) / (float)stacks); - float v1[3] = {r1 * cos2, r1 * sin2, h1}; - float v2[3] = {r2 * cos2, r2 * sin2, h2}; - float v3[3] = {r2 * cos1, r2 * sin1, h2}; - float v4[3] = {r1 * cos1, r1 * sin1, h1}; + const float v1[3] = {r1 * cos2, r1 * sin2, h1}; + const float v2[3] = {r2 * cos2, r2 * sin2, h2}; + const float v3[3] = {r2 * cos1, r2 * sin1, h2}; + const float v4[3] = {r1 * cos1, r1 * sin1, h1}; float n1[3], n2[3]; /* calc normals */ @@ -516,10 +516,10 @@ void imm_draw_cylinder_wire_3d( float h1 = height * ((float)j / (float)stacks); float h2 = height * ((float)(j + 1) / (float)stacks); - float v1[3] = {r1 * cos2, r1 * sin2, h1}; - float v2[3] = {r2 * cos2, r2 * sin2, h2}; - float v3[3] = {r2 * cos1, r2 * sin1, h2}; - float v4[3] = {r1 * cos1, r1 * sin1, h1}; + const float v1[3] = {r1 * cos2, r1 * sin2, h1}; + const float v2[3] = {r2 * cos2, r2 * sin2, h2}; + const float v3[3] = {r2 * cos1, r2 * sin1, h2}; + const float v4[3] = {r1 * cos1, r1 * sin1, h1}; immVertex3fv(pos, v1); immVertex3fv(pos, v2); @@ -554,10 +554,10 @@ void imm_draw_cylinder_fill_3d( float h1 = height * ((float)j / (float)stacks); float h2 = height * ((float)(j + 1) / (float)stacks); - float v1[3] = {r1 * cos2, r1 * sin2, h1}; - float v2[3] = {r2 * cos2, r2 * sin2, h2}; - float v3[3] = {r2 * cos1, r2 * sin1, h2}; - float v4[3] = {r1 * cos1, r1 * sin1, h1}; + const float v1[3] = {r1 * cos2, r1 * sin2, h1}; + const float v2[3] = {r2 * cos2, r2 * sin2, h2}; + const float v3[3] = {r2 * cos1, r2 * sin1, h2}; + const float v4[3] = {r1 * cos1, r1 * sin1, h1}; /* first tri */ immVertex3fv(pos, v1); diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c index 54ddb9351b9..c5061ec9ba3 100644 --- a/source/blender/gpu/intern/gpu_init_exit.c +++ b/source/blender/gpu/intern/gpu_init_exit.c @@ -95,7 +95,7 @@ void GPU_exit(void) initialized = false; } -bool GPU_is_initialized(void) +bool GPU_is_init(void) { return initialized; } diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index c65c1046b8f..8d2003591e4 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -85,7 +85,7 @@ struct GPUMaterial { bool has_surface_output; /* Only used by Eevee to know which bsdf are used. */ - int flag; + eGPUMatFlag flag; /* Used by 2.8 pipeline */ GPUUniformBuffer *ubo; /* UBOs for shader uniforms. */ @@ -311,12 +311,11 @@ static float eval_profile(float r, short falloff_type, float sharpness, float pa 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) { + if (falloff_type == SHD_SUBSURFACE_CUBIC) { return cubic_profile(r, param, sharpness); } - else { - return gaussian_profile(r, param); - } + + return gaussian_profile(r, param); } /* Resolution for each sample of the precomputed kernel profile */ @@ -659,7 +658,8 @@ GPUMaterial *GPU_material_from_nodetree(Scene *scene, const char *geom_code, const char *frag_lib, const char *defines, - const char *name) + const char *name, + GPUMaterialEvalCallbackFn callback) { LinkData *link; bool has_volume_output, has_surface_output; @@ -696,6 +696,9 @@ GPUMaterial *GPU_material_from_nodetree(Scene *scene, mat->has_volume_output = has_volume_output; if (mat->graph.outlink) { + if (callback) { + callback(mat, options, &vert_code, &geom_code, &frag_lib, &defines); + } /* HACK: this is only for eevee. We add the define here after the nodetree evaluation. */ if (GPU_material_flag_get(mat, GPU_MATFLAG_SSS)) { defines = BLI_string_joinN(defines, diff --git a/source/blender/gpu/intern/gpu_material_library.c b/source/blender/gpu/intern/gpu_material_library.c index 42cd9673ac2..e0165e1fa83 100644 --- a/source/blender/gpu/intern/gpu_material_library.c +++ b/source/blender/gpu/intern/gpu_material_library.c @@ -678,14 +678,13 @@ char *gpu_str_skip_token(char *str, char *token, int max) if (ELEM(*str, ' ', '(', ')', ',', ';', '\t', '\n', '\r')) { break; } - else { - if (token && len < max - 1) { - *token = *str; - token++; - len++; - } - str++; + + if (token && len < max - 1) { + *token = *str; + token++; + len++; } + str++; } if (token) { diff --git a/source/blender/gpu/intern/gpu_matrix.c b/source/blender/gpu/intern/gpu_matrix.cc index 669bf56b726..4174f498402 100644 --- a/source/blender/gpu/intern/gpu_matrix.c +++ b/source/blender/gpu/intern/gpu_matrix.cc @@ -37,8 +37,6 @@ #include "MEM_guardedalloc.h" -#define DEBUG_MATRIX_BIND 0 - #define MATRIX_STACK_DEPTH 32 typedef float Mat4[4][4]; @@ -79,7 +77,7 @@ GPUMatrixState *GPU_matrix_state_create(void) } \ } - GPUMatrixState *state = MEM_mallocN(sizeof(*state), __func__); + GPUMatrixState *state = (GPUMatrixState *)MEM_mallocN(sizeof(*state), __func__); const MatrixStack identity_stack = {{MATRIX_4X4_IDENTITY}, 0}; state->model_view_stack = state->projection_stack = identity_stack; @@ -592,9 +590,8 @@ const float (*GPU_matrix_model_view_get(float m[4][4]))[4] copy_m4_m4(m, ModelView); return m; } - else { - return ModelView; - } + + return ModelView; } const float (*GPU_matrix_projection_get(float m[4][4]))[4] @@ -603,9 +600,8 @@ const float (*GPU_matrix_projection_get(float m[4][4]))[4] copy_m4_m4(m, Projection); return m; } - else { - return Projection; - } + + return Projection; } const float (*GPU_matrix_model_view_projection_get(float m[4][4]))[4] @@ -662,51 +658,32 @@ void GPU_matrix_bind(const GPUShaderInterface *shaderface) int32_t MV_inv = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_MODELVIEW_INV); int32_t P_inv = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_PROJECTION_INV); + /* XXX(fclem) this works but this assumes shader is unused inside GPU_shader_uniform_vector. */ + GPUShader *sh = NULL; if (MV != -1) { -#if DEBUG_MATRIX_BIND - puts("setting MV matrix"); -#endif - - glUniformMatrix4fv(MV, 1, GL_FALSE, (const float *)GPU_matrix_model_view_get(NULL)); + GPU_shader_uniform_vector(sh, MV, 16, 1, (const float *)GPU_matrix_model_view_get(NULL)); } - if (P != -1) { -#if DEBUG_MATRIX_BIND - puts("setting P matrix"); -#endif - - glUniformMatrix4fv(P, 1, GL_FALSE, (const float *)GPU_matrix_projection_get(NULL)); + GPU_shader_uniform_vector(sh, P, 16, 1, (const float *)GPU_matrix_projection_get(NULL)); } - if (MVP != -1) { -#if DEBUG_MATRIX_BIND - puts("setting MVP matrix"); -#endif - - glUniformMatrix4fv( - MVP, 1, GL_FALSE, (const float *)GPU_matrix_model_view_projection_get(NULL)); + GPU_shader_uniform_vector( + sh, MVP, 16, 1, (const float *)GPU_matrix_model_view_projection_get(NULL)); } - if (N != -1) { -#if DEBUG_MATRIX_BIND - puts("setting normal matrix"); -#endif - - glUniformMatrix3fv(N, 1, GL_FALSE, (const float *)GPU_matrix_normal_get(NULL)); + GPU_shader_uniform_vector(sh, N, 9, 1, (const float *)GPU_matrix_normal_get(NULL)); } - if (MV_inv != -1) { Mat4 m; GPU_matrix_model_view_get(m); invert_m4(m); - glUniformMatrix4fv(MV_inv, 1, GL_FALSE, (const float *)m); + GPU_shader_uniform_vector(sh, MV_inv, 16, 1, (const float *)m); } - if (P_inv != -1) { Mat4 m; GPU_matrix_projection_get(m); invert_m4(m); - glUniformMatrix4fv(P_inv, 1, GL_FALSE, (const float *)m); + GPU_shader_uniform_vector(sh, P_inv, 16, 1, (const float *)m); } gpu_matrix_state_active_set_dirty(false); diff --git a/source/blender/gpu/intern/gpu_node_graph.h b/source/blender/gpu/intern/gpu_node_graph.h index 21bb139f610..7265abf4d65 100644 --- a/source/blender/gpu/intern/gpu_node_graph.h +++ b/source/blender/gpu/intern/gpu_node_graph.h @@ -28,7 +28,6 @@ #include "DNA_customdata_types.h" #include "DNA_listBase.h" -#include "GPU_glew.h" #include "GPU_material.h" #include "GPU_shader.h" diff --git a/source/blender/gpu/intern/gpu_platform.c b/source/blender/gpu/intern/gpu_platform.cc index 5cabde61bc3..5cabde61bc3 100644 --- a/source/blender/gpu/intern/gpu_platform.c +++ b/source/blender/gpu/intern/gpu_platform.cc diff --git a/source/blender/gpu/intern/gpu_primitive.c b/source/blender/gpu/intern/gpu_primitive.c index 2285c1ab95b..3b11b38db87 100644 --- a/source/blender/gpu/intern/gpu_primitive.c +++ b/source/blender/gpu/intern/gpu_primitive.c @@ -26,35 +26,6 @@ #include "GPU_primitive.h" #include "gpu_primitive_private.h" -GPUPrimClass GPU_primtype_class(GPUPrimType prim_type) -{ - static const GPUPrimClass classes[] = { - [GPU_PRIM_POINTS] = GPU_PRIM_CLASS_POINT, - [GPU_PRIM_LINES] = GPU_PRIM_CLASS_LINE, - [GPU_PRIM_LINE_STRIP] = GPU_PRIM_CLASS_LINE, - [GPU_PRIM_LINE_LOOP] = GPU_PRIM_CLASS_LINE, - [GPU_PRIM_TRIS] = GPU_PRIM_CLASS_SURFACE, - [GPU_PRIM_TRI_STRIP] = GPU_PRIM_CLASS_SURFACE, - [GPU_PRIM_TRI_FAN] = GPU_PRIM_CLASS_SURFACE, - - [GPU_PRIM_LINES_ADJ] = GPU_PRIM_CLASS_LINE, - [GPU_PRIM_LINE_STRIP_ADJ] = GPU_PRIM_CLASS_LINE, - [GPU_PRIM_TRIS_ADJ] = GPU_PRIM_CLASS_SURFACE, - - [GPU_PRIM_NONE] = GPU_PRIM_CLASS_NONE, - }; - - return classes[prim_type]; -} - -bool GPU_primtype_belongs_to_class(GPUPrimType prim_type, GPUPrimClass prim_class) -{ - if (prim_class == GPU_PRIM_CLASS_NONE && prim_type == GPU_PRIM_NONE) { - return true; - } - return prim_class & GPU_primtype_class(prim_type); -} - GLenum convert_prim_type_to_gl(GPUPrimType prim_type) { #if TRUST_NO_ONE diff --git a/source/blender/gpu/intern/gpu_primitive_private.h b/source/blender/gpu/intern/gpu_primitive_private.h index b3b6bd7fc88..e91eec18786 100644 --- a/source/blender/gpu/intern/gpu_primitive_private.h +++ b/source/blender/gpu/intern/gpu_primitive_private.h @@ -25,4 +25,13 @@ #pragma once +#ifdef __cplusplus +extern "C" { +#endif + +/* TODO(fclem) move to OGL backend */ GLenum convert_prim_type_to_gl(GPUPrimType); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/gpu/intern/gpu_private.h b/source/blender/gpu/intern/gpu_private.h index a5caa816ef4..ef96bedae4a 100644 --- a/source/blender/gpu/intern/gpu_private.h +++ b/source/blender/gpu/intern/gpu_private.h @@ -20,6 +20,10 @@ #pragma once +#ifdef __cplusplus +extern "C" { +#endif + /* call this before running any of the functions below */ void gpu_platform_init(void); void gpu_platform_exit(void); @@ -39,3 +43,7 @@ void gpu_framebuffer_module_exit(void); /* gpu_pbvh.c */ void gpu_pbvh_init(void); void gpu_pbvh_exit(void); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/gpu/intern/gpu_select.c b/source/blender/gpu/intern/gpu_select.c index 5766a176a96..c069cbe012f 100644 --- a/source/blender/gpu/intern/gpu_select.c +++ b/source/blender/gpu/intern/gpu_select.c @@ -26,7 +26,6 @@ #include <stdlib.h> #include <string.h> -#include "GPU_glew.h" #include "GPU_select.h" #include "MEM_guardedalloc.h" diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c index c6d8545527c..0f6f29fab40 100644 --- a/source/blender/gpu/intern/gpu_select_pick.c +++ b/source/blender/gpu/intern/gpu_select_pick.c @@ -27,7 +27,6 @@ #include <stdlib.h> #include <string.h> -#include "GPU_draw.h" #include "GPU_glew.h" #include "GPU_immediate.h" #include "GPU_select.h" @@ -205,12 +204,11 @@ static int depth_id_cmp(const void *v1, const void *v2) if (d1->id < d2->id) { return -1; } - else if (d1->id > d2->id) { + if (d1->id > d2->id) { return 1; } - else { - return 0; - } + + return 0; } static int depth_cmp(const void *v1, const void *v2) @@ -219,12 +217,11 @@ static int depth_cmp(const void *v1, const void *v2) if (d1->depth < d2->depth) { return -1; } - else if (d1->depth > d2->depth) { + if (d1->depth > d2->depth) { return 1; } - else { - return 0; - } + + return 0; } /* depth sorting */ diff --git a/source/blender/gpu/intern/gpu_select_sample_query.c b/source/blender/gpu/intern/gpu_select_sample_query.c index 70ad2f6759e..f67c9c36a6b 100644 --- a/source/blender/gpu/intern/gpu_select_sample_query.c +++ b/source/blender/gpu/intern/gpu_select_sample_query.c @@ -147,9 +147,8 @@ bool gpu_select_query_load_id(uint id) g_query_state.index++; return true; } - else { - return false; - } + + return false; } } diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc new file mode 100644 index 00000000000..76c439b86b5 --- /dev/null +++ b/source/blender/gpu/intern/gpu_shader.cc @@ -0,0 +1,838 @@ +/* + * 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. + */ + +/** \file + * \ingroup gpu + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_math_base.h" +#include "BLI_math_vector.h" +#include "BLI_path_util.h" +#include "BLI_string.h" +#include "BLI_string_utils.h" +#include "BLI_utildefines.h" + +#include "BKE_appdir.h" +#include "BKE_global.h" + +#include "DNA_space_types.h" + +#include "GPU_extensions.h" +#include "GPU_matrix.h" +#include "GPU_platform.h" +#include "GPU_shader.h" +#include "GPU_texture.h" +#include "GPU_uniformbuffer.h" + +#include "gpu_shader_private.h" + +extern "C" char datatoc_gpu_shader_colorspace_lib_glsl[]; + +/* Adjust these constants as needed. */ +#define MAX_DEFINE_LENGTH 256 +#define MAX_EXT_DEFINE_LENGTH 512 + +#ifndef NDEBUG +static uint g_shaderid = 0; +#endif + +/* -------------------------------------------------------------------- */ +/** \name Convenience functions + * \{ */ + +static void shader_print_errors(const char *task, const char *log, const char **code, int totcode) +{ + int line = 1; + + fprintf(stderr, "GPUShader: %s error:\n", task); + + for (int i = 0; i < totcode; i++) { + const char *c, *pos, *end = code[i] + strlen(code[i]); + + if (G.debug & G_DEBUG) { + fprintf(stderr, "===== shader string %d ====\n", i + 1); + + c = code[i]; + while ((c < end) && (pos = strchr(c, '\n'))) { + fprintf(stderr, "%2d ", line); + fwrite(c, (pos + 1) - c, 1, stderr); + c = pos + 1; + line++; + } + + fprintf(stderr, "%s", c); + } + } + + fprintf(stderr, "%s\n", log); +} + +static const char *gpu_shader_version(void) +{ + return "#version 330\n"; +} + +static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH]) +{ + /* enable extensions for features that are not part of our base GLSL version + * don't use an extension for something already available! + */ + + if (GLEW_ARB_texture_gather) { + /* There is a bug on older Nvidia GPU where GL_ARB_texture_gather + * is reported to be supported but yield a compile error (see T55802). */ + if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) || GLEW_VERSION_4_0) { + strcat(defines, "#extension GL_ARB_texture_gather: enable\n"); + + /* Some drivers don't agree on GLEW_ARB_texture_gather and the actual support in the + * shader so double check the preprocessor define (see T56544). */ + if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) && !GLEW_VERSION_4_0) { + strcat(defines, "#ifdef GL_ARB_texture_gather\n"); + strcat(defines, "# define GPU_ARB_texture_gather\n"); + strcat(defines, "#endif\n"); + } + else { + strcat(defines, "#define GPU_ARB_texture_gather\n"); + } + } + } + if (GLEW_ARB_texture_query_lod) { + /* a #version 400 feature, but we use #version 330 maximum so use extension */ + strcat(defines, "#extension GL_ARB_texture_query_lod: enable\n"); + } + if (GLEW_ARB_shader_draw_parameters) { + strcat(defines, "#extension GL_ARB_shader_draw_parameters : enable\n"); + } + if (GPU_arb_texture_cube_map_array_is_supported()) { + strcat(defines, "#extension GL_ARB_texture_cube_map_array : enable\n"); + strcat(defines, "#define GPU_ARB_texture_cube_map_array\n"); + } +} + +static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH]) +{ + /* some useful defines to detect GPU type */ + if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) { + strcat(defines, "#define GPU_ATI\n"); + if (GPU_crappy_amd_driver()) { + strcat(defines, "#define GPU_DEPRECATED_AMD_DRIVER\n"); + } + } + else if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY)) { + strcat(defines, "#define GPU_NVIDIA\n"); + } + else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) { + strcat(defines, "#define GPU_INTEL\n"); + } + + /* some useful defines to detect OS type */ + if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_WIN, GPU_DRIVER_ANY)) { + strcat(defines, "#define OS_WIN\n"); + } + else if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY)) { + strcat(defines, "#define OS_MAC\n"); + } + else if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_UNIX, GPU_DRIVER_ANY)) { + strcat(defines, "#define OS_UNIX\n"); + } + + float derivatives_factors[2]; + GPU_get_dfdy_factors(derivatives_factors); + if (derivatives_factors[0] == 1.0f) { + strcat(defines, "#define DFDX_SIGN 1.0\n"); + } + else { + strcat(defines, "#define DFDX_SIGN -1.0\n"); + } + + if (derivatives_factors[1] == 1.0f) { + strcat(defines, "#define DFDY_SIGN 1.0\n"); + } + else { + strcat(defines, "#define DFDY_SIGN -1.0\n"); + } +} + +#define DEBUG_SHADER_NONE "" +#define DEBUG_SHADER_VERTEX "vert" +#define DEBUG_SHADER_FRAGMENT "frag" +#define DEBUG_SHADER_GEOMETRY "geom" + +/** + * Dump GLSL shaders to disk + * + * This is used for profiling shader performance externally and debug if shader code is correct. + * If called with no code, it simply bumps the shader index, so different shaders for the same + * program share the same index. + */ +static void gpu_dump_shaders(const char **code, const int num_shaders, const char *extension) +{ + if ((G.debug & G_DEBUG_GPU_SHADERS) == 0) { + return; + } + + /* We use the same shader index for shaders in the same program. + * So we call this function once before calling for the individual shaders. */ + static int shader_index = 0; + if (code == NULL) { + shader_index++; + BLI_assert(STREQ(DEBUG_SHADER_NONE, extension)); + return; + } + + /* Determine the full path of the new shader. */ + char shader_path[FILE_MAX]; + + char file_name[512] = {'\0'}; + sprintf(file_name, "%04d.%s", shader_index, extension); + + BLI_join_dirfile(shader_path, sizeof(shader_path), BKE_tempdir_session(), file_name); + + /* Write shader to disk. */ + FILE *f = fopen(shader_path, "w"); + if (f == NULL) { + printf("Error writing to file: %s\n", shader_path); + } + for (int j = 0; j < num_shaders; j++) { + fprintf(f, "%s", code[j]); + } + fclose(f); + printf("Shader file written to disk: %s\n", shader_path); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Creation / Destruction + * \{ */ + +GPUShader *GPU_shader_create(const char *vertexcode, + const char *fragcode, + const char *geocode, + const char *libcode, + const char *defines, + const char *shname) +{ + return GPU_shader_create_ex( + vertexcode, fragcode, geocode, libcode, defines, GPU_SHADER_TFB_NONE, NULL, 0, shname); +} + +GPUShader *GPU_shader_create_from_python(const char *vertexcode, + const char *fragcode, + const char *geocode, + const char *libcode, + const char *defines) +{ + char *libcodecat = NULL; + + if (libcode == NULL) { + libcode = datatoc_gpu_shader_colorspace_lib_glsl; + } + else { + libcode = libcodecat = BLI_strdupcat(libcode, datatoc_gpu_shader_colorspace_lib_glsl); + } + + GPUShader *sh = GPU_shader_create_ex( + vertexcode, fragcode, geocode, libcode, defines, GPU_SHADER_TFB_NONE, NULL, 0, NULL); + + MEM_SAFE_FREE(libcodecat); + return sh; +} + +GPUShader *GPU_shader_load_from_binary(const char *binary, + const int binary_format, + const int binary_len, + const char *shname) +{ + BLI_assert(GL_ARB_get_program_binary); + int success; + int program = glCreateProgram(); + + glProgramBinary(program, binary_format, binary, binary_len); + glGetProgramiv(program, GL_LINK_STATUS, &success); + + if (success) { + glUseProgram(program); + + GPUShader *shader = (GPUShader *)MEM_callocN(sizeof(*shader), __func__); + shader->interface = GPU_shaderinterface_create(program); + shader->program = program; + +#ifndef NDEBUG + BLI_snprintf(shader->name, sizeof(shader->name), "%s_%u", shname, g_shaderid++); +#else + UNUSED_VARS(shname); +#endif + + return shader; + } + + glDeleteProgram(program); + return NULL; +} + +GPUShader *GPU_shader_create_ex(const char *vertexcode, + const char *fragcode, + const char *geocode, + const char *libcode, + const char *defines, + const eGPUShaderTFBType tf_type, + const char **tf_names, + const int tf_count, + const char *shname) +{ + GLint status; + GLchar log[5000]; + GLsizei length = 0; + GPUShader *shader; + char standard_defines[MAX_DEFINE_LENGTH] = ""; + char standard_extensions[MAX_EXT_DEFINE_LENGTH] = ""; + + shader = (GPUShader *)MEM_callocN(sizeof(GPUShader), "GPUShader"); + gpu_dump_shaders(NULL, 0, DEBUG_SHADER_NONE); + +#ifndef NDEBUG + BLI_snprintf(shader->name, sizeof(shader->name), "%s_%u", shname, g_shaderid++); +#else + UNUSED_VARS(shname); +#endif + + /* At least a vertex shader and a fragment shader are required. */ + BLI_assert((fragcode != NULL) && (vertexcode != NULL)); + + if (vertexcode) { + shader->vertex = glCreateShader(GL_VERTEX_SHADER); + } + if (fragcode) { + shader->fragment = glCreateShader(GL_FRAGMENT_SHADER); + } + if (geocode) { + shader->geometry = glCreateShader(GL_GEOMETRY_SHADER); + } + + shader->program = glCreateProgram(); + + if (!shader->program || (vertexcode && !shader->vertex) || (fragcode && !shader->fragment) || + (geocode && !shader->geometry)) { + fprintf(stderr, "GPUShader, object creation failed.\n"); + GPU_shader_free(shader); + return NULL; + } + + gpu_shader_standard_defines(standard_defines); + gpu_shader_standard_extensions(standard_extensions); + + if (vertexcode) { + const char *source[7]; + /* custom limit, may be too small, beware */ + int num_source = 0; + + source[num_source++] = gpu_shader_version(); + source[num_source++] = + "#define GPU_VERTEX_SHADER\n" + "#define IN_OUT out\n"; + source[num_source++] = standard_extensions; + source[num_source++] = standard_defines; + + if (geocode) { + source[num_source++] = "#define USE_GEOMETRY_SHADER\n"; + } + if (defines) { + source[num_source++] = defines; + } + source[num_source++] = vertexcode; + + gpu_dump_shaders(source, num_source, DEBUG_SHADER_VERTEX); + + glAttachShader(shader->program, shader->vertex); + glShaderSource(shader->vertex, num_source, source, NULL); + + glCompileShader(shader->vertex); + glGetShaderiv(shader->vertex, GL_COMPILE_STATUS, &status); + + if (!status) { + glGetShaderInfoLog(shader->vertex, sizeof(log), &length, log); + shader_print_errors("compile", log, source, num_source); + + GPU_shader_free(shader); + return NULL; + } + } + + if (fragcode) { + const char *source[8]; + int num_source = 0; + + source[num_source++] = gpu_shader_version(); + source[num_source++] = + "#define GPU_FRAGMENT_SHADER\n" + "#define IN_OUT in\n"; + source[num_source++] = standard_extensions; + source[num_source++] = standard_defines; + + if (geocode) { + source[num_source++] = "#define USE_GEOMETRY_SHADER\n"; + } + if (defines) { + source[num_source++] = defines; + } + if (libcode) { + source[num_source++] = libcode; + } + source[num_source++] = fragcode; + + gpu_dump_shaders(source, num_source, DEBUG_SHADER_FRAGMENT); + + glAttachShader(shader->program, shader->fragment); + glShaderSource(shader->fragment, num_source, source, NULL); + + glCompileShader(shader->fragment); + glGetShaderiv(shader->fragment, GL_COMPILE_STATUS, &status); + + if (!status) { + glGetShaderInfoLog(shader->fragment, sizeof(log), &length, log); + shader_print_errors("compile", log, source, num_source); + + GPU_shader_free(shader); + return NULL; + } + } + + if (geocode) { + const char *source[6]; + int num_source = 0; + + source[num_source++] = gpu_shader_version(); + source[num_source++] = "#define GPU_GEOMETRY_SHADER\n"; + source[num_source++] = standard_extensions; + source[num_source++] = standard_defines; + + if (defines) { + source[num_source++] = defines; + } + source[num_source++] = geocode; + + gpu_dump_shaders(source, num_source, DEBUG_SHADER_GEOMETRY); + + glAttachShader(shader->program, shader->geometry); + glShaderSource(shader->geometry, num_source, source, NULL); + + glCompileShader(shader->geometry); + glGetShaderiv(shader->geometry, GL_COMPILE_STATUS, &status); + + if (!status) { + glGetShaderInfoLog(shader->geometry, sizeof(log), &length, log); + shader_print_errors("compile", log, source, num_source); + + GPU_shader_free(shader); + return NULL; + } + } + + if (tf_names != NULL) { + glTransformFeedbackVaryings(shader->program, tf_count, tf_names, GL_INTERLEAVED_ATTRIBS); + /* Primitive type must be setup */ + BLI_assert(tf_type != GPU_SHADER_TFB_NONE); + shader->feedback_transform_type = tf_type; + } + + glLinkProgram(shader->program); + glGetProgramiv(shader->program, GL_LINK_STATUS, &status); + if (!status) { + glGetProgramInfoLog(shader->program, sizeof(log), &length, log); + /* print attached shaders in pipeline order */ + if (defines) { + shader_print_errors("linking", log, &defines, 1); + } + if (vertexcode) { + shader_print_errors("linking", log, &vertexcode, 1); + } + if (geocode) { + shader_print_errors("linking", log, &geocode, 1); + } + if (libcode) { + shader_print_errors("linking", log, &libcode, 1); + } + if (fragcode) { + shader_print_errors("linking", log, &fragcode, 1); + } + + GPU_shader_free(shader); + return NULL; + } + + glUseProgram(shader->program); + shader->interface = GPU_shaderinterface_create(shader->program); + + return shader; +} + +#undef DEBUG_SHADER_GEOMETRY +#undef DEBUG_SHADER_FRAGMENT +#undef DEBUG_SHADER_VERTEX +#undef DEBUG_SHADER_NONE + +void GPU_shader_free(GPUShader *shader) +{ +#if 0 /* Would be nice to have, but for now the Deferred compilation \ + * does not have a GPUContext. */ + BLI_assert(GPU_context_active_get() != NULL); +#endif + BLI_assert(shader); + + if (shader->vertex) { + glDeleteShader(shader->vertex); + } + if (shader->geometry) { + glDeleteShader(shader->geometry); + } + if (shader->fragment) { + glDeleteShader(shader->fragment); + } + if (shader->program) { + glDeleteProgram(shader->program); + } + + if (shader->interface) { + GPU_shaderinterface_discard(shader->interface); + } + + MEM_freeN(shader); +} + +static const char *string_join_array_maybe_alloc(const char **str_arr, bool *r_is_alloc) +{ + bool is_alloc = false; + if (str_arr == NULL) { + *r_is_alloc = false; + return NULL; + } + /* Skip empty strings (avoid alloc if we can). */ + while (str_arr[0] && str_arr[0][0] == '\0') { + str_arr++; + } + int i; + for (i = 0; str_arr[i]; i++) { + if (i != 0 && str_arr[i][0] != '\0') { + is_alloc = true; + } + } + *r_is_alloc = is_alloc; + if (is_alloc) { + return BLI_string_join_arrayN(str_arr, i); + } + + return str_arr[0]; +} + +/** + * Use via #GPU_shader_create_from_arrays macro (avoids passing in param). + * + * Similar to #DRW_shader_create_with_lib with the ability to include libs for each type of shader. + * + * It has the advantage that each item can be conditionally included + * without having to build the string inline, then free it. + * + * \param params: NULL terminated arrays of strings. + * + * Example: + * \code{.c} + * sh = GPU_shader_create_from_arrays({ + * .vert = (const char *[]){shader_lib_glsl, shader_vert_glsl, NULL}, + * .geom = (const char *[]){shader_geom_glsl, NULL}, + * .frag = (const char *[]){shader_frag_glsl, NULL}, + * .defs = (const char *[]){"#define DEFINE\n", test ? "#define OTHER_DEFINE\n" : "", NULL}, + * }); + * \endcode + */ +struct GPUShader *GPU_shader_create_from_arrays_impl( + const struct GPU_ShaderCreateFromArray_Params *params) +{ + struct { + const char *str; + bool is_alloc; + } str_dst[4] = {{0}}; + const char **str_src[4] = {params->vert, params->frag, params->geom, params->defs}; + + for (int i = 0; i < ARRAY_SIZE(str_src); i++) { + str_dst[i].str = string_join_array_maybe_alloc(str_src[i], &str_dst[i].is_alloc); + } + + GPUShader *sh = GPU_shader_create( + str_dst[0].str, str_dst[1].str, str_dst[2].str, NULL, str_dst[3].str, __func__); + + for (int i = 0; i < ARRAY_SIZE(str_dst); i++) { + if (str_dst[i].is_alloc) { + MEM_freeN((void *)str_dst[i].str); + } + } + return sh; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Binding + * \{ */ + +void GPU_shader_bind(GPUShader *shader) +{ + BLI_assert(shader && shader->program); + + glUseProgram(shader->program); + GPU_matrix_bind(shader->interface); + GPU_shader_set_srgb_uniform(shader->interface); +} + +void GPU_shader_unbind(void) +{ + glUseProgram(0); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Transform feedback + * \{ */ + +bool GPU_shader_transform_feedback_enable(GPUShader *shader, uint vbo_id) +{ + if (shader->feedback_transform_type == GPU_SHADER_TFB_NONE) { + return false; + } + + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vbo_id); + + switch (shader->feedback_transform_type) { + case GPU_SHADER_TFB_POINTS: + glBeginTransformFeedback(GL_POINTS); + return true; + case GPU_SHADER_TFB_LINES: + glBeginTransformFeedback(GL_LINES); + return true; + case GPU_SHADER_TFB_TRIANGLES: + glBeginTransformFeedback(GL_TRIANGLES); + return true; + default: + return false; + } +} + +void GPU_shader_transform_feedback_disable(GPUShader *UNUSED(shader)) +{ + glEndTransformFeedback(); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Uniforms / Resource location + * \{ */ + +int GPU_shader_get_uniform(GPUShader *shader, const char *name) +{ + BLI_assert(shader && shader->program); + const GPUShaderInput *uniform = GPU_shaderinterface_uniform(shader->interface, name); + return uniform ? uniform->location : -1; +} + +int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin) +{ + BLI_assert(shader && shader->program); + return GPU_shaderinterface_uniform_builtin(shader->interface, + static_cast<GPUUniformBuiltin>(builtin)); +} + +int GPU_shader_get_builtin_block(GPUShader *shader, int builtin) +{ + BLI_assert(shader && shader->program); + return GPU_shaderinterface_block_builtin(shader->interface, + static_cast<GPUUniformBlockBuiltin>(builtin)); +} + +int GPU_shader_get_uniform_block(GPUShader *shader, const char *name) +{ + BLI_assert(shader && shader->program); + const GPUShaderInput *ubo = GPU_shaderinterface_ubo(shader->interface, name); + return ubo ? ubo->location : -1; +} + +int GPU_shader_get_uniform_block_binding(GPUShader *shader, const char *name) +{ + BLI_assert(shader && shader->program); + const GPUShaderInput *ubo = GPU_shaderinterface_ubo(shader->interface, name); + return ubo ? ubo->binding : -1; +} + +int GPU_shader_get_texture_binding(GPUShader *shader, const char *name) +{ + BLI_assert(shader && shader->program); + const GPUShaderInput *tex = GPU_shaderinterface_uniform(shader->interface, name); + return tex ? tex->binding : -1; +} + +int GPU_shader_get_attribute(GPUShader *shader, const char *name) +{ + BLI_assert(shader && shader->program); + const GPUShaderInput *attr = GPU_shaderinterface_attr(shader->interface, name); + return attr ? attr->location : -1; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Getters + * \{ */ + +/* Clement : Temp */ +int GPU_shader_get_program(GPUShader *shader) +{ + return (int)shader->program; +} + +char *GPU_shader_get_binary(GPUShader *shader, uint *r_binary_format, int *r_binary_len) +{ + BLI_assert(GLEW_ARB_get_program_binary); + char *r_binary; + int binary_len = 0; + + glGetProgramiv(shader->program, GL_PROGRAM_BINARY_LENGTH, &binary_len); + r_binary = (char *)MEM_mallocN(binary_len, __func__); + glGetProgramBinary(shader->program, binary_len, NULL, r_binary_format, r_binary); + + if (r_binary_len) { + *r_binary_len = binary_len; + } + + return r_binary; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Uniforms setters + * \{ */ + +void GPU_shader_uniform_float(GPUShader *UNUSED(shader), int location, float value) +{ + if (location == -1) { + return; + } + + glUniform1f(location, value); +} + +void GPU_shader_uniform_vector( + GPUShader *UNUSED(shader), int location, int length, int arraysize, const float *value) +{ + if (location == -1 || value == NULL) { + return; + } + + switch (length) { + case 1: + glUniform1fv(location, arraysize, value); + break; + case 2: + glUniform2fv(location, arraysize, value); + break; + case 3: + glUniform3fv(location, arraysize, value); + break; + case 4: + glUniform4fv(location, arraysize, value); + break; + case 9: + glUniformMatrix3fv(location, arraysize, 0, value); + break; + case 16: + glUniformMatrix4fv(location, arraysize, 0, value); + break; + default: + BLI_assert(0); + break; + } +} + +void GPU_shader_uniform_int(GPUShader *UNUSED(shader), int location, int value) +{ + if (location == -1) { + return; + } + + glUniform1i(location, value); +} + +void GPU_shader_uniform_vector_int( + GPUShader *UNUSED(shader), int location, int length, int arraysize, const int *value) +{ + if (location == -1) { + return; + } + + switch (length) { + case 1: + glUniform1iv(location, arraysize, value); + break; + case 2: + glUniform2iv(location, arraysize, value); + break; + case 3: + glUniform3iv(location, arraysize, value); + break; + case 4: + glUniform4iv(location, arraysize, value); + break; + default: + BLI_assert(0); + break; + } +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name sRGB Rendering Workaround + * + * The viewport overlay frame-buffer is sRGB and will expect shaders to output display referred + * Linear colors. But other frame-buffers (i.e: the area frame-buffers) are not sRGB and require + * the shader output color to be in sRGB space + * (assumed display encoded color-space as the time of writing). + * For this reason we have a uniform to switch the transform on and off depending on the current + * frame-buffer color-space. + * \{ */ + +static int g_shader_builtin_srgb_transform = 0; + +void GPU_shader_set_srgb_uniform(const GPUShaderInterface *interface) +{ + int32_t loc = GPU_shaderinterface_uniform_builtin(interface, GPU_UNIFORM_SRGB_TRANSFORM); + if (loc != -1) { + glUniform1i(loc, g_shader_builtin_srgb_transform); + } +} + +void GPU_shader_set_framebuffer_srgb_target(int use_srgb_to_linear) +{ + g_shader_builtin_srgb_transform = use_srgb_to_linear; +} + +/** \} */ diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader_builtin.c index 9ea798e5669..9c0692b76e2 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader_builtin.c @@ -153,11 +153,6 @@ const struct GPUShaderConfigData GPU_shader_cfg_data[GPU_SHADER_CFG_LEN] = { /* cache of built-in shaders (each is created on first use) */ static GPUShader *builtin_shaders[GPU_SHADER_CFG_LEN][GPU_SHADER_BUILTIN_LEN] = {{NULL}}; -static int g_shader_builtin_srgb_transform = 0; - -#ifndef NDEBUG -static uint g_shaderid = 0; -#endif typedef struct { const char *vert; @@ -168,727 +163,6 @@ typedef struct { const char *defs; } GPUShaderStages; -static void shader_print_errors(const char *task, const char *log, const char **code, int totcode) -{ - int line = 1; - - fprintf(stderr, "GPUShader: %s error:\n", task); - - for (int i = 0; i < totcode; i++) { - const char *c, *pos, *end = code[i] + strlen(code[i]); - - if (G.debug & G_DEBUG) { - fprintf(stderr, "===== shader string %d ====\n", i + 1); - - c = code[i]; - while ((c < end) && (pos = strchr(c, '\n'))) { - fprintf(stderr, "%2d ", line); - fwrite(c, (pos + 1) - c, 1, stderr); - c = pos + 1; - line++; - } - - fprintf(stderr, "%s", c); - } - } - - fprintf(stderr, "%s\n", log); -} - -static const char *gpu_shader_version(void) -{ - return "#version 330\n"; -} - -static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH]) -{ - /* enable extensions for features that are not part of our base GLSL version - * don't use an extension for something already available! - */ - - if (GLEW_ARB_texture_gather) { - /* There is a bug on older Nvidia GPU where GL_ARB_texture_gather - * is reported to be supported but yield a compile error (see T55802). */ - if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) || GLEW_VERSION_4_0) { - strcat(defines, "#extension GL_ARB_texture_gather: enable\n"); - - /* Some drivers don't agree on GLEW_ARB_texture_gather and the actual support in the - * shader so double check the preprocessor define (see T56544). */ - if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) && !GLEW_VERSION_4_0) { - strcat(defines, "#ifdef GL_ARB_texture_gather\n"); - strcat(defines, "# define GPU_ARB_texture_gather\n"); - strcat(defines, "#endif\n"); - } - else { - strcat(defines, "#define GPU_ARB_texture_gather\n"); - } - } - } - if (GLEW_ARB_texture_query_lod) { - /* a #version 400 feature, but we use #version 330 maximum so use extension */ - strcat(defines, "#extension GL_ARB_texture_query_lod: enable\n"); - } - if (GLEW_ARB_shader_draw_parameters) { - strcat(defines, "#extension GL_ARB_shader_draw_parameters : enable\n"); - } - if (GPU_arb_texture_cube_map_array_is_supported()) { - strcat(defines, "#extension GL_ARB_texture_cube_map_array : enable\n"); - strcat(defines, "#define GPU_ARB_texture_cube_map_array\n"); - } -} - -static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH]) -{ - /* some useful defines to detect GPU type */ - if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) { - strcat(defines, "#define GPU_ATI\n"); - if (GPU_crappy_amd_driver()) { - strcat(defines, "#define GPU_DEPRECATED_AMD_DRIVER\n"); - } - } - else if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY)) { - strcat(defines, "#define GPU_NVIDIA\n"); - } - else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) { - strcat(defines, "#define GPU_INTEL\n"); - } - - /* some useful defines to detect OS type */ - if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_WIN, GPU_DRIVER_ANY)) { - strcat(defines, "#define OS_WIN\n"); - } - else if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY)) { - strcat(defines, "#define OS_MAC\n"); - } - else if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_UNIX, GPU_DRIVER_ANY)) { - strcat(defines, "#define OS_UNIX\n"); - } - - float derivatives_factors[2]; - GPU_get_dfdy_factors(derivatives_factors); - if (derivatives_factors[0] == 1.0f) { - strcat(defines, "#define DFDX_SIGN 1.0\n"); - } - else { - strcat(defines, "#define DFDX_SIGN -1.0\n"); - } - - if (derivatives_factors[1] == 1.0f) { - strcat(defines, "#define DFDY_SIGN 1.0\n"); - } - else { - strcat(defines, "#define DFDY_SIGN -1.0\n"); - } -} - -GPUShader *GPU_shader_create(const char *vertexcode, - const char *fragcode, - const char *geocode, - const char *libcode, - const char *defines, - const char *shname) -{ - return GPU_shader_create_ex( - vertexcode, fragcode, geocode, libcode, defines, GPU_SHADER_TFB_NONE, NULL, 0, shname); -} - -GPUShader *GPU_shader_create_from_python(const char *vertexcode, - const char *fragcode, - const char *geocode, - const char *libcode, - const char *defines) -{ - char *libcodecat = NULL; - - if (libcode == NULL) { - libcode = datatoc_gpu_shader_colorspace_lib_glsl; - } - else { - libcode = libcodecat = BLI_strdupcat(libcode, datatoc_gpu_shader_colorspace_lib_glsl); - } - - GPUShader *sh = GPU_shader_create_ex( - vertexcode, fragcode, geocode, libcode, defines, GPU_SHADER_TFB_NONE, NULL, 0, NULL); - - MEM_SAFE_FREE(libcodecat); - return sh; -} - -GPUShader *GPU_shader_load_from_binary(const char *binary, - const int binary_format, - const int binary_len, - const char *shname) -{ - BLI_assert(GL_ARB_get_program_binary); - int success; - int program = glCreateProgram(); - - glProgramBinary(program, binary_format, binary, binary_len); - glGetProgramiv(program, GL_LINK_STATUS, &success); - - if (success) { - glUseProgram(program); - - GPUShader *shader = MEM_callocN(sizeof(*shader), __func__); - shader->interface = GPU_shaderinterface_create(program); - shader->program = program; - -#ifndef NDEBUG - BLI_snprintf(shader->name, sizeof(shader->name), "%s_%u", shname, g_shaderid++); -#else - UNUSED_VARS(shname); -#endif - - return shader; - } - - glDeleteProgram(program); - return NULL; -} - -#define DEBUG_SHADER_NONE "" -#define DEBUG_SHADER_VERTEX "vert" -#define DEBUG_SHADER_FRAGMENT "frag" -#define DEBUG_SHADER_GEOMETRY "geom" - -/** - * Dump GLSL shaders to disk - * - * This is used for profiling shader performance externally and debug if shader code is correct. - * If called with no code, it simply bumps the shader index, so different shaders for the same - * program share the same index. - */ -static void gpu_dump_shaders(const char **code, const int num_shaders, const char *extension) -{ - if ((G.debug & G_DEBUG_GPU_SHADERS) == 0) { - return; - } - - /* We use the same shader index for shaders in the same program. - * So we call this function once before calling for the individual shaders. */ - static int shader_index = 0; - if (code == NULL) { - shader_index++; - BLI_assert(STREQ(DEBUG_SHADER_NONE, extension)); - return; - } - - /* Determine the full path of the new shader. */ - char shader_path[FILE_MAX]; - - char file_name[512] = {'\0'}; - sprintf(file_name, "%04d.%s", shader_index, extension); - - BLI_join_dirfile(shader_path, sizeof(shader_path), BKE_tempdir_session(), file_name); - - /* Write shader to disk. */ - FILE *f = fopen(shader_path, "w"); - if (f == NULL) { - printf("Error writing to file: %s\n", shader_path); - } - for (int j = 0; j < num_shaders; j++) { - fprintf(f, "%s", code[j]); - } - fclose(f); - printf("Shader file written to disk: %s\n", shader_path); -} - -GPUShader *GPU_shader_create_ex(const char *vertexcode, - const char *fragcode, - const char *geocode, - const char *libcode, - const char *defines, - const eGPUShaderTFBType tf_type, - const char **tf_names, - const int tf_count, - const char *shname) -{ - GLint status; - GLchar log[5000]; - GLsizei length = 0; - GPUShader *shader; - char standard_defines[MAX_DEFINE_LENGTH] = ""; - char standard_extensions[MAX_EXT_DEFINE_LENGTH] = ""; - - shader = MEM_callocN(sizeof(GPUShader), "GPUShader"); - gpu_dump_shaders(NULL, 0, DEBUG_SHADER_NONE); - -#ifndef NDEBUG - BLI_snprintf(shader->name, sizeof(shader->name), "%s_%u", shname, g_shaderid++); -#else - UNUSED_VARS(shname); -#endif - - /* At least a vertex shader and a fragment shader are required. */ - BLI_assert((fragcode != NULL) && (vertexcode != NULL)); - - if (vertexcode) { - shader->vertex = glCreateShader(GL_VERTEX_SHADER); - } - if (fragcode) { - shader->fragment = glCreateShader(GL_FRAGMENT_SHADER); - } - if (geocode) { - shader->geometry = glCreateShader(GL_GEOMETRY_SHADER); - } - - shader->program = glCreateProgram(); - - if (!shader->program || (vertexcode && !shader->vertex) || (fragcode && !shader->fragment) || - (geocode && !shader->geometry)) { - fprintf(stderr, "GPUShader, object creation failed.\n"); - GPU_shader_free(shader); - return NULL; - } - - gpu_shader_standard_defines(standard_defines); - gpu_shader_standard_extensions(standard_extensions); - - if (vertexcode) { - const char *source[6]; - /* custom limit, may be too small, beware */ - int num_source = 0; - - source[num_source++] = gpu_shader_version(); - source[num_source++] = - "#define GPU_VERTEX_SHADER\n" - "#define IN_OUT out\n"; - source[num_source++] = standard_extensions; - source[num_source++] = standard_defines; - - if (defines) { - source[num_source++] = defines; - } - source[num_source++] = vertexcode; - - gpu_dump_shaders(source, num_source, DEBUG_SHADER_VERTEX); - - glAttachShader(shader->program, shader->vertex); - glShaderSource(shader->vertex, num_source, source, NULL); - - glCompileShader(shader->vertex); - glGetShaderiv(shader->vertex, GL_COMPILE_STATUS, &status); - - if (!status) { - glGetShaderInfoLog(shader->vertex, sizeof(log), &length, log); - shader_print_errors("compile", log, source, num_source); - - GPU_shader_free(shader); - return NULL; - } - } - - if (fragcode) { - const char *source[7]; - int num_source = 0; - - source[num_source++] = gpu_shader_version(); - source[num_source++] = - "#define GPU_FRAGMENT_SHADER\n" - "#define IN_OUT in\n"; - source[num_source++] = standard_extensions; - source[num_source++] = standard_defines; - - if (defines) { - source[num_source++] = defines; - } - if (libcode) { - source[num_source++] = libcode; - } - source[num_source++] = fragcode; - - gpu_dump_shaders(source, num_source, DEBUG_SHADER_FRAGMENT); - - glAttachShader(shader->program, shader->fragment); - glShaderSource(shader->fragment, num_source, source, NULL); - - glCompileShader(shader->fragment); - glGetShaderiv(shader->fragment, GL_COMPILE_STATUS, &status); - - if (!status) { - glGetShaderInfoLog(shader->fragment, sizeof(log), &length, log); - shader_print_errors("compile", log, source, num_source); - - GPU_shader_free(shader); - return NULL; - } - } - - if (geocode) { - const char *source[6]; - int num_source = 0; - - source[num_source++] = gpu_shader_version(); - source[num_source++] = "#define GPU_GEOMETRY_SHADER\n"; - source[num_source++] = standard_extensions; - source[num_source++] = standard_defines; - - if (defines) { - source[num_source++] = defines; - } - source[num_source++] = geocode; - - gpu_dump_shaders(source, num_source, DEBUG_SHADER_GEOMETRY); - - glAttachShader(shader->program, shader->geometry); - glShaderSource(shader->geometry, num_source, source, NULL); - - glCompileShader(shader->geometry); - glGetShaderiv(shader->geometry, GL_COMPILE_STATUS, &status); - - if (!status) { - glGetShaderInfoLog(shader->geometry, sizeof(log), &length, log); - shader_print_errors("compile", log, source, num_source); - - GPU_shader_free(shader); - return NULL; - } - } - - if (tf_names != NULL) { - glTransformFeedbackVaryings(shader->program, tf_count, tf_names, GL_INTERLEAVED_ATTRIBS); - /* Primitive type must be setup */ - BLI_assert(tf_type != GPU_SHADER_TFB_NONE); - shader->feedback_transform_type = tf_type; - } - - glLinkProgram(shader->program); - glGetProgramiv(shader->program, GL_LINK_STATUS, &status); - if (!status) { - glGetProgramInfoLog(shader->program, sizeof(log), &length, log); - /* print attached shaders in pipeline order */ - if (vertexcode) { - shader_print_errors("linking", log, &vertexcode, 1); - } - if (geocode) { - shader_print_errors("linking", log, &geocode, 1); - } - if (libcode) { - shader_print_errors("linking", log, &libcode, 1); - } - if (fragcode) { - shader_print_errors("linking", log, &fragcode, 1); - } - - GPU_shader_free(shader); - return NULL; - } - - glUseProgram(shader->program); - shader->interface = GPU_shaderinterface_create(shader->program); - - return shader; -} - -#undef DEBUG_SHADER_GEOMETRY -#undef DEBUG_SHADER_FRAGMENT -#undef DEBUG_SHADER_VERTEX -#undef DEBUG_SHADER_NONE - -static const char *string_join_array_maybe_alloc(const char **str_arr, bool *r_is_alloc) -{ - bool is_alloc = false; - if (str_arr == NULL) { - *r_is_alloc = false; - return NULL; - } - /* Skip empty strings (avoid alloc if we can). */ - while (str_arr[0] && str_arr[0][0] == '\0') { - str_arr++; - } - int i; - for (i = 0; str_arr[i]; i++) { - if (i != 0 && str_arr[i][0] != '\0') { - is_alloc = true; - } - } - *r_is_alloc = is_alloc; - if (is_alloc) { - return BLI_string_join_arrayN(str_arr, i); - } - else { - return str_arr[0]; - } -} - -/** - * Use via #GPU_shader_create_from_arrays macro (avoids passing in param). - * - * Similar to #DRW_shader_create_with_lib with the ability to include libs for each type of shader. - * - * It has the advantage that each item can be conditionally included - * without having to build the string inline, then free it. - * - * \param params: NULL terminated arrays of strings. - * - * Example: - * \code{.c} - * sh = GPU_shader_create_from_arrays({ - * .vert = (const char *[]){shader_lib_glsl, shader_vert_glsl, NULL}, - * .geom = (const char *[]){shader_geom_glsl, NULL}, - * .frag = (const char *[]){shader_frag_glsl, NULL}, - * .defs = (const char *[]){"#define DEFINE\n", test ? "#define OTHER_DEFINE\n" : "", NULL}, - * }); - * \endcode - */ -struct GPUShader *GPU_shader_create_from_arrays_impl( - const struct GPU_ShaderCreateFromArray_Params *params) -{ - struct { - const char *str; - bool is_alloc; - } str_dst[4] = {{0}}; - const char **str_src[4] = {params->vert, params->frag, params->geom, params->defs}; - - for (int i = 0; i < ARRAY_SIZE(str_src); i++) { - str_dst[i].str = string_join_array_maybe_alloc(str_src[i], &str_dst[i].is_alloc); - } - - GPUShader *sh = GPU_shader_create( - str_dst[0].str, str_dst[1].str, str_dst[2].str, NULL, str_dst[3].str, __func__); - - for (int i = 0; i < ARRAY_SIZE(str_dst); i++) { - if (str_dst[i].is_alloc) { - MEM_freeN((void *)str_dst[i].str); - } - } - return sh; -} - -void GPU_shader_bind(GPUShader *shader) -{ - BLI_assert(shader && shader->program); - - glUseProgram(shader->program); - GPU_matrix_bind(shader->interface); - GPU_shader_set_srgb_uniform(shader->interface); -} - -void GPU_shader_unbind(void) -{ - glUseProgram(0); -} - -bool GPU_shader_transform_feedback_enable(GPUShader *shader, uint vbo_id) -{ - if (shader->feedback_transform_type == GPU_SHADER_TFB_NONE) { - return false; - } - - glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vbo_id); - - switch (shader->feedback_transform_type) { - case GPU_SHADER_TFB_POINTS: - glBeginTransformFeedback(GL_POINTS); - return true; - case GPU_SHADER_TFB_LINES: - glBeginTransformFeedback(GL_LINES); - return true; - case GPU_SHADER_TFB_TRIANGLES: - glBeginTransformFeedback(GL_TRIANGLES); - return true; - default: - return false; - } -} - -void GPU_shader_transform_feedback_disable(GPUShader *UNUSED(shader)) -{ - glEndTransformFeedback(); -} - -void GPU_shader_free(GPUShader *shader) -{ -#if 0 /* Would be nice to have, but for now the Deferred compilation \ - * does not have a GPUContext. */ - BLI_assert(GPU_context_active_get() != NULL); -#endif - BLI_assert(shader); - - if (shader->vertex) { - glDeleteShader(shader->vertex); - } - if (shader->geometry) { - glDeleteShader(shader->geometry); - } - if (shader->fragment) { - glDeleteShader(shader->fragment); - } - if (shader->program) { - glDeleteProgram(shader->program); - } - - if (shader->interface) { - GPU_shaderinterface_discard(shader->interface); - } - - MEM_freeN(shader); -} - -int GPU_shader_get_uniform(GPUShader *shader, const char *name) -{ - BLI_assert(shader && shader->program); - const GPUShaderInput *uniform = GPU_shaderinterface_uniform(shader->interface, name); - return uniform ? uniform->location : -1; -} - -int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin) -{ - BLI_assert(shader && shader->program); - return GPU_shaderinterface_uniform_builtin(shader->interface, builtin); -} - -int GPU_shader_get_builtin_block(GPUShader *shader, int builtin) -{ - BLI_assert(shader && shader->program); - return GPU_shaderinterface_block_builtin(shader->interface, builtin); -} - -int GPU_shader_get_uniform_block(GPUShader *shader, const char *name) -{ - BLI_assert(shader && shader->program); - const GPUShaderInput *ubo = GPU_shaderinterface_ubo(shader->interface, name); - return ubo ? ubo->location : -1; -} - -int GPU_shader_get_uniform_block_binding(GPUShader *shader, const char *name) -{ - BLI_assert(shader && shader->program); - const GPUShaderInput *ubo = GPU_shaderinterface_ubo(shader->interface, name); - return ubo ? ubo->binding : -1; -} - -int GPU_shader_get_texture_binding(GPUShader *shader, const char *name) -{ - BLI_assert(shader && shader->program); - const GPUShaderInput *tex = GPU_shaderinterface_uniform(shader->interface, name); - return tex ? tex->binding : -1; -} - -void *GPU_shader_get_interface(GPUShader *shader) -{ - return shader->interface; -} - -/* Clement : Temp */ -int GPU_shader_get_program(GPUShader *shader) -{ - return (int)shader->program; -} - -void GPU_shader_uniform_float(GPUShader *UNUSED(shader), int location, float value) -{ - if (location == -1) { - return; - } - - glUniform1f(location, value); -} - -void GPU_shader_uniform_vector( - GPUShader *UNUSED(shader), int location, int length, int arraysize, const float *value) -{ - if (location == -1 || value == NULL) { - return; - } - - switch (length) { - case 1: - glUniform1fv(location, arraysize, value); - break; - case 2: - glUniform2fv(location, arraysize, value); - break; - case 3: - glUniform3fv(location, arraysize, value); - break; - case 4: - glUniform4fv(location, arraysize, value); - break; - case 9: - glUniformMatrix3fv(location, arraysize, 0, value); - break; - case 16: - glUniformMatrix4fv(location, arraysize, 0, value); - break; - default: - BLI_assert(0); - break; - } -} - -void GPU_shader_uniform_vector_int( - GPUShader *UNUSED(shader), int location, int length, int arraysize, const int *value) -{ - if (location == -1) { - return; - } - - switch (length) { - case 1: - glUniform1iv(location, arraysize, value); - break; - case 2: - glUniform2iv(location, arraysize, value); - break; - case 3: - glUniform3iv(location, arraysize, value); - break; - case 4: - glUniform4iv(location, arraysize, value); - break; - default: - BLI_assert(0); - break; - } -} - -void GPU_shader_uniform_int(GPUShader *UNUSED(shader), int location, int value) -{ - if (location == -1) { - return; - } - - glUniform1i(location, value); -} - -void GPU_shader_set_srgb_uniform(const GPUShaderInterface *interface) -{ - int32_t loc = GPU_shaderinterface_uniform_builtin(interface, GPU_UNIFORM_SRGB_TRANSFORM); - if (loc != -1) { - glUniform1i(loc, g_shader_builtin_srgb_transform); - } -} - -int GPU_shader_get_attribute(GPUShader *shader, const char *name) -{ - BLI_assert(shader && shader->program); - const GPUShaderInput *attr = GPU_shaderinterface_attr(shader->interface, name); - return attr ? attr->location : -1; -} - -char *GPU_shader_get_binary(GPUShader *shader, uint *r_binary_format, int *r_binary_len) -{ - BLI_assert(GLEW_ARB_get_program_binary); - char *r_binary; - int binary_len = 0; - - glGetProgramiv(shader->program, GL_PROGRAM_BINARY_LENGTH, &binary_len); - r_binary = MEM_mallocN(binary_len, __func__); - glGetProgramBinary(shader->program, binary_len, NULL, r_binary_format, r_binary); - - if (r_binary_len) { - *r_binary_len = binary_len; - } - - return r_binary; -} - -void GPU_shader_set_framebuffer_srgb_target(int use_srgb_to_linear) -{ - g_shader_builtin_srgb_transform = use_srgb_to_linear; -} - static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = { [GPU_SHADER_TEXT] = { @@ -1242,6 +516,7 @@ GPUShader *GPU_shader_get_builtin_shader_with_config(eGPUBuiltinShader shader, return *sh_p; } + GPUShader *GPU_shader_get_builtin_shader(eGPUBuiltinShader shader) { return GPU_shader_get_builtin_shader_with_config(shader, GPU_SHADER_CFG_DEFAULT); diff --git a/source/blender/gpu/intern/gpu_shader_interface.c b/source/blender/gpu/intern/gpu_shader_interface.cc index 9d9f98c6bb0..7ac4365dd91 100644 --- a/source/blender/gpu/intern/gpu_shader_interface.c +++ b/source/blender/gpu/intern/gpu_shader_interface.cc @@ -47,47 +47,66 @@ static const char *BuiltinUniform_name(GPUUniformBuiltin u) { - static const char *names[] = { - [GPU_UNIFORM_MODEL] = "ModelMatrix", - [GPU_UNIFORM_VIEW] = "ViewMatrix", - [GPU_UNIFORM_MODELVIEW] = "ModelViewMatrix", - [GPU_UNIFORM_PROJECTION] = "ProjectionMatrix", - [GPU_UNIFORM_VIEWPROJECTION] = "ViewProjectionMatrix", - [GPU_UNIFORM_MVP] = "ModelViewProjectionMatrix", - - [GPU_UNIFORM_MODEL_INV] = "ModelMatrixInverse", - [GPU_UNIFORM_VIEW_INV] = "ViewMatrixInverse", - [GPU_UNIFORM_MODELVIEW_INV] = "ModelViewMatrixInverse", - [GPU_UNIFORM_PROJECTION_INV] = "ProjectionMatrixInverse", - [GPU_UNIFORM_VIEWPROJECTION_INV] = "ViewProjectionMatrixInverse", - - [GPU_UNIFORM_NORMAL] = "NormalMatrix", - [GPU_UNIFORM_ORCO] = "OrcoTexCoFactors", - [GPU_UNIFORM_CLIPPLANES] = "WorldClipPlanes", - - [GPU_UNIFORM_COLOR] = "color", - [GPU_UNIFORM_BASE_INSTANCE] = "baseInstance", - [GPU_UNIFORM_RESOURCE_CHUNK] = "resourceChunk", - [GPU_UNIFORM_RESOURCE_ID] = "resourceId", - [GPU_UNIFORM_SRGB_TRANSFORM] = "srgbTarget", - - [GPU_NUM_UNIFORMS] = NULL, - }; - - return names[u]; + switch (u) { + case GPU_UNIFORM_MODEL: + return "ModelMatrix"; + case GPU_UNIFORM_VIEW: + return "ViewMatrix"; + case GPU_UNIFORM_MODELVIEW: + return "ModelViewMatrix"; + case GPU_UNIFORM_PROJECTION: + return "ProjectionMatrix"; + case GPU_UNIFORM_VIEWPROJECTION: + return "ViewProjectionMatrix"; + case GPU_UNIFORM_MVP: + return "ModelViewProjectionMatrix"; + + case GPU_UNIFORM_MODEL_INV: + return "ModelMatrixInverse"; + case GPU_UNIFORM_VIEW_INV: + return "ViewMatrixInverse"; + case GPU_UNIFORM_MODELVIEW_INV: + return "ModelViewMatrixInverse"; + case GPU_UNIFORM_PROJECTION_INV: + return "ProjectionMatrixInverse"; + case GPU_UNIFORM_VIEWPROJECTION_INV: + return "ViewProjectionMatrixInverse"; + + case GPU_UNIFORM_NORMAL: + return "NormalMatrix"; + case GPU_UNIFORM_ORCO: + return "OrcoTexCoFactors"; + case GPU_UNIFORM_CLIPPLANES: + return "WorldClipPlanes"; + + case GPU_UNIFORM_COLOR: + return "color"; + case GPU_UNIFORM_BASE_INSTANCE: + return "baseInstance"; + case GPU_UNIFORM_RESOURCE_CHUNK: + return "resourceChunk"; + case GPU_UNIFORM_RESOURCE_ID: + return "resourceId"; + case GPU_UNIFORM_SRGB_TRANSFORM: + return "srgbTarget"; + + default: + return NULL; + } } static const char *BuiltinUniformBlock_name(GPUUniformBlockBuiltin u) { - static const char *names[] = { - [GPU_UNIFORM_BLOCK_VIEW] = "viewBlock", - [GPU_UNIFORM_BLOCK_MODEL] = "modelBlock", - [GPU_UNIFORM_BLOCK_INFO] = "infoBlock", - - [GPU_NUM_UNIFORM_BLOCKS] = NULL, - }; - - return names[u]; + switch (u) { + case GPU_UNIFORM_BLOCK_VIEW: + return "viewBlock"; + case GPU_UNIFORM_BLOCK_MODEL: + return "modelBlock"; + case GPU_UNIFORM_BLOCK_INFO: + return "infoBlock"; + default: + return NULL; + } } GPU_INLINE bool match(const char *a, const char *b) @@ -138,13 +157,12 @@ GPU_INLINE const GPUShaderInput *input_lookup(const GPUShaderInterface *shaderfa } return NULL; /* not found */ } - else { - /* This is a bit dangerous since we could have a hash collision. - * where the asked uniform that does not exist has the same hash - * as a real uniform. */ - BLI_assert(match(name, shaderface->name_buffer + inputs[i].name_offset)); - return inputs + i; - } + + /* This is a bit dangerous since we could have a hash collision. + * where the asked uniform that does not exist has the same hash + * as a real uniform. */ + BLI_assert(match(name, shaderface->name_buffer + inputs[i].name_offset)); + return inputs + i; } } return NULL; /* not found */ @@ -273,7 +291,7 @@ GPUShaderInterface *GPU_shaderinterface_create(int32_t program) /* Bit set to true if uniform comes from a uniform block. */ BLI_bitmap *uniforms_from_blocks = BLI_BITMAP_NEW(active_uniform_len, __func__); /* Set uniforms from block for exclusion. */ - GLint *ubo_uni_ids = MEM_mallocN(sizeof(GLint) * max_ubo_uni_len, __func__); + GLint *ubo_uni_ids = (GLint *)MEM_mallocN(sizeof(GLint) * max_ubo_uni_len, __func__); for (int i = 0; i < ubo_len; i++) { GLint ubo_uni_len; glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &ubo_uni_len); @@ -291,16 +309,18 @@ GPUShaderInterface *GPU_shaderinterface_create(int32_t program) int input_tot_len = attr_len + ubo_len + uniform_len; size_t interface_size = sizeof(GPUShaderInterface) + sizeof(GPUShaderInput) * input_tot_len; - GPUShaderInterface *shaderface = MEM_callocN(interface_size, "GPUShaderInterface"); + GPUShaderInterface *shaderface = (GPUShaderInterface *)MEM_callocN(interface_size, + "GPUShaderInterface"); shaderface->attribute_len = attr_len; shaderface->ubo_len = ubo_len; shaderface->uniform_len = uniform_len; - shaderface->name_buffer = MEM_mallocN(name_buffer_len, "name_buffer"); + shaderface->name_buffer = (char *)MEM_mallocN(name_buffer_len, "name_buffer"); GPUShaderInput *inputs = shaderface->inputs; /* Temp buffer. */ int input_tmp_len = max_iii(attr_len, ubo_len, uniform_len); - GPUShaderInput *inputs_tmp = MEM_mallocN(sizeof(GPUShaderInput) * input_tmp_len, "name_buffer"); + GPUShaderInput *inputs_tmp = (GPUShaderInput *)MEM_mallocN( + sizeof(GPUShaderInput) * input_tmp_len, "name_buffer"); /* Attributes */ shaderface->enabled_attr_mask = 0; @@ -366,27 +386,29 @@ GPUShaderInterface *GPU_shaderinterface_create(int32_t program) sort_input_list(inputs, inputs_tmp, shaderface->uniform_len); /* Builtin Uniforms */ - for (GPUUniformBuiltin u = 0; u < GPU_NUM_UNIFORMS; u++) { + for (int32_t u_int = 0; u_int < GPU_NUM_UNIFORMS; u_int++) { + GPUUniformBuiltin u = static_cast<GPUUniformBuiltin>(u_int); shaderface->builtins[u] = glGetUniformLocation(program, BuiltinUniform_name(u)); } /* Builtin Uniforms Blocks */ - for (GPUUniformBlockBuiltin u = 0; u < GPU_NUM_UNIFORM_BLOCKS; u++) { + for (int32_t u_int = 0; u_int < GPU_NUM_UNIFORM_BLOCKS; u_int++) { + GPUUniformBlockBuiltin u = static_cast<GPUUniformBlockBuiltin>(u_int); const GPUShaderInput *block = GPU_shaderinterface_ubo(shaderface, BuiltinUniformBlock_name(u)); shaderface->builtin_blocks[u] = (block != NULL) ? block->binding : -1; } /* Batches ref buffer */ shaderface->batches_len = GPU_SHADERINTERFACE_REF_ALLOC_COUNT; - shaderface->batches = MEM_callocN(shaderface->batches_len * sizeof(GPUBatch *), - "GPUShaderInterface batches"); + shaderface->batches = (GPUBatch **)MEM_callocN(shaderface->batches_len * sizeof(GPUBatch *), + "GPUShaderInterface batches"); MEM_freeN(uniforms_from_blocks); MEM_freeN(inputs_tmp); /* Resize name buffer to save some memory. */ if (name_buffer_offset < name_buffer_len) { - shaderface->name_buffer = MEM_reallocN(shaderface->name_buffer, name_buffer_offset); + shaderface->name_buffer = (char *)MEM_reallocN(shaderface->name_buffer, name_buffer_offset); } #if DEBUG_SHADER_INTERFACE @@ -501,8 +523,8 @@ void GPU_shaderinterface_add_batch_ref(GPUShaderInterface *shaderface, GPUBatch /* Not enough place, realloc the array. */ i = shaderface->batches_len; shaderface->batches_len += GPU_SHADERINTERFACE_REF_ALLOC_COUNT; - shaderface->batches = MEM_recallocN(shaderface->batches, - sizeof(GPUBatch *) * shaderface->batches_len); + shaderface->batches = (GPUBatch **)MEM_recallocN(shaderface->batches, + sizeof(GPUBatch *) * shaderface->batches_len); } shaderface->batches[i] = batch; } diff --git a/source/blender/gpu/intern/gpu_shader_private.h b/source/blender/gpu/intern/gpu_shader_private.h index e04d8655421..0f89fbda737 100644 --- a/source/blender/gpu/intern/gpu_shader_private.h +++ b/source/blender/gpu/intern/gpu_shader_private.h @@ -20,9 +20,12 @@ #pragma once -#include "GPU_glew.h" #include "GPU_shader_interface.h" +#ifdef __cplusplus +extern "C" { +#endif + struct GPUShader { /** Handle for full program (links shader stages below). */ GLuint program; @@ -44,4 +47,8 @@ struct GPUShader { }; /* XXX do not use it. Special hack to use OCIO with batch API. */ -void immGetProgram(GLuint *program, GPUShaderInterface **shaderface); +GPUShader *immGetShader(void); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/gpu/intern/gpu_state.c b/source/blender/gpu/intern/gpu_state.cc index bd7aff9772b..794c7a3eb97 100644 --- a/source/blender/gpu/intern/gpu_state.c +++ b/source/blender/gpu/intern/gpu_state.cc @@ -268,6 +268,12 @@ void GPU_clip_distances(int distances_new) distances_enabled = distances_new; } +bool GPU_mipmap_enabled(void) +{ + /* TODO(fclem) this used to be a userdef option. */ + return true; +} + /** \name GPU Push/Pop State * \{ */ @@ -276,33 +282,18 @@ void GPU_clip_distances(int distances_new) typedef struct { eGPUAttrMask mask; - /* GL_ENABLE_BIT */ + /* GL_BLEND_BIT */ uint is_blend : 1; - uint is_cull_face : 1; - uint is_depth_test : 1; - /* uint is_lighting : 1; */ /* UNUSED */ - uint is_line_smooth : 1; - uint is_color_logic_op : 1; - uint is_multisample : 1; - uint is_polygon_offset_line : 1; - uint is_polygon_offset_fill : 1; - uint is_polygon_smooth : 1; - uint is_sample_alpha_to_coverage : 1; - uint is_scissor_test : 1; - uint is_stencil_test : 1; - uint is_framebuffer_srgb : 1; - - bool is_clip_plane[6]; /* GL_DEPTH_BUFFER_BIT */ - /* uint is_depth_test : 1; */ + uint is_depth_test : 1; int depth_func; double depth_clear_value; bool depth_write_mask; /* GL_SCISSOR_BIT */ int scissor_box[4]; - /* uint is_scissor_test : 1; */ + uint is_scissor_test : 1; /* GL_VIEWPORT_BIT */ int viewport[4]; @@ -315,7 +306,8 @@ typedef struct { } GPUAttrStack; static GPUAttrStack state = { - .top = 0, + {}, + 0, }; #define AttrStack state @@ -338,26 +330,6 @@ void gpuPushAttr(eGPUAttrMask mask) glGetBooleanv(GL_DEPTH_WRITEMASK, (GLboolean *)&Attr.depth_write_mask); } - if ((mask & GPU_ENABLE_BIT) != 0) { - Attr.is_blend = glIsEnabled(GL_BLEND); - - for (int i = 0; i < 6; i++) { - Attr.is_clip_plane[i] = glIsEnabled(GL_CLIP_PLANE0 + i); - } - - Attr.is_cull_face = glIsEnabled(GL_CULL_FACE); - Attr.is_depth_test = glIsEnabled(GL_DEPTH_TEST); - Attr.is_line_smooth = glIsEnabled(GL_LINE_SMOOTH); - Attr.is_color_logic_op = glIsEnabled(GL_COLOR_LOGIC_OP); - Attr.is_multisample = glIsEnabled(GL_MULTISAMPLE); - Attr.is_polygon_offset_line = glIsEnabled(GL_POLYGON_OFFSET_LINE); - Attr.is_polygon_offset_fill = glIsEnabled(GL_POLYGON_OFFSET_FILL); - Attr.is_polygon_smooth = glIsEnabled(GL_POLYGON_SMOOTH); - Attr.is_sample_alpha_to_coverage = glIsEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE); - Attr.is_scissor_test = glIsEnabled(GL_SCISSOR_TEST); - Attr.is_stencil_test = glIsEnabled(GL_STENCIL_TEST); - } - if ((mask & GPU_SCISSOR_BIT) != 0) { Attr.is_scissor_test = glIsEnabled(GL_SCISSOR_TEST); glGetIntegerv(GL_SCISSOR_BOX, (GLint *)&Attr.scissor_box); @@ -366,7 +338,6 @@ void gpuPushAttr(eGPUAttrMask mask) if ((mask & GPU_VIEWPORT_BIT) != 0) { glGetDoublev(GL_DEPTH_RANGE, (GLdouble *)&Attr.near_far); glGetIntegerv(GL_VIEWPORT, (GLint *)&Attr.viewport); - Attr.is_framebuffer_srgb = glIsEnabled(GL_FRAMEBUFFER_SRGB); } if ((mask & GPU_BLEND_BIT) != 0) { @@ -401,30 +372,9 @@ void gpuPopAttr(void) glDepthMask(Attr.depth_write_mask); } - if ((mask & GPU_ENABLE_BIT) != 0) { - restore_mask(GL_BLEND, Attr.is_blend); - - for (int i = 0; i < 6; i++) { - restore_mask(GL_CLIP_PLANE0 + i, Attr.is_clip_plane[i]); - } - - restore_mask(GL_CULL_FACE, Attr.is_cull_face); - restore_mask(GL_DEPTH_TEST, Attr.is_depth_test); - restore_mask(GL_LINE_SMOOTH, Attr.is_line_smooth); - restore_mask(GL_COLOR_LOGIC_OP, Attr.is_color_logic_op); - restore_mask(GL_MULTISAMPLE, Attr.is_multisample); - restore_mask(GL_POLYGON_OFFSET_LINE, Attr.is_polygon_offset_line); - restore_mask(GL_POLYGON_OFFSET_FILL, Attr.is_polygon_offset_fill); - restore_mask(GL_POLYGON_SMOOTH, Attr.is_polygon_smooth); - restore_mask(GL_SAMPLE_ALPHA_TO_COVERAGE, Attr.is_sample_alpha_to_coverage); - restore_mask(GL_SCISSOR_TEST, Attr.is_scissor_test); - restore_mask(GL_STENCIL_TEST, Attr.is_stencil_test); - } - if ((mask & GPU_VIEWPORT_BIT) != 0) { glViewport(Attr.viewport[0], Attr.viewport[1], Attr.viewport[2], Attr.viewport[3]); glDepthRange(Attr.near_far[0], Attr.near_far[1]); - restore_mask(GL_FRAMEBUFFER_SRGB, Attr.is_framebuffer_srgb); } if ((mask & GPU_SCISSOR_BIT) != 0) { diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.cc index 1e81f6e86a4..5d86f3d16a3 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.cc @@ -26,6 +26,7 @@ #include "MEM_guardedalloc.h" #include "DNA_image_types.h" +#include "DNA_userdef_types.h" #include "BLI_blenlib.h" #include "BLI_math_base.h" @@ -36,7 +37,6 @@ #include "GPU_batch.h" #include "GPU_context.h" #include "GPU_debug.h" -#include "GPU_draw.h" #include "GPU_extensions.h" #include "GPU_framebuffer.h" #include "GPU_glew.h" @@ -45,6 +45,16 @@ #include "gpu_context_private.h" +#define WARN_NOT_BOUND(_tex) \ + { \ + if (_tex->number == -1) { \ + fprintf(stderr, "Warning : Trying to set parameter on a texture not bound.\n"); \ + BLI_assert(0); \ + return; \ + } \ + } \ + ((void)0) + static struct GPUTextureGlobal { /** Texture used in place of invalid textures (not loaded correctly, missing). */ GPUTexture *invalid_tex_1D; @@ -71,6 +81,8 @@ typedef enum eGPUTextureFormatFlag { GPU_FORMAT_ARRAY = (1 << 14), } eGPUTextureFormatFlag; +ENUM_OPERATORS(eGPUTextureFormatFlag) + /* GPUTexture */ struct GPUTexture { int w, h, d; /* width/height/depth */ @@ -103,7 +115,7 @@ static void gpu_texture_framebuffer_ensure(GPUTexture *tex); /* ------ Memory Management ------- */ /* Records every texture allocation / free * to estimate the Texture Pool Memory consumption */ -static uint memory_usage; +static uint memory_usage = 0; static uint gpu_texture_memory_footprint_compute(GPUTexture *tex) { @@ -161,54 +173,58 @@ uint GPU_texture_memory_usage_get(void) static const char *gl_enum_to_str(GLenum e) { -#define ENUM_TO_STRING(e) [GL_##e] = STRINGIFY_ARG(e) - static const char *enum_strings[] = { - ENUM_TO_STRING(TEXTURE_CUBE_MAP), - ENUM_TO_STRING(TEXTURE_CUBE_MAP_ARRAY), - ENUM_TO_STRING(TEXTURE_2D), - ENUM_TO_STRING(TEXTURE_2D_ARRAY), - ENUM_TO_STRING(TEXTURE_1D), - ENUM_TO_STRING(TEXTURE_1D_ARRAY), - ENUM_TO_STRING(TEXTURE_3D), - ENUM_TO_STRING(TEXTURE_2D_MULTISAMPLE), - ENUM_TO_STRING(RGBA32F), - ENUM_TO_STRING(RGBA16F), - ENUM_TO_STRING(RGBA16UI), - ENUM_TO_STRING(RGBA16I), - ENUM_TO_STRING(RGBA16), - ENUM_TO_STRING(RGBA8UI), - ENUM_TO_STRING(RGBA8I), - ENUM_TO_STRING(RGBA8), - ENUM_TO_STRING(RGB16F), - ENUM_TO_STRING(RG32F), - ENUM_TO_STRING(RG16F), - ENUM_TO_STRING(RG16UI), - ENUM_TO_STRING(RG16I), - ENUM_TO_STRING(RG16), - ENUM_TO_STRING(RG8UI), - ENUM_TO_STRING(RG8I), - ENUM_TO_STRING(RG8), - ENUM_TO_STRING(R8UI), - ENUM_TO_STRING(R8I), - ENUM_TO_STRING(R8), - ENUM_TO_STRING(R32F), - ENUM_TO_STRING(R32UI), - ENUM_TO_STRING(R32I), - ENUM_TO_STRING(R16F), - ENUM_TO_STRING(R16UI), - ENUM_TO_STRING(R16I), - ENUM_TO_STRING(R16), - ENUM_TO_STRING(R11F_G11F_B10F), - ENUM_TO_STRING(SRGB8_ALPHA8), - ENUM_TO_STRING(DEPTH24_STENCIL8), - ENUM_TO_STRING(DEPTH32F_STENCIL8), - ENUM_TO_STRING(DEPTH_COMPONENT32F), - ENUM_TO_STRING(DEPTH_COMPONENT24), - ENUM_TO_STRING(DEPTH_COMPONENT16), +#define ENUM_TO_STRING(e) \ + case GL_##e: { \ + return STRINGIFY_ARG(e); \ + } + + switch (e) { + ENUM_TO_STRING(TEXTURE_CUBE_MAP); + ENUM_TO_STRING(TEXTURE_CUBE_MAP_ARRAY); + ENUM_TO_STRING(TEXTURE_2D); + ENUM_TO_STRING(TEXTURE_2D_ARRAY); + ENUM_TO_STRING(TEXTURE_1D); + ENUM_TO_STRING(TEXTURE_1D_ARRAY); + ENUM_TO_STRING(TEXTURE_3D); + ENUM_TO_STRING(TEXTURE_2D_MULTISAMPLE); + ENUM_TO_STRING(RGBA32F); + ENUM_TO_STRING(RGBA16F); + ENUM_TO_STRING(RGBA16UI); + ENUM_TO_STRING(RGBA16I); + ENUM_TO_STRING(RGBA16); + ENUM_TO_STRING(RGBA8UI); + ENUM_TO_STRING(RGBA8I); + ENUM_TO_STRING(RGBA8); + ENUM_TO_STRING(RGB16F); + ENUM_TO_STRING(RG32F); + ENUM_TO_STRING(RG16F); + ENUM_TO_STRING(RG16UI); + ENUM_TO_STRING(RG16I); + ENUM_TO_STRING(RG16); + ENUM_TO_STRING(RG8UI); + ENUM_TO_STRING(RG8I); + ENUM_TO_STRING(RG8); + ENUM_TO_STRING(R8UI); + ENUM_TO_STRING(R8I); + ENUM_TO_STRING(R8); + ENUM_TO_STRING(R32F); + ENUM_TO_STRING(R32UI); + ENUM_TO_STRING(R32I); + ENUM_TO_STRING(R16F); + ENUM_TO_STRING(R16UI); + ENUM_TO_STRING(R16I); + ENUM_TO_STRING(R16); + ENUM_TO_STRING(R11F_G11F_B10F); + ENUM_TO_STRING(SRGB8_ALPHA8); + ENUM_TO_STRING(DEPTH24_STENCIL8); + ENUM_TO_STRING(DEPTH32F_STENCIL8); + ENUM_TO_STRING(DEPTH_COMPONENT32F); + ENUM_TO_STRING(DEPTH_COMPONENT24); + ENUM_TO_STRING(DEPTH_COMPONENT16); + default: + return "Unkown enum"; }; #undef ENUM_TO_STRING - - return enum_strings[e]; } static int gpu_get_component_count(eGPUTextureFormat format) @@ -296,31 +312,28 @@ static eGPUDataFormat gpu_get_data_format_from_tex_format(eGPUTextureFormat tex_ if (ELEM(tex_format, GPU_DEPTH_COMPONENT24, GPU_DEPTH_COMPONENT16, GPU_DEPTH_COMPONENT32F)) { return GPU_DATA_FLOAT; } - else if (ELEM(tex_format, GPU_DEPTH24_STENCIL8, GPU_DEPTH32F_STENCIL8)) { + if (ELEM(tex_format, GPU_DEPTH24_STENCIL8, GPU_DEPTH32F_STENCIL8)) { return GPU_DATA_UNSIGNED_INT_24_8; } - else { - /* Integer formats */ - if (ELEM(tex_format, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R8UI, GPU_R16UI, GPU_R32UI)) { - if (ELEM(tex_format, GPU_R8UI, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) { - return GPU_DATA_UNSIGNED_INT; - } - else { - return GPU_DATA_INT; - } - } - /* Byte formats */ - else if (ELEM(tex_format, GPU_R8)) { - return GPU_DATA_UNSIGNED_BYTE; - } - /* Special case */ - else if (ELEM(tex_format, GPU_R11F_G11F_B10F)) { - return GPU_DATA_10_11_11_REV; - } - else { - return GPU_DATA_FLOAT; + + /* Integer formats */ + if (ELEM(tex_format, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R8UI, GPU_R16UI, GPU_R32UI)) { + if (ELEM(tex_format, GPU_R8UI, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) { + return GPU_DATA_UNSIGNED_INT; } + + return GPU_DATA_INT; + } + /* Byte formats */ + if (ELEM(tex_format, GPU_R8)) { + return GPU_DATA_UNSIGNED_BYTE; + } + /* Special case */ + if (ELEM(tex_format, GPU_R11F_G11F_B10F)) { + return GPU_DATA_10_11_11_REV; } + + return GPU_DATA_FLOAT; } /* Definitely not complete, edit according to the gl specification. */ @@ -331,51 +344,50 @@ static GLenum gpu_get_gl_dataformat(eGPUTextureFormat data_type, *format_flag |= GPU_FORMAT_DEPTH; return GL_DEPTH_COMPONENT; } - else if (ELEM(data_type, GPU_DEPTH24_STENCIL8, GPU_DEPTH32F_STENCIL8)) { + if (ELEM(data_type, GPU_DEPTH24_STENCIL8, GPU_DEPTH32F_STENCIL8)) { *format_flag |= GPU_FORMAT_DEPTH | GPU_FORMAT_STENCIL; return GL_DEPTH_STENCIL; } - else { - /* Integer formats */ - if (ELEM(data_type, GPU_R8UI, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) { - *format_flag |= GPU_FORMAT_INTEGER; - switch (gpu_get_component_count(data_type)) { - case 1: - return GL_RED_INTEGER; - break; - case 2: - return GL_RG_INTEGER; - break; - case 3: - return GL_RGB_INTEGER; - break; - case 4: - return GL_RGBA_INTEGER; - break; - } - } - else if (ELEM(data_type, GPU_R8)) { - *format_flag |= GPU_FORMAT_FLOAT; - return GL_RED; + /* Integer formats */ + if (ELEM(data_type, GPU_R8UI, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) { + *format_flag |= GPU_FORMAT_INTEGER; + + switch (gpu_get_component_count(data_type)) { + case 1: + return GL_RED_INTEGER; + break; + case 2: + return GL_RG_INTEGER; + break; + case 3: + return GL_RGB_INTEGER; + break; + case 4: + return GL_RGBA_INTEGER; + break; } - else { - *format_flag |= GPU_FORMAT_FLOAT; + } + else if (ELEM(data_type, GPU_R8)) { + *format_flag |= GPU_FORMAT_FLOAT; + return GL_RED; + } + else { + *format_flag |= GPU_FORMAT_FLOAT; - switch (gpu_get_component_count(data_type)) { - case 1: - return GL_RED; - break; - case 2: - return GL_RG; - break; - case 3: - return GL_RGB; - break; - case 4: - return GL_RGBA; - break; - } + switch (gpu_get_component_count(data_type)) { + case 1: + return GL_RED; + break; + case 2: + return GL_RG; + break; + case 3: + return GL_RGB; + break; + case 4: + return GL_RGBA; + break; } } @@ -423,6 +435,13 @@ static uint gpu_get_bytesize(eGPUTextureFormat data_type) case GPU_R8: case GPU_R8UI: return 1; + case GPU_SRGB8_A8_DXT1: + case GPU_SRGB8_A8_DXT3: + case GPU_SRGB8_A8_DXT5: + case GPU_RGBA8_DXT1: + case GPU_RGBA8_DXT3: + case GPU_RGBA8_DXT5: + return 1; /* Incorrect but actual size is fractional. */ default: BLI_assert(!"Texture format incorrect or unsupported\n"); return 0; @@ -508,7 +527,18 @@ static GLenum gpu_format_to_gl_internalformat(eGPUTextureFormat format) case GPU_RGB16F: return GL_RGB16F; /* Special formats texture only */ - /* ** Add Format here */ + case GPU_SRGB8_A8_DXT1: + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; + case GPU_SRGB8_A8_DXT3: + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; + case GPU_SRGB8_A8_DXT5: + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; + case GPU_RGBA8_DXT1: + return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + case GPU_RGBA8_DXT3: + return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + case GPU_RGBA8_DXT5: + return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; /* Depth Formats */ case GPU_DEPTH_COMPONENT32F: return GL_DEPTH_COMPONENT32F; @@ -522,99 +552,6 @@ static GLenum gpu_format_to_gl_internalformat(eGPUTextureFormat format) } } -static eGPUTextureFormat gl_internalformat_to_gpu_format(const GLint glformat) -{ - /* You can add any of the available type to this list - * For available types see GPU_texture.h */ - switch (glformat) { - /* Formats texture & renderbuffer */ - case GL_RGBA8UI: - return GPU_RGBA8UI; - case GL_RGBA8I: - return GPU_RGBA8I; - case GL_RGBA8: - return GPU_RGBA8; - case GL_RGBA32UI: - return GPU_RGBA32UI; - case GL_RGBA32I: - return GPU_RGBA32I; - case GL_RGBA32F: - return GPU_RGBA32F; - case GL_RGBA16UI: - return GPU_RGBA16UI; - case GL_RGBA16I: - return GPU_RGBA16I; - case GL_RGBA16F: - return GPU_RGBA16F; - case GL_RGBA16: - return GPU_RGBA16; - case GL_RG8UI: - return GPU_RG8UI; - case GL_RG8I: - return GPU_RG8I; - case GL_RG8: - return GPU_RG8; - case GL_RG32UI: - return GPU_RG32UI; - case GL_RG32I: - return GPU_RG32I; - case GL_RG32F: - return GPU_RG32F; - case GL_RG16UI: - return GPU_RG16UI; - case GL_RG16I: - return GPU_RG16I; - case GL_RG16F: - return GPU_RGBA32F; - case GL_RG16: - return GPU_RG16; - case GL_R8UI: - return GPU_R8UI; - case GL_R8I: - return GPU_R8I; - case GL_R8: - return GPU_R8; - case GL_R32UI: - return GPU_R32UI; - case GL_R32I: - return GPU_R32I; - case GL_R32F: - return GPU_R32F; - case GL_R16UI: - return GPU_R16UI; - case GL_R16I: - return GPU_R16I; - case GL_R16F: - return GPU_R16F; - case GL_R16: - return GPU_R16; - /* Special formats texture & renderbuffer */ - case GL_R11F_G11F_B10F: - return GPU_R11F_G11F_B10F; - case GL_DEPTH32F_STENCIL8: - return GPU_DEPTH32F_STENCIL8; - case GL_DEPTH24_STENCIL8: - return GPU_DEPTH24_STENCIL8; - case GL_SRGB8_ALPHA8: - return GPU_SRGB8_A8; - /* Texture only format */ - case GL_RGB16F: - return GPU_RGB16F; - /* Special formats texture only */ - /* ** Add Format here */ - /* Depth Formats */ - case GL_DEPTH_COMPONENT32F: - return GPU_DEPTH_COMPONENT32F; - case GL_DEPTH_COMPONENT24: - return GPU_DEPTH_COMPONENT24; - case GL_DEPTH_COMPONENT16: - return GPU_DEPTH_COMPONENT16; - default: - BLI_assert(!"Internal format incorrect or unsupported\n"); - } - return -1; -} - static GLenum gpu_get_gl_datatype(eGPUDataFormat format) { switch (format) { @@ -640,8 +577,8 @@ static float *GPU_texture_rescale_3d( GPUTexture *tex, int w, int h, int d, int channels, const float *fpixels) { const uint xf = w / tex->w, yf = h / tex->h, zf = d / tex->d; - float *nfpixels = MEM_mallocN(channels * sizeof(float) * tex->w * tex->h * tex->d, - "GPUTexture Rescaled 3Dtex"); + float *nfpixels = (float *)MEM_mallocN(channels * sizeof(float) * tex->w * tex->h * tex->d, + "GPUTexture Rescaled 3Dtex"); if (nfpixels) { GPU_print_error_debug("You need to scale a 3D texture, feel the pain!"); @@ -726,31 +663,30 @@ static bool gpu_texture_check_capacity( return true; } - else { - switch (proxy) { - case GL_PROXY_TEXTURE_1D: - glTexImage1D(proxy, 0, internalformat, tex->w, 0, data_format, data_type, NULL); - break; - case GL_PROXY_TEXTURE_1D_ARRAY: - case GL_PROXY_TEXTURE_2D: - case GL_PROXY_TEXTURE_CUBE_MAP: - glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, NULL); - break; - case GL_PROXY_TEXTURE_2D_ARRAY: - case GL_PROXY_TEXTURE_3D: - glTexImage3D( - proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, data_format, data_type, NULL); - break; - case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB: - glTexImage3D( - proxy, 0, internalformat, tex->w, tex->h, tex->d * 6, 0, data_format, data_type, NULL); - break; - } - int width = 0; - glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &width); - return (width > 0); + switch (proxy) { + case GL_PROXY_TEXTURE_1D: + glTexImage1D(proxy, 0, internalformat, tex->w, 0, data_format, data_type, NULL); + break; + case GL_PROXY_TEXTURE_1D_ARRAY: + case GL_PROXY_TEXTURE_2D: + case GL_PROXY_TEXTURE_CUBE_MAP: + glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, NULL); + break; + case GL_PROXY_TEXTURE_2D_ARRAY: + case GL_PROXY_TEXTURE_3D: + glTexImage3D( + proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, data_format, data_type, NULL); + break; + case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB: + glTexImage3D( + proxy, 0, internalformat, tex->w, tex->h, tex->d * 6, 0, data_format, data_type, NULL); + break; } + int width = 0; + glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &width); + + return (width > 0); } /* This tries to allocate video memory for a given texture @@ -836,7 +772,7 @@ GPUTexture *GPU_texture_create_nD(int w, tex_format = GPU_DEPTH32F_STENCIL8; } - GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture"); + GPUTexture *tex = (GPUTexture *)MEM_callocN(sizeof(GPUTexture), __func__); tex->w = w; tex->h = h; tex->d = d; @@ -845,7 +781,7 @@ GPUTexture *GPU_texture_create_nD(int w, tex->format = tex_format; tex->components = gpu_get_component_count(tex_format); tex->mipmaps = 0; - tex->format_flag = 0; + tex->format_flag = static_cast<eGPUTextureFormatFlag>(0); tex->number = -1; if (n == 2) { @@ -929,7 +865,7 @@ GPUTexture *GPU_texture_create_nD(int w, data_type, tex->components, can_rescale, - pixels, + (float *)pixels, &rescaled_pixels); if (G.debug & G_DEBUG_GPU || !valid) { @@ -962,7 +898,7 @@ GPUTexture *GPU_texture_create_nD(int w, gpu_texture_memory_footprint_add(tex); /* Upload Texture */ - const float *pix = (rescaled_pixels) ? rescaled_pixels : pixels; + const void *pix = (rescaled_pixels) ? rescaled_pixels : pixels; if (tex->target == GL_TEXTURE_2D || tex->target == GL_TEXTURE_2D_MULTISAMPLE || tex->target == GL_TEXTURE_1D_ARRAY) { @@ -1012,7 +948,7 @@ GPUTexture *GPU_texture_cube_create(int w, eGPUDataFormat gpu_data_format, char err_out[256]) { - GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture"); + GPUTexture *tex = (GPUTexture *)MEM_callocN(sizeof(GPUTexture), __func__); tex->w = w; tex->h = w; tex->d = d; @@ -1161,11 +1097,11 @@ GPUTexture *GPU_texture_cube_create(int w, /* Special buffer textures. tex_format must be compatible with the buffer content. */ GPUTexture *GPU_texture_create_buffer(eGPUTextureFormat tex_format, const GLuint buffer) { - GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture"); + GPUTexture *tex = (GPUTexture *)MEM_callocN(sizeof(GPUTexture), __func__); tex->refcount = 1; tex->format = tex_format; tex->components = gpu_get_component_count(tex_format); - tex->format_flag = 0; + tex->format_flag = static_cast<eGPUTextureFormatFlag>(0); tex->target_base = tex->target = GL_TEXTURE_BUFFER; tex->mipmaps = 0; tex->number = -1; @@ -1211,44 +1147,87 @@ GPUTexture *GPU_texture_create_buffer(eGPUTextureFormat tex_format, const GLuint return tex; } -GPUTexture *GPU_texture_from_bindcode(int textarget, int bindcode) +static GLenum convert_target_to_gl(int dimension, bool is_array) { - GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture"); - tex->bindcode = bindcode; + switch (dimension) { + case 1: + return is_array ? GL_TEXTURE_1D : GL_TEXTURE_1D_ARRAY; + case 2: + return is_array ? GL_TEXTURE_2D : GL_TEXTURE_2D_ARRAY; + case 3: + return GL_TEXTURE_3D; + default: + BLI_assert(0); + return GL_TEXTURE_2D; + } +} + +/* Create an error texture that will bind an invalid texture (pink) at draw time. */ +GPUTexture *GPU_texture_create_error(int dimension, bool is_array) +{ + GLenum textarget = convert_target_to_gl(dimension, is_array); + + GPUTexture *tex = (GPUTexture *)MEM_callocN(sizeof(GPUTexture), __func__); + tex->bindcode = 0; tex->refcount = 1; tex->target = textarget; tex->target_base = textarget; tex->samples = 0; - tex->sampler_state = GPU_SAMPLER_REPEAT | GPU_SAMPLER_ANISO; - if (GPU_get_mipmap()) { - tex->sampler_state |= (GPU_SAMPLER_MIPMAP | GPU_SAMPLER_FILTER); - } + tex->sampler_state = GPU_SAMPLER_DEFAULT; tex->number = -1; - if (!glIsTexture(tex->bindcode)) { - GPU_print_error_debug("Blender Texture Not Loaded"); + GPU_print_error_debug("Blender Texture Not Loaded"); + return tex; +} + +/* DDS texture loading. Return NULL if support is not available. */ +GPUTexture *GPU_texture_create_compressed( + int w, int h, int miplen, eGPUTextureFormat tex_format, const void *data) +{ + if (!GLEW_EXT_texture_compression_s3tc) { + return NULL; } - else { - GLint w, h, gl_format; - GLenum gettarget; - gettarget = (textarget == GL_TEXTURE_CUBE_MAP) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : textarget; - - glBindTexture(textarget, tex->bindcode); - glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_WIDTH, &w); - glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_HEIGHT, &h); - glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &gl_format); - tex->w = w; - tex->h = h; - tex->format = gl_internalformat_to_gpu_format(gl_format); - tex->components = gpu_get_component_count(tex->format); - glBindTexture(textarget, 0); - - /* Depending on how this bindcode was obtained, the memory used here could - * already have been computed. - * But that is not the case currently. */ - gpu_texture_memory_footprint_add(tex); + + GPUTexture *tex = (GPUTexture *)MEM_callocN(sizeof(GPUTexture), __func__); + tex->w = w; + tex->h = h; + tex->refcount = 1; + tex->target = tex->target_base = GL_TEXTURE_2D; + tex->format_flag = static_cast<eGPUTextureFormatFlag>(0); + tex->components = gpu_get_component_count(tex_format); + tex->mipmaps = miplen - 1; + tex->sampler_state = GPU_SAMPLER_DEFAULT; + tex->number = -1; + + GLenum internalformat = gpu_format_to_gl_internalformat(tex_format); + + glGenTextures(1, &tex->bindcode); + glBindTexture(tex->target, tex->bindcode); + + /* Reset to opengl Defaults. (Untested, might not be needed) */ + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + + int blocksize = (ELEM(tex_format, GPU_RGBA8_DXT1, GPU_SRGB8_A8_DXT1)) ? 8 : 16; + + size_t ofs = 0; + for (int mip = 0; mip < miplen && (w || h); mip++, w >>= 1, h >>= 1) { + w = max_ii(1, w); + h = max_ii(1, h); + size_t size = ((w + 3) / 4) * ((h + 3) / 4) * blocksize; + + glCompressedTexImage2D(tex->target, mip, internalformat, w, h, 0, size, (uchar *)data + ofs); + + ofs += size; } + /* Restore Blender default. */ + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glTexParameteri(tex->target, GL_TEXTURE_MAX_LEVEL, tex->mipmaps); + glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glBindTexture(tex->target, 0); + return tex; } @@ -1503,7 +1482,8 @@ void GPU_texture_update_sub(GPUTexture *tex, GLenum data_format = gpu_get_gl_dataformat(tex->format, &tex->format_flag); GLenum data_type = gpu_get_gl_datatype(gpu_data_format); - glBindTexture(tex->target, tex->bindcode); + WARN_NOT_BOUND(tex); + switch (tex->target) { case GL_TEXTURE_1D: glTexSubImage1D(tex->target, 0, offset_x, width, data_format, data_type, pixels); @@ -1531,8 +1511,6 @@ void GPU_texture_update_sub(GPUTexture *tex, default: BLI_assert(!"tex->target mode not supported"); } - - glBindTexture(tex->target, 0); } void *GPU_texture_read(GPUTexture *tex, eGPUDataFormat gpu_data_format, int miplvl) @@ -1826,16 +1804,6 @@ void GPU_texture_unbind_all(void) glActiveTexture(GL_TEXTURE0); } -#define WARN_NOT_BOUND(_tex) \ - { \ - if (_tex->number == -1) { \ - fprintf(stderr, "Warning : Trying to set parameter on a texture not bound.\n"); \ - BLI_assert(0); \ - return; \ - } \ - } \ - ((void)0) - void GPU_texture_generate_mipmap(GPUTexture *tex) { WARN_NOT_BOUND(tex); @@ -1979,6 +1947,14 @@ void GPU_texture_mipmap_mode(GPUTexture *tex, bool use_mipmap, bool use_filter) SET_FLAG_FROM_TEST(tex->sampler_state, use_filter, GPU_SAMPLER_FILTER); } +void GPU_texture_anisotropic_filter(GPUTexture *tex, bool use_aniso) +{ + /* Stencil and integer format does not support filtering. */ + BLI_assert(!(use_aniso) || !(GPU_texture_stencil(tex) || GPU_texture_integer(tex))); + + SET_FLAG_FROM_TEST(tex->sampler_state, use_aniso, GPU_SAMPLER_ANISO); +} + void GPU_texture_wrap_mode(GPUTexture *tex, bool use_repeat, bool use_clamp) { SET_FLAG_FROM_TEST(tex->sampler_state, use_repeat, GPU_SAMPLER_REPEAT); @@ -2193,7 +2169,7 @@ void GPU_samplers_init(void) { glGenSamplers(GPU_SAMPLER_MAX, GG.samplers); for (int i = 0; i < GPU_SAMPLER_MAX; i++) { - eGPUSamplerState state = i; + eGPUSamplerState state = static_cast<eGPUSamplerState>(i); GLenum clamp_type = (state & GPU_SAMPLER_CLAMP_BORDER) ? GL_CLAMP_TO_BORDER : GL_CLAMP_TO_EDGE; GLenum wrap_s = (state & GPU_SAMPLER_REPEAT_S) ? GL_REPEAT : clamp_type; GLenum wrap_t = (state & GPU_SAMPLER_REPEAT_T) ? GL_REPEAT : clamp_type; @@ -2203,8 +2179,9 @@ void GPU_samplers_init(void) ((state & GPU_SAMPLER_MIPMAP) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) : ((state & GPU_SAMPLER_MIPMAP) ? GL_NEAREST_MIPMAP_LINEAR : GL_NEAREST); GLenum compare_mode = (state & GPU_SAMPLER_COMPARE) ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE; + /* TODO(fclem) Anisotropic level should be a render engine parameter. */ float aniso_filter = ((state & GPU_SAMPLER_MIPMAP) && (state & GPU_SAMPLER_ANISO)) ? - GPU_get_anisotropic() : + U.anisotropic_filter : 1.0f; glSamplerParameteri(GG.samplers[i], GL_TEXTURE_WRAP_S, wrap_s); diff --git a/source/blender/gpu/intern/gpu_uniformbuffer.c b/source/blender/gpu/intern/gpu_uniformbuffer.cc index 130e8fe7da1..f0724ce7c9a 100644 --- a/source/blender/gpu/intern/gpu_uniformbuffer.c +++ b/source/blender/gpu/intern/gpu_uniformbuffer.cc @@ -25,6 +25,7 @@ #include <string.h> #include "BLI_blenlib.h" +#include "BLI_math_base.h" #include "gpu_context_private.h" #include "gpu_node_graph.h" @@ -34,217 +35,63 @@ #include "GPU_material.h" #include "GPU_uniformbuffer.h" -typedef enum eGPUUniformBufferFlag { - GPU_UBO_FLAG_INITIALIZED = (1 << 0), - GPU_UBO_FLAG_DIRTY = (1 << 1), -} eGPUUniformBufferFlag; - -typedef enum eGPUUniformBufferType { - GPU_UBO_STATIC = 0, - GPU_UBO_DYNAMIC = 1, -} eGPUUniformBufferType; - -struct GPUUniformBuffer { - int size; /* in bytes */ - GLuint bindcode; /* opengl identifier for UBO */ - int bindpoint; /* current binding point */ - eGPUUniformBufferType type; -}; - -#define GPUUniformBufferStatic GPUUniformBuffer - -typedef struct GPUUniformBufferDynamic { - GPUUniformBuffer buffer; - void *data; /* Continuous memory block to copy to GPU. */ - char flag; -} GPUUniformBufferDynamic; - -/* Prototypes */ -static eGPUType get_padded_gpu_type(struct LinkData *link); -static void gpu_uniformbuffer_inputs_sort(struct ListBase *inputs); - -/* Only support up to this type, if you want to extend it, make sure the - * padding logic is correct for the new types. */ -#define MAX_UBO_GPU_TYPE GPU_MAT4 - -static void gpu_uniformbuffer_initialize(GPUUniformBuffer *ubo, const void *data) -{ - glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode); - glBufferData(GL_UNIFORM_BUFFER, ubo->size, data, GL_DYNAMIC_DRAW); - glBindBuffer(GL_UNIFORM_BUFFER, 0); -} +typedef struct GPUUniformBuffer { + /** Data size in bytes. */ + int size; + /** GL handle for UBO. */ + GLuint bindcode; + /** Current binding point. */ + int bindpoint; + /** Continuous memory block to copy to GPU. Is own by the GPUUniformBuffer. */ + void *data; +} GPUUniformBuffer; GPUUniformBuffer *GPU_uniformbuffer_create(int size, const void *data, char err_out[256]) { /* Make sure that UBO is padded to size of vec4 */ BLI_assert((size % 16) == 0); - GPUUniformBuffer *ubo = MEM_callocN(sizeof(GPUUniformBufferStatic), "GPUUniformBufferStatic"); - ubo->size = size; - ubo->bindpoint = -1; - - /* Generate Buffer object */ - ubo->bindcode = GPU_buf_alloc(); - - if (!ubo->bindcode) { - if (err_out) { - BLI_strncpy(err_out, "GPUUniformBuffer: UBO create failed", 256); - } - GPU_uniformbuffer_free(ubo); - return NULL; - } - - if (ubo->size > GPU_max_ubo_size()) { + if (size > GPU_max_ubo_size()) { if (err_out) { BLI_strncpy(err_out, "GPUUniformBuffer: UBO too big", 256); } - GPU_uniformbuffer_free(ubo); - return NULL; - } - - gpu_uniformbuffer_initialize(ubo, data); - return ubo; -} - -/** - * Create dynamic UBO from parameters - * Return NULL if failed to create or if \param inputs: is empty. - * - * \param inputs: ListBase of #BLI_genericNodeN(#GPUInput). - */ -GPUUniformBuffer *GPU_uniformbuffer_dynamic_create(ListBase *inputs, char err_out[256]) -{ - /* There is no point on creating an UBO if there is no arguments. */ - if (BLI_listbase_is_empty(inputs)) { return NULL; } - GPUUniformBufferDynamic *ubo = MEM_callocN(sizeof(GPUUniformBufferDynamic), - "GPUUniformBufferDynamic"); - ubo->buffer.type = GPU_UBO_DYNAMIC; - ubo->buffer.bindpoint = -1; - ubo->flag = GPU_UBO_FLAG_DIRTY; - - /* Generate Buffer object. */ - ubo->buffer.bindcode = GPU_buf_alloc(); - - if (!ubo->buffer.bindcode) { - if (err_out) { - BLI_strncpy(err_out, "GPUUniformBuffer: UBO create failed", 256); - } - GPU_uniformbuffer_free(&ubo->buffer); - return NULL; - } - - if (ubo->buffer.size > GPU_max_ubo_size()) { - if (err_out) { - BLI_strncpy(err_out, "GPUUniformBuffer: UBO too big", 256); - } - GPU_uniformbuffer_free(&ubo->buffer); - return NULL; - } - - /* Make sure we comply to the ubo alignment requirements. */ - gpu_uniformbuffer_inputs_sort(inputs); - - LISTBASE_FOREACH (LinkData *, link, inputs) { - const eGPUType gputype = get_padded_gpu_type(link); - ubo->buffer.size += gputype * sizeof(float); - } - - /* Round up to size of vec4 */ - ubo->buffer.size = ((ubo->buffer.size + 15) / 16) * 16; - - /* Allocate the data. */ - ubo->data = MEM_mallocN(ubo->buffer.size, __func__); + GPUUniformBuffer *ubo = (GPUUniformBuffer *)MEM_mallocN(sizeof(GPUUniformBuffer), __func__); + ubo->size = size; + ubo->data = NULL; + ubo->bindcode = 0; + ubo->bindpoint = -1; - /* Now that we know the total ubo size we can start populating it. */ - float *offset = ubo->data; - LISTBASE_FOREACH (LinkData *, link, inputs) { - GPUInput *input = link->data; - memcpy(offset, input->vec, input->type * sizeof(float)); - offset += get_padded_gpu_type(link); + /* Direct init. */ + if (data != NULL) { + GPU_uniformbuffer_update(ubo, data); } - /* Note since we may create the UBOs in the CPU in a different thread than the main drawing one, - * we don't create the UBO in the GPU here. This will happen when we first bind the UBO. - */ - - return &ubo->buffer; -} - -/** - * Free the data - */ -static void gpu_uniformbuffer_dynamic_free(GPUUniformBuffer *ubo_) -{ - BLI_assert(ubo_->type == GPU_UBO_DYNAMIC); - GPUUniformBufferDynamic *ubo = (GPUUniformBufferDynamic *)ubo_; - - ubo->buffer.size = 0; - if (ubo->data) { - MEM_freeN(ubo->data); - } + return ubo; } void GPU_uniformbuffer_free(GPUUniformBuffer *ubo) { - if (ubo->type == GPU_UBO_DYNAMIC) { - gpu_uniformbuffer_dynamic_free(ubo); - } - + MEM_SAFE_FREE(ubo->data); GPU_buf_free(ubo->bindcode); MEM_freeN(ubo); } -static void gpu_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data) -{ - glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode); - glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo->size, data); - glBindBuffer(GL_UNIFORM_BUFFER, 0); -} - -void GPU_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data) -{ - BLI_assert(ubo->type == GPU_UBO_STATIC); - gpu_uniformbuffer_update(ubo, data); -} - -/** - * We need to recalculate the internal data, and re-generate it - * from its populated items. - */ -void GPU_uniformbuffer_dynamic_update(GPUUniformBuffer *ubo_) -{ - BLI_assert(ubo_->type == GPU_UBO_DYNAMIC); - GPUUniformBufferDynamic *ubo = (GPUUniformBufferDynamic *)ubo_; - - if (ubo->flag & GPU_UBO_FLAG_INITIALIZED) { - gpu_uniformbuffer_update(ubo_, ubo->data); - } - else { - ubo->flag |= GPU_UBO_FLAG_INITIALIZED; - gpu_uniformbuffer_initialize(ubo_, ubo->data); - } - - ubo->flag &= ~GPU_UBO_FLAG_DIRTY; -} - /** * We need to pad some data types (vec3) on the C side * To match the GPU expected memory block alignment. */ static eGPUType get_padded_gpu_type(LinkData *link) { - GPUInput *input = link->data; + GPUInput *input = (GPUInput *)link->data; eGPUType gputype = input->type; - /* Unless the vec3 is followed by a float we need to treat it as a vec4. */ if (gputype == GPU_VEC3 && (link->next != NULL) && (((GPUInput *)link->next->data)->type != GPU_FLOAT)) { gputype = GPU_VEC4; } - return gputype; } @@ -254,8 +101,9 @@ static eGPUType get_padded_gpu_type(LinkData *link) */ static int inputs_cmp(const void *a, const void *b) { - const LinkData *link_a = a, *link_b = b; - const GPUInput *input_a = link_a->data, *input_b = link_b->data; + const LinkData *link_a = (const LinkData *)a, *link_b = (const LinkData *)b; + const GPUInput *input_a = (const GPUInput *)link_a->data; + const GPUInput *input_b = (const GPUInput *)link_b->data; return input_a->type < input_b->type ? 1 : 0; } @@ -265,22 +113,26 @@ static int inputs_cmp(const void *a, const void *b) */ static void gpu_uniformbuffer_inputs_sort(ListBase *inputs) { +/* Only support up to this type, if you want to extend it, make sure the + * padding logic is correct for the new types. */ +#define MAX_UBO_GPU_TYPE GPU_MAT4 + /* Order them as mat4, vec4, vec3, vec2, float. */ BLI_listbase_sort(inputs, inputs_cmp); /* Creates a lookup table for the different types; */ LinkData *inputs_lookup[MAX_UBO_GPU_TYPE + 1] = {NULL}; - eGPUType cur_type = MAX_UBO_GPU_TYPE + 1; + eGPUType cur_type = static_cast<eGPUType>(MAX_UBO_GPU_TYPE + 1); LISTBASE_FOREACH (LinkData *, link, inputs) { - GPUInput *input = link->data; + GPUInput *input = (GPUInput *)link->data; if (input->type == GPU_MAT3) { /* Alignment for mat3 is not handled currently, so not supported */ BLI_assert(!"mat3 not supported in UBO"); continue; } - else if (input->type > MAX_UBO_GPU_TYPE) { + if (input->type > MAX_UBO_GPU_TYPE) { BLI_assert(!"GPU type not supported in UBO"); continue; } @@ -288,10 +140,9 @@ static void gpu_uniformbuffer_inputs_sort(ListBase *inputs) if (input->type == cur_type) { continue; } - else { - inputs_lookup[input->type] = link; - cur_type = input->type; - } + + inputs_lookup[input->type] = link; + cur_type = input->type; } /* If there is no GPU_VEC3 there is no need for alignment. */ @@ -319,6 +170,74 @@ static void gpu_uniformbuffer_inputs_sort(ListBase *inputs) link = link_next; } +#undef MAX_UBO_GPU_TYPE +} + +/** + * Create dynamic UBO from parameters + * Return NULL if failed to create or if \param inputs: is empty. + * + * \param inputs: ListBase of #BLI_genericNodeN(#GPUInput). + */ +GPUUniformBuffer *GPU_uniformbuffer_dynamic_create(ListBase *inputs, char err_out[256]) +{ + /* There is no point on creating an UBO if there is no arguments. */ + if (BLI_listbase_is_empty(inputs)) { + return NULL; + } + /* Make sure we comply to the ubo alignment requirements. */ + gpu_uniformbuffer_inputs_sort(inputs); + + size_t buffer_size = 0; + + LISTBASE_FOREACH (LinkData *, link, inputs) { + const eGPUType gputype = get_padded_gpu_type(link); + buffer_size += gputype * sizeof(float); + } + /* Round up to size of vec4. (Opengl Requirement) */ + size_t alignment = sizeof(float[4]); + buffer_size = divide_ceil_u(buffer_size, alignment) * alignment; + void *data = MEM_mallocN(buffer_size, __func__); + + /* Now that we know the total ubo size we can start populating it. */ + float *offset = (float *)data; + LISTBASE_FOREACH (LinkData *, link, inputs) { + GPUInput *input = (GPUInput *)link->data; + memcpy(offset, input->vec, input->type * sizeof(float)); + offset += get_padded_gpu_type(link); + } + + /* Pass data as NULL for late init. */ + GPUUniformBuffer *ubo = GPU_uniformbuffer_create(buffer_size, NULL, err_out); + /* Data will be update just before binding. */ + ubo->data = data; + return ubo; +} + +static void gpu_uniformbuffer_init(GPUUniformBuffer *ubo) +{ + BLI_assert(ubo->bindcode == 0); + ubo->bindcode = GPU_buf_alloc(); + + if (ubo->bindcode == 0) { + fprintf(stderr, "GPUUniformBuffer: UBO create failed"); + BLI_assert(0); + return; + } + + glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode); + glBufferData(GL_UNIFORM_BUFFER, ubo->size, NULL, GL_DYNAMIC_DRAW); +} + +void GPU_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data) +{ + if (ubo->bindcode == 0) { + gpu_uniformbuffer_init(ubo); + } + + glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode); + glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo->size, data); + glBindBuffer(GL_UNIFORM_BUFFER, 0); } void GPU_uniformbuffer_bind(GPUUniformBuffer *ubo, int number) @@ -328,28 +247,30 @@ void GPU_uniformbuffer_bind(GPUUniformBuffer *ubo, int number) return; } - if (ubo->type == GPU_UBO_DYNAMIC) { - GPUUniformBufferDynamic *ubo_dynamic = (GPUUniformBufferDynamic *)ubo; - if (ubo_dynamic->flag & GPU_UBO_FLAG_DIRTY) { - GPU_uniformbuffer_dynamic_update(ubo); - } + if (ubo->bindcode == 0) { + gpu_uniformbuffer_init(ubo); } - if (ubo->bindcode != 0) { - glBindBufferBase(GL_UNIFORM_BUFFER, number, ubo->bindcode); + if (ubo->data != NULL) { + GPU_uniformbuffer_update(ubo, ubo->data); + MEM_SAFE_FREE(ubo->data); } + glBindBufferBase(GL_UNIFORM_BUFFER, number, ubo->bindcode); ubo->bindpoint = number; } void GPU_uniformbuffer_unbind(GPUUniformBuffer *ubo) { - ubo->bindpoint = -1; +#ifndef NDEBUG + glBindBufferBase(GL_UNIFORM_BUFFER, ubo->bindpoint, 0); +#endif + ubo->bindpoint = 0; } -int GPU_uniformbuffer_bindpoint(GPUUniformBuffer *ubo) +void GPU_uniformbuffer_unbind_all(void) { - return ubo->bindpoint; + for (int i = 0; i < GPU_max_ubo_binds(); i++) { + glBindBufferBase(GL_UNIFORM_BUFFER, i, 0); + } } - -#undef MAX_UBO_GPU_TYPE diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.c b/source/blender/gpu/intern/gpu_vertex_buffer.cc index 3b4d469542c..eda6d1c7300 100644 --- a/source/blender/gpu/intern/gpu_vertex_buffer.c +++ b/source/blender/gpu/intern/gpu_vertex_buffer.cc @@ -39,17 +39,22 @@ static uint vbo_memory_usage; static GLenum convert_usage_type_to_gl(GPUUsageType type) { - static const GLenum table[] = { - [GPU_USAGE_STREAM] = GL_STREAM_DRAW, - [GPU_USAGE_STATIC] = GL_STATIC_DRAW, - [GPU_USAGE_DYNAMIC] = GL_DYNAMIC_DRAW, - }; - return table[type]; + switch (type) { + case GPU_USAGE_STREAM: + return GL_STREAM_DRAW; + case GPU_USAGE_DYNAMIC: + return GL_DYNAMIC_DRAW; + case GPU_USAGE_STATIC: + return GL_STATIC_DRAW; + default: + BLI_assert(0); + return GL_STATIC_DRAW; + } } GPUVertBuf *GPU_vertbuf_create(GPUUsageType usage) { - GPUVertBuf *verts = MEM_mallocN(sizeof(GPUVertBuf), "GPUVertBuf"); + GPUVertBuf *verts = (GPUVertBuf *)MEM_mallocN(sizeof(GPUVertBuf), "GPUVertBuf"); GPU_vertbuf_init(verts, usage); return verts; } @@ -109,7 +114,7 @@ GPUVertBuf *GPU_vertbuf_duplicate(GPUVertBuf *verts) } if (verts->data) { - verts_dst->data = MEM_dupallocN(verts->data); + verts_dst->data = (uchar *)MEM_dupallocN(verts->data); } return verts_dst; } @@ -161,7 +166,7 @@ void GPU_vertbuf_data_alloc(GPUVertBuf *verts, uint v_len) #endif verts->dirty = true; verts->vertex_len = verts->vertex_alloc = v_len; - verts->data = MEM_mallocN(sizeof(GLubyte) * GPU_vertbuf_size_get(verts), "GPUVertBuf data"); + verts->data = (uchar *)MEM_mallocN(sizeof(GLubyte) * GPU_vertbuf_size_get(verts), __func__); } /* resize buffer keeping existing data */ @@ -178,7 +183,7 @@ void GPU_vertbuf_data_resize(GPUVertBuf *verts, uint v_len) #endif verts->dirty = true; verts->vertex_len = verts->vertex_alloc = v_len; - verts->data = MEM_reallocN(verts->data, sizeof(GLubyte) * GPU_vertbuf_size_get(verts)); + verts->data = (uchar *)MEM_reallocN(verts->data, sizeof(GLubyte) * GPU_vertbuf_size_get(verts)); } /* Set vertex count but does not change allocation. diff --git a/source/blender/gpu/intern/gpu_vertex_format.c b/source/blender/gpu/intern/gpu_vertex_format.cc index 585a22277b2..2e8017660d0 100644 --- a/source/blender/gpu/intern/gpu_vertex_format.c +++ b/source/blender/gpu/intern/gpu_vertex_format.cc @@ -63,21 +63,29 @@ void GPU_vertformat_copy(GPUVertFormat *dest, const GPUVertFormat *src) memcpy(dest, src, sizeof(GPUVertFormat)); } -static GLenum convert_comp_type_to_gl(GPUVertCompType type) +GLenum convert_comp_type_to_gl(GPUVertCompType type) { - static const GLenum table[] = { - [GPU_COMP_I8] = GL_BYTE, - [GPU_COMP_U8] = GL_UNSIGNED_BYTE, - [GPU_COMP_I16] = GL_SHORT, - [GPU_COMP_U16] = GL_UNSIGNED_SHORT, - [GPU_COMP_I32] = GL_INT, - [GPU_COMP_U32] = GL_UNSIGNED_INT, - - [GPU_COMP_F32] = GL_FLOAT, - - [GPU_COMP_I10] = GL_INT_2_10_10_10_REV, - }; - return table[type]; + switch (type) { + case GPU_COMP_I8: + return GL_BYTE; + case GPU_COMP_U8: + return GL_UNSIGNED_BYTE; + case GPU_COMP_I16: + return GL_SHORT; + case GPU_COMP_U16: + return GL_UNSIGNED_SHORT; + case GPU_COMP_I32: + return GL_INT; + case GPU_COMP_U32: + return GL_UNSIGNED_INT; + case GPU_COMP_F32: + return GL_FLOAT; + case GPU_COMP_I10: + return GL_INT_2_10_10_10_REV; + default: + BLI_assert(0); + return GL_FLOAT; + } } static uint comp_sz(GPUVertCompType type) @@ -94,7 +102,7 @@ static uint attr_sz(const GPUVertAttr *a) if (a->comp_type == GPU_COMP_I10) { return 4; /* always packed as 10_10_10_2 */ } - return a->comp_len * comp_sz(a->comp_type); + return a->comp_len * comp_sz(static_cast<GPUVertCompType>(a->comp_type)); } static uint attr_align(const GPUVertAttr *a) @@ -102,13 +110,12 @@ static uint attr_align(const GPUVertAttr *a) if (a->comp_type == GPU_COMP_I10) { return 4; /* always packed as 10_10_10_2 */ } - uint c = comp_sz(a->comp_type); + uint c = comp_sz(static_cast<GPUVertCompType>(a->comp_type)); if (a->comp_len == 3 && c <= 2) { return 4 * c; /* AMD HW can't fetch these well, so pad it out (other vendors too?) */ } - else { - return c; /* most fetches are ok if components are naturally aligned */ - } + + return c; /* most fetches are ok if components are naturally aligned */ } uint vertex_buffer_size(const GPUVertFormat *format, uint vertex_len) @@ -185,7 +192,6 @@ uint GPU_vertformat_attr_add(GPUVertFormat *format, attr->names[attr->name_len++] = copy_attr_name(format, name); attr->comp_type = comp_type; - attr->gl_comp_type = convert_comp_type_to_gl(comp_type); attr->comp_len = (comp_type == GPU_COMP_I10) ? 4 : comp_len; /* system needs 10_10_10_2 to be 4 or BGRA */ @@ -279,7 +285,7 @@ void GPU_vertformat_attr_rename(GPUVertFormat *format, int attr_id, const char * /* Encode 8 original bytes into 11 safe bytes. */ static void safe_bytes(char out[11], const char data[8]) { - char safe_chars[63] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; + char safe_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; uint64_t in = *(uint64_t *)data; for (int i = 0; i < 11; i++) { @@ -368,14 +374,6 @@ static void show_pack(uint a_idx, uint sz, uint pad) void VertexFormat_pack(GPUVertFormat *format) { - /* For now, attributes are packed in the order they were added, - * making sure each attribute is naturally aligned (add padding where necessary) - * Later we can implement more efficient packing w/ reordering - * (keep attribute ID order, adjust their offsets to reorder in buffer). */ - - /* TODO: realloc just enough to hold the final combo string. And just enough to - * hold used attributes, not all 16. */ - GPUVertAttr *a0 = &format->attrs[0]; a0->offset = 0; uint offset = a0->sz; @@ -512,7 +510,6 @@ void GPU_vertformat_from_shader(GPUVertFormat *format, const GPUShader *shader) attr->sz = attr->comp_len * 4; attr->fetch_mode = fetch_mode; attr->comp_type = comp_type; - attr->gl_comp_type = convert_comp_type_to_gl(comp_type); attr += 1; } } diff --git a/source/blender/gpu/intern/gpu_vertex_format_private.h b/source/blender/gpu/intern/gpu_vertex_format_private.h index a80c085b44a..45523c0e956 100644 --- a/source/blender/gpu/intern/gpu_vertex_format_private.h +++ b/source/blender/gpu/intern/gpu_vertex_format_private.h @@ -25,6 +25,15 @@ #pragma once +#ifdef __cplusplus +extern "C" { +#endif + void VertexFormat_pack(GPUVertFormat *format); uint padding(uint offset, uint alignment); uint vertex_buffer_size(const GPUVertFormat *format, uint vertex_len); +GLenum convert_comp_type_to_gl(GPUVertCompType type); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c index 7f133ca626d..ba938349761 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -38,7 +38,6 @@ #include "DNA_vec_types.h" #include "GPU_framebuffer.h" -#include "GPU_glew.h" #include "GPU_immediate.h" #include "GPU_matrix.h" #include "GPU_texture.h" @@ -913,9 +912,8 @@ GPUTexture *GPU_viewport_color_texture(GPUViewport *viewport, int view) if (viewport->active_view == view) { return dtxl->color; } - else { - return dtxl->color_stereo; - } + + return dtxl->color_stereo; } return NULL; diff --git a/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl b/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl new file mode 100644 index 00000000000..f7bf3d33361 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl @@ -0,0 +1,87 @@ + +vec3 calc_barycentric_distances(vec3 pos0, vec3 pos1, vec3 pos2) +{ + vec3 edge21 = pos2 - pos1; + vec3 edge10 = pos1 - pos0; + vec3 edge02 = pos0 - pos2; + vec3 d21 = normalize(edge21); + vec3 d10 = normalize(edge10); + vec3 d02 = normalize(edge02); + + vec3 dists; + float d = dot(d21, edge02); + dists.x = sqrt(dot(edge02, edge02) - d * d); + d = dot(d02, edge10); + dists.y = sqrt(dot(edge10, edge10) - d * d); + d = dot(d10, edge21); + dists.z = sqrt(dot(edge21, edge21) - d * d); + return dists; +} + +vec2 calc_barycentric_co(int vertid) +{ + vec2 bary; + bary.x = float((vertid % 3) == 0); + bary.y = float((vertid % 3) == 1); + return bary; +} + +#ifdef HAIR_SHADER + +/* Hairs uv and col attributes are passed by bufferTextures. */ +# define DEFINE_ATTR(type, attr) uniform samplerBuffer attr +# define GET_ATTR(type, attr) hair_get_customdata_##type(attr) + +# define barycentric_get() hair_get_barycentric() +# define barycentric_resolve(bary) hair_resolve_barycentric(bary) + +vec3 orco_get(vec3 local_pos, mat4 modelmatinv, vec4 orco_madd[2], const samplerBuffer orco_samp) +{ + /* TODO: fix ORCO with modifiers. */ + vec3 orco = (modelmatinv * vec4(local_pos, 1.0)).xyz; + return orco_madd[0].xyz + orco * orco_madd[1].xyz; +} + +vec4 tangent_get(const samplerBuffer attr, mat3 normalmat) +{ + /* Unsupported */ + return vec4(0.0); +} + +#else /* MESH_SHADER */ + +# define DEFINE_ATTR(type, attr) in type attr +# define GET_ATTR(type, attr) attr + +/* Calculated in geom shader later with calc_barycentric_co. */ +# define barycentric_get() vec2(0) +# define barycentric_resolve(bary) bary + +vec3 orco_get(vec3 local_pos, mat4 modelmatinv, vec4 orco_madd[2], vec4 orco) +{ + /* If the object does not have any deformation, the orco layer calculation is done on the fly + * using the orco_madd factors. + * We know when there is no orco layer when orco.w is 1.0 because it uses the generic vertex + * attrib (which is [0,0,0,1]). */ + if (orco.w == 0.0) { + return orco.xyz * 0.5 + 0.5; + } + else { + return orco_madd[0].xyz + local_pos * orco_madd[1].xyz; + } +} + +vec4 tangent_get(vec4 attr, mat3 normalmat) +{ + vec4 tangent; + tangent.xyz = normalmat * attr.xyz; + tangent.w = attr.w; + float len_sqr = dot(tangent.xyz, tangent.xyz); + /* Normalize only if vector is not null. */ + if (len_sqr > 0.0) { + tangent.xyz *= inversesqrt(len_sqr); + } + return tangent; +} + +#endif diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl index d6d6fbab971..eea8d19efce 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl @@ -3,7 +3,7 @@ void node_ambient_occlusion( vec4 color, float distance, vec3 normal, out vec4 result_color, out float result_ao) { vec3 bent_normal; - vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0); + vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); result_ao = occlusion_compute(normalize(normal), viewPosition, 1.0, rand, bent_normal); result_color = result_ao * color; } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl index 3b23ac976ae..6330daa4391 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl @@ -1,3 +1,15 @@ + +float wang_hash_noise(uint s) +{ + s = (s ^ 61u) ^ (s >> 16u); + s *= 9u; + s = s ^ (s >> 4u); + s *= 0x27d4eb2du; + s = s ^ (s >> 15u); + + return fract(float(s) / 4294967296.0); +} + void node_hair_info(out float is_strand, out float intercept, out float thickness, diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_world_normals.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_world_normals.glsl index f9691beee6f..d33465fa846 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_world_normals.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_world_normals.glsl @@ -6,7 +6,7 @@ void world_normals_get(out vec3 N) vec3 B = normalize(cross(worldNormal, hairTangent)); float cos_theta; if (hairThicknessRes == 1) { - vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0); + vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); /* Random cosine normal distribution on the hair surface. */ cos_theta = rand.x * 2.0 - 1.0; } diff --git a/source/blender/ikplugin/BIK_api.h b/source/blender/ikplugin/BIK_api.h index fa7d7ff555c..674b384adf2 100644 --- a/source/blender/ikplugin/BIK_api.h +++ b/source/blender/ikplugin/BIK_api.h @@ -35,10 +35,10 @@ struct bConstraint; struct bPose; struct bPoseChannel; -void BIK_initialize_tree(struct Depsgraph *depsgraph, - struct Scene *scene, - struct Object *ob, - float ctime); +void BIK_init_tree(struct Depsgraph *depsgraph, + struct Scene *scene, + struct Object *ob, + float ctime); void BIK_execute_tree(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, diff --git a/source/blender/ikplugin/intern/ikplugin_api.c b/source/blender/ikplugin/intern/ikplugin_api.c index 5e683d36408..233150a77aa 100644 --- a/source/blender/ikplugin/intern/ikplugin_api.c +++ b/source/blender/ikplugin/intern/ikplugin_api.c @@ -80,7 +80,7 @@ static IKPlugin *get_plugin(bPose *pose) /*----------------------------------------*/ /* Plugin API */ -void BIK_initialize_tree(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime) +void BIK_init_tree(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime) { IKPlugin *plugin = get_plugin(ob->pose); diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c index 3646686e81f..ba096653e0f 100644 --- a/source/blender/ikplugin/intern/iksolver_plugin.c +++ b/source/blender/ikplugin/intern/iksolver_plugin.c @@ -452,21 +452,20 @@ static void execute_posetree(struct Depsgraph *depsgraph, /* don't solve IK when we are setting the pole angle */ break; } - else { - mul_m4_m4m4(goal, goalinv, rootmat); - copy_v3_v3(polepos, goal[3]); - poleconstrain = 1; - - /* for pole targets, we blend the result of the ik solver - * instead of the target position, otherwise we can't get - * a smooth transition */ - resultblend = 1; - resultinf = target->con->enforce; - - if (data->flag & CONSTRAINT_IK_GETANGLE) { - poleangledata = data; - data->flag &= ~CONSTRAINT_IK_GETANGLE; - } + + mul_m4_m4m4(goal, goalinv, rootmat); + copy_v3_v3(polepos, goal[3]); + poleconstrain = 1; + + /* for pole targets, we blend the result of the ik solver + * instead of the target position, otherwise we can't get + * a smooth transition */ + resultblend = 1; + resultinf = target->con->enforce; + + if (data->flag & CONSTRAINT_IK_GETANGLE) { + poleangledata = data; + data->flag &= ~CONSTRAINT_IK_GETANGLE; } } diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp index 8f84d04f602..a5fdb9ef491 100644 --- a/source/blender/ikplugin/intern/itasc_plugin.cpp +++ b/source/blender/ikplugin/intern/itasc_plugin.cpp @@ -446,24 +446,21 @@ static double EulerAngleFromMatrix(const KDL::Rotation &R, int axis) if (axis == 0) { return -KDL::atan2(R(1, 2), R(2, 2)); } - else if (axis == 1) { + if (axis == 1) { return KDL::atan2(-R(0, 2), t); } - else { - return -KDL::atan2(R(0, 1), R(0, 0)); - } + + return -KDL::atan2(R(0, 1), R(0, 0)); } - else { - if (axis == 0) { - return -KDL::atan2(-R(2, 1), R(1, 1)); - } - else if (axis == 1) { - return KDL::atan2(-R(0, 2), t); - } - else { - return 0.0f; - } + + if (axis == 0) { + return -KDL::atan2(-R(2, 1), R(1, 1)); + } + if (axis == 1) { + return KDL::atan2(-R(0, 2), t); } + + return 0.0f; } static double ComputeTwist(const KDL::Rotation &R) diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt index cad0be659ec..cf637a06405 100644 --- a/source/blender/imbuf/CMakeLists.txt +++ b/source/blender/imbuf/CMakeLists.txt @@ -23,6 +23,7 @@ set(INC ../blenkernel ../blenlib ../blenloader + ../gpu ../makesdna ../makesrna ../../../intern/guardedalloc @@ -63,6 +64,7 @@ set(SRC intern/thumbs_blend.c intern/thumbs_font.c intern/util.c + intern/util_gpu.c intern/writeimage.c IMB_colormanagement.h diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 0f3d121ff96..37046521dd8 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -89,6 +89,12 @@ struct Stereo3dFormat; /** * + * \attention defined in GPU_texture.h + */ +struct GPUTexture; + +/** + * * \attention Defined in allocimbuf.c */ void IMB_init(void); @@ -728,6 +734,25 @@ const char *IMB_ffmpeg_last_error(void); /** * + * \attention defined in util_gpu.c + */ +struct GPUTexture *IMB_create_gpu_texture(struct ImBuf *ibuf, + bool use_high_bitdepth, + bool use_premult); +struct GPUTexture *IMB_touch_gpu_texture( + struct ImBuf *ibuf, int w, int h, int layers, bool use_high_bitdepth); +void IMB_update_gpu_texture_sub(struct GPUTexture *tex, + struct ImBuf *ibuf, + int x, + int y, + int z, + int w, + int h, + bool use_high_bitdepth, + bool use_premult); + +/** + * * \attention defined in stereoimbuf.c */ void IMB_stereo3d_write_dimensions(const char mode, diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c index 4b3858e6d5a..4205a6ecc39 100644 --- a/source/blender/imbuf/intern/allocimbuf.c +++ b/source/blender/imbuf/intern/allocimbuf.c @@ -423,9 +423,8 @@ bool imb_addrectImBuf(ImBuf *ibuf) if (ibuf->planes > 32) { return (addzbufImBuf(ibuf)); } - else { - return true; - } + + return true; } return false; diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index 9fab450cc76..01372d5ed68 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -803,7 +803,7 @@ static void ffmpeg_postprocess(struct anim *anim) if (ENDIAN_ORDER == B_ENDIAN) { int *dstStride = anim->pFrameRGB->linesize; uint8_t **dst = anim->pFrameRGB->data; - int dstStride2[4] = {dstStride[0], 0, 0, 0}; + const int dstStride2[4] = {dstStride[0], 0, 0, 0}; uint8_t *dst2[4] = {dst[0], 0, 0, 0}; int x, y, h, w; unsigned char *bottom; @@ -849,7 +849,7 @@ static void ffmpeg_postprocess(struct anim *anim) else { int *dstStride = anim->pFrameRGB->linesize; uint8_t **dst = anim->pFrameRGB->data; - int dstStride2[4] = {-dstStride[0], 0, 0, 0}; + const int dstStride2[4] = {-dstStride[0], 0, 0, 0}; uint8_t *dst2[4] = {dst[0] + (anim->y - 1) * dstStride[0], 0, 0, 0}; sws_scale(anim->img_convert_ctx, diff --git a/source/blender/imbuf/intern/cineon/logImageCore.c b/source/blender/imbuf/intern/cineon/logImageCore.c index e9030496498..362a558b505 100644 --- a/source/blender/imbuf/intern/cineon/logImageCore.c +++ b/source/blender/imbuf/intern/cineon/logImageCore.c @@ -119,7 +119,7 @@ LogImageFile *logImageOpenFromFile(const char *filename, int cineon) if (logImageIsDpx(&magicNum)) { return dpxOpen((const unsigned char *)filename, 0, 0); } - else if (logImageIsCineon(&magicNum)) { + if (logImageIsCineon(&magicNum)) { return cineonOpen((const unsigned char *)filename, 0, 0); } @@ -131,7 +131,7 @@ LogImageFile *logImageOpenFromMemory(const unsigned char *buffer, unsigned int s if (logImageIsDpx(buffer)) { return dpxOpen(buffer, 1, size); } - else if (logImageIsCineon(buffer)) { + if (logImageIsCineon(buffer)) { return cineonOpen(buffer, 1, size); } @@ -154,18 +154,17 @@ LogImageFile *logImageCreate(const char *filename, if (cineon) { return cineonCreate(filename, width, height, bitsPerSample, creator); } - else { - return dpxCreate(filename, - width, - height, - bitsPerSample, - isLogarithmic, - hasAlpha, - referenceWhite, - referenceBlack, - gamma, - creator); - } + + return dpxCreate(filename, + width, + height, + bitsPerSample, + isLogarithmic, + hasAlpha, + referenceWhite, + referenceBlack, + gamma, + creator); return NULL; } @@ -1677,7 +1676,7 @@ static int convertLogElementToRGBA( if (rvalue == 1) { return 1; } - else if (dstIsLinearRGB) { + if (dstIsLinearRGB) { /* convert data from sRGB to Linear RGB via lut */ float *lut = getSrgbToLinLut(logElement); src_ptr = dst; // no error here diff --git a/source/blender/imbuf/intern/cineon/logmemfile.c b/source/blender/imbuf/intern/cineon/logmemfile.c index 91351d309de..aca84df91ca 100644 --- a/source/blender/imbuf/intern/cineon/logmemfile.c +++ b/source/blender/imbuf/intern/cineon/logmemfile.c @@ -64,10 +64,9 @@ int logimage_fwrite(void *buffer, size_t size, unsigned int count, LogImageFile if (logFile->file) { return fwrite(buffer, size, count, logFile->file); } - else { /* we're writing to memory */ - /* do nothing as this isn't supported yet */ - return count; - } + /* we're writing to memory */ + /* do nothing as this isn't supported yet */ + return count; } int logimage_fread(void *buffer, size_t size, unsigned int count, LogImageFile *logFile) @@ -75,23 +74,22 @@ int logimage_fread(void *buffer, size_t size, unsigned int count, LogImageFile * if (logFile->file) { return fread(buffer, size, count, logFile->file); } - else { /* we're reading from memory */ - unsigned char *buf = (unsigned char *)buffer; - uintptr_t pos = (uintptr_t)logFile->memCursor - (uintptr_t)logFile->memBuffer; - size_t total_size = size * count; - if (pos + total_size > logFile->memBufferSize) { - /* how many elements can we read without overflow ? */ - count = (logFile->memBufferSize - pos) / size; - /* recompute the size */ - total_size = size * count; - } - - if (total_size != 0) { - memcpy(buf, logFile->memCursor, total_size); - } + /* we're reading from memory */ + unsigned char *buf = (unsigned char *)buffer; + uintptr_t pos = (uintptr_t)logFile->memCursor - (uintptr_t)logFile->memBuffer; + size_t total_size = size * count; + if (pos + total_size > logFile->memBufferSize) { + /* how many elements can we read without overflow ? */ + count = (logFile->memBufferSize - pos) / size; + /* recompute the size */ + total_size = size * count; + } - return count; + if (total_size != 0) { + memcpy(buf, logFile->memCursor, total_size); } + + return count; } int logimage_read_uchar(unsigned char *x, LogImageFile *logFile) diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index c9b3db39976..08e1bc5f674 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -1399,9 +1399,8 @@ const char *IMB_colormanagement_get_float_colorspace(ImBuf *ibuf) if (ibuf->float_colorspace) { return ibuf->float_colorspace->name; } - else { - return IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR); - } + + return IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR); } const char *IMB_colormanagement_get_rect_colorspace(ImBuf *ibuf) @@ -1409,9 +1408,8 @@ const char *IMB_colormanagement_get_rect_colorspace(ImBuf *ibuf) if (ibuf->rect_colorspace) { return ibuf->rect_colorspace->name; } - else { - return IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_BYTE); - } + + return IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_BYTE); } bool IMB_colormanagement_space_is_data(ColorSpace *colorspace) @@ -3958,7 +3956,7 @@ static void curve_mapping_to_ocio_settings(CurveMapping *curve_mapping, { int i; - BKE_curvemapping_initialize(curve_mapping); + BKE_curvemapping_init(curve_mapping); BKE_curvemapping_premultiply(curve_mapping, false); BKE_curvemapping_table_RGBA( curve_mapping, &curve_mapping_settings->lut, &curve_mapping_settings->lut_size); diff --git a/source/blender/imbuf/intern/dds/BlockDXT.cpp b/source/blender/imbuf/intern/dds/BlockDXT.cpp index 9fd6d71e091..1fbe7b46963 100644 --- a/source/blender/imbuf/intern/dds/BlockDXT.cpp +++ b/source/blender/imbuf/intern/dds/BlockDXT.cpp @@ -97,21 +97,20 @@ uint BlockDXT1::evaluatePalette(Color32 color_array[4]) const return 4; } - else { - // Three-color block: derive the other color. - color_array[2].r = (color_array[0].r + color_array[1].r) / 2; - color_array[2].g = (color_array[0].g + color_array[1].g) / 2; - color_array[2].b = (color_array[0].b + color_array[1].b) / 2; - color_array[2].a = 0xFF; - // Set all components to 0 to match DXT specs. - color_array[3].r = 0x00; // color_array[2].r; - color_array[3].g = 0x00; // color_array[2].g; - color_array[3].b = 0x00; // color_array[2].b; - color_array[3].a = 0x00; + // Three-color block: derive the other color. + color_array[2].r = (color_array[0].r + color_array[1].r) / 2; + color_array[2].g = (color_array[0].g + color_array[1].g) / 2; + color_array[2].b = (color_array[0].b + color_array[1].b) / 2; + color_array[2].a = 0xFF; - return 3; - } + // Set all components to 0 to match DXT specs. + color_array[3].r = 0x00; // color_array[2].r; + color_array[3].g = 0x00; // color_array[2].g; + color_array[3].b = 0x00; // color_array[2].b; + color_array[3].a = 0x00; + + return 3; } uint BlockDXT1::evaluatePaletteNV5x(Color32 color_array[4]) const @@ -143,21 +142,20 @@ uint BlockDXT1::evaluatePaletteNV5x(Color32 color_array[4]) const return 4; } - else { - // Three-color block: derive the other color. - color_array[2].r = ((col0.r + col1.r) * 33) / 8; - color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 128) / 256; - color_array[2].b = ((col0.b + col1.b) * 33) / 8; - color_array[2].a = 0xFF; - // Set all components to 0 to match DXT specs. - color_array[3].r = 0x00; // color_array[2].r; - color_array[3].g = 0x00; // color_array[2].g; - color_array[3].b = 0x00; // color_array[2].b; - color_array[3].a = 0x00; + // Three-color block: derive the other color. + color_array[2].r = ((col0.r + col1.r) * 33) / 8; + color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 128) / 256; + color_array[2].b = ((col0.b + col1.b) * 33) / 8; + color_array[2].a = 0xFF; - return 3; - } + // Set all components to 0 to match DXT specs. + color_array[3].r = 0x00; // color_array[2].r; + color_array[3].g = 0x00; // color_array[2].g; + color_array[3].b = 0x00; // color_array[2].b; + color_array[3].a = 0x00; + + return 3; } // Evaluate palette assuming 3 color block. diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp index 9730153819e..92dd475813a 100644 --- a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp +++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp @@ -864,9 +864,8 @@ uint DDSHeader::d3d9Format() const if (pf.flags & DDPF_FOURCC) { return pf.fourcc; } - else { - return findD3D9Format(pf.bitcount, pf.rmask, pf.gmask, pf.bmask, pf.amask); - } + + return findD3D9Format(pf.bitcount, pf.rmask, pf.gmask, pf.bmask, pf.amask); } DirectDrawSurface::DirectDrawSurface(unsigned char *mem, uint size) : stream(mem, size), header() @@ -923,33 +922,32 @@ bool DirectDrawSurface::isSupported() const return false; } - else { - if (header.pf.flags & DDPF_FOURCC) { - if (header.pf.fourcc != FOURCC_DXT1 && header.pf.fourcc != FOURCC_DXT2 && - header.pf.fourcc != FOURCC_DXT3 && header.pf.fourcc != FOURCC_DXT4 && - header.pf.fourcc != FOURCC_DXT5 && header.pf.fourcc != FOURCC_RXGB && - header.pf.fourcc != FOURCC_ATI1 && header.pf.fourcc != FOURCC_ATI2) { - // Unknown fourcc code. - return false; - } - } - else if ((header.pf.flags & DDPF_RGB) || (header.pf.flags & DDPF_LUMINANCE)) { - // All RGB and luminance formats are supported now. - } - else { - return false; - } - if (isTextureCube() && - (header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) != DDSCAPS2_CUBEMAP_ALL_FACES) { - // Cubemaps must contain all faces. + if (header.pf.flags & DDPF_FOURCC) { + if (header.pf.fourcc != FOURCC_DXT1 && header.pf.fourcc != FOURCC_DXT2 && + header.pf.fourcc != FOURCC_DXT3 && header.pf.fourcc != FOURCC_DXT4 && + header.pf.fourcc != FOURCC_DXT5 && header.pf.fourcc != FOURCC_RXGB && + header.pf.fourcc != FOURCC_ATI1 && header.pf.fourcc != FOURCC_ATI2) { + // Unknown fourcc code. return false; } + } + else if ((header.pf.flags & DDPF_RGB) || (header.pf.flags & DDPF_LUMINANCE)) { + // All RGB and luminance formats are supported now. + } + else { + return false; + } - if (isTexture3D()) { - // @@ 3D textures not supported yet. - return false; - } + if (isTextureCube() && + (header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) != DDSCAPS2_CUBEMAP_ALL_FACES) { + // Cubemaps must contain all faces. + return false; + } + + if (isTexture3D()) { + // @@ 3D textures not supported yet. + return false; } return true; @@ -963,23 +961,21 @@ bool DirectDrawSurface::hasAlpha() const header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM || header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM; } - else { - if (header.pf.flags & DDPF_RGB) { - return header.pf.amask != 0; - } - else if (header.pf.flags & DDPF_FOURCC) { - if (header.pf.fourcc == FOURCC_RXGB || header.pf.fourcc == FOURCC_ATI1 || - header.pf.fourcc == FOURCC_ATI2 || header.pf.flags & DDPF_NORMAL) { - return false; - } - else { - // @@ Here we could check the ALPHA_PIXELS flag, but nobody sets it. (except us?) - return true; - } + + if (header.pf.flags & DDPF_RGB) { + return header.pf.amask != 0; + } + if (header.pf.flags & DDPF_FOURCC) { + if (header.pf.fourcc == FOURCC_RXGB || header.pf.fourcc == FOURCC_ATI1 || + header.pf.fourcc == FOURCC_ATI2 || header.pf.flags & DDPF_NORMAL) { + return false; } - return false; + // @@ Here we could check the ALPHA_PIXELS flag, but nobody sets it. (except us?) + return true; } + + return false; } uint DirectDrawSurface::mipmapCount() const @@ -987,9 +983,8 @@ uint DirectDrawSurface::mipmapCount() const if (header.flags & DDSD_MIPMAPCOUNT) { return header.mipmapcount; } - else { - return 1; - } + + return 1; } uint DirectDrawSurface::fourCC() const @@ -1002,9 +997,8 @@ uint DirectDrawSurface::width() const if (header.flags & DDSD_WIDTH) { return header.width; } - else { - return 1; - } + + return 1; } uint DirectDrawSurface::height() const @@ -1012,9 +1006,8 @@ uint DirectDrawSurface::height() const if (header.flags & DDSD_HEIGHT) { return header.height; } - else { - return 1; - } + + return 1; } uint DirectDrawSurface::depth() const @@ -1022,9 +1015,8 @@ uint DirectDrawSurface::depth() const if (header.flags & DDSD_DEPTH) { return header.depth; } - else { - return 1; - } + + return 1; } bool DirectDrawSurface::isTexture1D() const @@ -1040,9 +1032,8 @@ bool DirectDrawSurface::isTexture2D() const if (header.hasDX10Header()) { return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE2D; } - else { - return !isTexture3D() && !isTextureCube(); - } + + return !isTexture3D() && !isTextureCube(); } bool DirectDrawSurface::isTexture3D() const @@ -1050,9 +1041,8 @@ bool DirectDrawSurface::isTexture3D() const if (header.hasDX10Header()) { return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE3D; } - else { - return (header.caps.caps2 & DDSCAPS2_VOLUME) != 0; - } + + return (header.caps.caps2 & DDSCAPS2_VOLUME) != 0; } bool DirectDrawSurface::isTextureCube() const @@ -1355,16 +1345,15 @@ uint DirectDrawSurface::mipmapSize(uint mipmap) const h = (h + 3) / 4; return blockSize() * w * h; } - else if (header.pf.flags & DDPF_RGB || (header.pf.flags & DDPF_LUMINANCE)) { + if (header.pf.flags & DDPF_RGB || (header.pf.flags & DDPF_LUMINANCE)) { uint pitch = computePitch( w, header.pf.bitcount, 8); // Assuming 8 bit alignment, which is the same D3DX expects. return pitch * h * d; } - else { - printf("DDS: mipmap format not supported\n"); - return (0); - } + + printf("DDS: mipmap format not supported\n"); + return (0); } uint DirectDrawSurface::faceSize() const diff --git a/source/blender/imbuf/intern/dds/FlipDXT.cpp b/source/blender/imbuf/intern/dds/FlipDXT.cpp index f5c937654b3..f46f50eb2b9 100644 --- a/source/blender/imbuf/intern/dds/FlipDXT.cpp +++ b/source/blender/imbuf/intern/dds/FlipDXT.cpp @@ -217,7 +217,7 @@ int FlipDXTCImage( // no flip to do, and we're done. break; } - else if (mip_height == 2) { + if (mip_height == 2) { // flip the first 2 lines in each block. for (unsigned int i = 0; i < blocks_per_row; i++) { half_block_function(data + i * block_bytes); diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c index d8a5096af71..12f90f27309 100644 --- a/source/blender/imbuf/intern/filter.c +++ b/source/blender/imbuf/intern/filter.c @@ -394,9 +394,8 @@ static int filter_make_index(const int x, const int y, const int w, const int h) if (x < 0 || x >= w || y < 0 || y >= h) { return -1; /* return bad index */ } - else { - return y * w + x; - } + + return y * w + x; } static int check_pixel_assigned( diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c index 7cc31b99077..dd2edebedff 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -268,9 +268,8 @@ int IMB_indexer_get_frame_index(struct anim_index *idx, int frameno) if (first == idx->num_entries) { return idx->num_entries - 1; } - else { - return first; - } + + return first; } unsigned long long IMB_indexer_get_pts(struct anim_index *idx, int frame_index) @@ -633,9 +632,8 @@ static int add_to_proxy_output_ffmpeg(struct proxy_output_ctx *ctx, AVFrame *fra return 1; } - else { - return 0; - } + + return 0; } static void free_proxy_output_ffmpeg(struct proxy_output_ctx *ctx, int rollback) diff --git a/source/blender/imbuf/intern/iris.c b/source/blender/imbuf/intern/iris.c index 2516df22151..5f698543aa9 100644 --- a/source/blender/imbuf/intern/iris.c +++ b/source/blender/imbuf/intern/iris.c @@ -892,10 +892,9 @@ static int output_iris(uint *lptr, int xsize, int ysize, int zsize, const char * if (goodwrite) { return 1; } - else { - fprintf(stderr, "output_iris: not enough space for image!!\n"); - return 0; - } + + fprintf(stderr, "output_iris: not enough space for image!!\n"); + return 0; } /* static utility functions for output_iris */ diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c index 5154f50c7e8..a5b977be2ce 100644 --- a/source/blender/imbuf/intern/jp2.c +++ b/source/blender/imbuf/intern/jp2.c @@ -73,12 +73,11 @@ static OPJ_CODEC_FORMAT format_from_header(const unsigned char mem[JP2_FILEHEADE if (check_jp2(mem)) { return OPJ_CODEC_JP2; } - else if (check_j2k(mem)) { + if (check_j2k(mem)) { return OPJ_CODEC_J2K; } - else { - return OPJ_CODEC_UNKNOWN; - } + + return OPJ_CODEC_UNKNOWN; } int imb_is_a_jp2(const unsigned char *buf) @@ -339,16 +338,14 @@ ImBuf *imb_load_jp2_filepath(const char *filepath, int flags, char colorspace[IM if (stream) { return NULL; } - else { - if (fread(mem, sizeof(mem), 1, p_file) != sizeof(mem)) { - opj_stream_destroy(stream); - return NULL; - } - else { - fseek(p_file, 0, SEEK_SET); - } + + if (fread(mem, sizeof(mem), 1, p_file) != sizeof(mem)) { + opj_stream_destroy(stream); + return NULL; } + fseek(p_file, 0, SEEK_SET); + const OPJ_CODEC_FORMAT format = format_from_header(mem); ImBuf *ibuf = imb_load_jp2_stream(stream, format, flags, colorspace); opj_stream_destroy(stream); @@ -651,7 +648,7 @@ BLI_INLINE int DOWNSAMPLE_FLOAT_TO_16BIT(const float _val) #define COMP_24_CS 1041666 /*Maximum size per color component for 2K & 4K @ 24fps*/ #define COMP_48_CS 520833 /*Maximum size per color component for 2K @ 48fps*/ -static int initialise_4K_poc(opj_poc_t *POC, int numres) +static int init_4K_poc(opj_poc_t *POC, int numres) { POC[0].tile = 1; POC[0].resno0 = 0; @@ -750,7 +747,7 @@ static void cinema_setup_encoder(opj_cparameters_t *parameters, else { parameters->cp_rsiz = DCP_CINEMA2K; } - parameters->numpocs = initialise_4K_poc(parameters->POC, parameters->numresolution); + parameters->numpocs = init_4K_poc(parameters->POC, parameters->numresolution); break; case OPJ_OFF: /* do nothing */ diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c index 96ecbdce9cc..f7b033869e3 100644 --- a/source/blender/imbuf/intern/moviecache.c +++ b/source/blender/imbuf/intern/moviecache.c @@ -192,9 +192,8 @@ static size_t get_size_in_memory(ImBuf *ibuf) if (ibuf->userflags & IB_PERSISTENT) { return 0; } - else { - return IMB_get_size_in_memory(ibuf); - } + + return IMB_get_size_in_memory(ibuf); } static size_t get_item_size(void *p) { diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index 9b614eab0dc..05592a7d408 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -131,9 +131,8 @@ class IMemStream : public Imf::IStream { _exrpos += n; return true; } - else { - return false; - } + + return false; } virtual Int64 tellg() @@ -597,15 +596,13 @@ int imb_save_openexr(struct ImBuf *ibuf, const char *name, int flags) if (ibuf->foptions.flag & OPENEXR_HALF) { return (int)imb_save_openexr_half(ibuf, name, flags); } - else { - /* when no float rect, we save as half (16 bits is sufficient) */ - if (ibuf->rect_float == NULL) { - return (int)imb_save_openexr_half(ibuf, name, flags); - } - else { - return (int)imb_save_openexr_float(ibuf, name, flags); - } + + /* when no float rect, we save as half (16 bits is sufficient) */ + if (ibuf->rect_float == NULL) { + return (int)imb_save_openexr_half(ibuf, name, flags); } + + return (int)imb_save_openexr_float(ibuf, name, flags); } /* ******* Nicer API, MultiLayer and with Tile file support ************************************ */ @@ -719,9 +716,8 @@ static int imb_exr_get_multiView_id(StringVector &views, const std::string &name if (name == *i) { return count; } - else { - count++; - } + + count++; } /* no views or wrong name */ @@ -741,7 +737,7 @@ static void imb_exr_get_views(MultiPartInputFile &file, StringVector &views) else { for (int p = 0; p < file.parts(); p++) { - std::string view = ""; + std::string view; if (file.header(p).hasView()) { view = file.header(p).view(); } @@ -1421,7 +1417,7 @@ static int imb_exr_split_channel_name(ExrChannel *echan, char *layname, char *pa printf("multilayer read: bad channel name: %s\n", name); return 0; } - else if (len == 1) { + if (len == 1) { echan->chan_id = token[0]; } else if (len > 1) { diff --git a/source/blender/imbuf/intern/stereoimbuf.c b/source/blender/imbuf/intern/stereoimbuf.c index 5569e119b95..247122065de 100644 --- a/source/blender/imbuf/intern/stereoimbuf.c +++ b/source/blender/imbuf/intern/stereoimbuf.c @@ -669,17 +669,17 @@ static void imb_stereo3d_squeeze_rect( /*************************** preparing to call the write functions **************************/ -static void imb_stereo3d_data_initialize(Stereo3DData *s3d_data, - const bool is_float, - const size_t x, - const size_t y, - const size_t channels, - int *rect_left, - int *rect_right, - int *rect_stereo, - float *rectf_left, - float *rectf_right, - float *rectf_stereo) +static void imb_stereo3d_data_init(Stereo3DData *s3d_data, + const bool is_float, + const size_t x, + const size_t y, + const size_t channels, + int *rect_left, + int *rect_right, + int *rect_stereo, + float *rectf_left, + float *rectf_right, + float *rectf_stereo) { s3d_data->is_float = is_float; s3d_data->x = x; @@ -709,7 +709,7 @@ int *IMB_stereo3d_from_rect(ImageFormatData *im_format, im_format->stereo3d_format.display_mode, false, x, y, &width, &height); r_rect = MEM_mallocN(channels * sizeof(int) * width * height, __func__); - imb_stereo3d_data_initialize( + imb_stereo3d_data_init( &s3d_data, is_float, x, y, channels, rect_left, rect_right, r_rect, NULL, NULL, NULL); imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format); imb_stereo3d_squeeze_rect(r_rect, &im_format->stereo3d_format, x, y, channels); @@ -733,7 +733,7 @@ float *IMB_stereo3d_from_rectf(ImageFormatData *im_format, im_format->stereo3d_format.display_mode, false, x, y, &width, &height); r_rectf = MEM_mallocN(channels * sizeof(float) * width * height, __func__); - imb_stereo3d_data_initialize( + imb_stereo3d_data_init( &s3d_data, is_float, x, y, channels, NULL, NULL, NULL, rectf_left, rectf_right, r_rectf); imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format); imb_stereo3d_squeeze_rectf(r_rectf, &im_format->stereo3d_format, x, y, channels); @@ -759,17 +759,17 @@ ImBuf *IMB_stereo3d_ImBuf(ImageFormatData *im_format, ImBuf *ibuf_left, ImBuf *i ibuf_stereo->flags = ibuf_left->flags; - imb_stereo3d_data_initialize(&s3d_data, - is_float, - ibuf_left->x, - ibuf_left->y, - 4, - (int *)ibuf_left->rect, - (int *)ibuf_right->rect, - (int *)ibuf_stereo->rect, - ibuf_left->rect_float, - ibuf_right->rect_float, - ibuf_stereo->rect_float); + imb_stereo3d_data_init(&s3d_data, + is_float, + ibuf_left->x, + ibuf_left->y, + 4, + (int *)ibuf_left->rect, + (int *)ibuf_right->rect, + (int *)ibuf_stereo->rect, + ibuf_left->rect_float, + ibuf_right->rect_float, + ibuf_stereo->rect_float); imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format); imb_stereo3d_squeeze_ImBuf(ibuf_stereo, &im_format->stereo3d_format, ibuf_left->x, ibuf_left->y); @@ -1286,17 +1286,17 @@ void IMB_ImBufFromStereo3d(Stereo3dFormat *s3d, &height); imb_stereo3d_unsqueeze_ImBuf(ibuf_stereo3d, s3d, width, height); - imb_stereo3d_data_initialize(&s3d_data, - is_float, - ibuf_left->x, - ibuf_left->y, - 4, - (int *)ibuf_left->rect, - (int *)ibuf_right->rect, - (int *)ibuf_stereo3d->rect, - ibuf_left->rect_float, - ibuf_right->rect_float, - ibuf_stereo3d->rect_float); + imb_stereo3d_data_init(&s3d_data, + is_float, + ibuf_left->x, + ibuf_left->y, + 4, + (int *)ibuf_left->rect, + (int *)ibuf_right->rect, + (int *)ibuf_stereo3d->rect, + ibuf_left->rect_float, + ibuf_right->rect_float, + ibuf_stereo3d->rect_float); imb_stereo3d_read_doit(&s3d_data, s3d); @@ -1310,17 +1310,17 @@ void IMB_ImBufFromStereo3d(Stereo3dFormat *s3d, addzbufImBuf(ibuf_right); } - imb_stereo3d_data_initialize(&s3d_data, - is_float, - ibuf_left->x, - ibuf_left->y, - 1, - (int *)ibuf_left->zbuf, - (int *)ibuf_right->zbuf, - (int *)ibuf_stereo3d->zbuf, - ibuf_left->zbuf_float, - ibuf_right->zbuf_float, - ibuf_stereo3d->zbuf_float); + imb_stereo3d_data_init(&s3d_data, + is_float, + ibuf_left->x, + ibuf_left->y, + 1, + (int *)ibuf_left->zbuf, + (int *)ibuf_right->zbuf, + (int *)ibuf_stereo3d->zbuf, + ibuf_left->zbuf_float, + ibuf_right->zbuf_float, + ibuf_stereo3d->zbuf_float); imb_stereo3d_read_doit(&s3d_data, s3d); } diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c index 715f2aaf621..5d72066675b 100644 --- a/source/blender/imbuf/intern/tiff.c +++ b/source/blender/imbuf/intern/tiff.c @@ -306,8 +306,8 @@ static TIFF *imb_tiff_client_open(ImbTIFFMemFile *memFile, const unsigned char * #define IMB_TIFF_NCB 4 /* number of comparison bytes used */ int imb_is_a_tiff(const unsigned char *mem) { - char big_endian[IMB_TIFF_NCB] = {0x4d, 0x4d, 0x00, 0x2a}; - char lil_endian[IMB_TIFF_NCB] = {0x49, 0x49, 0x2a, 0x00}; + const char big_endian[IMB_TIFF_NCB] = {0x4d, 0x4d, 0x00, 0x2a}; + const char lil_endian[IMB_TIFF_NCB] = {0x49, 0x49, 0x2a, 0x00}; return ((memcmp(big_endian, mem, IMB_TIFF_NCB) == 0) || (memcmp(lil_endian, mem, IMB_TIFF_NCB) == 0)); @@ -792,16 +792,16 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags) "not yet supported.\n"); return (0); } - else { - /* create image as a file */ + + /* create image as a file */ #ifdef WIN32 - wchar_t *wname = alloc_utf16_from_8(name, 0); - image = TIFFOpenW(wname, "w"); - free(wname); + wchar_t *wname = alloc_utf16_from_8(name, 0); + image = TIFFOpenW(wname, "w"); + free(wname); #else - image = TIFFOpen(name, "w"); + image = TIFFOpen(name, "w"); #endif - } + if (image == NULL) { fprintf(stderr, "imb_savetiff: could not open TIFF for writing.\n"); return (0); diff --git a/source/blender/imbuf/intern/util_gpu.c b/source/blender/imbuf/intern/util_gpu.c new file mode 100644 index 00000000000..1a46572fb20 --- /dev/null +++ b/source/blender/imbuf/intern/util_gpu.c @@ -0,0 +1,260 @@ +/* + * 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. + * util.c + */ + +/** \file + * \ingroup imbuf + */ + +#include "imbuf.h" + +#include "BLI_math.h" +#include "BLI_utildefines.h" +#include "MEM_guardedalloc.h" + +#include "BKE_global.h" + +#include "GPU_extensions.h" +#include "GPU_texture.h" + +#include "IMB_colormanagement.h" +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + +/* gpu ibuf utils */ + +static void imb_gpu_get_format(const ImBuf *ibuf, + bool high_bitdepth, + eGPUDataFormat *r_data_format, + eGPUTextureFormat *r_texture_format) +{ + const bool float_rect = (ibuf->rect_float != NULL); + const bool use_srgb = (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace) && + !IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace)); + high_bitdepth = (!(ibuf->flags & IB_halffloat) && high_bitdepth); + + *r_data_format = (float_rect) ? GPU_DATA_FLOAT : GPU_DATA_UNSIGNED_BYTE; + + if (float_rect) { + *r_texture_format = high_bitdepth ? GPU_RGBA32F : GPU_RGBA16F; + } + else { + *r_texture_format = use_srgb ? GPU_SRGB8_A8 : GPU_RGBA8; + } +} + +/* Return false if no suitable format was found. */ +#ifdef WITH_DDS +static bool IMB_gpu_get_compressed_format(const ImBuf *ibuf, eGPUTextureFormat *r_texture_format) +{ + /* For DDS we only support data, scene linear and sRGB. Converting to + * different colorspace would break the compression. */ + const bool use_srgb = (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace) && + !IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace)); + + if (ibuf->dds_data.fourcc == FOURCC_DXT1) { + *r_texture_format = (use_srgb) ? GPU_SRGB8_A8_DXT1 : GPU_RGBA8_DXT1; + } + else if (ibuf->dds_data.fourcc == FOURCC_DXT3) { + *r_texture_format = (use_srgb) ? GPU_SRGB8_A8_DXT3 : GPU_RGBA8_DXT3; + } + else if (ibuf->dds_data.fourcc == FOURCC_DXT5) { + *r_texture_format = (use_srgb) ? GPU_SRGB8_A8_DXT5 : GPU_RGBA8_DXT5; + } + else { + return false; + } + return true; +} +#endif + +/** + * Apply colormanagement and scale buffer if needed. + * *r_freedata is set to true if the returned buffer need to be manually freed. + **/ +static void *imb_gpu_get_data(const ImBuf *ibuf, + const bool do_rescale, + const int rescale_size[2], + const bool compress_as_srgb, + const bool store_premultiplied, + bool *r_freedata) +{ + const bool is_float_rect = (ibuf->rect_float != NULL); + void *data_rect = (is_float_rect) ? (void *)ibuf->rect_float : (void *)ibuf->rect; + + if (is_float_rect) { + /* Float image is already in scene linear colorspace or non-color data by + * convention, no colorspace conversion needed. But we do require 4 channels + * currently. */ + if (ibuf->channels != 4 || !store_premultiplied) { + data_rect = MEM_mallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, __func__); + *r_freedata = true; + + if (data_rect == NULL) { + return NULL; + } + + IMB_colormanagement_imbuf_to_float_texture( + (float *)data_rect, 0, 0, ibuf->x, ibuf->y, ibuf, store_premultiplied); + } + } + else { + /* Byte image is in original colorspace from the file. If the file is sRGB + * scene linear, or non-color data no conversion is needed. Otherwise we + * compress as scene linear + sRGB transfer function to avoid precision loss + * in common cases. + * + * We must also convert to premultiplied for correct texture interpolation + * and consistency with float images. */ + if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) { + data_rect = MEM_mallocN(sizeof(uchar) * 4 * ibuf->x * ibuf->y, __func__); + *r_freedata = true; + + if (data_rect == NULL) { + return NULL; + } + + /* Texture storage of images is defined by the alpha mode of the image. The + * downside of this is that there can be artifacts near alpha edges. However, + * this allows us to use sRGB texture formats and preserves color values in + * zero alpha areas, and appears generally closer to what game engines that we + * want to be compatible with do. */ + IMB_colormanagement_imbuf_to_byte_texture( + (uchar *)data_rect, 0, 0, ibuf->x, ibuf->y, ibuf, compress_as_srgb, store_premultiplied); + } + } + + if (do_rescale) { + uint *rect = (is_float_rect) ? NULL : (uint *)data_rect; + float *rect_float = (is_float_rect) ? (float *)data_rect : NULL; + + ImBuf *scale_ibuf = IMB_allocFromBuffer(rect, rect_float, ibuf->x, ibuf->y, 4); + IMB_scaleImBuf(scale_ibuf, UNPACK2(rescale_size)); + + data_rect = (is_float_rect) ? (void *)scale_ibuf->rect_float : (void *)scale_ibuf->rect; + *r_freedata = true; + /* Steal the rescaled buffer to avoid double free. */ + scale_ibuf->rect_float = NULL; + scale_ibuf->rect = NULL; + IMB_freeImBuf(scale_ibuf); + } + return data_rect; +} + +/* The ibuf is only here to detect the storage type. The produced texture will have undefined + * content. It will need to be populated by using IMB_update_gpu_texture_sub(). */ +GPUTexture *IMB_touch_gpu_texture(ImBuf *ibuf, int w, int h, int layers, bool use_high_bitdepth) +{ + eGPUDataFormat data_format; + eGPUTextureFormat tex_format; + imb_gpu_get_format(ibuf, use_high_bitdepth, &data_format, &tex_format); + + GPUTexture *tex = GPU_texture_create_nD( + w, h, layers, 2, NULL, tex_format, data_format, 0, false, NULL); + + GPU_texture_anisotropic_filter(tex, true); + return tex; +} + +/* Will update a GPUTexture using the content of the ImBuf. Only one layer will be updated. + * Will resize the ibuf if needed. + * z is the layer to update. Unused if the texture is 2D. */ +void IMB_update_gpu_texture_sub(GPUTexture *tex, + ImBuf *ibuf, + int x, + int y, + int z, + int w, + int h, + bool use_high_bitdepth, + bool use_premult) +{ + const bool do_rescale = (ibuf->x != w || ibuf->y != h); + const int size[2] = {w, h}; + + eGPUDataFormat data_format; + eGPUTextureFormat tex_format; + imb_gpu_get_format(ibuf, use_high_bitdepth, &data_format, &tex_format); + + const bool compress_as_srgb = (tex_format == GPU_SRGB8_A8); + bool freebuf = false; + + void *data = imb_gpu_get_data(ibuf, do_rescale, size, compress_as_srgb, use_premult, &freebuf); + + /* Update Texture. */ + GPU_texture_update_sub(tex, data_format, data, x, y, z, w, h, 1); + + if (freebuf) { + MEM_freeN(data); + } +} + +GPUTexture *IMB_create_gpu_texture(ImBuf *ibuf, bool use_high_bitdepth, bool use_premult) +{ + GPUTexture *tex = NULL; + const int size[2] = {GPU_texture_size_with_limit(ibuf->x), GPU_texture_size_with_limit(ibuf->y)}; + bool do_rescale = (ibuf->x != size[0]) || (ibuf->y != size[1]); + +#ifdef WITH_DDS + if (ibuf->ftype == IMB_FTYPE_DDS) { + eGPUTextureFormat compressed_format; + if (!IMB_gpu_get_compressed_format(ibuf, &compressed_format)) { + fprintf(stderr, "Unable to find a suitable DXT compression,"); + } + else if (do_rescale) { + fprintf(stderr, "Unable to load DXT image resolution,"); + } + else if (!is_power_of_2_i(ibuf->x) || !is_power_of_2_i(ibuf->y)) { + fprintf(stderr, "Unable to load non-power-of-two DXT image resolution,"); + } + else { + tex = GPU_texture_create_compressed( + ibuf->x, ibuf->y, ibuf->dds_data.nummipmaps, compressed_format, ibuf->dds_data.data); + + if (tex != NULL) { + return tex; + } + + fprintf(stderr, "ST3C support not found,"); + } + /* Fallback to uncompressed texture. */ + fprintf(stderr, " falling back to uncompressed.\n"); + } +#endif + + eGPUDataFormat data_format; + eGPUTextureFormat tex_format; + imb_gpu_get_format(ibuf, use_high_bitdepth, &data_format, &tex_format); + + const bool compress_as_srgb = (tex_format == GPU_SRGB8_A8); + bool freebuf = false; + + void *data = imb_gpu_get_data(ibuf, do_rescale, size, compress_as_srgb, use_premult, &freebuf); + + /* Create Texture. */ + tex = GPU_texture_create_nD(UNPACK2(size), 0, 2, data, tex_format, data_format, 0, false, NULL); + + GPU_texture_anisotropic_filter(tex, true); + + if (freebuf) { + MEM_freeN(data); + } + + return tex; +} diff --git a/source/blender/io/alembic/ABC_alembic.h b/source/blender/io/alembic/ABC_alembic.h index ddf75aa3258..67f8aeb0a67 100644 --- a/source/blender/io/alembic/ABC_alembic.h +++ b/source/blender/io/alembic/ABC_alembic.h @@ -128,6 +128,16 @@ struct CacheReader *CacheReader_open_alembic_object(struct AbcArchiveHandle *han struct Object *object, const char *object_path); +bool ABC_has_vec3_array_property_named(struct CacheReader *reader, const char *name); + +/* r_vertex_velocities should point to a preallocated array of num_vertices floats */ +int ABC_read_velocity_cache(struct CacheReader *reader, + const char *velocity_name, + float time, + float fps, + int num_vertices, + float *r_vertex_velocities); + #ifdef __cplusplus } #endif diff --git a/source/blender/io/alembic/intern/abc_axis_conversion.cc b/source/blender/io/alembic/intern/abc_axis_conversion.cc index cebab1f2e41..396c8fdb28b 100644 --- a/source/blender/io/alembic/intern/abc_axis_conversion.cc +++ b/source/blender/io/alembic/intern/abc_axis_conversion.cc @@ -170,4 +170,4 @@ void create_transform_matrix(Object *obj, } // namespace alembic } // namespace io -} // namespace blender
\ No newline at end of file +} // namespace blender diff --git a/source/blender/io/alembic/intern/abc_axis_conversion.h b/source/blender/io/alembic/intern/abc_axis_conversion.h index 9a19e9116be..645d9fc783b 100644 --- a/source/blender/io/alembic/intern/abc_axis_conversion.h +++ b/source/blender/io/alembic/intern/abc_axis_conversion.h @@ -100,4 +100,4 @@ void create_transform_matrix(Object *obj, } // namespace alembic } // namespace io -} // namespace blender
\ No newline at end of file +} // namespace blender diff --git a/source/blender/io/alembic/intern/alembic_capi.cc b/source/blender/io/alembic/intern/alembic_capi.cc index 7cde2d4fe73..eba7f64db02 100644 --- a/source/blender/io/alembic/intern/alembic_capi.cc +++ b/source/blender/io/alembic/intern/alembic_capi.cc @@ -22,6 +22,7 @@ #include <Alembic/AbcMaterial/IMaterial.h> +#include "abc_axis_conversion.h" #include "abc_reader_archive.h" #include "abc_reader_camera.h" #include "abc_reader_curves.h" @@ -47,18 +48,13 @@ #include "BKE_lib_id.h" #include "BKE_object.h" #include "BKE_scene.h" +#include "BKE_screen.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" #include "ED_undo.h" -/* SpaceType struct has a member called 'new' which obviously conflicts with C++ - * so temporarily redefining the new keyword to make it compile. */ -#define new extern_new -#include "BKE_screen.h" -#undef new - #include "BLI_compiler_compat.h" #include "BLI_fileops.h" #include "BLI_ghash.h" @@ -70,7 +66,10 @@ #include "WM_api.h" #include "WM_types.h" +using Alembic::Abc::IV3fArrayProperty; using Alembic::Abc::ObjectHeader; +using Alembic::Abc::PropertyHeader; +using Alembic::Abc::V3fArraySamplePtr; using Alembic::AbcGeom::ICamera; using Alembic::AbcGeom::ICurves; using Alembic::AbcGeom::IFaceSet; @@ -79,9 +78,11 @@ using Alembic::AbcGeom::INuPatch; using Alembic::AbcGeom::IObject; using Alembic::AbcGeom::IPoints; using Alembic::AbcGeom::IPolyMesh; +using Alembic::AbcGeom::IPolyMeshSchema; using Alembic::AbcGeom::ISampleSelector; using Alembic::AbcGeom::ISubD; using Alembic::AbcGeom::IXform; +using Alembic::AbcGeom::kWrapExisting; using Alembic::AbcGeom::MetaData; using Alembic::AbcMaterial::IMaterial; @@ -859,3 +860,136 @@ CacheReader *CacheReader_open_alembic_object(AbcArchiveHandle *handle, return reinterpret_cast<CacheReader *>(abc_reader); } + +/* ************************************************************************** */ + +static const PropertyHeader *get_property_header(const IPolyMeshSchema &schema, const char *name) +{ + const PropertyHeader *prop_header = schema.getPropertyHeader(name); + + if (prop_header) { + return prop_header; + } + + ICompoundProperty prop = schema.getArbGeomParams(); + + if (!has_property(prop, name)) { + return nullptr; + } + + return prop.getPropertyHeader(name); +} + +bool ABC_has_vec3_array_property_named(struct CacheReader *reader, const char *name) +{ + AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader); + + if (!abc_reader) { + return false; + } + + IObject iobject = abc_reader->iobject(); + + if (!iobject.valid()) { + return false; + } + + const ObjectHeader &header = iobject.getHeader(); + + if (!IPolyMesh::matches(header)) { + return false; + } + + IPolyMesh mesh(iobject, kWrapExisting); + IPolyMeshSchema schema = mesh.getSchema(); + + const PropertyHeader *prop_header = get_property_header(schema, name); + + if (!prop_header) { + return false; + } + + return IV3fArrayProperty::matches(prop_header->getMetaData()); +} + +static V3fArraySamplePtr get_velocity_prop(const IPolyMeshSchema &schema, + const ISampleSelector &iss, + const std::string &name) +{ + const PropertyHeader *prop_header = schema.getPropertyHeader(name); + + if (prop_header) { + const IV3fArrayProperty &velocity_prop = IV3fArrayProperty(schema, name, 0); + return velocity_prop.getValue(iss); + } + + ICompoundProperty prop = schema.getArbGeomParams(); + + if (!has_property(prop, name)) { + return V3fArraySamplePtr(); + } + + const IV3fArrayProperty &velocity_prop = IV3fArrayProperty(prop, name, 0); + + if (velocity_prop) { + return velocity_prop.getValue(iss); + } + + return V3fArraySamplePtr(); +} + +int ABC_read_velocity_cache(CacheReader *reader, + const char *velocity_name, + const float time, + float velocity_scale, + int num_vertices, + float *r_vertex_velocities) +{ + AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader); + + if (!abc_reader) { + return -1; + } + + IObject iobject = abc_reader->iobject(); + + if (!iobject.valid()) { + return -1; + } + + const ObjectHeader &header = iobject.getHeader(); + + if (!IPolyMesh::matches(header)) { + return -1; + } + + IPolyMesh mesh(iobject, kWrapExisting); + IPolyMeshSchema schema = mesh.getSchema(); + ISampleSelector sample_sel(time); + const IPolyMeshSchema::Sample sample = schema.getValue(sample_sel); + + V3fArraySamplePtr velocities = get_velocity_prop(schema, sample_sel, velocity_name); + + if (!velocities) { + return -1; + } + + float vel[3]; + + int num_velocity_vectors = static_cast<int>(velocities->size()); + + if (num_velocity_vectors != num_vertices) { + return -1; + } + + for (size_t i = 0; i < velocities->size(); ++i) { + const Imath::V3f &vel_in = (*velocities)[i]; + copy_zup_from_yup(vel, vel_in.getValue()); + + mul_v3_fl(vel, velocity_scale); + + copy_v3_v3(r_vertex_velocities + i * 3, vel); + } + + return num_vertices; +} diff --git a/source/blender/io/avi/intern/avi.c b/source/blender/io/avi/intern/avi.c index e829a15deba..0ab51b7a084 100644 --- a/source/blender/io/avi/intern/avi.c +++ b/source/blender/io/avi/intern/avi.c @@ -116,9 +116,8 @@ int AVI_get_stream(AviMovie *movie, int avist_type, int stream_num) if (stream_num == 0) { return cur_stream; } - else { - stream_num--; - } + + stream_num--; } } @@ -572,9 +571,8 @@ AviError AVI_open_movie(const char *name, AviMovie *movie) if (GET_FCC(movie->fp) == FCC("movi")) { break; } - else { - BLI_fseek(movie->fp, size - 4, SEEK_CUR); - } + + BLI_fseek(movie->fp, size - 4, SEEK_CUR); } else { BLI_fseek(movie->fp, size, SEEK_CUR); diff --git a/source/blender/io/avi/intern/avi_rgb.c b/source/blender/io/avi/intern/avi_rgb.c index 44542af96ae..8af728f0737 100644 --- a/source/blender/io/avi/intern/avi_rgb.c +++ b/source/blender/io/avi/intern/avi_rgb.c @@ -96,35 +96,34 @@ void *avi_converter_from_avi_rgb(AviMovie *movie, return buf; } - else { - buf = imb_alloc_pixels( - movie->header->Height, movie->header->Width, 3, sizeof(unsigned char), "fromavirgbbuf"); - - if (buf) { - size_t rowstride = movie->header->Width * 3; - BLI_assert(bits != 16); - if (movie->header->Width % 2) { - rowstride++; - } - for (size_t y = 0; y < movie->header->Height; y++) { - memcpy(&buf[y * movie->header->Width * 3], - &buffer[((movie->header->Height - 1) - y) * rowstride], - movie->header->Width * 3); - } + buf = imb_alloc_pixels( + movie->header->Height, movie->header->Width, 3, sizeof(unsigned char), "fromavirgbbuf"); - for (size_t y = 0; y < (size_t)movie->header->Height * (size_t)movie->header->Width * 3; - y += 3) { - int i = buf[y]; - buf[y] = buf[y + 2]; - buf[y + 2] = i; - } + if (buf) { + size_t rowstride = movie->header->Width * 3; + BLI_assert(bits != 16); + if (movie->header->Width % 2) { + rowstride++; } - MEM_freeN(buffer); + for (size_t y = 0; y < movie->header->Height; y++) { + memcpy(&buf[y * movie->header->Width * 3], + &buffer[((movie->header->Height - 1) - y) * rowstride], + movie->header->Width * 3); + } - return buf; + for (size_t y = 0; y < (size_t)movie->header->Height * (size_t)movie->header->Width * 3; + y += 3) { + int i = buf[y]; + buf[y] = buf[y + 2]; + buf[y + 2] = i; + } } + + MEM_freeN(buffer); + + return buf; } void *avi_converter_to_avi_rgb(AviMovie *movie, int stream, unsigned char *buffer, size_t *size) diff --git a/source/blender/io/collada/AnimationExporter.cpp b/source/blender/io/collada/AnimationExporter.cpp index c25b4ea543b..a4302a680a3 100644 --- a/source/blender/io/collada/AnimationExporter.cpp +++ b/source/blender/io/collada/AnimationExporter.cpp @@ -230,7 +230,7 @@ void AnimationExporter::export_matrix_animation(Object *ob, BCAnimationSampler & std::string name = encode_xml(id_name(ob)); std::string action_name = (action == NULL) ? name + "-action" : id_name(action); std::string channel_type = "transform"; - std::string axis = ""; + std::string axis; std::string id = bc_get_action_id(action_name, name, channel_type, axis); std::string target = translate_id(name) + '/' + channel_type; @@ -395,15 +395,15 @@ bool AnimationExporter::is_bone_deform_group(Bone *bone) return true; } /* Check child bones */ - else { - for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { - /* loop through all the children until deform bone is found, and then return */ - is_def = is_bone_deform_group(child); - if (is_def) { - return true; - } + + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { + /* loop through all the children until deform bone is found, and then return */ + is_def = is_bone_deform_group(child); + if (is_def) { + return true; } } + /* no deform bone found in children also */ return false; } @@ -840,12 +840,11 @@ std::string AnimationExporter::get_collada_sid(const BCAnimationCurve &curve, if (is_angle) { return tm_name + std::string(axis_name) + ".ANGLE"; } - else if (!axis_name.empty()) { + if (!axis_name.empty()) { return tm_name + "." + std::string(axis_name); } - else { - return tm_name; - } + + return tm_name; } return tm_name; diff --git a/source/blender/io/collada/AnimationImporter.cpp b/source/blender/io/collada/AnimationImporter.cpp index b53aa95a11f..1dada68293e 100644 --- a/source/blender/io/collada/AnimationImporter.cpp +++ b/source/blender/io/collada/AnimationImporter.cpp @@ -717,37 +717,36 @@ void AnimationImporter::Assign_float_animations(const COLLADAFW::UniqueId &listi if (animlist_map.find(listid) == animlist_map.end()) { return; } - else { - /* anim_type has animations */ - const COLLADAFW::AnimationList *animlist = animlist_map[listid]; - const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings(); - /* all the curves belonging to the current binding */ - std::vector<FCurve *> animcurves; - for (unsigned int j = 0; j < bindings.getCount(); j++) { - animcurves = curve_map[bindings[j].animation]; - - BLI_strncpy(rna_path, anim_type, sizeof(rna_path)); - modify_fcurve(&animcurves, rna_path, 0); - std::vector<FCurve *>::iterator iter; - /* Add the curves of the current animation to the object */ - for (iter = animcurves.begin(); iter != animcurves.end(); iter++) { - FCurve *fcu = *iter; - /* All anim_types whose values are to be converted from Degree to Radians can be ORed here + + /* anim_type has animations */ + const COLLADAFW::AnimationList *animlist = animlist_map[listid]; + const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings(); + /* all the curves belonging to the current binding */ + std::vector<FCurve *> animcurves; + for (unsigned int j = 0; j < bindings.getCount(); j++) { + animcurves = curve_map[bindings[j].animation]; + + BLI_strncpy(rna_path, anim_type, sizeof(rna_path)); + modify_fcurve(&animcurves, rna_path, 0); + std::vector<FCurve *>::iterator iter; + /* Add the curves of the current animation to the object */ + for (iter = animcurves.begin(); iter != animcurves.end(); iter++) { + FCurve *fcu = *iter; + /* All anim_types whose values are to be converted from Degree to Radians can be ORed here + */ + if (STREQ("spot_size", anim_type)) { + /* NOTE: Do NOT convert if imported file was made by blender <= 2.69.10 + * Reason: old blender versions stored spot_size in radians (was a bug) */ - if (STREQ("spot_size", anim_type)) { - /* NOTE: Do NOT convert if imported file was made by blender <= 2.69.10 - * Reason: old blender versions stored spot_size in radians (was a bug) - */ - if (this->import_from_version.empty() || - BLI_strcasecmp_natural(this->import_from_version.c_str(), "2.69.10") != -1) { - fcurve_deg_to_rad(fcu); - } + if (this->import_from_version.empty() || + BLI_strcasecmp_natural(this->import_from_version.c_str(), "2.69.10") != -1) { + fcurve_deg_to_rad(fcu); } - /** XXX What About animtype "rotation" ? */ - - BLI_addtail(AnimCurves, fcu); - fcurve_is_used(fcu); } + /** XXX What About animtype "rotation" ? */ + + BLI_addtail(AnimCurves, fcu); + fcurve_is_used(fcu); } } } @@ -780,35 +779,34 @@ void AnimationImporter::Assign_lens_animations(const COLLADAFW::UniqueId &listid if (animlist_map.find(listid) == animlist_map.end()) { return; } - else { - /* anim_type has animations */ - const COLLADAFW::AnimationList *animlist = animlist_map[listid]; - const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings(); - /* all the curves belonging to the current binding */ - std::vector<FCurve *> animcurves; - for (unsigned int j = 0; j < bindings.getCount(); j++) { - animcurves = curve_map[bindings[j].animation]; - BLI_strncpy(rna_path, anim_type, sizeof(rna_path)); + /* anim_type has animations */ + const COLLADAFW::AnimationList *animlist = animlist_map[listid]; + const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings(); + /* all the curves belonging to the current binding */ + std::vector<FCurve *> animcurves; + for (unsigned int j = 0; j < bindings.getCount(); j++) { + animcurves = curve_map[bindings[j].animation]; - modify_fcurve(&animcurves, rna_path, 0); - std::vector<FCurve *>::iterator iter; - /* Add the curves of the current animation to the object */ - for (iter = animcurves.begin(); iter != animcurves.end(); iter++) { - FCurve *fcu = *iter; + BLI_strncpy(rna_path, anim_type, sizeof(rna_path)); - for (unsigned int i = 0; i < fcu->totvert; i++) { - fcu->bezt[i].vec[0][1] = convert_to_focal_length( - fcu->bezt[i].vec[0][1], fov_type, aspect, cam->sensor_x); - fcu->bezt[i].vec[1][1] = convert_to_focal_length( - fcu->bezt[i].vec[1][1], fov_type, aspect, cam->sensor_x); - fcu->bezt[i].vec[2][1] = convert_to_focal_length( - fcu->bezt[i].vec[2][1], fov_type, aspect, cam->sensor_x); - } + modify_fcurve(&animcurves, rna_path, 0); + std::vector<FCurve *>::iterator iter; + /* Add the curves of the current animation to the object */ + for (iter = animcurves.begin(); iter != animcurves.end(); iter++) { + FCurve *fcu = *iter; - BLI_addtail(AnimCurves, fcu); - fcurve_is_used(fcu); + for (unsigned int i = 0; i < fcu->totvert; i++) { + fcu->bezt[i].vec[0][1] = convert_to_focal_length( + fcu->bezt[i].vec[0][1], fov_type, aspect, cam->sensor_x); + fcu->bezt[i].vec[1][1] = convert_to_focal_length( + fcu->bezt[i].vec[1][1], fov_type, aspect, cam->sensor_x); + fcu->bezt[i].vec[2][1] = convert_to_focal_length( + fcu->bezt[i].vec[2][1], fov_type, aspect, cam->sensor_x); } + + BLI_addtail(AnimCurves, fcu); + fcurve_is_used(fcu); } } } @@ -1077,35 +1075,34 @@ void AnimationImporter::translate_Animations( if (animlist_map.find(listid) == animlist_map.end()) { continue; } - else { - /* transformation has animations */ - const COLLADAFW::AnimationList *animlist = animlist_map[listid]; - const COLLADAFW::AnimationList::AnimationBindings &bindings = - animlist->getAnimationBindings(); - /* all the curves belonging to the current binding */ - std::vector<FCurve *> animcurves; - for (unsigned int j = 0; j < bindings.getCount(); j++) { - animcurves = curve_map[bindings[j].animation]; - if (is_matrix) { - apply_matrix_curves(ob, animcurves, root, node, transform); - } - else { - /* calculate rnapaths and array index of fcurves according to transformation and - * animation class */ - Assign_transform_animations( - transform, &bindings[j], &animcurves, is_joint, joint_path); - - std::vector<FCurve *>::iterator iter; - /* Add the curves of the current animation to the object */ - for (iter = animcurves.begin(); iter != animcurves.end(); iter++) { - FCurve *fcu = *iter; - - BLI_addtail(AnimCurves, fcu); - fcurve_is_used(fcu); - } + + /* transformation has animations */ + const COLLADAFW::AnimationList *animlist = animlist_map[listid]; + const COLLADAFW::AnimationList::AnimationBindings &bindings = + animlist->getAnimationBindings(); + /* all the curves belonging to the current binding */ + std::vector<FCurve *> animcurves; + for (unsigned int j = 0; j < bindings.getCount(); j++) { + animcurves = curve_map[bindings[j].animation]; + if (is_matrix) { + apply_matrix_curves(ob, animcurves, root, node, transform); + } + else { + /* calculate rnapaths and array index of fcurves according to transformation and + * animation class */ + Assign_transform_animations(transform, &bindings[j], &animcurves, is_joint, joint_path); + + std::vector<FCurve *>::iterator iter; + /* Add the curves of the current animation to the object */ + for (iter = animcurves.begin(); iter != animcurves.end(); iter++) { + FCurve *fcu = *iter; + + BLI_addtail(AnimCurves, fcu); + fcurve_is_used(fcu); } } } + if (is_rotation && !(is_joint || is_matrix)) { ob->rotmode = ROT_MODE_EUL; } @@ -1423,10 +1420,9 @@ AnimationImporter::AnimMix *AnimationImporter::get_animation_type( if (animlist_map.find(listid) == animlist_map.end()) { continue; } - else { - types->transform = types->transform | BC_NODE_TRANSFORM; - break; - } + + types->transform = types->transform | BC_NODE_TRANSFORM; + break; } const COLLADAFW::InstanceLightPointerArray &nodeLights = node->getInstanceLights(); @@ -1995,7 +1991,7 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm, return true; } - else if (is_scale || is_translate) { + if (is_scale || is_translate) { bool is_xyz = animclass == COLLADAFW::AnimationList::POSITION_XYZ; if ((!is_xyz && curves.size() != 1) || (is_xyz && curves.size() != 3)) { diff --git a/source/blender/io/collada/BCAnimationCurve.cpp b/source/blender/io/collada/BCAnimationCurve.cpp index 61dded368b5..5fdbb65fb6e 100644 --- a/source/blender/io/collada/BCAnimationCurve.cpp +++ b/source/blender/io/collada/BCAnimationCurve.cpp @@ -559,9 +559,8 @@ inline bool operator<(const BCAnimationCurve &lhs, const BCAnimationCurve &rhs) const int rha = rhs.get_channel_index(); return lha < rha; } - else { - return lhtgt < rhtgt; - } + + return lhtgt < rhtgt; } BCCurveKey::BCCurveKey() diff --git a/source/blender/io/collada/DocumentImporter.cpp b/source/blender/io/collada/DocumentImporter.cpp index 0f84db79c28..83c8a805076 100644 --- a/source/blender/io/collada/DocumentImporter.cpp +++ b/source/blender/io/collada/DocumentImporter.cpp @@ -1254,9 +1254,6 @@ bool DocumentImporter::is_armature(COLLADAFW::Node *node) if (child_nodes[i]->getType() == COLLADAFW::Node::JOINT) { return true; } - else { - continue; - } } /* no child is JOINT */ diff --git a/source/blender/io/collada/collada_internal.cpp b/source/blender/io/collada/collada_internal.cpp index f123e8ea31f..b3fa9ba1251 100644 --- a/source/blender/io/collada/collada_internal.cpp +++ b/source/blender/io/collada/collada_internal.cpp @@ -277,7 +277,7 @@ std::string encode_xml(std::string xml) {'<', "<"}, {'>', ">"}, {'"', """}, {'\'', "'"}, {'&', "&"}}; std::map<char, std::string>::const_iterator it; - std::string encoded_xml = ""; + std::string encoded_xml; for (unsigned int i = 0; i < xml.size(); i++) { char c = xml.at(i); diff --git a/source/blender/io/collada/collada_utils.cpp b/source/blender/io/collada/collada_utils.cpp index 2c54a49198a..2493b3a386b 100644 --- a/source/blender/io/collada/collada_utils.cpp +++ b/source/blender/io/collada/collada_utils.cpp @@ -88,9 +88,8 @@ float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray &array, unsigned in if (array.getType() == COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT) { return array.getFloatValues()->getData()[index]; } - else { - return array.getDoubleValues()->getData()[index]; - } + + return array.getDoubleValues()->getData()[index]; } /* copied from /editors/object/object_relations.c */ @@ -330,9 +329,8 @@ bool bc_is_root_bone(Bone *aBone, bool deform_bones_only) } return (aBone == root); } - else { - return !(aBone->parent); - } + + return !(aBone->parent); } int bc_get_active_UVLayer(Object *ob) @@ -672,8 +670,7 @@ void BoneExtended::set_bone_layers(std::string layerString, std::vector<std::str std::string BoneExtended::get_bone_layers(int bitfield) { - std::string result = ""; - std::string sep = ""; + std::string sep; int bit = 1u; std::ostringstream ss; @@ -1323,9 +1320,8 @@ COLLADASW::ColorOrTexture bc_get_base_color(Material *ma) if (ma->use_nodes && shader) { return bc_get_cot_from_shader(shader, "Base Color", default_color, false); } - else { - return bc_get_cot(default_color); - } + + return bc_get_cot(default_color); } COLLADASW::ColorOrTexture bc_get_emission(Material *ma) @@ -1335,9 +1331,8 @@ COLLADASW::ColorOrTexture bc_get_emission(Material *ma) if (ma->use_nodes && shader) { return bc_get_cot_from_shader(shader, "Emission", default_color); } - else { - return bc_get_cot(default_color); /* default black */ - } + + return bc_get_cot(default_color); /* default black */ } COLLADASW::ColorOrTexture bc_get_ambient(Material *ma) @@ -1420,9 +1415,8 @@ COLLADASW::ColorOrTexture bc_get_cot_from_shader(bNode *shader, float *col = dcol->value; return bc_get_cot(col, with_alpha); } - else { - return bc_get_cot(default_color, with_alpha); - } + + return bc_get_cot(default_color, with_alpha); } bNode *bc_get_master_shader(Material *ma) diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index 10a7dbcd811..c79ae68678f 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -66,7 +66,9 @@ typedef struct BrushGpencilSettings { short draw_smoothlvl; /** Number of times to subdivide new strokes. */ short draw_subdivide; - char _pad[4]; + /** Layers used for fill. */ + short fill_layer_mode; + char _pad[2]; /** Factor for transparency. */ float fill_threshold; @@ -117,7 +119,8 @@ typedef struct BrushGpencilSettings { int sculpt_mode_flag; /** Preset type (used to reset brushes - internal). */ short preset_type; - char _pad3[2]; + /** Brush preselected mode (Active/Material/Vertexcolor). */ + short brush_draw_mode; /** Randomness for Hue. */ float random_hue; @@ -250,6 +253,16 @@ typedef enum eGP_FillDrawModes { GP_FILL_DMODE_CONTROL = 2, } eGP_FillDrawModes; +/* BrushGpencilSettings->fill_layer_mode */ +typedef enum eGP_FillLayerModes { + GP_FILL_GPLMODE_VISIBLE = 0, + GP_FILL_GPLMODE_ACTIVE = 1, + GP_FILL_GPLMODE_ALL_ABOVE = 2, + GP_FILL_GPLMODE_ALL_BELOW = 3, + GP_FILL_GPLMODE_ABOVE = 4, + GP_FILL_GPLMODE_BELOW = 5, +} eGP_FillLayerModes; + /* BrushGpencilSettings->gp_eraser_mode */ typedef enum eGP_BrushEraserMode { GP_BRUSH_ERASER_SOFT = 0, @@ -257,6 +270,13 @@ typedef enum eGP_BrushEraserMode { GP_BRUSH_ERASER_STROKE = 2, } eGP_BrushEraserMode; +/* BrushGpencilSettings->brush_draw_mode */ +typedef enum eGP_BrushMode { + GP_BRUSH_MODE_ACTIVE = 0, + GP_BRUSH_MODE_MATERIAL = 1, + GP_BRUSH_MODE_VERTEXCOLOR = 2, +} eGP_BrushMode; + /* BrushGpencilSettings default brush icons */ typedef enum eGP_BrushIcons { GP_BRUSH_ICON_PENCIL = 1, @@ -330,6 +350,11 @@ typedef enum eBrushClothForceFalloffType { BRUSH_CLOTH_FORCE_FALLOFF_PLANE = 1, } eBrushClothForceFalloffType; +typedef enum eBrushClothSimulationAreaType { + BRUSH_CLOTH_SIMULATION_AREA_LOCAL = 0, + BRUSH_CLOTH_SIMULATION_AREA_GLOBAL = 1, +} eBrushClothSimulationAreaType; + typedef enum eBrushPoseDeformType { BRUSH_POSE_DEFORM_ROTATE_TWIST = 0, BRUSH_POSE_DEFORM_SCALE_TRASLATE = 1, @@ -499,7 +524,7 @@ typedef struct Brush { /** Source for fill tool color gradient application. */ char gradient_fill_mode; - char _pad0[1]; + char _pad0[5]; /** Projection shape (sphere, circle). */ char falloff_shape; @@ -525,7 +550,7 @@ typedef struct Brush { char gpencil_sculpt_tool; /** Active grease pencil weight tool. */ char gpencil_weight_tool; - char _pad1[6]; + char _pad1[2]; float autosmooth_factor; @@ -564,6 +589,7 @@ typedef struct Brush { /* cloth */ int cloth_deform_type; int cloth_force_falloff_type; + int cloth_simulation_area_type; float cloth_mass; float cloth_damping; @@ -571,6 +597,8 @@ typedef struct Brush { float cloth_sim_limit; float cloth_sim_falloff; + float cloth_constraint_softbody_strength; + /* smooth */ int smooth_deform_type; float surface_smooth_shape_preservation; @@ -715,6 +743,9 @@ typedef enum eBrushFlags2 { BRUSH_MULTIPLANE_SCRAPE_PLANES_PREVIEW = (1 << 1), BRUSH_POSE_IK_ANCHORED = (1 << 2), BRUSH_USE_CONNECTED_ONLY = (1 << 3), + BRUSH_CLOTH_PIN_SIMULATION_BOUNDARY = (1 << 4), + BRUSH_POSE_USE_LOCK_ROTATION = (1 << 5), + BRUSH_CLOTH_USE_COLLISION = (1 << 6), } eBrushFlags2; typedef enum { diff --git a/source/blender/makesdna/DNA_cachefile_types.h b/source/blender/makesdna/DNA_cachefile_types.h index 581248ed52b..04c99c6c4b1 100644 --- a/source/blender/makesdna/DNA_cachefile_types.h +++ b/source/blender/makesdna/DNA_cachefile_types.h @@ -52,6 +52,13 @@ typedef struct AlembicObjectPath { char path[4096]; } AlembicObjectPath; +/* CacheFile::velocity_unit + * Determines what temporal unit is used to interpret velocity vectors for motion blur effects. */ +enum { + CACHEFILE_VELOCITY_UNIT_FRAME, + CACHEFILE_VELOCITY_UNIT_SECOND, +}; + typedef struct CacheFile { ID id; struct AnimData *adt; @@ -77,7 +84,11 @@ typedef struct CacheFile { short flag; short draw_flag; /* UNUSED */ - char _pad[4]; + char _pad[3]; + + char velocity_unit; + /* Name of the velocity property in the Alembic file. */ + char velocity_name[64]; /* Runtime */ struct AbcArchiveHandle *handle; diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index c442e160bad..2ae9ba13177 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -273,9 +273,12 @@ typedef struct Curve { int selstart, selend; /* text data */ - /** Number of characters (strinfo). */ - int len_wchar; - /** Number of bytes (str - utf8). */ + /** + * Number of characters (unicode code-points) + * This is the length of #Curve.strinfo and the result of `BLI_strlen_utf8(cu->str)`. + */ + int len_char32; + /** Number of bytes: `strlen(Curve.str)`. */ int len; char *str; struct EditFont *editfont; diff --git a/source/blender/makesdna/DNA_curveprofile_types.h b/source/blender/makesdna/DNA_curveprofile_types.h index b45eb832232..5b425741df2 100644 --- a/source/blender/makesdna/DNA_curveprofile_types.h +++ b/source/blender/makesdna/DNA_curveprofile_types.h @@ -30,7 +30,7 @@ /** Number of table points per control point. */ #define PROF_RESOL 16 /** Dynamic size of widget's high resolution table. Input should be profile->totpoint. */ -#define PROF_N_TABLE(n_pts) min_ii(PROF_TABLE_MAX, (((n_pts - 1)) * PROF_RESOL) + 1) +#define PROF_TABLE_LEN(n_pts) min_ii(PROF_TABLE_MAX, (((n_pts - 1)) * PROF_RESOL) + 1) /** * Each control point that makes up the profile. diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h index 17f3fe24fbc..749bc55fcb9 100644 --- a/source/blender/makesdna/DNA_image_types.h +++ b/source/blender/makesdna/DNA_image_types.h @@ -116,13 +116,13 @@ typedef struct ImageTile { #define IMA_NEED_FRAME_RECALC (1 << 3) #define IMA_SHOW_STEREO (1 << 4) -enum { - TEXTARGET_TEXTURE_2D = 0, - TEXTARGET_TEXTURE_CUBE_MAP = 1, - TEXTARGET_TEXTURE_2D_ARRAY = 2, - TEXTARGET_TEXTURE_TILE_MAPPING = 3, - TEXTARGET_COUNT = 4, -}; +/* Used to get the correct gpu texture from an Image datablock. */ +typedef enum eGPUTextureTarget { + TEXTARGET_2D = 0, + TEXTARGET_2D_ARRAY, + TEXTARGET_TILE_MAPPING, + TEXTARGET_COUNT, +} eGPUTextureTarget; typedef struct Image { ID id; @@ -132,8 +132,8 @@ typedef struct Image { /** Not written in file. */ struct MovieCache *cache; - /** Not written in file 4 = TEXTARGET_COUNT, 2 = stereo eyes. */ - struct GPUTexture *gputexture[4][2]; + /** Not written in file 3 = TEXTARGET_COUNT, 2 = stereo eyes. */ + struct GPUTexture *gputexture[3][2]; /* sources from: */ ListBase anims; diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 93434e64df1..b01b3f42e6a 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -1276,7 +1276,11 @@ typedef struct OceanModifierData { struct Ocean *ocean; struct OceanCache *oceancache; + /** Render resolution. */ int resolution; + /** Viewport resolution for the non-render case. */ + int viewport_resolution; + int spatial_size; float wind_velocity; @@ -1293,8 +1297,6 @@ typedef struct OceanModifierData { float foam_coverage; float time; - char _pad1[4]; - /* Spectrum being used. */ int spectrum; @@ -2051,6 +2053,10 @@ enum { MOD_NORMALEDIT_MIX_MUL = 3, }; +typedef struct MeshCacheVertexVelocity { + float vel[3]; +} MeshCacheVertexVelocity; + typedef struct MeshSeqCacheModifierData { ModifierData modifier; @@ -2059,11 +2065,31 @@ typedef struct MeshSeqCacheModifierData { char object_path[1024]; char read_flag; - char _pad[7]; + char _pad[3]; + + float velocity_scale; /* Runtime. */ struct CacheReader *reader; char reader_object_path[1024]; + + /* Vertex velocities read from the cache. The velocities are not automatically read during + * modifier execution, and therefore have to manually be read when needed. This is only used + * through the RNA for now. */ + struct MeshCacheVertexVelocity *vertex_velocities; + + /* The number of vertices of the Alembic mesh, set when the modifier is executed. */ + int num_vertices; + + /* Time (in frames or seconds) between two velocity samples. Automatically computed to + * scale the velocity vectors at render time for generating proper motion blur data. */ + float velocity_delta; + + /* Caches the scene time (in seconds) used to lookup data in the Alembic archive when the + * modifier was last executed. Used to access Alembic samples through the RNA. */ + float last_lookup_time; + + int _pad1; } MeshSeqCacheModifierData; /* MeshSeqCacheModifierData.read_flag */ diff --git a/source/blender/makesdna/DNA_movieclip_types.h b/source/blender/makesdna/DNA_movieclip_types.h index 123ff5bfb7e..2b1fd546450 100644 --- a/source/blender/makesdna/DNA_movieclip_types.h +++ b/source/blender/makesdna/DNA_movieclip_types.h @@ -63,8 +63,8 @@ typedef struct MovieClipProxy { typedef struct MovieClip_RuntimeGPUTexture { void *next, *prev; MovieClipUser user; - /** Not written in file 4 = TEXTARGET_COUNT. */ - struct GPUTexture *gputexture[4]; + /** Not written in file 3 = TEXTARGET_COUNT. */ + struct GPUTexture *gputexture[3]; } MovieClip_RuntimeGPUTexture; typedef struct MovieClip_Runtime { diff --git a/source/blender/makesdna/DNA_rigidbody_types.h b/source/blender/makesdna/DNA_rigidbody_types.h index 3a4925217ff..02a4a158d8c 100644 --- a/source/blender/makesdna/DNA_rigidbody_types.h +++ b/source/blender/makesdna/DNA_rigidbody_types.h @@ -213,7 +213,7 @@ typedef enum eRigidBody_Shape { RB_SHAPE_TRIMESH = 6, /* concave mesh approximated using primitives */ - // RB_SHAPE_COMPOUND, + RB_SHAPE_COMPOUND = 7, } eRigidBody_Shape; typedef enum eRigidBody_MeshSource { diff --git a/source/blender/makesdna/DNA_simulation_types.h b/source/blender/makesdna/DNA_simulation_types.h index de4c9522334..8cc2db99332 100644 --- a/source/blender/makesdna/DNA_simulation_types.h +++ b/source/blender/makesdna/DNA_simulation_types.h @@ -29,16 +29,21 @@ typedef struct Simulation { struct bNodeTree *nodetree; - int flag; + uint32_t flag; + + /** This is the frame in scene time, that the states correspond to. */ float current_frame; + + /** Time since the start of the simulation in simulation time (which might differ from scene + * time). */ float current_simulation_time; char _pad[4]; /** List containing SimulationState objects. */ struct ListBase states; - /** List containing PersistentDataHandleItem objects. */ - struct ListBase persistent_data_handles; + /** List containing SimulationDependency objects. */ + struct ListBase dependencies; } Simulation; typedef struct SimulationState { @@ -53,8 +58,8 @@ typedef struct ParticleSimulationState { SimulationState head; /** Contains the state of the particles at time Simulation->current_frame. */ - int tot_particles; - int next_particle_id; + int32_t tot_particles; + int32_t next_particle_id; struct CustomData attributes; } ParticleSimulationState; @@ -65,19 +70,26 @@ typedef struct ParticleMeshEmitterSimulationState { char _pad[4]; } ParticleMeshEmitterSimulationState; -/** Stores a mapping between an integer handle and a corresponding ID data block. */ -typedef struct PersistentDataHandleItem { - struct PersistentDataHandleItem *next; - struct PersistentDataHandleItem *prev; +/** Stores a reference to data that the simulation depends on. This is partially derived from the + * simulation node tree. */ +typedef struct SimulationDependency { + struct SimulationDependency *next; + struct SimulationDependency *prev; struct ID *id; - int handle; - char _pad[4]; -} PersistentDataHandleItem; + int32_t handle; + uint32_t flag; +} SimulationDependency; /* Simulation.flag */ enum { SIM_DS_EXPAND = (1 << 0), }; +/* SimulationDependency.flag */ +enum { + SIM_DEPENDS_ON_TRANSFORM = (1 << 0), + SIM_DEPENDS_ON_GEOMETRY = (1 << 1), +}; + #define SIM_TYPE_NAME_PARTICLE_SIMULATION "Particle Simulation" #define SIM_TYPE_NAME_PARTICLE_MESH_EMITTER "Particle Mesh Emitter" diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index a632d42fd8b..c2ed6c97d3d 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -732,7 +732,7 @@ typedef struct UserDef { char _pad1[2]; int undomemory; float gpu_viewport_quality DNA_DEPRECATED; - short gp_manhattendist, gp_euclideandist, gp_eraser; + short gp_manhattandist, gp_euclideandist, gp_eraser; /** #eGP_UserdefSettings. */ short gp_settings; char _pad13[4]; diff --git a/source/blender/makesdna/DNA_view2d_types.h b/source/blender/makesdna/DNA_view2d_types.h index d7a6386d12f..63038b6be2d 100644 --- a/source/blender/makesdna/DNA_view2d_types.h +++ b/source/blender/makesdna/DNA_view2d_types.h @@ -136,7 +136,7 @@ enum { /* apply pixel offsets on y-axis when setting view matrices */ V2D_PIXELOFS_Y = (1 << 3), /* view settings need to be set still... */ - V2D_IS_INITIALISED = (1 << 10), + V2D_IS_INIT = (1 << 10), }; /* scroller flags for View2D (v2d->scroll) */ diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 4a6d642bcb6..dd11fed021d 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -197,8 +197,8 @@ typedef struct wmWindowManager { /* wmWindowManager.initialized */ enum { - WM_WINDOW_IS_INITIALIZED = (1 << 0), - WM_KEYCONFIG_IS_INITIALIZED = (1 << 1), + WM_WINDOW_IS_INIT = (1 << 0), + WM_KEYCONFIG_IS_INIT = (1 << 1), }; /* wmWindowManager.outliner_sync_select_dirty */ diff --git a/source/blender/makesdna/intern/dna_genfile.c b/source/blender/makesdna/intern/dna_genfile.c index 3d95eba4aed..53ed010952e 100644 --- a/source/blender/makesdna/intern/dna_genfile.c +++ b/source/blender/makesdna/intern/dna_genfile.c @@ -356,141 +356,140 @@ static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error *r_error_message = "SDNA error in SDNA file"; return false; } - else { - const char *cp; - data++; - /* Names array ('NAME') */ - if (*data == MAKE_ID('N', 'A', 'M', 'E')) { - data++; + const char *cp; - sdna->names_len = *data; - if (do_endian_swap) { - BLI_endian_switch_int32(&sdna->names_len); - } - sdna->names_len_alloc = sdna->names_len; + data++; + /* Names array ('NAME') */ + if (*data == MAKE_ID('N', 'A', 'M', 'E')) { + data++; - data++; - sdna->names = MEM_callocN(sizeof(void *) * sdna->names_len, "sdnanames"); - } - else { - *r_error_message = "NAME error in SDNA file"; - return false; + sdna->names_len = *data; + if (do_endian_swap) { + BLI_endian_switch_int32(&sdna->names_len); } + sdna->names_len_alloc = sdna->names_len; - cp = (char *)data; - for (int nr = 0; nr < sdna->names_len; nr++) { - sdna->names[nr] = cp; - - /* "float gravity [3]" was parsed wrong giving both "gravity" and - * "[3]" members. we rename "[3]", and later set the type of - * "gravity" to "void" so the offsets work out correct */ - if (*cp == '[' && strcmp(cp, "[3]") == 0) { - if (nr && strcmp(sdna->names[nr - 1], "Cvi") == 0) { - sdna->names[nr] = "gravity[3]"; - gravity_fix = nr; - } - } - while (*cp) { - cp++; + data++; + sdna->names = MEM_callocN(sizeof(void *) * sdna->names_len, "sdnanames"); + } + else { + *r_error_message = "NAME error in SDNA file"; + return false; + } + + cp = (char *)data; + for (int nr = 0; nr < sdna->names_len; nr++) { + sdna->names[nr] = cp; + + /* "float gravity [3]" was parsed wrong giving both "gravity" and + * "[3]" members. we rename "[3]", and later set the type of + * "gravity" to "void" so the offsets work out correct */ + if (*cp == '[' && strcmp(cp, "[3]") == 0) { + if (nr && strcmp(sdna->names[nr - 1], "Cvi") == 0) { + sdna->names[nr] = "gravity[3]"; + gravity_fix = nr; } + } + while (*cp) { cp++; } + cp++; + } - cp = pad_up_4(cp); - - /* Type names array ('TYPE') */ - data = (int *)cp; - if (*data == MAKE_ID('T', 'Y', 'P', 'E')) { - data++; + cp = pad_up_4(cp); - sdna->types_len = *data; - if (do_endian_swap) { - BLI_endian_switch_int32(&sdna->types_len); - } + /* Type names array ('TYPE') */ + data = (int *)cp; + if (*data == MAKE_ID('T', 'Y', 'P', 'E')) { + data++; - data++; - sdna->types = MEM_callocN(sizeof(void *) * sdna->types_len, "sdnatypes"); - } - else { - *r_error_message = "TYPE error in SDNA file"; - return false; + sdna->types_len = *data; + if (do_endian_swap) { + BLI_endian_switch_int32(&sdna->types_len); } - cp = (char *)data; - for (int nr = 0; nr < sdna->types_len; nr++) { - /* WARNING! See: DNA_struct_rename_legacy_hack_static_from_alias docs. */ - sdna->types[nr] = DNA_struct_rename_legacy_hack_static_from_alias(cp); - while (*cp) { - cp++; - } + data++; + sdna->types = MEM_callocN(sizeof(void *) * sdna->types_len, "sdnatypes"); + } + else { + *r_error_message = "TYPE error in SDNA file"; + return false; + } + + cp = (char *)data; + for (int nr = 0; nr < sdna->types_len; nr++) { + /* WARNING! See: DNA_struct_rename_legacy_hack_static_from_alias docs. */ + sdna->types[nr] = DNA_struct_rename_legacy_hack_static_from_alias(cp); + while (*cp) { cp++; } + cp++; + } - cp = pad_up_4(cp); - - /* Type lengths array ('TLEN') */ - data = (int *)cp; - if (*data == MAKE_ID('T', 'L', 'E', 'N')) { - data++; - sp = (short *)data; - sdna->types_size = sp; + cp = pad_up_4(cp); - if (do_endian_swap) { - BLI_endian_switch_int16_array(sp, sdna->types_len); - } + /* Type lengths array ('TLEN') */ + data = (int *)cp; + if (*data == MAKE_ID('T', 'L', 'E', 'N')) { + data++; + sp = (short *)data; + sdna->types_size = sp; - sp += sdna->types_len; - } - else { - *r_error_message = "TLEN error in SDNA file"; - return false; - } - /* prevent BUS error */ - if (sdna->types_len & 1) { - sp++; + if (do_endian_swap) { + BLI_endian_switch_int16_array(sp, sdna->types_len); } - /* Struct array ('STRC') */ - data = (int *)sp; - if (*data == MAKE_ID('S', 'T', 'R', 'C')) { - data++; + sp += sdna->types_len; + } + else { + *r_error_message = "TLEN error in SDNA file"; + return false; + } + /* prevent BUS error */ + if (sdna->types_len & 1) { + sp++; + } - sdna->structs_len = *data; - if (do_endian_swap) { - BLI_endian_switch_int32(&sdna->structs_len); - } + /* Struct array ('STRC') */ + data = (int *)sp; + if (*data == MAKE_ID('S', 'T', 'R', 'C')) { + data++; - data++; - sdna->structs = MEM_callocN(sizeof(void *) * sdna->structs_len, "sdnastrcs"); - } - else { - *r_error_message = "STRC error in SDNA file"; - return false; + sdna->structs_len = *data; + if (do_endian_swap) { + BLI_endian_switch_int32(&sdna->structs_len); } - sp = (short *)data; - for (int nr = 0; nr < sdna->structs_len; nr++) { - sdna->structs[nr] = sp; + data++; + sdna->structs = MEM_callocN(sizeof(void *) * sdna->structs_len, "sdnastrcs"); + } + else { + *r_error_message = "STRC error in SDNA file"; + return false; + } + + sp = (short *)data; + for (int nr = 0; nr < sdna->structs_len; nr++) { + sdna->structs[nr] = sp; - if (do_endian_swap) { - short a; + if (do_endian_swap) { + short a; + BLI_endian_switch_int16(&sp[0]); + BLI_endian_switch_int16(&sp[1]); + + a = sp[1]; + sp += 2; + while (a--) { BLI_endian_switch_int16(&sp[0]); BLI_endian_switch_int16(&sp[1]); - - a = sp[1]; sp += 2; - while (a--) { - BLI_endian_switch_int16(&sp[0]); - BLI_endian_switch_int16(&sp[1]); - sp += 2; - } - } - else { - sp += 2 * sp[1] + 2; } } + else { + sp += 2 * sp[1] + 2; + } } { @@ -578,16 +577,15 @@ SDNA *DNA_sdna_from_data(const void *data, if (init_structDNA(sdna, do_endian_swap, &error_message)) { return sdna; } + + if (r_error_message == NULL) { + fprintf(stderr, "Error decoding blend file SDNA: %s\n", error_message); + } else { - if (r_error_message == NULL) { - fprintf(stderr, "Error decoding blend file SDNA: %s\n", error_message); - } - else { - *r_error_message = error_message; - } - DNA_sdna_free(sdna); - return NULL; + *r_error_message = error_message; } + DNA_sdna_free(sdna); + return NULL; } /** @@ -764,34 +762,33 @@ static eSDNA_Type sdna_type_nr(const char *dna_type) if (STR_ELEM(dna_type, "char", "const char")) { return SDNA_TYPE_CHAR; } - else if (STR_ELEM(dna_type, "uchar", "unsigned char")) { + if (STR_ELEM(dna_type, "uchar", "unsigned char")) { return SDNA_TYPE_UCHAR; } - else if (STR_ELEM(dna_type, "short")) { + if (STR_ELEM(dna_type, "short")) { return SDNA_TYPE_SHORT; } - else if (STR_ELEM(dna_type, "ushort", "unsigned short")) { + if (STR_ELEM(dna_type, "ushort", "unsigned short")) { return SDNA_TYPE_USHORT; } - else if (STR_ELEM(dna_type, "int")) { + if (STR_ELEM(dna_type, "int")) { return SDNA_TYPE_INT; } - else if (STR_ELEM(dna_type, "float")) { + if (STR_ELEM(dna_type, "float")) { return SDNA_TYPE_FLOAT; } - else if (STR_ELEM(dna_type, "double")) { + if (STR_ELEM(dna_type, "double")) { return SDNA_TYPE_DOUBLE; } - else if (STR_ELEM(dna_type, "int64_t")) { + if (STR_ELEM(dna_type, "int64_t")) { return SDNA_TYPE_INT64; } - else if (STR_ELEM(dna_type, "uint64_t")) { + if (STR_ELEM(dna_type, "uint64_t")) { return SDNA_TYPE_UINT64; } /* invalid! */ - else { - return -1; - } + + return -1; } /** @@ -1150,7 +1147,7 @@ static void reconstruct_elem(const SDNA *newsdna, return; } - else if (countpos != 0) { /* name is an array */ + if (countpos != 0) { /* name is an array */ if (oname[countpos] == '[' && strncmp(name, oname, countpos) == 0) { /* basis equal */ const int new_name_array_len = newsdna->names_array_len[new_name_nr]; diff --git a/source/blender/makesdna/intern/dna_rename_defs.h b/source/blender/makesdna/intern/dna_rename_defs.h index f2cf72843bd..a73fc747f84 100644 --- a/source/blender/makesdna/intern/dna_rename_defs.h +++ b/source/blender/makesdna/intern/dna_rename_defs.h @@ -67,6 +67,7 @@ DNA_STRUCT_RENAME_ELEM(Bone, scaleOut, scale_out_x) DNA_STRUCT_RENAME_ELEM(BrushGpencilSettings, gradient_f, hardeness) DNA_STRUCT_RENAME_ELEM(BrushGpencilSettings, gradient_s, aspect_ratio) DNA_STRUCT_RENAME_ELEM(Camera, YF_dofdist, dof_distance) +DNA_STRUCT_RENAME_ELEM(Curve, len_wchar, len_char32) DNA_STRUCT_RENAME_ELEM(Camera, clipend, clip_end) DNA_STRUCT_RENAME_ELEM(Camera, clipsta, clip_start) DNA_STRUCT_RENAME_ELEM(Collection, dupli_ofs, instance_offset) @@ -90,6 +91,7 @@ DNA_STRUCT_RENAME_ELEM(ParticleSettings, dupliweights, instance_weights) DNA_STRUCT_RENAME_ELEM(Text, name, filepath) DNA_STRUCT_RENAME_ELEM(ThemeSpace, scrubbing_background, time_scrub_background) DNA_STRUCT_RENAME_ELEM(ThemeSpace, show_back_grad, background_type) +DNA_STRUCT_RENAME_ELEM(UserDef, gp_manhattendist, gp_manhattandist) DNA_STRUCT_RENAME_ELEM(VFont, name, filepath) DNA_STRUCT_RENAME_ELEM(View3D, far, clip_end) DNA_STRUCT_RENAME_ELEM(View3D, near, clip_start) diff --git a/source/blender/makesdna/intern/dna_utils.c b/source/blender/makesdna/intern/dna_utils.c index 97f4785374a..3cf5c52a4c6 100644 --- a/source/blender/makesdna/intern/dna_utils.c +++ b/source/blender/makesdna/intern/dna_utils.c @@ -235,7 +235,9 @@ void DNA_alias_maps(enum eDNA_RenameDir version_dir, GHash **r_struct_map, GHash if (version_dir == DNA_RENAME_STATIC_FROM_ALIAS) { const char *renames[][2] = { - {"int8_t", "char"}, /* Note that a char is always unsigned in Blender. */ + /* Disable 'int8_t' until we support 'signed char', since changing negative + * values to a different type isn't supported and will change the value. */ + /* {"int8_t", "char"}, */ {"uint8_t", "uchar"}, {"int16_t", "short"}, {"uint16_t", "ushort"}, diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index 898d2e58e45..af0d914391a 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -360,7 +360,7 @@ static int add_type(const char *str, int size) if (str[0] == 0) { return -1; } - else if (strchr(str, '*')) { + if (strchr(str, '*')) { /* note: this is valid C syntax but we can't parse, complain! * `struct SomeStruct* some_var;` <-- correct but we cant handle right now. */ return -1; @@ -1532,12 +1532,21 @@ int main(int argc, char **argv) #endif /* if 0 */ -/* even though DNA supports, 'long' shouldn't be used since it can be either 32 or 64bit, - * use int or int64_t instead. +/** + * Disable types: + * + * - 'long': even though DNA supports, 'long' shouldn't be used since it can be either 32 or 64bit, + * use int, int32_t or int64_t instead. + * - 'int8_t': as DNA doesn't yet support 'signed char' types, + * all char types are assumed to be unsigned. + * We should be able to support this, it's just not something which has been added yet. + * * Only valid use would be as a runtime variable if an API expected a long, - * but so far we dont have this happening. */ + * but so far we don't have this happening. + */ #ifdef __GNUC__ # pragma GCC poison long +# pragma GCC poison int8_t #endif #include "DNA_ID.h" diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index b7f0fb87536..8781a3f448f 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -175,7 +175,7 @@ static int replace_if_different(const char *tmpfile, const char *dep_files[]) if (dep_files) { int pass; for (pass = 0; dep_files[pass]; pass++) { - char from_path[4096] = __FILE__; + const char from_path[4096] = __FILE__; char *p1, *p2; /* dir only */ @@ -5147,7 +5147,7 @@ int main(int argc, char **argv) { int return_status = 0; - MEM_initialize_memleak_detection(); + MEM_init_memleak_detection(); MEM_set_error_callback(mem_error_cb); CLG_init(); diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 84f9ec749cb..11b563dae52 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -237,12 +237,27 @@ static EnumPropertyItem rna_enum_gpencil_fill_draw_modes_items[] = { {GP_FILL_DMODE_BOTH, "BOTH", 0, - "Default", + "All", "Use both visible strokes and edit lines as fill boundary limits"}, {GP_FILL_DMODE_STROKE, "STROKE", 0, "Strokes", "Use visible strokes as fill boundary limits"}, {GP_FILL_DMODE_CONTROL, "CONTROL", 0, "Edit Lines", "Use edit lines as fill boundary limits"}, {0, NULL, 0, NULL, NULL}}; +static EnumPropertyItem rna_enum_gpencil_fill_layers_modes_items[] = { + {GP_FILL_GPLMODE_VISIBLE, "VISIBLE", 0, "Visible", "Visible layers"}, + {GP_FILL_GPLMODE_ACTIVE, "ACTIVE", 0, "Active", "Only active layer"}, + {GP_FILL_GPLMODE_ABOVE, "ABOVE", 0, "Layer Above", "Layer above active"}, + {GP_FILL_GPLMODE_BELOW, "BELOW", 0, "Layer Below", "Layer below active"}, + {GP_FILL_GPLMODE_ALL_ABOVE, "ALL_ABOVE", 0, "All Above", "All layers above active"}, + {GP_FILL_GPLMODE_ALL_BELOW, "ALL_BELOW", 0, "All Below", "All layers below active"}, + {0, NULL, 0, NULL, NULL}}; + +static EnumPropertyItem rna_enum_gpencil_brush_modes_items[] = { + {GP_BRUSH_MODE_ACTIVE, "ACTIVE", 0, "Active", "Use current mode"}, + {GP_BRUSH_MODE_MATERIAL, "MATERIAL", 0, "Material", "Use always material mode"}, + {GP_BRUSH_MODE_VERTEXCOLOR, "VERTEXCOLOR", 0, "Vertex Color", "Use always Vertex Color mode"}, + {0, NULL, 0, NULL, NULL}}; + static EnumPropertyItem rna_enum_gpencil_brush_paint_icons_items[] = { {GP_BRUSH_ICON_PENCIL, "PENCIL", ICON_GPBRUSH_PENCIL, "Pencil", ""}, {GP_BRUSH_ICON_PEN, "PEN", ICON_GPBRUSH_PEN, "Pen", ""}, @@ -359,7 +374,7 @@ static bool rna_BrushCapabilities_has_overlay_get(PointerRNA *ptr) static bool rna_BrushCapabilitiesSculpt_has_persistence_get(PointerRNA *ptr) { Brush *br = (Brush *)ptr->data; - return br->sculpt_tool == SCULPT_TOOL_LAYER; + return ELEM(br->sculpt_tool, SCULPT_TOOL_LAYER, SCULPT_TOOL_CLOTH); } static bool rna_BrushCapabilitiesSculpt_has_pinch_factor_get(PointerRNA *ptr) @@ -1640,6 +1655,18 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Mode", "Mode to draw boundary limits"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + prop = RNA_def_property(srna, "fill_layer_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "fill_layer_mode"); + RNA_def_property_enum_items(prop, rna_enum_gpencil_fill_layers_modes_items); + RNA_def_property_ui_text(prop, "Layer Mode", "Layers used as boundaries"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + + prop = RNA_def_property(srna, "brush_draw_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "brush_draw_mode"); + RNA_def_property_enum_items(prop, rna_enum_gpencil_brush_modes_items); + RNA_def_property_ui_text(prop, "Mode", "Preselected mode when using this brush"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + prop = RNA_def_property(srna, "trim", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_TRIM_STROKE); RNA_def_property_boolean_default(prop, false); @@ -1956,6 +1983,16 @@ static void rna_def_brush(BlenderRNA *brna) {0, NULL, 0, NULL, NULL}, }; + static const EnumPropertyItem brush_cloth_simulation_area_type_items[] = { + {BRUSH_CLOTH_SIMULATION_AREA_LOCAL, + "LOCAL", + 0, + "Local", + "Simulates only a specific area arround the brush limited by a fixed radius"}, + {BRUSH_CLOTH_SIMULATION_AREA_GLOBAL, "GLOBAL", 0, "Global", "Simulates the entire mesh"}, + {0, NULL, 0, NULL, NULL}, + }; + static const EnumPropertyItem brush_smooth_deform_type_items[] = { {BRUSH_SMOOTH_DEFORM_LAPLACIAN, "LAPLACIAN", @@ -1973,7 +2010,7 @@ static void rna_def_brush(BlenderRNA *brna) static const EnumPropertyItem brush_pose_deform_type_items[] = { {BRUSH_POSE_DEFORM_ROTATE_TWIST, "ROTATE_TWIST", 0, "Rotate/Twist", ""}, {BRUSH_POSE_DEFORM_SCALE_TRASLATE, "SCALE_TRANSLATE", 0, "Scale/Translate", ""}, - {BRUSH_POSE_DEFORM_SQUASH_STRETCH, "SQUASH_STRETCH", 0, "Squash/Stretch", ""}, + {BRUSH_POSE_DEFORM_SQUASH_STRETCH, "SQUASH_STRETCH", 0, "Squash & Stretch", ""}, {0, NULL, 0, NULL, NULL}, }; @@ -2126,6 +2163,14 @@ static void rna_def_brush(BlenderRNA *brna) prop, "Force Falloff", "Shape used in the brush to apply force to the cloth"); RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "cloth_simulation_area_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, brush_cloth_simulation_area_type_items); + RNA_def_property_ui_text( + prop, + "Simulation Area", + "Part of the mesh that is going to be simulated when the stroke is active"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "smooth_deform_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, brush_smooth_deform_type_items); RNA_def_property_ui_text(prop, "Deformation", "Deformation type that is used in the brush"); @@ -2556,6 +2601,15 @@ static void rna_def_brush(BlenderRNA *brna) "Area to apply deformation falloff to the effects of the simulation"); RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "cloth_constraint_softbody_strength", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "cloth_constraint_softbody_strength"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text( + prop, + "Soft Body Influence", + "How much the simulation preserves the original shape, acting as a soft body"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "hardness", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "hardness"); RNA_def_property_range(prop, 0.0f, 1.0f); @@ -2767,11 +2821,32 @@ static void rna_def_brush(BlenderRNA *brna) prop, "Keep Anchor Point", "Keep the position of the last segment in the IK chain fixed"); RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "use_pose_lock_rotation", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_POSE_USE_LOCK_ROTATION); + RNA_def_property_ui_text(prop, + "Lock Rotation When Scaling", + "Do not rotate the segment when using the scale deform mode"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "use_connected_only", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_USE_CONNECTED_ONLY); RNA_def_property_ui_text(prop, "Connected Only", "Affect only topologically connected elements"); RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "use_cloth_pin_simulation_boundary", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_CLOTH_PIN_SIMULATION_BOUNDARY); + RNA_def_property_ui_text( + prop, + "Pin Simulation Boundary", + "Lock the position of the vertices in the simulation falloff area to avoid artifacts and " + "create a softer transitionwith with unnafected areas"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + + prop = RNA_def_property(srna, "use_cloth_collision", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_CLOTH_USE_COLLISION); + RNA_def_property_ui_text(prop, "Enable Collision", "Collide with objects during the simulation"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "invert_to_scrape_fill", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_INVERT_TO_SCRAPE_FILL); RNA_def_property_ui_text(prop, diff --git a/source/blender/makesrna/intern/rna_cachefile.c b/source/blender/makesrna/intern/rna_cachefile.c index f9275ef1993..c25cea1b4b3 100644 --- a/source/blender/makesrna/intern/rna_cachefile.c +++ b/source/blender/makesrna/intern/rna_cachefile.c @@ -174,6 +174,32 @@ static void rna_def_cachefile(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Object Paths", "Paths of the objects inside the Alembic archive"); + /* ----------------- Alembic Velocity Attribute ----------------- */ + + prop = RNA_def_property(srna, "velocity_name", PROP_STRING, PROP_NONE); + RNA_def_property_ui_text(prop, + "Velocity Attribute", + "Name of the Alembic attribute used for generating motion blur data"); + RNA_def_property_update(prop, 0, "rna_CacheFile_update"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + + static const EnumPropertyItem velocity_unit_items[] = { + {CACHEFILE_VELOCITY_UNIT_SECOND, "SECOND", 0, "Second", ""}, + {CACHEFILE_VELOCITY_UNIT_FRAME, "FRAME", 0, "Frame", ""}, + {0, NULL, 0, NULL, NULL}, + }; + + prop = RNA_def_property(srna, "velocity_unit", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "velocity_unit"); + RNA_def_property_enum_items(prop, velocity_unit_items); + RNA_def_property_ui_text( + prop, + "Velocity Unit", + "Define how the velocity vectors are interpreted with regard to time, 'frame' means " + "the delta time is 1 frame, 'second' means the delta time is 1 / FPS"); + RNA_def_property_update(prop, 0, "rna_CacheFile_update"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_define_lib_overridable(false); rna_def_cachefile_object_paths(brna, prop); diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index 56ad8e2677b..60b6cc40792 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -702,7 +702,7 @@ static float rna_CurveMapping_evaluateF(struct CurveMapping *cumap, static void rna_CurveMap_initialize(struct CurveMapping *cumap) { - BKE_curvemapping_initialize(cumap); + BKE_curvemapping_init(cumap); } #else diff --git a/source/blender/makesrna/intern/rna_context.c b/source/blender/makesrna/intern/rna_context.c index c8abf774561..e6dceb5af72 100644 --- a/source/blender/makesrna/intern/rna_context.c +++ b/source/blender/makesrna/intern/rna_context.c @@ -41,7 +41,7 @@ const EnumPropertyItem rna_enum_context_mode_items[] = { {CTX_MODE_EDIT_ARMATURE, "EDIT_ARMATURE", 0, "Armature Edit", ""}, {CTX_MODE_EDIT_METABALL, "EDIT_METABALL", 0, "Metaball Edit", ""}, {CTX_MODE_EDIT_LATTICE, "EDIT_LATTICE", 0, "Lattice Edit", ""}, - {CTX_MODE_POSE, "POSE", 0, "Pose ", ""}, + {CTX_MODE_POSE, "POSE", 0, "Pose", ""}, {CTX_MODE_SCULPT, "SCULPT", 0, "Sculpt", ""}, {CTX_MODE_PAINT_WEIGHT, "PAINT_WEIGHT", 0, "Weight Paint", ""}, {CTX_MODE_PAINT_VERTEX, "PAINT_VERTEX", 0, "Vertex Paint", ""}, diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 771235c85aa..1768d79fe8f 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -570,7 +570,7 @@ static void rna_Curve_body_set(PointerRNA *ptr, const char *value) Curve *cu = (Curve *)ptr->owner_id; - cu->len_wchar = len_chars; + cu->len_char32 = len_chars; cu->len = len_bytes; cu->pos = len_chars; @@ -1191,9 +1191,9 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna) RNA_def_property_ui_text( prop, "Object Font", - "Use Objects as font characters (give font objects a common name " + "Use objects as font characters (give font objects a common name " "followed by the character they represent, eg. 'family-a', 'family-b', etc, " - "set this setting to 'family-', and turn on Vertex Duplication)"); + "set this setting to 'family-', and turn on Vertex Instancing)"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); prop = RNA_def_property(srna, "body", PROP_STRING, PROP_NONE); @@ -1206,7 +1206,7 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna) RNA_def_property_update(prop, 0, "rna_Curve_update_data"); prop = RNA_def_property(srna, "body_format", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "strinfo", "len_wchar"); + RNA_def_property_collection_sdna(prop, NULL, "strinfo", "len_char32"); RNA_def_property_struct_type(prop, "TextCharacterFormat"); RNA_def_property_ui_text(prop, "Character Info", "Stores the style of each character"); diff --git a/source/blender/makesrna/intern/rna_curveprofile.c b/source/blender/makesrna/intern/rna_curveprofile.c index ce91fc79085..ee1c659fcd5 100644 --- a/source/blender/makesrna/intern/rna_curveprofile.c +++ b/source/blender/makesrna/intern/rna_curveprofile.c @@ -146,7 +146,7 @@ static void rna_CurveProfile_evaluate(struct CurveProfile *profile, static void rna_CurveProfile_initialize(struct CurveProfile *profile, int segments_len) { - BKE_curveprofile_initialize(profile, (short)segments_len); + BKE_curveprofile_init(profile, (short)segments_len); } static void rna_CurveProfile_update(struct CurveProfile *profile) diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index 3ae16f8577a..d5449a69cf6 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -1635,7 +1635,7 @@ static void rna_def_fmodifier(BlenderRNA *brna) /* TODO: setting this to true must ensure that all others in stack are turned off too... */ prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", FMODIFIER_FLAG_ACTIVE); - RNA_def_property_ui_text(prop, "Active", "F-Curve Modifier is the one being edited "); + RNA_def_property_ui_text(prop, "Active", "F-Curve Modifier is the one being edited"); RNA_def_property_boolean_funcs(prop, NULL, "rna_FModifier_active_set"); RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, "rna_FModifier_active_update"); RNA_def_property_ui_icon(prop, ICON_RADIOBUT_OFF, 1); diff --git a/source/blender/makesrna/intern/rna_fluid.c b/source/blender/makesrna/intern/rna_fluid.c index 47e0333edb1..0a58f8af593 100644 --- a/source/blender/makesrna/intern/rna_fluid.c +++ b/source/blender/makesrna/intern/rna_fluid.c @@ -1681,7 +1681,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna) RNA_def_property_range(prop, 0.001, 1.0); RNA_def_property_ui_range(prop, 0.01, 1.0, 0.05, -1); RNA_def_property_ui_text(prop, - "Obstacle-Fluid Threshold ", + "Obstacle-Fluid Threshold", "Determines how much fluid is allowed in an obstacle cell " "(higher values will tag a boundary cell as an obstacle easier " "and reduce the boundary smoothening effect)"); @@ -2052,6 +2052,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna) prop, "Start", "Frame on which the simulation starts. This is the first frame that will be baked"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); prop = RNA_def_property(srna, "cache_frame_end", PROP_INT, PROP_TIME); RNA_def_property_int_sdna(prop, NULL, "cache_frame_end"); @@ -2061,6 +2062,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna) prop, "End", "Frame on which the simulation stops. This is the last frame that will be baked"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); prop = RNA_def_property(srna, "cache_frame_offset", PROP_INT, PROP_TIME); RNA_def_property_int_sdna(prop, NULL, "cache_frame_offset"); @@ -2070,6 +2072,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna) "Offset", "Frame offset that is used when loading the simulation from the cache. It is not considered " "when baking the simulation, only when loading it"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); prop = RNA_def_property(srna, "cache_frame_pause_data", PROP_INT, PROP_TIME); RNA_def_property_int_sdna(prop, NULL, "cache_frame_pause_data"); @@ -2093,6 +2096,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna) prop, NULL, "rna_Fluid_cachetype_mesh_set", "rna_Fluid_cachetype_mesh_itemf"); RNA_def_property_ui_text( prop, "File Format", "Select the file format to be used for caching surface data"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_meshcache_reset"); prop = RNA_def_property(srna, "cache_data_format", PROP_ENUM, PROP_NONE); @@ -2102,6 +2106,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna) prop, NULL, "rna_Fluid_cachetype_data_set", "rna_Fluid_cachetype_volume_itemf"); RNA_def_property_ui_text( prop, "File Format", "Select the file format to be used for caching volumetric data"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_datacache_reset"); prop = RNA_def_property(srna, "cache_particle_format", PROP_ENUM, PROP_NONE); @@ -2111,6 +2116,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna) prop, NULL, "rna_Fluid_cachetype_particle_set", "rna_Fluid_cachetype_particle_itemf"); RNA_def_property_ui_text( prop, "File Format", "Select the file format to be used for caching particle data"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_particlescache_reset"); prop = RNA_def_property(srna, "cache_noise_format", PROP_ENUM, PROP_NONE); @@ -2120,6 +2126,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna) prop, NULL, "rna_Fluid_cachetype_noise_set", "rna_Fluid_cachetype_volume_itemf"); RNA_def_property_ui_text( prop, "File Format", "Select the file format to be used for caching noise data"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_noisecache_reset"); prop = RNA_def_property(srna, "cache_type", PROP_ENUM, PROP_NONE); @@ -2127,6 +2134,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna) RNA_def_property_enum_items(prop, cache_types); RNA_def_property_enum_funcs(prop, NULL, "rna_Fluid_cachetype_set", NULL); RNA_def_property_ui_text(prop, "Type", "Change the cache type of the simulation"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Fluid_domain_data_reset"); prop = RNA_def_property(srna, "cache_resumable", PROP_BOOLEAN, PROP_NONE); @@ -2137,6 +2145,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna) "Additional data will be saved so that the bake jobs can be resumed after pausing. Because " "more data will be written to disk it is recommended to avoid enabling this option when " "baking at high resolutions"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_datacache_reset"); prop = RNA_def_property(srna, "cache_directory", PROP_STRING, PROP_DIRPATH); diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index 887bded8540..1c43815d3a2 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -67,7 +67,6 @@ static const EnumPropertyItem image_source_items[] = { # include "BKE_global.h" -# include "GPU_draw.h" # include "GPU_texture.h" # include "IMB_imbuf.h" @@ -200,7 +199,7 @@ static void rna_Image_gpu_texture_update(Main *UNUSED(bmain), Image *ima = (Image *)ptr->owner_id; if (!G.background) { - GPU_free_image(ima); + BKE_image_free_gputextures(ima); } WM_main_add_notifier(NC_IMAGE | ND_DISPLAY, &ima->id); @@ -398,7 +397,7 @@ static void rna_Image_resolution_set(PointerRNA *ptr, const float *values) static int rna_Image_bindcode_get(PointerRNA *ptr) { Image *ima = (Image *)ptr->data; - GPUTexture *tex = ima->gputexture[TEXTARGET_TEXTURE_2D][0]; + GPUTexture *tex = ima->gputexture[TEXTARGET_2D][0]; return (tex) ? GPU_texture_opengl_bindcode(tex) : 0; } @@ -516,7 +515,7 @@ static void rna_Image_pixels_set(PointerRNA *ptr, const float *values) ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID | IB_MIPMAP_INVALID; BKE_image_mark_dirty(ima, ibuf); if (!G.background) { - GPU_free_image(ima); + BKE_image_free_gputextures(ima); } WM_main_add_notifier(NC_IMAGE | ND_DISPLAY, &ima->id); } diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c index 41c0e724234..6f876923e52 100644 --- a/source/blender/makesrna/intern/rna_image_api.c +++ b/source/blender/makesrna/intern/rna_image_api.c @@ -50,8 +50,6 @@ # include "DNA_image_types.h" # include "DNA_scene_types.h" -# include "GPU_glew.h" - # include "MEM_guardedalloc.h" static void rna_ImagePackedFile_save(ImagePackedFile *imapf, Main *bmain, ReportList *reports) @@ -222,23 +220,24 @@ static int rna_Image_gl_load(Image *image, ReportList *reports, int frame) BKE_imageuser_default(&iuser); iuser.framenr = frame; - GPUTexture *tex = GPU_texture_from_blender(image, &iuser, NULL, GL_TEXTURE_2D); + GPUTexture *tex = BKE_image_get_gpu_texture(image, &iuser, NULL); if (tex == NULL) { BKE_reportf(reports, RPT_ERROR, "Failed to load image texture '%s'", image->id.name + 2); - return (int)GL_INVALID_OPERATION; + /* TODO(fclem) this error code makes no sense for vulkan. */ + return 0x0502; /* GL_INVALID_OPERATION */ } - return GL_NO_ERROR; + return 0; /* GL_NO_ERROR */ } static int rna_Image_gl_touch(Image *image, ReportList *reports, int frame) { - int error = GL_NO_ERROR; + int error = 0; /* GL_NO_ERROR */ BKE_image_tag_time(image); - if (image->gputexture[TEXTARGET_TEXTURE_2D] == NULL) { + if (image->gputexture[TEXTARGET_2D][0] == NULL) { error = rna_Image_gl_load(image, reports, frame); } @@ -247,7 +246,7 @@ static int rna_Image_gl_touch(Image *image, ReportList *reports, int frame) static void rna_Image_gl_free(Image *image) { - GPU_free_image(image); + BKE_image_free_gputextures(image); /* remove the nocollect flag, image is available for garbage collection again */ image->flag &= ~IMA_NOCOLLECT; diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 86f05c350f3..05e11ffc919 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -302,7 +302,7 @@ const EnumPropertyItem rna_enum_modifier_triangulate_quad_method_items[] = { {MOD_TRIANGULATE_QUAD_BEAUTY, "BEAUTY", 0, - "Beauty ", + "Beauty", "Split the quads in nice triangles, slower method"}, {MOD_TRIANGULATE_QUAD_FIXED, "FIXED", @@ -1163,7 +1163,7 @@ static void rna_BevelModifier_update_segments(Main *bmain, Scene *scene, Pointer BevelModifierData *bmd = (BevelModifierData *)ptr->data; if (RNA_enum_get(ptr, "profile_type") == MOD_BEVEL_PROFILE_CUSTOM) { short segments = (short)RNA_int_get(ptr, "segments"); - BKE_curveprofile_initialize(bmd->custom_profile, segments); + BKE_curveprofile_init(bmd->custom_profile, segments); } rna_Modifier_update(bmain, scene, ptr); } @@ -1699,6 +1699,51 @@ static bool rna_Modifier_show_expanded_get(PointerRNA *ptr) return md->ui_expand_flag & (1 << 0); } +static int rna_MeshSequenceCacheModifier_has_velocity_get(PointerRNA *ptr) +{ +# ifdef WITH_ALEMBIC + MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)ptr->data; + return ABC_has_vec3_array_property_named(mcmd->reader, mcmd->cache_file->velocity_name); +# else + return false; + UNUSED_VARS(ptr); +# endif +} + +static int rna_MeshSequenceCacheModifier_read_velocity_get(PointerRNA *ptr) +{ +# ifdef WITH_ALEMBIC + MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)ptr->data; + + if (mcmd->num_vertices == 0) { + return 0; + } + + if (mcmd->vertex_velocities) { + MEM_freeN(mcmd->vertex_velocities); + } + + mcmd->vertex_velocities = MEM_mallocN(sizeof(MeshCacheVertexVelocity) * mcmd->num_vertices, + "Mesh Cache Velocities"); + + int num_read = ABC_read_velocity_cache(mcmd->reader, + mcmd->cache_file->velocity_name, + mcmd->last_lookup_time, + mcmd->velocity_scale * mcmd->velocity_delta, + mcmd->num_vertices, + (float *)mcmd->vertex_velocities); + + if (num_read == -1 || num_read != mcmd->num_vertices) { + return false; + } + + return true; +# else + return false; + UNUSED_VARS(ptr); +# endif +} + #else /* NOTE: *MUST* return subdivision_type property. */ @@ -5667,7 +5712,17 @@ static void rna_def_modifier_ocean(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_range(prop, 1, 1024); RNA_def_property_ui_range(prop, 1, 32, 1, -1); - RNA_def_property_ui_text(prop, "Resolution", "Resolution of the generated surface"); + RNA_def_property_ui_text( + prop, "Render Resolution", "Resolution of the generated surface for rendering and baking"); + RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update"); + + prop = RNA_def_property(srna, "viewport_resolution", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_sdna(prop, NULL, "viewport_resolution"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_range(prop, 1, 1024); + RNA_def_property_ui_range(prop, 1, 32, 1, -1); + RNA_def_property_ui_text( + prop, "Viewport Resolution", "Viewport resolution of the generated surface"); RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update"); prop = RNA_def_property(srna, "spatial_size", PROP_INT, PROP_NONE); @@ -5905,7 +5960,7 @@ static void rna_def_modifier_triangulate(BlenderRNA *brna) static void rna_def_modifier_meshcache(BlenderRNA *brna) { static const EnumPropertyItem prop_format_type_items[] = { - {MOD_MESHCACHE_TYPE_MDD, "MDD", 0, "MDD ", ""}, + {MOD_MESHCACHE_TYPE_MDD, "MDD", 0, "MDD", ""}, {MOD_MESHCACHE_TYPE_PC2, "PC2", 0, "PC2", ""}, {0, NULL, 0, NULL, NULL}, }; @@ -5926,7 +5981,7 @@ static void rna_def_modifier_meshcache(BlenderRNA *brna) }; static const EnumPropertyItem prop_interpolation_type_items[] = { - {MOD_MESHCACHE_INTERP_NONE, "NONE", 0, "None ", ""}, + {MOD_MESHCACHE_INTERP_NONE, "NONE", 0, "None", ""}, {MOD_MESHCACHE_INTERP_LINEAR, "LINEAR", 0, "Linear", ""}, /* for cardinal we'd need to read 4x cache's */ // {MOD_MESHCACHE_INTERP_CARDINAL, "CARDINAL", 0, "Cardinal", ""}, @@ -6066,6 +6121,22 @@ static void rna_def_modifier_meshcache(BlenderRNA *brna) RNA_define_lib_overridable(false); } +static void rna_def_mesh_cache_velocities(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "MeshCacheVertexVelocity", NULL); + RNA_def_struct_ui_text(srna, "Mesh Cache Velocity", "Velocity attribute of an Alembic mesh"); + RNA_def_struct_ui_icon(srna, ICON_VERTEXSEL); + + prop = RNA_def_property(srna, "velocity", PROP_FLOAT, PROP_VELOCITY); + RNA_def_property_array(prop, 3); + RNA_def_property_float_sdna(prop, NULL, "vel"); + RNA_def_property_ui_text(prop, "Velocity", ""); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); +} + static void rna_def_modifier_meshseqcache(BlenderRNA *brna) { StructRNA *srna; @@ -6108,6 +6179,35 @@ static void rna_def_modifier_meshseqcache(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "velocity_scale", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "velocity_scale"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_text( + prop, + "Velocity Scale", + "Multiplier used to control the magnitude of the velocity vectors for time effects"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + /* -------------------------- Velocity Vectors -------------------------- */ + + prop = RNA_def_property(srna, "vertex_velocities", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "vertex_velocities", "num_vertices"); + RNA_def_property_struct_type(prop, "MeshCacheVertexVelocity"); + RNA_def_property_ui_text( + prop, "Fluid Mesh Vertices", "Vertices of the fluid mesh generated by simulation"); + + rna_def_mesh_cache_velocities(brna); + + prop = RNA_def_property(srna, "has_velocity", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_ui_text(prop, "Has Velocity Cache", ""); + RNA_def_property_boolean_funcs(prop, "rna_MeshSequenceCacheModifier_has_velocity_get", NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop = RNA_def_property(srna, "read_velocity", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_ui_text(prop, "Read Velocity Cache", ""); + RNA_def_property_boolean_funcs(prop, "rna_MeshSequenceCacheModifier_read_velocity_get", NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_define_lib_overridable(false); } diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 3eb2c15c053..af07185ab4a 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -38,6 +38,7 @@ #include "BKE_animsys.h" #include "BKE_image.h" #include "BKE_node.h" +#include "BKE_simulation.h" #include "BKE_texture.h" #include "RNA_access.h" @@ -2848,6 +2849,14 @@ static void rna_NodeSocketStandard_value_update(struct bContext *C, PointerRNA * } } +static void rna_NodeSocketStandard_value_and_relation_update(struct bContext *C, PointerRNA *ptr) +{ + rna_NodeSocketStandard_value_update(C, ptr); + bNodeTree *ntree = (bNodeTree *)ptr->owner_id; + Main *bmain = CTX_data_main(C); + ntreeUpdateTree(bmain, ntree); +} + /* ******** Node Types ******** */ static void rna_NodeInternalSocketTemplate_name_get(PointerRNA *ptr, char *value) @@ -6495,7 +6504,7 @@ static void def_cmp_channel_matte(StructRNA *srna) static const EnumPropertyItem algorithm_items[] = { {0, "SINGLE", 0, "Single", "Limit by single channel"}, - {1, "MAX", 0, "Max", "Limit by max of other channels "}, + {1, "MAX", 0, "Max", "Limit by max of other channels"}, {0, NULL, 0, NULL, NULL}, }; @@ -8868,7 +8877,8 @@ static void rna_def_node_socket_object(BlenderRNA *brna, RNA_def_property_pointer_sdna(prop, NULL, "value"); RNA_def_property_struct_type(prop, "Object"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update"); + RNA_def_property_update( + prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_and_relation_update"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE); /* socket interface */ @@ -8902,7 +8912,8 @@ static void rna_def_node_socket_image(BlenderRNA *brna, RNA_def_property_pointer_sdna(prop, NULL, "value"); RNA_def_property_struct_type(prop, "Image"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update"); + RNA_def_property_update( + prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_and_relation_update"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE); /* socket interface */ @@ -9916,7 +9927,7 @@ static void rna_def_composite_nodetree(BlenderRNA *brna) prop = RNA_def_property(srna, "use_viewer_border", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", NTREE_VIEWER_BORDER); RNA_def_property_ui_text( - prop, "Viewer Border", "Use boundaries for viewer nodes and composite backdrop"); + prop, "Viewer Region", "Use boundaries for viewer nodes and composite backdrop"); RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, "rna_NodeTree_update"); } diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 84b83bee089..08ca3f16b6d 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -193,6 +193,12 @@ static EnumPropertyItem instance_items_nogroup[] = { INSTANCE_ITEMS_SHARED, {0, NULL, 0, NULL, NULL}, }; + +static EnumPropertyItem instance_items_pointcloud[] = { + {0, "NONE", 0, "None", ""}, + {OB_DUPLIVERTS, "POINTS", 0, "Points", "Instantiate child objects on all points"}, + {0, NULL, 0, NULL, NULL}, +}; #endif #undef INSTANCE_ITEMS_SHARED #undef INSTANCE_ITEM_COLLECTION @@ -707,6 +713,9 @@ static const EnumPropertyItem *rna_Object_instance_type_itemf(bContext *UNUSED(C if (ob->type == OB_EMPTY) { item = instance_items; } + else if (ob->type == OB_POINTCLOUD) { + item = instance_items_pointcloud; + } else { item = instance_items_nogroup; } diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index af1f1847fc6..3067a5a9453 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -2887,7 +2887,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_int_sdna(prop, NULL, "userjit"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_range(prop, 0, 1000); - RNA_def_property_ui_text(prop, "P/F", "Emission locations / face (0 = automatic)"); + RNA_def_property_ui_text(prop, "Particles/Face", "Emission locations per face (0 = automatic)"); RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop = RNA_def_property(srna, "grid_resolution", PROP_INT, PROP_UNSIGNED); diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c index 325c4e3caa9..450d148d8a3 100644 --- a/source/blender/makesrna/intern/rna_rigidbody.c +++ b/source/blender/makesrna/intern/rna_rigidbody.c @@ -75,6 +75,11 @@ const EnumPropertyItem rna_enum_rigidbody_object_shape_items[] = { "Mesh", "Mesh consisting of triangles only, allowing for more detailed interactions than convex " "hulls"}, + {RB_SHAPE_COMPOUND, + "COMPOUND", + ICON_MESH_DATA, + "Compound Parent", + "Combines all of its direct rigid body children into one rigid object."}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 66698d60423..262c9f87b66 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2862,7 +2862,7 @@ static void rna_def_tool_settings(BlenderRNA *brna) "3D Cursor", "Draw stroke at 3D cursor location"}, /* Weird, GP_PROJECT_VIEWALIGN is inverted. */ - {0, "VIEW", ICON_RESTRICT_VIEW_ON, "View", "Stick stroke to the view "}, + {0, "VIEW", ICON_RESTRICT_VIEW_ON, "View", "Stick stroke to the view"}, {GP_PROJECT_VIEWSPACE | GP_PROJECT_DEPTH_VIEW, "SURFACE", ICON_FACESEL, @@ -3589,7 +3589,7 @@ static void rna_def_unified_paint_settings(BlenderRNA *brna) RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); RNA_def_property_enum_items(prop, brush_size_unit_items); RNA_def_property_ui_text( - prop, "Radius Unit", "Measure brush size relative to the view or the scene "); + prop, "Radius Unit", "Measure brush size relative to the view or the scene"); } static void rna_def_curve_paint_settings(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index a66e20258d2..06c73fbb19c 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -138,8 +138,7 @@ static void rna_SceneRender_get_frame_path( } static void rna_Scene_ray_cast(Scene *scene, - Main *bmain, - ViewLayer *view_layer, + Depsgraph *depsgraph, float origin[3], float direction[3], float ray_dist, @@ -151,8 +150,6 @@ static void rna_Scene_ray_cast(Scene *scene, float r_obmat[16]) { normalize_v3(direction); - - Depsgraph *depsgraph = BKE_scene_get_depsgraph(bmain, scene, view_layer, true); SnapObjectContext *sctx = ED_transform_snap_object_context_create(scene, 0); bool ret = ED_transform_snap_object_project_ray_ex(sctx, @@ -292,9 +289,9 @@ void RNA_api_scene(StructRNA *srna) /* Ray Cast */ func = RNA_def_function(srna, "ray_cast", "rna_Scene_ray_cast"); - RNA_def_function_flag(func, FUNC_USE_MAIN); RNA_def_function_ui_description(func, "Cast a ray onto in object space"); - parm = RNA_def_pointer(func, "view_layer", "ViewLayer", "", "Scene Layer"); + + parm = RNA_def_pointer(func, "depsgraph", "Depsgraph", "", "The current dependency graph"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); /* ray start and end */ parm = RNA_def_float_vector(func, "origin", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4); diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c index 24c4818694f..fb2a60db0fd 100644 --- a/source/blender/makesrna/intern/rna_screen.c +++ b/source/blender/makesrna/intern/rna_screen.c @@ -231,7 +231,7 @@ static int rna_Area_ui_type_get(PointerRNA *ptr) * the area type is changing. * So manually do the lookup in those cases, but do not actually change area->type * since that prevents a proper exit when the area type is changing. - * Logic copied from `ED_area_initialize()`.*/ + * Logic copied from `ED_area_init()`.*/ SpaceType *type = area->type; if (type == NULL || area_changing) { type = BKE_spacetype_from_id(area_type); diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index 4157747455d..59cedf8fcb8 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -370,13 +370,14 @@ static void rna_Sequences_remove( Sequence *seq = seq_ptr->data; Scene *scene = (Scene *)id; - if (BLI_remlink_safe(&ed->seqbase, seq) == false) { + if (BLI_findindex(&ed->seqbase, seq) == -1) { BKE_reportf( reports, RPT_ERROR, "Sequence '%s' not in scene '%s'", seq->name + 2, scene->id.name + 2); return; } - BKE_sequence_free(scene, seq, true); + BKE_sequencer_flag_for_removal(scene, &ed->seqbase, seq); + BKE_sequencer_remove_flagged_sequences(scene, &ed->seqbase); RNA_POINTER_INVALIDATE(seq_ptr); DEG_relations_tag_update(bmain); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 494fcec4c31..155f5ab3043 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1776,87 +1776,28 @@ static const EnumPropertyItem *rna_SpaceProperties_context_itemf(bContext *UNUSE { SpaceProperties *sbuts = (SpaceProperties *)(ptr->data); EnumPropertyItem *item = NULL; - int totitem = 0; - - if (sbuts->pathflag & (1 << BCONTEXT_TOOL)) { - RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_TOOL); - } - - if (totitem) { - RNA_enum_item_add_separator(&item, &totitem); - } - - if (sbuts->pathflag & (1 << BCONTEXT_RENDER)) { - RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_RENDER); - } - - if (sbuts->pathflag & (1 << BCONTEXT_OUTPUT)) { - RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_OUTPUT); - } - - if (sbuts->pathflag & (1 << BCONTEXT_VIEW_LAYER)) { - RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_VIEW_LAYER); - } - - if (sbuts->pathflag & (1 << BCONTEXT_SCENE)) { - RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_SCENE); - } - - if (sbuts->pathflag & (1 << BCONTEXT_WORLD)) { - RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_WORLD); - } - if (totitem) { - RNA_enum_item_add_separator(&item, &totitem); - } - - if (sbuts->pathflag & (1 << BCONTEXT_OBJECT)) { - RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_OBJECT); - } - - if (sbuts->pathflag & (1 << BCONTEXT_MODIFIER)) { - RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_MODIFIER); - } - - if (sbuts->pathflag & (1 << BCONTEXT_SHADERFX)) { - RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_SHADERFX); - } - - if (sbuts->pathflag & (1 << BCONTEXT_PARTICLE)) { - RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_PARTICLE); - } - - if (sbuts->pathflag & (1 << BCONTEXT_PHYSICS)) { - RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_PHYSICS); - } - - if (sbuts->pathflag & (1 << BCONTEXT_CONSTRAINT)) { - RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_CONSTRAINT); - } - - if (sbuts->pathflag & (1 << BCONTEXT_DATA)) { - RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_DATA); - (item + totitem - 1)->icon = sbuts->dataicon; - } - - if (sbuts->pathflag & (1 << BCONTEXT_BONE)) { - RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_BONE); - } - - if (sbuts->pathflag & (1 << BCONTEXT_BONE_CONSTRAINT)) { - RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_BONE_CONSTRAINT); - } - - if (sbuts->pathflag & (1 << BCONTEXT_MATERIAL)) { - RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_MATERIAL); - } + /* We use 32 tabs maximum here so a flag for each can fit into a 32 bit integer flag. + * A theoretical maximum would be BCONTEXT_TOT * 2, with every tab displayed and a spacer + * in every other item. But this size is currently limited by the size of integer + * supported by RNA enums. */ + int context_tabs_array[32]; + int totitem = ED_buttons_tabs_list(sbuts, context_tabs_array); + BLI_assert(totitem <= ARRAY_SIZE(context_tabs_array)); + + int totitem_added = 0; + for (int i = 0; i < totitem; i++) { + if (context_tabs_array[i] == -1) { + RNA_enum_item_add_separator(&item, &totitem_added); + continue; + } - if (totitem) { - RNA_enum_item_add_separator(&item, &totitem); - } + RNA_enum_items_add_value(&item, &totitem_added, buttons_context_items, context_tabs_array[i]); - if (sbuts->pathflag & (1 << BCONTEXT_TEXTURE)) { - RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_TEXTURE); + /* Add the object data icon dynamically for the data tab. */ + if (context_tabs_array[i] == BCONTEXT_DATA) { + (item + totitem_added - 1)->icon = sbuts->dataicon; + } } RNA_enum_item_end(&item, &totitem); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 00bbff5cf51..0567b22d23f 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -179,6 +179,7 @@ static const EnumPropertyItem rna_enum_userdef_viewport_aa_items[] = { # include "BKE_blender.h" # include "BKE_global.h" # include "BKE_idprop.h" +# include "BKE_image.h" # include "BKE_main.h" # include "BKE_mesh_runtime.h" # include "BKE_paint.h" @@ -187,9 +188,9 @@ static const EnumPropertyItem rna_enum_userdef_viewport_aa_items[] = { # include "DEG_depsgraph.h" -# include "GPU_draw.h" # include "GPU_extensions.h" # include "GPU_select.h" +# include "GPU_texture.h" # include "BLF_api.h" @@ -363,13 +364,14 @@ static void rna_userdef_load_ui_update(Main *UNUSED(bmain), Scene *UNUSED(scene) static void rna_userdef_anisotropic_update(Main *bmain, Scene *scene, PointerRNA *ptr) { - GPU_set_anisotropic(U.anisotropic_filter); + GPU_samplers_free(); + GPU_samplers_init(); rna_userdef_update(bmain, scene, ptr); } static void rna_userdef_gl_texture_limit_update(Main *bmain, Scene *scene, PointerRNA *ptr) { - GPU_free_images(bmain); + BKE_image_free_all_gputextures(bmain); rna_userdef_update(bmain, scene, ptr); } @@ -4593,7 +4595,7 @@ static void rna_def_userdef_view(BlenderRNA *brna) "no matter opening direction"); static const EnumPropertyItem header_align_items[] = { - {0, "NONE", 0, "Default", "Keep existing header alignment"}, + {0, "NONE", 0, "Keep Existing", "Keep existing header alignment"}, {USER_HEADER_FROM_PREF, "TOP", 0, "Top", "Top aligned on load"}, {USER_HEADER_FROM_PREF | USER_HEADER_BOTTOM, "BOTTOM", @@ -4988,7 +4990,7 @@ static void rna_def_userdef_edit(BlenderRNA *brna) /* grease pencil */ prop = RNA_def_property(srna, "grease_pencil_manhattan_distance", PROP_INT, PROP_PIXEL); - RNA_def_property_int_sdna(prop, NULL, "gp_manhattendist"); + RNA_def_property_int_sdna(prop, NULL, "gp_manhattandist"); RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_text(prop, "Grease Pencil Manhattan Distance", diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index 48d69f8e02c..1c98cec915e 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -139,12 +139,11 @@ static int svert_sum_cmp(const void *e1, const void *e2) if (sv1->sum_co > sv2->sum_co) { return 1; } - else if (sv1->sum_co < sv2->sum_co) { + if (sv1->sum_co < sv2->sum_co) { return -1; } - else { - return 0; - } + + return 0; } static void svert_from_mvert(SortVertsElem *sv, @@ -826,10 +825,10 @@ static bool isDisabled(const struct Scene *UNUSED(scene), if (amd->curve_ob && amd->curve_ob->type != OB_CURVE) { return true; } - else if (amd->start_cap && amd->start_cap->type != OB_MESH) { + if (amd->start_cap && amd->start_cap->type != OB_MESH) { return true; } - else if (amd->end_cap && amd->end_cap->type != OB_MESH) { + if (amd->end_cap && amd->end_cap->type != OB_MESH) { return true; } diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c index 9b9dd0a079c..191623112bb 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -103,9 +103,8 @@ static bool dependsOnTime(ModifierData *md) if (dmd->texture) { return BKE_texture_dependsOnTime(dmd->texture); } - else { - return false; - } + + return false; } static bool dependsOnNormals(ModifierData *md) diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 4e46e135b72..d520cccf0a2 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -1180,9 +1180,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * BKE_id_free(NULL, split_m); return explode; } - else { - return explodeMesh(emd, psmd, ctx, scene, mesh); - } + + return explodeMesh(emd, psmd, ctx, scene, mesh); } return mesh; } diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c index 083348dfb26..86592245368 100644 --- a/source/blender/modifiers/intern/MOD_hook.c +++ b/source/blender/modifiers/intern/MOD_hook.c @@ -185,7 +185,7 @@ static float hook_falloff(const struct HookData_cb *hd, const float len_sq) if (len_sq > hd->falloff_sq) { return 0.0f; } - else if (len_sq > 0.0f) { + if (len_sq > 0.0f) { float fac; if (hd->falloff_type == eHook_Falloff_Const) { @@ -304,7 +304,7 @@ static void deformVerts_do(HookModifierData *hmd, } if (hmd->curfalloff) { - BKE_curvemapping_initialize(hmd->curfalloff); + BKE_curvemapping_init(hmd->curfalloff); } /* Generic data needed for applying per-vertex calculations (initialize all members) */ diff --git a/source/blender/modifiers/intern/MOD_mask.cc b/source/blender/modifiers/intern/MOD_mask.cc index 93fb7749392..7b09d3c470d 100644 --- a/source/blender/modifiers/intern/MOD_mask.cc +++ b/source/blender/modifiers/intern/MOD_mask.cc @@ -44,12 +44,7 @@ #include "BKE_lib_query.h" #include "BKE_mesh.h" #include "BKE_modifier.h" - -/* SpaceType struct has a member called 'new' which obviously conflicts with C++ - * so temporarily redefining the new keyword to make it compile. */ -#define new extern_new #include "BKE_screen.h" -#undef new #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/modifiers/intern/MOD_meshcache_mdd.c b/source/blender/modifiers/intern/MOD_meshcache_mdd.c index 60376f61708..6787ef5b47e 100644 --- a/source/blender/modifiers/intern/MOD_meshcache_mdd.c +++ b/source/blender/modifiers/intern/MOD_meshcache_mdd.c @@ -238,22 +238,19 @@ bool MOD_meshcache_read_mdd_frame(FILE *fp, MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str)) { return true; } - else { - return false; - } + + return false; } - else { - /* read both and interpolate */ - if ((BLI_fseek(fp, 0, SEEK_SET) == 0) && - MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str) && - (BLI_fseek(fp, 0, SEEK_SET) == 0) && - MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[1], factor, err_str)) { - return true; - } - else { - return false; - } + + /* read both and interpolate */ + if ((BLI_fseek(fp, 0, SEEK_SET) == 0) && + MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str) && + (BLI_fseek(fp, 0, SEEK_SET) == 0) && + MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[1], factor, err_str)) { + return true; } + + return false; } bool MOD_meshcache_read_mdd_times(const char *filepath, diff --git a/source/blender/modifiers/intern/MOD_meshcache_pc2.c b/source/blender/modifiers/intern/MOD_meshcache_pc2.c index 60011458c67..1ea71730db7 100644 --- a/source/blender/modifiers/intern/MOD_meshcache_pc2.c +++ b/source/blender/modifiers/intern/MOD_meshcache_pc2.c @@ -213,22 +213,19 @@ bool MOD_meshcache_read_pc2_frame(FILE *fp, MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str)) { return true; } - else { - return false; - } + + return false; } - else { - /* read both and interpolate */ - if ((BLI_fseek(fp, 0, SEEK_SET) == 0) && - MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str) && - (BLI_fseek(fp, 0, SEEK_SET) == 0) && - MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[1], factor, err_str)) { - return true; - } - else { - return false; - } + + /* read both and interpolate */ + if ((BLI_fseek(fp, 0, SEEK_SET) == 0) && + MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str) && + (BLI_fseek(fp, 0, SEEK_SET) == 0) && + MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[1], factor, err_str)) { + return true; } + + return false; } bool MOD_meshcache_read_pc2_times(const char *filepath, diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c index 8f6676dd0b2..5513e6b4971 100644 --- a/source/blender/modifiers/intern/MOD_meshsequencecache.c +++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c @@ -33,6 +33,8 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" +#include "MEM_guardedalloc.h" + #include "BKE_cachefile.h" #include "BKE_context.h" #include "BKE_lib_query.h" @@ -65,6 +67,9 @@ static void initData(ModifierData *md) mcmd->cache_file = NULL; mcmd->object_path[0] = '\0'; mcmd->read_flag = MOD_MESHSEQ_READ_ALL; + mcmd->velocity_scale = 1.0f; + mcmd->vertex_velocities = NULL; + mcmd->num_vertices = 0; mcmd->reader = NULL; mcmd->reader_object_path[0] = '\0'; @@ -91,6 +96,10 @@ static void freeData(ModifierData *md) mcmd->reader_object_path[0] = '\0'; BKE_cachefile_reader_free(mcmd->cache_file, &mcmd->reader); } + + if (mcmd->vertex_velocities) { + MEM_freeN(mcmd->vertex_velocities); + } } static bool isDisabled(const struct Scene *UNUSED(scene), @@ -154,6 +163,17 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * Mesh *result = ABC_read_mesh(mcmd->reader, ctx->object, mesh, time, &err_str, mcmd->read_flag); + mcmd->velocity_delta = 1.0f; + if (mcmd->cache_file->velocity_unit == CACHEFILE_VELOCITY_UNIT_SECOND) { + mcmd->velocity_delta /= FPS; + } + + mcmd->last_lookup_time = time; + + if (result != NULL) { + mcmd->num_vertices = result->totvert; + } + if (err_str) { BKE_modifier_set_error(md, "%s", err_str); } @@ -221,6 +241,8 @@ static void panel_draw(const bContext *C, Panel *panel) uiItemR(layout, &ptr, "read_data", UI_ITEM_R_EXPAND, NULL, ICON_NONE); } + uiItemR(layout, &ptr, "velocity_scale", 0, NULL, ICON_NONE); + modifier_panel_end(layout, &ptr); } diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c index 7039b24cfc6..66ab6b9e4db 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.c +++ b/source/blender/modifiers/intern/MOD_normal_edit.c @@ -472,7 +472,7 @@ static bool is_valid_target(NormalEditModifierData *enmd) if (enmd->mode == MOD_NORMALEDIT_MODE_RADIAL) { return true; } - else if ((enmd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) && enmd->target) { + if ((enmd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) && enmd->target) { return true; } BKE_modifier_set_error((ModifierData *)enmd, "Invalid target settings"); diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index 6374f081581..7b31886a220 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -59,7 +59,7 @@ #include "MOD_ui_common.h" #ifdef WITH_OCEANSIM -static void init_cache_data(Object *ob, struct OceanModifierData *omd) +static void init_cache_data(Object *ob, struct OceanModifierData *omd, const int resolution) { const char *relbase = BKE_modifier_path_relbase_from_global(ob); @@ -71,7 +71,7 @@ static void init_cache_data(Object *ob, struct OceanModifierData *omd) omd->chop_amount, omd->foam_coverage, omd->foam_fade, - omd->resolution); + resolution); } static void simulate_ocean_modifier(struct OceanModifierData *omd) @@ -87,7 +87,11 @@ static void initData(ModifierData *md) #ifdef WITH_OCEANSIM OceanModifierData *omd = (OceanModifierData *)md; + /* Render resolution */ omd->resolution = 7; + /* Display resolution for the non-render case */ + omd->viewport_resolution = 7; + omd->spatial_size = 50; omd->wave_alignment = 0.0; @@ -126,7 +130,7 @@ static void initData(ModifierData *md) omd->spraylayername[0] = '\0'; /* layer name empty by default */ omd->ocean = BKE_ocean_add(); - BKE_ocean_init_from_modifier(omd->ocean, omd); + BKE_ocean_init_from_modifier(omd->ocean, omd, omd->viewport_resolution); simulate_ocean_modifier(omd); #else /* WITH_OCEANSIM */ /* unused */ @@ -164,7 +168,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla tomd->oceancache = NULL; tomd->ocean = BKE_ocean_add(); - BKE_ocean_init_from_modifier(tomd->ocean, tomd); + BKE_ocean_init_from_modifier(tomd->ocean, tomd, tomd->viewport_resolution); simulate_ocean_modifier(tomd); #else /* WITH_OCEANSIM */ /* unused */ @@ -288,7 +292,7 @@ static void generate_ocean_geometry_uvs(void *__restrict userdata, } } -static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig) +static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, const int resolution) { Mesh *result; @@ -297,10 +301,10 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig) int num_verts; int num_polys; - const bool use_threading = omd->resolution > 4; + const bool use_threading = resolution > 4; - gogd.rx = omd->resolution * omd->resolution; - gogd.ry = omd->resolution * omd->resolution; + gogd.rx = resolution * resolution; + gogd.ry = resolution * resolution; gogd.res_x = gogd.rx * omd->repeat_x; gogd.res_y = gogd.ry * omd->repeat_y; @@ -362,6 +366,9 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes Mesh *result = NULL; OceanResult ocr; + const int resolution = (ctx->flag & MOD_APPLY_RENDER) ? omd->resolution : + omd->viewport_resolution; + MVert *mverts; int cfra_for_cache; @@ -383,7 +390,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes /* do ocean simulation */ if (omd->cached == true) { if (!omd->oceancache) { - init_cache_data(ob, omd); + init_cache_data(ob, omd, resolution); } BKE_ocean_simulate_cache(omd->oceancache, cfra_scene); } @@ -393,12 +400,12 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes * This function is only called on an original object when applying the modifier * using the 'Apply Modifier' button, and thus it is not called frequently for * simulation. */ - allocated_ocean |= BKE_ocean_ensure(omd); + allocated_ocean |= BKE_ocean_ensure(omd, resolution); simulate_ocean_modifier(omd); } if (omd->geometry_mode == MOD_OCEAN_GEOM_GENERATE) { - result = generate_ocean_geometry(omd, mesh); + result = generate_ocean_geometry(omd, mesh, resolution); BKE_mesh_ensure_normals(result); } else if (omd->geometry_mode == MOD_OCEAN_GEOM_DISPLACE) { @@ -558,7 +565,10 @@ static void panel_draw(const bContext *C, Panel *panel) uiItemR(sub, &ptr, "repeat_x", 0, IFACE_("Repeat X"), ICON_NONE); uiItemR(sub, &ptr, "repeat_y", 0, IFACE_("Y"), ICON_NONE); } - uiItemR(col, &ptr, "resolution", 0, NULL, ICON_NONE); + + sub = uiLayoutColumn(col, true); + uiItemR(sub, &ptr, "viewport_resolution", 0, IFACE_("Resolution Viewport"), ICON_NONE); + uiItemR(sub, &ptr, "resolution", 0, IFACE_("Render"), ICON_NONE); uiItemR(col, &ptr, "time", 0, NULL, ICON_NONE); diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index dd881f1ac74..d3d2f891929 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -198,12 +198,11 @@ static bool particle_skip(ParticleInstanceModifierData *pimd, ParticleSystem *ps if (maxp > minp) { return randp < minp || randp >= maxp; } - else if (maxp < minp) { + if (maxp < minp) { return randp < minp && randp >= maxp; } - else { - return true; - } + + return true; return false; } @@ -443,7 +442,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * float angle = 2.0f * M_PI * (pimd->rotation + pimd->random_rotation * (psys_frand(psys, 19957323 + p) - 0.5f)); - float eul[3] = {0.0f, 0.0f, angle}; + const float eul[3] = {0.0f, 0.0f, angle}; float rot[4]; eul_to_quat(rot, eul); diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index b9bb7add811..3bb7ecd43f4 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -301,7 +301,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * float totlen = len_v3(mtx_tx[3]); if (totlen != 0.0f) { - float zero[3] = {0.0f, 0.0f, 0.0f}; + const float zero[3] = {0.0f, 0.0f, 0.0f}; float cp[3]; screw_ofs = closest_to_line_v3(cp, mtx_tx[3], zero, axis_vec); } @@ -412,7 +412,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)totvert); if (mloopuv_layers_tot) { - float zero_co[3] = {0}; + const float zero_co[3] = {0}; plane_from_point_normal_v3(uv_axis_plane, zero_co, axis_vec); } diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c index a5f6be04a08..c40fbffc506 100644 --- a/source/blender/modifiers/intern/MOD_shrinkwrap.c +++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c @@ -96,7 +96,7 @@ static bool isDisabled(const struct Scene *UNUSED(scene), if (!smd->target || smd->target->type != OB_MESH) { return true; } - else if (smd->auxTarget && smd->auxTarget->type != OB_MESH) { + if (smd->auxTarget && smd->auxTarget->type != OB_MESH) { return true; } return false; diff --git a/source/blender/modifiers/intern/MOD_simulation.cc b/source/blender/modifiers/intern/MOD_simulation.cc index d9cc9840e08..92ad02ae34a 100644 --- a/source/blender/modifiers/intern/MOD_simulation.cc +++ b/source/blender/modifiers/intern/MOD_simulation.cc @@ -46,16 +46,11 @@ #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_pointcloud.h" +#include "BKE_screen.h" #include "BKE_simulation.h" #include "BLO_read_write.h" -/* SpaceType struct has a member called 'new' which obviously conflicts with C++ - * so temporarily redefining the new keyword to make it compile. */ -#define new extern_new -#include "BKE_screen.h" -#undef new - #include "UI_interface.h" #include "UI_resources.h" @@ -114,10 +109,12 @@ static PointCloud *modifyPointCloud(ModifierData *md, const float3 *positions = (const float3 *)CustomData_get_layer_named( &state->attributes, CD_PROP_FLOAT3, "Position"); + const float *radii = (const float *)CustomData_get_layer_named( + &state->attributes, CD_PROP_FLOAT, "Radius"); memcpy(pointcloud->co, positions, sizeof(float3) * state->tot_particles); for (int i = 0; i < state->tot_particles; i++) { - pointcloud->radius[i] = 0.03f; + pointcloud->radius[i] = radii[i]; } return pointcloud; @@ -131,6 +128,9 @@ static void panel_draw(const bContext *C, Panel *panel) PointerRNA ob_ptr; modifier_panel_get_property_pointers(C, panel, &ob_ptr, &ptr); + uiLayoutSetPropSep(layout, true); + uiLayoutSetPropDecorate(layout, false); + uiItemR(layout, &ptr, "simulation", 0, NULL, ICON_NONE); uiItemR(layout, &ptr, "data_path", 0, NULL, ICON_NONE); diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index 8f0174fe6d9..1bf07bdefbb 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -222,9 +222,8 @@ static bool skin_frame_find_contained_faces(const Frame *frame, BMFace *fill_fac if (diag) { return BM_edge_face_pair(diag, &fill_faces[0], &fill_faces[1]); } - else { - return false; - } + + return false; } /* Returns true if hull is successfully built, false otherwise */ @@ -460,7 +459,7 @@ static void node_frames_init(SkinNode *nf, int totframe) } static void create_frame( - Frame *frame, const float co[3], const float radius[2], float mat[3][3], float offset) + Frame *frame, const float co[3], const float radius[2], const float mat[3][3], float offset) { float rx[3], ry[3], rz[3]; int i; @@ -814,9 +813,8 @@ static int calc_edge_subdivisions(const MVert *mvert, if (v1_branch && v2_branch) { return 2; } - else { - return 0; - } + + return 0; } avg_radius = half_v2(evs[0]->radius) + half_v2(evs[1]->radius); diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.c b/source/blender/modifiers/intern/MOD_solidify_extrude.c index 7e5e4ecd9d3..7a4c45b73bd 100644 --- a/source/blender/modifiers/intern/MOD_solidify_extrude.c +++ b/source/blender/modifiers/intern/MOD_solidify_extrude.c @@ -182,7 +182,7 @@ static void mesh_calc_hq_normal(Mesh *mesh, float (*poly_nors)[3], float (*r_ver /* -------------------------------------------------------------------- */ /** \name Main Solidify Function * \{ */ - +/* NOLINTNEXTLINE: readability-function-size */ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { Mesh *result; diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c index 423a6b4458a..1e0269617ec 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c @@ -132,6 +132,7 @@ static int comp_float_int_pair(const void *a, const void *b) return (int)(x->angle > y->angle) - (int)(x->angle < y->angle); } +/* NOLINTNEXTLINE: readability-function-size */ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) @@ -479,12 +480,12 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, old_edge_vert_ref->edges_len++; break; } - else if (vm[orig_medge[edge].v1] == vs[1 - j]) { + if (vm[orig_medge[edge].v1] == vs[1 - j]) { invalid_edge_index = edge + 1; invalid_edge_reversed = (j == 0); break; } - else if (vm[orig_medge[edge].v2] == vs[1 - j]) { + if (vm[orig_medge[edge].v2] == vs[1 - j]) { invalid_edge_index = edge + 1; invalid_edge_reversed = (j == 1); break; @@ -936,7 +937,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } break; } - else if (edge->faces[0] == eg_track_faces[0]) { + if (edge->faces[0] == eg_track_faces[0]) { insert_at_start = true; eg_track_faces[0] = edge->faces[1]; found_edge = edge; @@ -945,14 +946,14 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } break; } - else if (edge->faces[1] != NULL) { + if (edge->faces[1] != NULL) { if (edge->faces[1] == eg_track_faces[1]) { insert_at_start = false; eg_track_faces[1] = edge->faces[0]; found_edge = edge; break; } - else if (edge->faces[1] == eg_track_faces[0]) { + if (edge->faces[1] == eg_track_faces[0]) { insert_at_start = true; eg_track_faces[0] = edge->faces[0]; found_edge = edge; diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c index 6a0e82a686b..962e93be215 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.c +++ b/source/blender/modifiers/intern/MOD_surfacedeform.c @@ -372,9 +372,8 @@ BLI_INLINE uint nearestVert(SDefBindCalcData *const data, const float point_co[3 len_squared_v3v3(point_co, data->targetCos[edge->v2])) { return edge->v1; } - else { - return edge->v2; - } + + return edge->v2; } BLI_INLINE int isPolyValid(const float coords[][2], const uint nr) @@ -450,7 +449,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, SDefBindWeightData *bwdata; SDefBindPoly *bpoly; - float world[3] = {0.0f, 0.0f, 1.0f}; + const float world[3] = {0.0f, 0.0f, 1.0f}; float avg_point_dist = 0.0f; float tot_weight = 0.0f; int inf_weight_flags = 0; @@ -1283,7 +1282,7 @@ static void surfacedeformModifier_do(ModifierData *md, BKE_modifier_set_error(md, "Vertices changed from %u to %u", smd->numverts, numverts); return; } - else if (smd->numpoly != tnumpoly) { + if (smd->numpoly != tnumpoly) { BKE_modifier_set_error(md, "Target polygons changed from %u to %u", smd->numpoly, tnumpoly); return; } diff --git a/source/blender/modifiers/intern/MOD_ui_common.c b/source/blender/modifiers/intern/MOD_ui_common.c index 01b9e972086..8de4b042eb3 100644 --- a/source/blender/modifiers/intern/MOD_ui_common.c +++ b/source/blender/modifiers/intern/MOD_ui_common.c @@ -179,12 +179,11 @@ static int modifier_is_simulation(ModifierData *md) return 1; } /* Particle Tab */ - else if (md->type == eModifierType_ParticleSystem) { + if (md->type == eModifierType_ParticleSystem) { return 2; } - else { - return 0; - } + + return 0; } static bool modifier_can_delete(ModifierData *md) diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index c6dff375109..179996d5acf 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -143,10 +143,9 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd, MEM_freeN(done); return; } - else { - /* if there are no UVs, default to local */ - texmapping = MOD_DISP_MAP_LOCAL; - } + + /* if there are no UVs, default to local */ + texmapping = MOD_DISP_MAP_LOCAL; } MVert *mv = mesh->mvert; diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c index 4aca3c28ed8..adc89f1b954 100644 --- a/source/blender/modifiers/intern/MOD_uvwarp.c +++ b/source/blender/modifiers/intern/MOD_uvwarp.c @@ -49,7 +49,9 @@ #include "MOD_ui_common.h" #include "MOD_util.h" -static void uv_warp_from_mat4_pair(float uv_dst[2], const float uv_src[2], float warp_mat[4][4]) +static void uv_warp_from_mat4_pair(float uv_dst[2], + const float uv_src[2], + const float warp_mat[4][4]) { float tuv[3] = {0.0f}; @@ -185,7 +187,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * mul_m4_m4m4(warp_mat, mat_cent, warp_mat); } - int shuf_indices[4] = {axis_u, axis_v, -1, 3}; + const int shuf_indices[4] = {axis_u, axis_v, -1, 3}; shuffle_m4(shuf_mat, shuf_indices); mul_m4_m4m4(warp_mat, shuf_mat, warp_mat); transpose_m4(shuf_mat); diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c index cbe774e91da..45252fed031 100644 --- a/source/blender/modifiers/intern/MOD_warp.c +++ b/source/blender/modifiers/intern/MOD_warp.c @@ -123,9 +123,8 @@ static bool dependsOnTime(ModifierData *md) if (wmd->texture) { return BKE_texture_dependsOnTime(wmd->texture); } - else { - return false; - } + + return false; } static void freeData(ModifierData *md) @@ -236,7 +235,7 @@ static void warpModifier_do(WarpModifierData *wmd, } if (wmd->curfalloff) { - BKE_curvemapping_initialize(wmd->curfalloff); + BKE_curvemapping_init(wmd->curfalloff); } invert_m4_m4(obinv, ob->obmat); diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c index 54d3aa46344..4ee1f9f669a 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.c +++ b/source/blender/modifiers/intern/MOD_weightvg_util.c @@ -83,7 +83,7 @@ void weightvg_do_map( } if (cmap && falloff_type == MOD_WVG_MAPPING_CURVE) { - BKE_curvemapping_initialize(cmap); + BKE_curvemapping_init(cmap); } /* Map each weight (vertex) to its new value, accordingly to the chosen mode. */ @@ -382,4 +382,4 @@ void weightvg_ui_common(const bContext *C, PointerRNA *ob_ptr, PointerRNA *ptr, } } } -}
\ No newline at end of file +} diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c index 8039856172a..6bb4f3dc1b5 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.c +++ b/source/blender/modifiers/intern/MOD_weightvgedit.c @@ -72,7 +72,7 @@ static void initData(ModifierData *md) wmd->default_weight = 0.0f; wmd->cmap_curve = BKE_curvemapping_add(1, 0.0, 0.0, 1.0, 1.0); - BKE_curvemapping_initialize(wmd->cmap_curve); + BKE_curvemapping_init(wmd->cmap_curve); wmd->rem_threshold = 0.01f; wmd->add_threshold = 0.01f; diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c index d1c618df68b..9821ead2340 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.c +++ b/source/blender/modifiers/intern/MOD_weightvgmix.c @@ -95,16 +95,16 @@ static float mix_weight(float weight, float weight2, char mix_mode) if (mix_mode == MOD_WVG_MIX_SET) { return weight2; } - else if (mix_mode == MOD_WVG_MIX_ADD) { + if (mix_mode == MOD_WVG_MIX_ADD) { return (weight + weight2); } - else if (mix_mode == MOD_WVG_MIX_SUB) { + if (mix_mode == MOD_WVG_MIX_SUB) { return (weight - weight2); } - else if (mix_mode == MOD_WVG_MIX_MUL) { + if (mix_mode == MOD_WVG_MIX_MUL) { return (weight * weight2); } - else if (mix_mode == MOD_WVG_MIX_DIV) { + if (mix_mode == MOD_WVG_MIX_DIV) { /* Avoid dividing by zero (or really small values). */ if (weight2 < 0.0f && weight2 > -MOD_WVG_ZEROFLOOR) { weight2 = -MOD_WVG_ZEROFLOOR; @@ -114,15 +114,14 @@ static float mix_weight(float weight, float weight2, char mix_mode) } return (weight / weight2); } - else if (mix_mode == MOD_WVG_MIX_DIF) { + if (mix_mode == MOD_WVG_MIX_DIF) { return (weight < weight2 ? weight2 - weight : weight - weight2); } - else if (mix_mode == MOD_WVG_MIX_AVG) { + if (mix_mode == MOD_WVG_MIX_AVG) { return (weight + weight2) * 0.5f; } - else { - return weight2; - } + + return weight2; } /************************************** diff --git a/source/blender/modifiers/intern/MOD_weld.c b/source/blender/modifiers/intern/MOD_weld.c index cf92da1b0e6..a89209f5dbb 100644 --- a/source/blender/modifiers/intern/MOD_weld.c +++ b/source/blender/modifiers/intern/MOD_weld.c @@ -1850,23 +1850,22 @@ static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContex &iter, wp, weld_mesh.wloop, mloop, weld_mesh.loop_map, group_buffer)) { continue; } - else { - if (wp->poly_dst != OUT_OF_CONTEXT) { - continue; - } - while (weld_iter_loop_of_poly_next(&iter)) { - customdata_weld(&mesh->ldata, &result->ldata, group_buffer, iter.group_len, loop_cur); - uint v = vert_final[iter.v]; - uint e = edge_final[iter.e]; - r_ml->v = v; - r_ml->e = e; - r_ml++; - loop_cur++; - if (iter.type) { - result->medge[e].flag &= ~ME_LOOSEEDGE; - } - BLI_assert((result->medge[e].flag & ME_LOOSEEDGE) == 0); + + if (wp->poly_dst != OUT_OF_CONTEXT) { + continue; + } + while (weld_iter_loop_of_poly_next(&iter)) { + customdata_weld(&mesh->ldata, &result->ldata, group_buffer, iter.group_len, loop_cur); + uint v = vert_final[iter.v]; + uint e = edge_final[iter.e]; + r_ml->v = v; + r_ml->e = e; + r_ml++; + loop_cur++; + if (iter.type) { + result->medge[e].flag &= ~ME_LOOSEEDGE; } + BLI_assert((result->medge[e].flag & ME_LOOSEEDGE) == 0); } } @@ -1885,24 +1884,24 @@ static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContex &iter, wp, weld_mesh.wloop, mloop, weld_mesh.loop_map, group_buffer)) { continue; } - else { - if (wp->poly_dst != OUT_OF_CONTEXT) { - continue; - } - while (weld_iter_loop_of_poly_next(&iter)) { - customdata_weld(&mesh->ldata, &result->ldata, group_buffer, iter.group_len, loop_cur); - uint v = vert_final[iter.v]; - uint e = edge_final[iter.e]; - r_ml->v = v; - r_ml->e = e; - r_ml++; - loop_cur++; - if (iter.type) { - result->medge[e].flag &= ~ME_LOOSEEDGE; - } - BLI_assert((result->medge[e].flag & ME_LOOSEEDGE) == 0); + + if (wp->poly_dst != OUT_OF_CONTEXT) { + continue; + } + while (weld_iter_loop_of_poly_next(&iter)) { + customdata_weld(&mesh->ldata, &result->ldata, group_buffer, iter.group_len, loop_cur); + uint v = vert_final[iter.v]; + uint e = edge_final[iter.e]; + r_ml->v = v; + r_ml->e = e; + r_ml++; + loop_cur++; + if (iter.type) { + result->medge[e].flag &= ~ME_LOOSEEDGE; } + BLI_assert((result->medge[e].flag & ME_LOOSEEDGE) == 0); } + r_mp->loopstart = loop_start; r_mp->totloop = loop_cur - loop_start; r_mp++; diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 80720f5206a..33b95d50cc0 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -136,6 +136,7 @@ set(SRC function/nodes/node_fn_float_compare.cc function/nodes/node_fn_group_instance_id.cc function/nodes/node_fn_object_transforms.cc + function/nodes/node_fn_random_float.cc function/nodes/node_fn_switch.cc function/node_function_util.cc @@ -160,7 +161,7 @@ set(SRC shader/nodes/node_shader_bsdf_velvet.c shader/nodes/node_shader_bump.c shader/nodes/node_shader_camera.c - shader/nodes/node_shader_clamp.c + shader/nodes/node_shader_clamp.cc shader/nodes/node_shader_common.c shader/nodes/node_shader_curves.c shader/nodes/node_shader_displacement.c @@ -232,10 +233,12 @@ set(SRC shader/node_shader_tree.c shader/node_shader_util.c + simulation/nodes/node_sim_age_reached_event.cc simulation/nodes/node_sim_common.cc simulation/nodes/node_sim_emit_particles.cc simulation/nodes/node_sim_execute_condition.cc simulation/nodes/node_sim_force.cc + simulation/nodes/node_sim_kill_particle.cc simulation/nodes/node_sim_multi_execute.cc simulation/nodes/node_sim_particle_attribute.cc simulation/nodes/node_sim_particle_birth_event.cc @@ -278,6 +281,7 @@ set(SRC intern/node_common.c intern/node_exec.c intern/node_socket.cc + intern/node_tree_dependencies.cc intern/node_tree_multi_function.cc intern/node_tree_ref.cc intern/node_util.c @@ -292,6 +296,7 @@ set(SRC NOD_composite.h NOD_derived_node_tree.hh NOD_function.h + NOD_node_tree_dependencies.hh NOD_node_tree_multi_function.hh NOD_node_tree_ref.hh NOD_shader.h diff --git a/source/blender/nodes/NOD_derived_node_tree.hh b/source/blender/nodes/NOD_derived_node_tree.hh index 205ba68dd0a..570b6cb704d 100644 --- a/source/blender/nodes/NOD_derived_node_tree.hh +++ b/source/blender/nodes/NOD_derived_node_tree.hh @@ -171,7 +171,6 @@ using NodeTreeRefMap = Map<bNodeTree *, std::unique_ptr<const NodeTreeRef>>; class DerivedNodeTree : NonCopyable, NonMovable { private: LinearAllocator<> allocator_; - bNodeTree *btree_; Vector<DNode *> nodes_by_id_; Vector<DGroupInput *> group_inputs_; Vector<DParentNode *> parent_nodes_; @@ -180,7 +179,7 @@ class DerivedNodeTree : NonCopyable, NonMovable { Vector<DInputSocket *> input_sockets_; Vector<DOutputSocket *> output_sockets_; - Map<const bNodeType *, Vector<DNode *>> nodes_by_type_; + MultiValueMap<const bNodeType *, DNode *> nodes_by_type_; public: DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_refs); @@ -482,13 +481,7 @@ inline Span<const DNode *> DerivedNodeTree::nodes_by_type(StringRefNull idname) inline Span<const DNode *> DerivedNodeTree::nodes_by_type(const bNodeType *nodetype) const { - const Vector<DNode *> *nodes = nodes_by_type_.lookup_ptr(nodetype); - if (nodes == nullptr) { - return {}; - } - else { - return *nodes; - } + return nodes_by_type_.lookup(nodetype); } inline Span<const DSocket *> DerivedNodeTree::sockets() const diff --git a/source/blender/nodes/NOD_function.h b/source/blender/nodes/NOD_function.h index 5391951debb..58a968151ac 100644 --- a/source/blender/nodes/NOD_function.h +++ b/source/blender/nodes/NOD_function.h @@ -26,6 +26,7 @@ void register_node_type_fn_switch(void); void register_node_type_fn_group_instance_id(void); void register_node_type_fn_combine_strings(void); void register_node_type_fn_object_transforms(void); +void register_node_type_fn_random_float(void); #ifdef __cplusplus } diff --git a/source/blender/nodes/NOD_node_tree_dependencies.hh b/source/blender/nodes/NOD_node_tree_dependencies.hh new file mode 100644 index 00000000000..13bb2bde2f3 --- /dev/null +++ b/source/blender/nodes/NOD_node_tree_dependencies.hh @@ -0,0 +1,76 @@ +/* + * 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. + */ + +#pragma once + +#include "BLI_vector_set.hh" + +#include "DNA_ID.h" +#include "DNA_object_types.h" + +struct bNodeTree; + +namespace blender::nodes { + +class NodeTreeDependencies { + private: + VectorSet<Object *> transform_deps_; + VectorSet<Object *> geometry_deps_; + VectorSet<ID *> id_deps_; + + public: + void add_transform_dependency(Object *object) + { + if (object == nullptr) { + return; + } + transform_deps_.add(object); + id_deps_.add(&object->id); + } + + void add_geometry_dependency(Object *object) + { + if (object == nullptr) { + return; + } + geometry_deps_.add(object); + id_deps_.add(&object->id); + } + + bool depends_on(ID *id) const + { + return id_deps_.contains(id); + } + + Span<Object *> transform_dependencies() + { + return transform_deps_; + } + + Span<Object *> geometry_dependencies() + { + return geometry_deps_; + } + + Span<ID *> id_dependencies() + { + return id_deps_; + } +}; + +NodeTreeDependencies find_node_tree_dependencies(bNodeTree &ntree); + +} // namespace blender::nodes diff --git a/source/blender/nodes/NOD_node_tree_multi_function.hh b/source/blender/nodes/NOD_node_tree_multi_function.hh index f5cb827dc4f..cbd7a47f090 100644 --- a/source/blender/nodes/NOD_node_tree_multi_function.hh +++ b/source/blender/nodes/NOD_node_tree_multi_function.hh @@ -250,19 +250,17 @@ class MFNetworkBuilderBase { */ class SocketMFNetworkBuilder : public MFNetworkBuilderBase { private: - const DSocket *dsocket_ = nullptr; - const DGroupInput *group_input_ = nullptr; bNodeSocket *bsocket_; fn::MFOutputSocket *built_socket_ = nullptr; public: SocketMFNetworkBuilder(CommonMFNetworkBuilderData &common, const DSocket &dsocket) - : MFNetworkBuilderBase(common), dsocket_(&dsocket), bsocket_(dsocket.bsocket()) + : MFNetworkBuilderBase(common), bsocket_(dsocket.bsocket()) { } SocketMFNetworkBuilder(CommonMFNetworkBuilderData &common, const DGroupInput &group_input) - : MFNetworkBuilderBase(common), group_input_(&group_input), bsocket_(group_input.bsocket()) + : MFNetworkBuilderBase(common), bsocket_(group_input.bsocket()) { } diff --git a/source/blender/nodes/NOD_node_tree_ref.hh b/source/blender/nodes/NOD_node_tree_ref.hh index f18a20d6df9..6d1c239d2cb 100644 --- a/source/blender/nodes/NOD_node_tree_ref.hh +++ b/source/blender/nodes/NOD_node_tree_ref.hh @@ -46,6 +46,7 @@ #include "BLI_array.hh" #include "BLI_linear_allocator.hh" #include "BLI_map.hh" +#include "BLI_multi_value_map.hh" #include "BLI_string_ref.hh" #include "BLI_timeit.hh" #include "BLI_utility_mixins.hh" @@ -161,7 +162,7 @@ class NodeTreeRef : NonCopyable, NonMovable { Vector<SocketRef *> sockets_by_id_; Vector<InputSocketRef *> input_sockets_; Vector<OutputSocketRef *> output_sockets_; - Map<const bNodeType *, Vector<NodeRef *>> nodes_by_type_; + MultiValueMap<const bNodeType *, NodeRef *> nodes_by_type_; public: NodeTreeRef(bNodeTree *btree); @@ -410,13 +411,7 @@ inline Span<const NodeRef *> NodeTreeRef::nodes_by_type(StringRefNull idname) co inline Span<const NodeRef *> NodeTreeRef::nodes_by_type(const bNodeType *nodetype) const { - const Vector<NodeRef *> *nodes = nodes_by_type_.lookup_ptr(nodetype); - if (nodes == nullptr) { - return {}; - } - else { - return *nodes; - } + return nodes_by_type_.lookup(nodetype); } inline Span<const SocketRef *> NodeTreeRef::sockets() const diff --git a/source/blender/nodes/NOD_simulation.h b/source/blender/nodes/NOD_simulation.h index d769bbce204..266ded997c6 100644 --- a/source/blender/nodes/NOD_simulation.h +++ b/source/blender/nodes/NOD_simulation.h @@ -38,6 +38,8 @@ void register_node_type_sim_particle_mesh_collision_event(void); void register_node_type_sim_emit_particles(void); void register_node_type_sim_time(void); void register_node_type_sim_particle_attribute(void); +void register_node_type_sim_age_reached_event(void); +void register_node_type_sim_kill_particle(void); #ifdef __cplusplus } diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 31ce3f81450..7922a73902c 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -270,6 +270,8 @@ DefNode(SimulationNode, SIM_NODE_PARTICLE_MESH_COLLISION_EVENT, 0, "PARTIC DefNode(SimulationNode, SIM_NODE_EMIT_PARTICLES, 0, "EMIT_PARTICLES", EmitParticles, "Emit Particles", "") DefNode(SimulationNode, SIM_NODE_TIME, def_sim_time, "TIME", Time, "Time", "") DefNode(SimulationNode, SIM_NODE_PARTICLE_ATTRIBUTE, def_sim_particle_attribute, "PARTICLE_ATTRIBUTE", ParticleAttribute, "Particle Attribute", "") +DefNode(SimulationNode, SIM_NODE_AGE_REACHED_EVENT, 0, "AGE_REACHED_EVENT", AgeReachedEvent, "Age Reached Event", "") +DefNode(SimulationNode, SIM_NODE_KILL_PARTICLE, 0, "KILL_PARTICLE", KillParticle, "Kill Particle", "") DefNode(FunctionNode, FN_NODE_BOOLEAN_MATH, def_boolean_math, "BOOLEAN_MATH", BooleanMath, "Boolean Math", "") DefNode(FunctionNode, FN_NODE_FLOAT_COMPARE, def_float_compare, "FLOAT_COMPARE", FloatCompare, "Float Compare", "") @@ -277,7 +279,7 @@ DefNode(FunctionNode, FN_NODE_SWITCH, def_fn_switch, "SWITCH", DefNode(FunctionNode, FN_NODE_GROUP_INSTANCE_ID, 0, "GROUP_INSTANCE_ID", GroupInstanceID, "Group Instance ID", "") DefNode(FunctionNode, FN_NODE_COMBINE_STRINGS, 0, "COMBINE_STRINGS", CombineStrings, "Combine Strings", "") DefNode(FunctionNode, FN_NODE_OBJECT_TRANSFORMS, 0, "OBJECT_TRANSFORMS", ObjectTransforms, "Object Transforms", "") - +DefNode(FunctionNode, FN_NODE_RANDOM_FLOAT, 0, "RANDOM_FLOAT", RandomFloat, "Random Float", "") /* undefine macros */ diff --git a/source/blender/nodes/function/nodes/node_fn_random_float.cc b/source/blender/nodes/function/nodes/node_fn_random_float.cc new file mode 100644 index 00000000000..2ee0830637a --- /dev/null +++ b/source/blender/nodes/function/nodes/node_fn_random_float.cc @@ -0,0 +1,89 @@ +/* + * 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. + */ + +#include "node_function_util.hh" + +#include "BLI_hash.h" + +static bNodeSocketTemplate fn_node_random_float_in[] = { + {SOCK_FLOAT, N_("Min"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f, PROP_NONE}, + {SOCK_FLOAT, N_("Max"), 1.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f, PROP_NONE}, + {SOCK_INT, N_("Seed")}, + {-1, ""}, +}; + +static bNodeSocketTemplate fn_node_random_float_out[] = { + {SOCK_FLOAT, N_("Value")}, + {-1, ""}, +}; + +class RandomFloatFunction : public blender::fn::MultiFunction { + private: + uint32_t function_seed_; + + public: + RandomFloatFunction(uint32_t function_seed) : function_seed_(function_seed) + { + blender::fn::MFSignatureBuilder signature = this->get_builder("Random float"); + signature.single_input<float>("Min"); + signature.single_input<float>("Max"); + signature.single_input<int>("Seed"); + signature.single_output<float>("Value"); + } + + void call(blender::IndexMask mask, + blender::fn::MFParams params, + blender::fn::MFContext UNUSED(context)) const override + { + blender::fn::VSpan<float> min_values = params.readonly_single_input<float>(0, "Min"); + blender::fn::VSpan<float> max_values = params.readonly_single_input<float>(1, "Max"); + blender::fn::VSpan<int> seeds = params.readonly_single_input<int>(2, "Seed"); + blender::MutableSpan<float> values = params.uninitialized_single_output<float>(3, "Value"); + + for (int64_t i : mask) { + const float min_value = min_values[i]; + const float max_value = max_values[i]; + const int seed = seeds[i]; + const float value = BLI_hash_int_01((uint32_t)seed ^ function_seed_); + values[i] = value * (max_value - min_value) + min_value; + } + } +}; + +static void fn_node_random_float_expand_in_mf_network( + blender::nodes::NodeMFNetworkBuilder &builder) +{ + uint32_t function_seed = 1746872341u; + const blender::nodes::DNode &node = builder.dnode(); + const blender::DefaultHash<blender::StringRefNull> hasher; + function_seed = 33 * function_seed + hasher(node.name()); + for (const blender::nodes::DParentNode *parent = node.parent(); parent != nullptr; + parent = parent->parent()) { + function_seed = 33 * function_seed + hasher(parent->node_ref().name()); + } + + builder.construct_and_set_matching_fn<RandomFloatFunction>(function_seed); +} + +void register_node_type_fn_random_float() +{ + static bNodeType ntype; + + fn_node_type_base(&ntype, FN_NODE_RANDOM_FLOAT, "Random Float", 0, 0); + node_type_socket_templates(&ntype, fn_node_random_float_in, fn_node_random_float_out); + ntype.expand_in_mf_network = fn_node_random_float_expand_in_mf_network; + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/intern/derived_node_tree.cc b/source/blender/nodes/intern/derived_node_tree.cc index b7c78cb1499..bcef8c33a3b 100644 --- a/source/blender/nodes/intern/derived_node_tree.cc +++ b/source/blender/nodes/intern/derived_node_tree.cc @@ -28,7 +28,7 @@ static const NodeTreeRef &get_tree_ref(NodeTreeRefMap &node_tree_refs, bNodeTree [&]() { return std::make_unique<NodeTreeRef>(btree); }); } -DerivedNodeTree::DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_refs) : btree_(btree) +DerivedNodeTree::DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_refs) { const NodeTreeRef &main_tree_ref = get_tree_ref(node_tree_refs, btree); @@ -321,7 +321,7 @@ BLI_NOINLINE void DerivedNodeTree::store_in_this_and_init_ids( node->id_ = node_index; const bNodeType *nodetype = node->node_ref_->bnode()->typeinfo; - nodes_by_type_.lookup_or_add_default(nodetype).append(node); + nodes_by_type_.add(nodetype, node); for (DInputSocket *socket : node->inputs_) { socket->id_ = sockets_by_id_.append_and_get_index(socket); diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index 439e41b963b..aa1f23163a0 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -84,13 +84,11 @@ bool node_group_poll_instance(bNode *node, bNodeTree *nodetree) if (grouptree) { return nodeGroupPoll(nodetree, grouptree); } - else { - return true; /* without a linked node tree, group node is always ok */ - } - } - else { - return false; + + return true; /* without a linked node tree, group node is always ok */ } + + return false; } int nodeGroupPoll(bNodeTree *nodetree, bNodeTree *grouptree) diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc index 04d86f5b44e..0dfae7424cb 100644 --- a/source/blender/nodes/intern/node_socket.cc +++ b/source/blender/nodes/intern/node_socket.cc @@ -634,10 +634,10 @@ static bNodeSocketType *make_socket_type_string() class ObjectSocketMultiFunction : public blender::fn::MultiFunction { private: - const Object *object_; + Object *object_; public: - ObjectSocketMultiFunction(const Object *object) : object_(object) + ObjectSocketMultiFunction(Object *object) : object_(object) { blender::fn::MFSignatureBuilder signature = this->get_builder("Object Socket"); signature.depends_on_context(); @@ -679,7 +679,7 @@ static bNodeSocketType *make_socket_type_object() return blender::fn::MFDataType::ForSingle<blender::bke::PersistentObjectHandle>(); }; socktype->expand_in_mf_network = [](blender::nodes::SocketMFNetworkBuilder &builder) { - const Object *object = builder.socket_default_value<bNodeSocketValueObject>()->value; + Object *object = builder.socket_default_value<bNodeSocketValueObject>()->value; builder.construct_generator_fn<ObjectSocketMultiFunction>(object); }; return socktype; diff --git a/source/blender/nodes/intern/node_tree_dependencies.cc b/source/blender/nodes/intern/node_tree_dependencies.cc new file mode 100644 index 00000000000..efe75a10f7e --- /dev/null +++ b/source/blender/nodes/intern/node_tree_dependencies.cc @@ -0,0 +1,57 @@ +/* + * 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. + */ + +#include "NOD_node_tree_dependencies.hh" + +#include "DNA_node_types.h" + +#include "BKE_node.h" + +namespace blender::nodes { + +static void add_dependencies_of_node_tree(bNodeTree &ntree, NodeTreeDependencies &r_dependencies) +{ + /* TODO: Do a bit more sophisticated parsing to see which dependencies are really required. */ + LISTBASE_FOREACH (bNode *, node, &ntree.nodes) { + LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) { + if (socket->type == SOCK_OBJECT) { + Object *object = ((bNodeSocketValueObject *)socket->default_value)->value; + if (object != nullptr) { + r_dependencies.add_transform_dependency(object); + if (object->type == OB_MESH) { + r_dependencies.add_geometry_dependency(object); + } + } + } + } + + if (node->type == NODE_GROUP) { + bNodeTree *group = (bNodeTree *)node->id; + if (group != nullptr) { + add_dependencies_of_node_tree(*group, r_dependencies); + } + } + } +} + +NodeTreeDependencies find_node_tree_dependencies(bNodeTree &ntree) +{ + NodeTreeDependencies dependencies; + add_dependencies_of_node_tree(ntree, dependencies); + return dependencies; +} + +} // namespace blender::nodes diff --git a/source/blender/nodes/intern/node_tree_multi_function.cc b/source/blender/nodes/intern/node_tree_multi_function.cc index 82842c4ef32..09a80fd23f4 100644 --- a/source/blender/nodes/intern/node_tree_multi_function.cc +++ b/source/blender/nodes/intern/node_tree_multi_function.cc @@ -176,13 +176,12 @@ static fn::MFOutputSocket *try_find_origin(CommonMFNetworkBuilderData &common, } return nullptr; } - else { - const DGroupInput &from_group_input = *from_group_inputs[0]; - if (is_multi_function_data_socket(from_group_input.bsocket())) { - return &common.network_map.lookup(from_group_input); - } - return nullptr; + + const DGroupInput &from_group_input = *from_group_inputs[0]; + if (is_multi_function_data_socket(from_group_input.bsocket())) { + return &common.network_map.lookup(from_group_input); } + return nullptr; } using ImplicitConversionsMap = diff --git a/source/blender/nodes/intern/node_tree_ref.cc b/source/blender/nodes/intern/node_tree_ref.cc index 186ca750f10..47669bc5ca2 100644 --- a/source/blender/nodes/intern/node_tree_ref.cc +++ b/source/blender/nodes/intern/node_tree_ref.cc @@ -79,7 +79,7 @@ NodeTreeRef::NodeTreeRef(bNodeTree *btree) : btree_(btree) for (NodeRef *node : nodes_by_id_) { const bNodeType *nodetype = node->bnode_->typeinfo; - nodes_by_type_.lookup_or_add_default(nodetype).append(node); + nodes_by_type_.add(nodetype, node); } } diff --git a/source/blender/nodes/intern/node_util.c b/source/blender/nodes/intern/node_util.c index 9efbdc079e6..b2309abe32e 100644 --- a/source/blender/nodes/intern/node_util.c +++ b/source/blender/nodes/intern/node_util.c @@ -73,7 +73,7 @@ void *node_initexec_curves(bNodeExecContext *UNUSED(context), bNode *node, bNodeInstanceKey UNUSED(key)) { - BKE_curvemapping_initialize(node->storage); + BKE_curvemapping_init(node->storage); return NULL; /* unused return */ } diff --git a/source/blender/nodes/shader/nodes/node_shader_attribute.c b/source/blender/nodes/shader/nodes/node_shader_attribute.c index 6b5d46e250b..116bc181997 100644 --- a/source/blender/nodes/shader/nodes/node_shader_attribute.c +++ b/source/blender/nodes/shader/nodes/node_shader_attribute.c @@ -55,17 +55,16 @@ static int node_shader_gpu_attribute(GPUMaterial *mat, return 1; } - else { - GPUNodeLink *cd_attr = GPU_attribute(mat, CD_AUTO_FROM_NAME, attr->name); - GPU_stack_link(mat, node, "node_attribute", in, out, cd_attr); - /* for each output. */ - for (int i = 0; sh_node_attribute_out[i].type != -1; i++) { - node_shader_gpu_bump_tex_coord(mat, node, &out[i].link); - } + GPUNodeLink *cd_attr = GPU_attribute(mat, CD_AUTO_FROM_NAME, attr->name); + GPU_stack_link(mat, node, "node_attribute", in, out, cd_attr); - return 1; + /* for each output. */ + for (int i = 0; sh_node_attribute_out[i].type != -1; i++) { + node_shader_gpu_bump_tex_coord(mat, node, &out[i].link); } + + return 1; } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_clamp.c b/source/blender/nodes/shader/nodes/node_shader_clamp.cc index 808f9686f0a..d3a893e1d76 100644 --- a/source/blender/nodes/shader/nodes/node_shader_clamp.c +++ b/source/blender/nodes/shader/nodes/node_shader_clamp.cc @@ -50,6 +50,29 @@ static int gpu_shader_clamp(GPUMaterial *mat, GPU_stack_link(mat, node, "clamp_range", in, out); } +static void sh_node_clamp_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder &builder) +{ + static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, float> minmax_fn{ + "Clamp (Min Max)", + [](float value, float min, float max) { return std::min(std::max(value, min), max); }}; + static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, float> range_fn{ + "Clamp (Range)", [](float value, float a, float b) { + if (a < b) { + return clamp_f(value, a, b); + } + + return clamp_f(value, b, a); + }}; + + int clamp_type = builder.bnode().custom1; + if (clamp_type == NODE_CLAMP_MINMAX) { + builder.set_matching_fn(minmax_fn); + } + else { + builder.set_matching_fn(range_fn); + } +} + void register_node_type_sh_clamp(void) { static bNodeType ntype; @@ -58,6 +81,7 @@ void register_node_type_sh_clamp(void) node_type_socket_templates(&ntype, sh_node_clamp_in, sh_node_clamp_out); node_type_init(&ntype, node_shader_init_clamp); node_type_gpu(&ntype, gpu_shader_clamp); + ntype.expand_in_mf_network = sh_node_clamp_expand_in_mf_network; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c index 68f252cb092..42299a193e2 100644 --- a/source/blender/nodes/shader/nodes/node_shader_curves.c +++ b/source/blender/nodes/shader/nodes/node_shader_curves.c @@ -168,7 +168,7 @@ static int gpu_shader_curve_rgb(GPUMaterial *mat, CurveMapping *cumap = node->storage; - BKE_curvemapping_initialize(cumap); + BKE_curvemapping_init(cumap); BKE_curvemapping_table_RGBA(cumap, &array, &size); GPUNodeLink *tex = GPU_color_band(mat, size, array, &layer); @@ -215,20 +215,19 @@ static int gpu_shader_curve_rgb(GPUMaterial *mat, GPU_uniform(range_rgba), GPU_uniform(ext_rgba[3])); } - else { - return GPU_stack_link(mat, - node, - "curves_rgb", - in, - out, - tex, - GPU_constant(&layer), - GPU_uniform(range_rgba), - GPU_uniform(ext_rgba[0]), - GPU_uniform(ext_rgba[1]), - GPU_uniform(ext_rgba[2]), - GPU_uniform(ext_rgba[3])); - } + + return GPU_stack_link(mat, + node, + "curves_rgb", + in, + out, + tex, + GPU_constant(&layer), + GPU_uniform(range_rgba), + GPU_uniform(ext_rgba[0]), + GPU_uniform(ext_rgba[1]), + GPU_uniform(ext_rgba[2]), + GPU_uniform(ext_rgba[3])); } void register_node_type_sh_curve_rgb(void) diff --git a/source/blender/nodes/shader/nodes/node_shader_displacement.c b/source/blender/nodes/shader/nodes/node_shader_displacement.c index 22fbe4e4da6..649aad370c0 100644 --- a/source/blender/nodes/shader/nodes/node_shader_displacement.c +++ b/source/blender/nodes/shader/nodes/node_shader_displacement.c @@ -64,10 +64,9 @@ static int gpu_shader_displacement(GPUMaterial *mat, 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)); - } + + return GPU_stack_link( + mat, node, "node_displacement_world", in, out, GPU_builtin(GPU_OBJECT_MATRIX)); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_geometry.c b/source/blender/nodes/shader/nodes/node_shader_geometry.c index deb0ee9037c..f66633e64c8 100644 --- a/source/blender/nodes/shader/nodes/node_shader_geometry.c +++ b/source/blender/nodes/shader/nodes/node_shader_geometry.c @@ -42,9 +42,12 @@ static int node_shader_gpu_geometry(GPUMaterial *mat, { /* HACK: Don't request GPU_BARYCENTRIC_TEXCO if not used because it will * trigger the use of geometry shader (and the performance penalty it implies). */ - float val[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float val[4] = {0.0f, 0.0f, 0.0f, 0.0f}; GPUNodeLink *bary_link = (!out[5].hasoutput) ? GPU_constant(val) : GPU_builtin(GPU_BARYCENTRIC_TEXCO); + if (out[5].hasoutput) { + GPU_material_flag_set(mat, GPU_MATFLAG_BARYCENTRIC); + } /* Opti: don't request orco if not needed. */ GPUNodeLink *orco_link = (!out[2].hasoutput) ? GPU_constant(val) : GPU_attribute(mat, CD_ORCO, ""); diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.c b/source/blender/nodes/shader/nodes/node_shader_mapping.c index 6750acf5ee1..774e7fed029 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mapping.c +++ b/source/blender/nodes/shader/nodes/node_shader_mapping.c @@ -53,9 +53,8 @@ static int gpu_shader_mapping(GPUMaterial *mat, if (node->custom1 < ARRAY_SIZE(names) && names[node->custom1]) { return GPU_stack_link(mat, node, names[node->custom1], in, out); } - else { - return 0; - } + + return 0; } static void node_shader_update_mapping(bNodeTree *UNUSED(ntree), bNode *node) diff --git a/source/blender/nodes/shader/nodes/node_shader_math.cc b/source/blender/nodes/shader/nodes/node_shader_math.cc index c7035da8c70..e7bbadfbcb0 100644 --- a/source/blender/nodes/shader/nodes/node_shader_math.cc +++ b/source/blender/nodes/shader/nodes/node_shader_math.cc @@ -141,9 +141,8 @@ static int gpu_shader_math(GPUMaterial *mat, } return ret; } - else { - return 0; - } + + return 0; } static const blender::fn::MultiFunction &get_base_multi_function( diff --git a/source/blender/nodes/shader/nodes/node_shader_mixRgb.c b/source/blender/nodes/shader/nodes/node_shader_mixRgb.c index 93e88664d1a..8725122b12c 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mixRgb.c +++ b/source/blender/nodes/shader/nodes/node_shader_mixRgb.c @@ -91,16 +91,15 @@ static int gpu_shader_mix_rgb(GPUMaterial *mat, if (node->custom1 < ARRAY_SIZE(names) && names[node->custom1]) { int ret = GPU_stack_link(mat, node, names[node->custom1], in, out); if (ret && node->custom2 & SHD_MIXRGB_CLAMP) { - float min[3] = {0.0f, 0.0f, 0.0f}; - float max[3] = {1.0f, 1.0f, 1.0f}; + const float min[3] = {0.0f, 0.0f, 0.0f}; + const float max[3] = {1.0f, 1.0f, 1.0f}; GPU_link( mat, "clamp_color", out[0].link, GPU_constant(min), GPU_constant(max), &out[0].link); } return ret; } - else { - return 0; - } + + return 0; } void register_node_type_sh_mix_rgb(void) diff --git a/source/blender/nodes/shader/nodes/node_shader_tangent.c b/source/blender/nodes/shader/nodes/node_shader_tangent.c index e8bedde0a62..2c12bf9bc01 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tangent.c +++ b/source/blender/nodes/shader/nodes/node_shader_tangent.c @@ -45,28 +45,27 @@ static int node_shader_gpu_tangent(GPUMaterial *mat, return GPU_stack_link( mat, node, "node_tangentmap", in, out, GPU_attribute(mat, CD_TANGENT, attr->uv_map)); } - else { - GPUNodeLink *orco = GPU_attribute(mat, CD_ORCO, ""); - if (attr->axis == SHD_TANGENT_AXIS_X) { - GPU_link(mat, "tangent_orco_x", orco, &orco); - } - else if (attr->axis == SHD_TANGENT_AXIS_Y) { - GPU_link(mat, "tangent_orco_y", orco, &orco); - } - else { - GPU_link(mat, "tangent_orco_z", orco, &orco); - } + GPUNodeLink *orco = GPU_attribute(mat, CD_ORCO, ""); - return GPU_stack_link(mat, - node, - "node_tangent", - in, - out, - GPU_builtin(GPU_WORLD_NORMAL), - orco, - GPU_builtin(GPU_OBJECT_MATRIX)); + if (attr->axis == SHD_TANGENT_AXIS_X) { + GPU_link(mat, "tangent_orco_x", orco, &orco); + } + else if (attr->axis == SHD_TANGENT_AXIS_Y) { + GPU_link(mat, "tangent_orco_y", orco, &orco); } + else { + GPU_link(mat, "tangent_orco_z", orco, &orco); + } + + return GPU_stack_link(mat, + node, + "node_tangent", + in, + out, + GPU_builtin(GPU_WORLD_NORMAL), + orco, + GPU_builtin(GPU_OBJECT_MATRIX)); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c index 0cf4b51f307..38e79ebe94d 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c @@ -19,8 +19,6 @@ #include "../node_shader_util.h" -#include "GPU_draw.h" - /* **************** OUTPUT ******************** */ static bNodeSocketTemplate sh_node_tex_environment_in[] = { @@ -59,7 +57,8 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, NodeTexImage *tex_original = node_original->storage; ImageUser *iuser = &tex_original->iuser; eGPUSamplerState sampler = GPU_SAMPLER_REPEAT | GPU_SAMPLER_ANISO | GPU_SAMPLER_FILTER; - if (GPU_get_mipmap()) { + /* TODO(fclem) For now assume mipmap is always enabled. */ + if (true) { sampler |= GPU_SAMPLER_MIPMAP; } 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 cbda72cd228..1a78d2f5bf2 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c @@ -19,8 +19,6 @@ #include "../node_shader_util.h" -#include "GPU_draw.h" - /* **************** OUTPUT ******************** */ static bNodeSocketTemplate sh_node_tex_image_in[] = { @@ -95,7 +93,8 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, if (tex->interpolation != SHD_INTERP_CLOSEST) { sampler_state |= GPU_SAMPLER_ANISO | GPU_SAMPLER_FILTER; - sampler_state |= GPU_get_mipmap() ? GPU_SAMPLER_MIPMAP : 0; + /* TODO(fclem) For now assume mipmap is always enabled. */ + sampler_state |= true ? GPU_SAMPLER_MIPMAP : 0; } const bool use_cubic = ELEM(tex->interpolation, SHD_INTERP_CUBIC, SHD_INTERP_SMART); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_sky.c b/source/blender/nodes/shader/nodes/node_shader_tex_sky.c index 94ffbbe0c55..9ef05d781bd 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_sky.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_sky.c @@ -170,7 +170,7 @@ static int node_shader_gpu_tex_sky(GPUMaterial *mat, GPU_uniform(xyz_to_rgb.g), GPU_uniform(xyz_to_rgb.b)); } - else if (tex->sky_model == 1) { + if (tex->sky_model == 1) { /* Hosek / Wilkie */ sun_angles[0] = fmin(M_PI_2, sun_angles[0]); /* clamp to horizon */ SKY_ArHosekSkyModelState *sky_state = SKY_arhosek_xyz_skymodelstate_alloc_init( @@ -210,9 +210,8 @@ static int node_shader_gpu_tex_sky(GPUMaterial *mat, GPU_uniform(xyz_to_rgb.g), GPU_uniform(xyz_to_rgb.b)); } - else { - return GPU_stack_link(mat, node, "node_tex_sky_nishita", in, out); - } + + return GPU_stack_link(mat, node, "node_tex_sky_nishita", in, out); } static void node_shader_update_sky(bNodeTree *UNUSED(ntree), bNode *node) diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.c b/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.c index 817ccdc8b6a..56ecb6d4476 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.c @@ -54,9 +54,8 @@ static int gpu_shader_tex_white_noise(GPUMaterial *mat, if (node->custom1 < ARRAY_SIZE(names) && names[node->custom1]) { return GPU_stack_link(mat, node, names[node->custom1], in, out); } - else { - return 0; - } + + return 0; } static void node_shader_update_tex_white_noise(bNodeTree *UNUSED(ntree), bNode *node) diff --git a/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc b/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc index 7f712b0db40..7b4e568e923 100644 --- a/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc +++ b/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc @@ -121,9 +121,8 @@ static int gpu_shader_valtorgb(GPUMaterial *mat, if (coba->ipotype == COLBAND_INTERP_CONSTANT) { return GPU_stack_link(mat, node, "valtorgb_nearest", in, out, tex, GPU_constant(&layer)); } - else { - return GPU_stack_link(mat, node, "valtorgb", in, out, tex, GPU_constant(&layer)); - } + + return GPU_stack_link(mat, node, "valtorgb", in, out, tex, GPU_constant(&layer)); } class ColorBandFunction : public blender::fn::MultiFunction { diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c index c9f79293328..0e82f346529 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c +++ b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c @@ -55,13 +55,12 @@ static int gpu_shader_vector_displacement(GPUMaterial *mat, GPU_builtin(GPU_OBJECT_MATRIX), GPU_builtin(GPU_VIEW_MATRIX)); } - else if (node->custom1 == SHD_SPACE_OBJECT) { + 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); - } + + return GPU_stack_link(mat, node, "node_vector_displacement_world", in, out); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc index c18ad8bb244..e8396c7cfc1 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc +++ b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc @@ -103,9 +103,8 @@ static int gpu_shader_vector_math(GPUMaterial *mat, if (name != nullptr) { return GPU_stack_link(mat, node, name, in, out); } - else { - return 0; - } + + return 0; } static void node_shader_update_vector_math(bNodeTree *UNUSED(ntree), bNode *node) diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.c b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.c index 46a6ff1f353..b2132c59cde 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.c +++ b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.c @@ -53,9 +53,8 @@ static int gpu_shader_vector_rotate(GPUMaterial *mat, float invert = (node->custom2) ? -1.0 : 1.0; return GPU_stack_link(mat, node, names[node->custom1], in, out, GPU_constant(&invert)); } - else { - return 0; - } + + return 0; } static void node_shader_update_vector_rotate(bNodeTree *UNUSED(ntree), bNode *node) diff --git a/source/blender/nodes/shader/nodes/node_shader_wireframe.c b/source/blender/nodes/shader/nodes/node_shader_wireframe.c index e1da1cd34e4..37e60ddb205 100644 --- a/source/blender/nodes/shader/nodes/node_shader_wireframe.c +++ b/source/blender/nodes/shader/nodes/node_shader_wireframe.c @@ -36,20 +36,20 @@ static int node_shader_gpu_wireframe(GPUMaterial *mat, GPUNodeStack *in, GPUNodeStack *out) { + GPU_material_flag_set(mat, GPU_MATFLAG_BARYCENTRIC); /* node->custom1 is use_pixel_size */ if (node->custom1) { return GPU_stack_link( mat, node, "node_wireframe_screenspace", in, out, GPU_builtin(GPU_BARYCENTRIC_TEXCO)); } - else { - return GPU_stack_link(mat, - node, - "node_wireframe", - in, - out, - GPU_builtin(GPU_BARYCENTRIC_TEXCO), - GPU_builtin(GPU_BARYCENTRIC_DIST)); - } + + return GPU_stack_link(mat, + node, + "node_wireframe", + in, + out, + GPU_builtin(GPU_BARYCENTRIC_TEXCO), + GPU_builtin(GPU_BARYCENTRIC_DIST)); } /* node type definition */ diff --git a/source/blender/nodes/simulation/nodes/node_sim_age_reached_event.cc b/source/blender/nodes/simulation/nodes/node_sim_age_reached_event.cc new file mode 100644 index 00000000000..add8c4eba4d --- /dev/null +++ b/source/blender/nodes/simulation/nodes/node_sim_age_reached_event.cc @@ -0,0 +1,38 @@ +/* + * 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. + */ + +#include "node_simulation_util.h" + +static bNodeSocketTemplate sim_node_age_reached_event_in[] = { + {SOCK_FLOAT, N_("Age"), 3, 0, 0, 0, 0, 10000000}, + {SOCK_CONTROL_FLOW, N_("Execute")}, + {-1, ""}, +}; + +static bNodeSocketTemplate sim_node_age_reached_event_out[] = { + {SOCK_EVENTS, N_("Event")}, + {-1, ""}, +}; + +void register_node_type_sim_age_reached_event() +{ + static bNodeType ntype; + + sim_node_type_base(&ntype, SIM_NODE_AGE_REACHED_EVENT, "Age Reached Event", 0, 0); + node_type_socket_templates( + &ntype, sim_node_age_reached_event_in, sim_node_age_reached_event_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/simulation/nodes/node_sim_kill_particle.cc b/source/blender/nodes/simulation/nodes/node_sim_kill_particle.cc new file mode 100644 index 00000000000..793b40d9365 --- /dev/null +++ b/source/blender/nodes/simulation/nodes/node_sim_kill_particle.cc @@ -0,0 +1,36 @@ +/* + * 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. + */ + +#include "node_simulation_util.h" + +static bNodeSocketTemplate sim_node_kill_particle_in[] = { + {SOCK_CONTROL_FLOW, N_("Execute")}, + {-1, ""}, +}; + +static bNodeSocketTemplate sim_node_kill_particle_out[] = { + {SOCK_CONTROL_FLOW, N_("Execute")}, + {-1, ""}, +}; + +void register_node_type_sim_kill_particle() +{ + static bNodeType ntype; + + sim_node_type_base(&ntype, SIM_NODE_KILL_PARTICLE, "Kill Particle", 0, 0); + node_type_socket_templates(&ntype, sim_node_kill_particle_in, sim_node_kill_particle_out); + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/simulation/nodes/node_sim_particle_mesh_emitter.cc b/source/blender/nodes/simulation/nodes/node_sim_particle_mesh_emitter.cc index 2de7be2d3eb..5e1a6c35d52 100644 --- a/source/blender/nodes/simulation/nodes/node_sim_particle_mesh_emitter.cc +++ b/source/blender/nodes/simulation/nodes/node_sim_particle_mesh_emitter.cc @@ -20,7 +20,8 @@ static bNodeSocketTemplate sim_node_particle_mesh_emitter_in[] = { {SOCK_OBJECT, N_("Object")}, - {SOCK_FLOAT, N_("Rate"), 10.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX}, + {SOCK_FLOAT, N_("Rate"), 100.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX}, + {SOCK_CONTROL_FLOW, N_("Execute")}, {-1, ""}, }; diff --git a/source/blender/nodes/simulation/nodes/node_sim_set_particle_attribute.cc b/source/blender/nodes/simulation/nodes/node_sim_set_particle_attribute.cc index 8696dbe340c..8f5c6818cb4 100644 --- a/source/blender/nodes/simulation/nodes/node_sim_set_particle_attribute.cc +++ b/source/blender/nodes/simulation/nodes/node_sim_set_particle_attribute.cc @@ -18,6 +18,7 @@ #include "node_simulation_util.h" static bNodeSocketTemplate sim_node_set_particle_attribute_in[] = { + {SOCK_CONTROL_FLOW, N_("Execute")}, {SOCK_STRING, N_("Name")}, {SOCK_FLOAT, N_("Float"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, {SOCK_INT, N_("Int"), 0, 0, 0, 0, -10000, 10000}, @@ -38,7 +39,7 @@ static void sim_node_set_particle_attribute_update(bNodeTree *UNUSED(ntree), bNo { int index = 0; LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) { - if (index >= 1) { + if (index >= 2) { nodeSetSocketAvailability(sock, sock->type == node->custom1); } index++; diff --git a/source/blender/nodes/texture/node_texture_util.c b/source/blender/nodes/texture/node_texture_util.c index 1d7641753e0..981fc4e308a 100644 --- a/source/blender/nodes/texture/node_texture_util.c +++ b/source/blender/nodes/texture/node_texture_util.c @@ -145,14 +145,13 @@ void tex_output(bNode *node, /* do not add a delegate if the node is muted */ return; } + + if (!out->data) { + /* Freed in tex_end_exec (node.c) */ + dg = out->data = MEM_mallocN(sizeof(TexDelegate), "tex delegate"); + } else { - if (!out->data) { - /* Freed in tex_end_exec (node.c) */ - dg = out->data = MEM_mallocN(sizeof(TexDelegate), "tex delegate"); - } - else { - dg = out->data; - } + dg = out->data; } dg->cdata = cdata; diff --git a/source/blender/nodes/texture/nodes/node_texture_curves.c b/source/blender/nodes/texture/nodes/node_texture_curves.c index d42985ba041..70f7e731720 100644 --- a/source/blender/nodes/texture/nodes/node_texture_curves.c +++ b/source/blender/nodes/texture/nodes/node_texture_curves.c @@ -39,7 +39,7 @@ static void time_colorfn( fac = (p->cfra - node->custom1) / (float)(node->custom2 - node->custom1); } - BKE_curvemapping_initialize(node->storage); + BKE_curvemapping_init(node->storage); fac = BKE_curvemapping_evaluateF(node->storage, 0, fac); out[0] = CLAMPIS(fac, 0.0f, 1.0f); } diff --git a/source/blender/nodes/texture/nodes/node_texture_rotate.c b/source/blender/nodes/texture/nodes/node_texture_rotate.c index 825f9d56147..06eb632378c 100644 --- a/source/blender/nodes/texture/nodes/node_texture_rotate.c +++ b/source/blender/nodes/texture/nodes/node_texture_rotate.c @@ -38,7 +38,7 @@ static bNodeSocketTemplate outputs[] = { {-1, ""}, }; -static void rotate(float new_co[3], float a, float ax[3], const float co[3]) +static void rotate(float new_co[3], float a, const float ax[3], const float co[3]) { float para[3]; float perp[3]; diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h index da9b5d642ef..7bcf96116b9 100644 --- a/source/blender/python/BPY_extern.h +++ b/source/blender/python/BPY_extern.h @@ -82,23 +82,23 @@ bool BPY_execute_text(struct bContext *C, bool BPY_execute_string_as_number(struct bContext *C, const char *imports[], const char *expr, - const bool verbose, + const char *report_prefix, double *r_value); bool BPY_execute_string_as_intptr(struct bContext *C, const char *imports[], const char *expr, - const bool verbose, + const char *report_prefix, intptr_t *r_value); bool BPY_execute_string_as_string_and_size(struct bContext *C, const char *imports[], const char *expr, - const bool verbose, + const char *report_prefix, char **r_value, size_t *r_value_size); bool BPY_execute_string_as_string(struct bContext *C, const char *imports[], const char *expr, - const bool verbose, + const char *report_prefix, char **r_value); bool BPY_execute_string_ex(struct bContext *C, diff --git a/source/blender/python/bmesh/bmesh_py_ops.c b/source/blender/python/bmesh/bmesh_py_ops.c index 1eccfe06d15..cdbd4832159 100644 --- a/source/blender/python/bmesh/bmesh_py_ops.c +++ b/source/blender/python/bmesh/bmesh_py_ops.c @@ -250,11 +250,9 @@ static PyObject *bpy_bmesh_ops_fakemod_getattro(PyObject *UNUSED(self), PyObject if (BMO_opcode_from_opname(opname) != -1) { return bpy_bmesh_op_CreatePyObject(opname); } - else { - PyErr_Format( - PyExc_AttributeError, "BMeshOpsModule: operator \"%.200s\" doesn't exist", opname); - return NULL; - } + + PyErr_Format(PyExc_AttributeError, "BMeshOpsModule: operator \"%.200s\" doesn't exist", opname); + return NULL; } static PyObject *bpy_bmesh_ops_fakemod_dir(PyObject *UNUSED(self)) diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c index b1e5c1c761b..a387ba31c84 100644 --- a/source/blender/python/bmesh/bmesh_py_ops_call.c +++ b/source/blender/python/bmesh/bmesh_py_ops_call.c @@ -82,7 +82,7 @@ static int bpy_slot_from_py_elem_check(BPy_BMElem *value, Py_TYPE(value)->tp_name); return -1; } - else if (value->bm == NULL) { + if (value->bm == NULL) { PyErr_Format(PyExc_TypeError, "%.200s: keyword \"%.200s\" %.200s invalidated element", opname, @@ -90,7 +90,7 @@ static int bpy_slot_from_py_elem_check(BPy_BMElem *value, descr); return -1; } - else if (value->bm != bm) { /* we may want to make this check optional by setting 'bm' to NULL */ + if (value->bm != bm) { /* we may want to make this check optional by setting 'bm' to NULL */ PyErr_Format(PyExc_TypeError, "%.200s: keyword \"%.200s\" %.200s invalidated element", opname, @@ -127,7 +127,7 @@ static int bpy_slot_from_py_elemseq_check(BPy_BMGeneric *value, descr); return -1; } - else if (value->bm != bm) { /* we may want to make this check optional by setting 'bm' to NULL */ + if (value->bm != bm) { /* we may want to make this check optional by setting 'bm' to NULL */ PyErr_Format(PyExc_TypeError, "%.200s: keyword \"%.200s\" %.200s, invalidated sequence", opname, @@ -135,7 +135,7 @@ static int bpy_slot_from_py_elemseq_check(BPy_BMGeneric *value, descr); return -1; } - else if ((htype_py & htype_bmo) == 0) { + if ((htype_py & htype_bmo) == 0) { char str_bmo[32]; char str_py[32]; PyErr_Format(PyExc_TypeError, @@ -175,9 +175,8 @@ static int bpy_slot_from_py(BMesh *bm, Py_TYPE(value)->tp_name); return -1; } - else { - BMO_SLOT_AS_BOOL(slot) = param; - } + + BMO_SLOT_AS_BOOL(slot) = param; break; } @@ -223,9 +222,8 @@ static int bpy_slot_from_py(BMesh *bm, Py_TYPE(value)->tp_name); return -1; } - else { - BMO_SLOT_AS_INT(slot) = param; - } + + BMO_SLOT_AS_INT(slot) = param; } break; } @@ -239,9 +237,9 @@ static int bpy_slot_from_py(BMesh *bm, Py_TYPE(value)->tp_name); return -1; } - else { - BMO_SLOT_AS_FLOAT(slot) = param; - } + + BMO_SLOT_AS_FLOAT(slot) = param; + break; } case BMO_OP_SLOT_MAT: { diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index fccdfe7fbdc..e39b5faf3c4 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -292,14 +292,13 @@ static int bpy_bmesh_select_mode_set(BPy_BMesh *self, PyObject *value) -1) { return -1; } - else if (flag == 0) { + if (flag == 0) { PyErr_SetString(PyExc_TypeError, "bm.select_mode: cant assignt an empty value"); return -1; } - else { - self->bm->selectmode = flag; - return 0; - } + + self->bm->selectmode = flag; + return 0; } PyDoc_STRVAR(bpy_bmesh_select_history_doc, @@ -338,9 +337,8 @@ static int bpy_bmvert_co_set(BPy_BMVert *self, PyObject *value) if (mathutils_array_parse(self->v->co, 3, 3, value, "BMVert.co") != -1) { return 0; } - else { - return -1; - } + + return -1; } PyDoc_STRVAR( @@ -359,9 +357,8 @@ static int bpy_bmvert_normal_set(BPy_BMVert *self, PyObject *value) if (mathutils_array_parse(self->v->no, 3, 3, value, "BMVert.normal") != -1) { return 0; } - else { - return -1; - } + + return -1; } PyDoc_STRVAR(bpy_bmvert_is_manifold_doc, @@ -453,9 +450,8 @@ static int bpy_bmface_normal_set(BPy_BMFace *self, PyObject *value) if (mathutils_array_parse(self->f->no, 3, 3, value, "BMFace.normal") != -1) { return 0; } - else { - return -1; - } + + return -1; } PyDoc_STRVAR(bpy_bmface_material_index_doc, "The face's material index.\n\n:type: int"); @@ -481,10 +477,9 @@ static int bpy_bmface_material_index_set(BPy_BMFace *self, PyObject *value) PyErr_SetString(PyExc_ValueError, "material index outside of usable range (0 - 32766)"); return -1; } - else { - self->f->mat_nr = (short)param; - return 0; - } + + self->f->mat_nr = (short)param; + return 0; } /* Loop @@ -586,9 +581,8 @@ static PyObject *bpy_bmfaceseq_active_get(BPy_BMElemSeq *self, void *UNUSED(clos if (bm->act_face) { return BPy_BMElem_CreatePyObject(bm, (BMHeader *)bm->act_face); } - else { - Py_RETURN_NONE; - } + + Py_RETURN_NONE; } static int bpy_bmfaceseq_active_set(BPy_BMElem *self, PyObject *value, void *UNUSED(closure)) @@ -598,18 +592,17 @@ static int bpy_bmfaceseq_active_set(BPy_BMElem *self, PyObject *value, void *UNU bm->act_face = NULL; return 0; } - else if (BPy_BMFace_Check(value)) { + if (BPy_BMFace_Check(value)) { BPY_BM_CHECK_SOURCE_INT(bm, "faces.active = f", value); bm->act_face = ((BPy_BMFace *)value)->f; return 0; } - else { - PyErr_Format(PyExc_TypeError, - "faces.active = f: expected BMFace or None, not %.200s", - Py_TYPE(value)->tp_name); - return -1; - } + + PyErr_Format(PyExc_TypeError, + "faces.active = f: expected BMFace or None, not %.200s", + Py_TYPE(value)->tp_name); + return -1; } static PyGetSetDef bpy_bmesh_getseters[] = { @@ -971,10 +964,9 @@ static PyObject *bpy_bmesh_copy(BPy_BMesh *self) if (bm_copy) { return BPy_BMesh_CreatePyObject(bm_copy, BPY_BMFLAG_NOP); } - else { - PyErr_SetString(PyExc_SystemError, "Unable to copy BMesh, internal error"); - return NULL; - } + + PyErr_SetString(PyExc_SystemError, "Unable to copy BMesh, internal error"); + return NULL; } PyDoc_STRVAR(bpy_bmesh_clear_doc, @@ -1141,9 +1133,8 @@ static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args, PyObject "evaluation mode is RENDER"); return NULL; } - else { - me_eval = mesh_create_eval_final_render(depsgraph, scene_eval, ob_eval, &data_masks); - } + + me_eval = mesh_create_eval_final_render(depsgraph, scene_eval, ob_eval, &data_masks); } else { if (use_cage) { @@ -1161,7 +1152,7 @@ static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args, PyObject "from_object(...): cage arg is unsupported when deform=False"); return NULL; } - else if (use_render) { + if (use_render) { me_eval = mesh_create_eval_no_deform_render(depsgraph, scene_eval, ob, &data_masks); } else { @@ -1329,38 +1320,36 @@ static PyObject *bpy_bmesh_transform(BPy_BMElem *self, PyObject *args, PyObject &filter)) { return NULL; } - else { - BMVert *eve; - BMIter iter; - void *mat_ptr; - if (BaseMath_ReadCallback(mat) == -1) { - return NULL; - } - else if (mat->num_col != 4 || mat->num_row != 4) { - PyErr_SetString(PyExc_ValueError, "expected a 4x4 matrix"); - return NULL; - } + BMVert *eve; + BMIter iter; + void *mat_ptr; - if (filter != NULL && - PyC_FlagSet_ToBitfield(bpy_bm_hflag_all_flags, filter, &filter_flags, "bm.transform") == - -1) { - return NULL; - } + if (BaseMath_ReadCallback(mat) == -1) { + return NULL; + } + if (mat->num_col != 4 || mat->num_row != 4) { + PyErr_SetString(PyExc_ValueError, "expected a 4x4 matrix"); + return NULL; + } - mat_ptr = mat->matrix; + if (filter != NULL && PyC_FlagSet_ToBitfield( + bpy_bm_hflag_all_flags, filter, &filter_flags, "bm.transform") == -1) { + return NULL; + } - if (!filter_flags) { - BM_ITER_MESH (eve, &iter, self->bm, BM_VERTS_OF_MESH) { - mul_m4_v3((float(*)[4])mat_ptr, eve->co); - } + mat_ptr = mat->matrix; + + if (!filter_flags) { + BM_ITER_MESH (eve, &iter, self->bm, BM_VERTS_OF_MESH) { + mul_m4_v3((float(*)[4])mat_ptr, eve->co); } - else { - char filter_flags_ch = (char)filter_flags; - BM_ITER_MESH (eve, &iter, self->bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(eve, filter_flags_ch)) { - mul_m4_v3((float(*)[4])mat_ptr, eve->co); - } + } + else { + char filter_flags_ch = (char)filter_flags; + BM_ITER_MESH (eve, &iter, self->bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(eve, filter_flags_ch)) { + mul_m4_v3((float(*)[4])mat_ptr, eve->co); } } } @@ -1388,9 +1377,8 @@ static PyObject *bpy_bmesh_calc_volume(BPy_BMElem *self, PyObject *args, PyObjec args, kw, "|O!:calc_volume", (char **)kwlist, &PyBool_Type, &is_signed)) { return NULL; } - else { - return PyFloat_FromDouble(BM_mesh_calc_volume(self->bm, is_signed != Py_False)); - } + + return PyFloat_FromDouble(BM_mesh_calc_volume(self->bm, is_signed != Py_False)); } PyDoc_STRVAR(bpy_bmesh_calc_loop_triangles_doc, @@ -1531,30 +1519,29 @@ static PyObject *bpy_bmvert_copy_from_vert_interp(BPy_BMVert *self, PyObject *ar if (!PyArg_ParseTuple(args, "Of:BMVert.copy_from_vert_interp", &vert_seq, &fac)) { return NULL; } - else { - BMesh *bm = self->bm; - BMVert **vert_array = NULL; - Py_ssize_t vert_seq_len; /* always 2 */ - - vert_array = BPy_BMElem_PySeq_As_Array(&bm, - vert_seq, - 2, - 2, - &vert_seq_len, - BM_VERT, - true, - true, - "BMVert.copy_from_vert_interp(...)"); - - if (vert_array == NULL) { - return NULL; - } - - BM_data_interp_from_verts(bm, vert_array[0], vert_array[1], self->v, clamp_f(fac, 0.0f, 1.0f)); - PyMem_FREE(vert_array); - Py_RETURN_NONE; + BMesh *bm = self->bm; + BMVert **vert_array = NULL; + Py_ssize_t vert_seq_len; /* always 2 */ + + vert_array = BPy_BMElem_PySeq_As_Array(&bm, + vert_seq, + 2, + 2, + &vert_seq_len, + BM_VERT, + true, + true, + "BMVert.copy_from_vert_interp(...)"); + + if (vert_array == NULL) { + return NULL; } + + BM_data_interp_from_verts(bm, vert_array[0], vert_array[1], self->v, clamp_f(fac, 0.0f, 1.0f)); + + PyMem_FREE(vert_array); + Py_RETURN_NONE; } PyDoc_STRVAR(bpy_bmvert_copy_from_face_interp_doc, @@ -1574,15 +1561,14 @@ static PyObject *bpy_bmvert_copy_from_face_interp(BPy_BMVert *self, PyObject *ar if (!PyArg_ParseTuple(args, "O!:BMVert.copy_from_face_interp", &BPy_BMFace_Type, &py_face)) { return NULL; } - else { - BMesh *bm = self->bm; - BPY_BM_CHECK_SOURCE_OBJ(bm, "copy_from_face_interp()", py_face); + BMesh *bm = self->bm; - BM_vert_interp_from_face(bm, self->v, py_face->f); + BPY_BM_CHECK_SOURCE_OBJ(bm, "copy_from_face_interp()", py_face); - Py_RETURN_NONE; - } + BM_vert_interp_from_face(bm, self->v, py_face->f); + + Py_RETURN_NONE; } PyDoc_STRVAR(bpy_bmvert_calc_edge_angle_doc, @@ -1615,12 +1601,11 @@ static PyObject *bpy_bmvert_calc_edge_angle(BPy_BMVert *self, PyObject *args) Py_INCREF(fallback); return fallback; } - else { - PyErr_SetString(PyExc_ValueError, - "BMVert.calc_edge_angle(): " - "vert must connect to exactly 2 edges"); - return NULL; - } + + PyErr_SetString(PyExc_ValueError, + "BMVert.calc_edge_angle(): " + "vert must connect to exactly 2 edges"); + return NULL; } return PyFloat_FromDouble(angle); @@ -1697,12 +1682,11 @@ static PyObject *bpy_bmedge_calc_face_angle(BPy_BMEdge *self, PyObject *args) Py_INCREF(fallback); return fallback; } - else { - PyErr_SetString(PyExc_ValueError, - "BMEdge.calc_face_angle(): " - "edge doesn't use 2 faces"); - return NULL; - } + + PyErr_SetString(PyExc_ValueError, + "BMEdge.calc_face_angle(): " + "edge doesn't use 2 faces"); + return NULL; } return PyFloat_FromDouble(angle); @@ -1737,12 +1721,11 @@ static PyObject *bpy_bmedge_calc_face_angle_signed(BPy_BMEdge *self, PyObject *a Py_INCREF(fallback); return fallback; } - else { - PyErr_SetString(PyExc_ValueError, - "BMEdge.calc_face_angle_signed(): " - "edge doesn't use 2 faces"); - return NULL; - } + + PyErr_SetString(PyExc_ValueError, + "BMEdge.calc_face_angle_signed(): " + "edge doesn't use 2 faces"); + return NULL; } return PyFloat_FromDouble(angle); @@ -1767,13 +1750,12 @@ static PyObject *bpy_bmedge_calc_tangent(BPy_BMEdge *self, PyObject *args) if (!PyArg_ParseTuple(args, "O!:BMEdge.calc_face_tangent", &BPy_BMLoop_Type, &py_loop)) { return NULL; } - else { - float vec[3]; - BPY_BM_CHECK_OBJ(py_loop); - /* no need to check if they are from the same mesh or even connected */ - BM_edge_calc_face_tangent(self->e, py_loop->l, vec); - return Vector_CreatePyObject(vec, 3, NULL); - } + + float vec[3]; + BPY_BM_CHECK_OBJ(py_loop); + /* no need to check if they are from the same mesh or even connected */ + BM_edge_calc_face_tangent(self->e, py_loop->l, vec); + return Vector_CreatePyObject(vec, 3, NULL); } PyDoc_STRVAR( @@ -1805,10 +1787,9 @@ static PyObject *bpy_bmedge_other_vert(BPy_BMEdge *self, BPy_BMVert *value) if (other) { return BPy_BMVert_CreatePyObject(self->bm, other); } - else { - /* could raise an exception here */ - Py_RETURN_NONE; - } + + /* could raise an exception here */ + Py_RETURN_NONE; } PyDoc_STRVAR(bpy_bmedge_normal_update_doc, @@ -1852,15 +1833,14 @@ static PyObject *bpy_bmface_copy_from_face_interp(BPy_BMFace *self, PyObject *ar &do_vertex)) { return NULL; } - else { - BMesh *bm = self->bm; - BPY_BM_CHECK_SOURCE_OBJ(bm, "BMFace.copy_from_face_interp(face)", py_face); + BMesh *bm = self->bm; - BM_face_interp_from_face(bm, self->f, py_face->f, do_vertex); + BPY_BM_CHECK_SOURCE_OBJ(bm, "BMFace.copy_from_face_interp(face)", py_face); - Py_RETURN_NONE; - } + BM_face_interp_from_face(bm, self->f, py_face->f, do_vertex); + + Py_RETURN_NONE; } PyDoc_STRVAR(bpy_bmface_copy_doc, @@ -1901,11 +1881,9 @@ static PyObject *bpy_bmface_copy(BPy_BMFace *self, PyObject *args, PyObject *kw) if (f_cpy) { return BPy_BMFace_CreatePyObject(bm, f_cpy); } - else { - PyErr_SetString(PyExc_ValueError, - "BMFace.copy(): couldn't create the new face, internal error"); - return NULL; - } + + PyErr_SetString(PyExc_ValueError, "BMFace.copy(): couldn't create the new face, internal error"); + return NULL; } PyDoc_STRVAR(bpy_bmface_calc_area_doc, @@ -2109,15 +2087,14 @@ static PyObject *bpy_bmloop_copy_from_face_interp(BPy_BMLoop *self, PyObject *ar &do_multires)) { return NULL; } - else { - BMesh *bm = self->bm; - BPY_BM_CHECK_SOURCE_OBJ(bm, "BMLoop.copy_from_face_interp(face)", py_face); + BMesh *bm = self->bm; - BM_loop_interp_from_face(bm, self->l, py_face->f, do_vertex, do_multires); + BPY_BM_CHECK_SOURCE_OBJ(bm, "BMLoop.copy_from_face_interp(face)", py_face); - Py_RETURN_NONE; - } + BM_loop_interp_from_face(bm, self->l, py_face->f, do_vertex, do_multires); + + Py_RETURN_NONE; } PyDoc_STRVAR(bpy_bmloop_calc_angle_doc, @@ -2190,33 +2167,32 @@ static PyObject *bpy_bmvertseq_new(BPy_BMElemSeq *self, PyObject *args) if (!PyArg_ParseTuple(args, "|OO!:verts.new", &py_co, &BPy_BMVert_Type, &py_vert_example)) { return NULL; } - else { - BMesh *bm = self->bm; - BMVert *v; - float co[3] = {0.0f, 0.0f, 0.0f}; - if (py_vert_example) { - BPY_BM_CHECK_OBJ(py_vert_example); - } + BMesh *bm = self->bm; + BMVert *v; + float co[3] = {0.0f, 0.0f, 0.0f}; - if (py_co && mathutils_array_parse(co, 3, 3, py_co, "verts.new(co)") == -1) { - return NULL; - } + if (py_vert_example) { + BPY_BM_CHECK_OBJ(py_vert_example); + } - v = BM_vert_create(bm, co, NULL, BM_CREATE_NOP); + if (py_co && mathutils_array_parse(co, 3, 3, py_co, "verts.new(co)") == -1) { + return NULL; + } - if (v == NULL) { - PyErr_SetString(PyExc_ValueError, - "faces.new(verts): couldn't create the new face, internal error"); - return NULL; - } + v = BM_vert_create(bm, co, NULL, BM_CREATE_NOP); - if (py_vert_example) { - BM_elem_attrs_copy(py_vert_example->bm, bm, py_vert_example->v, v); - } + if (v == NULL) { + PyErr_SetString(PyExc_ValueError, + "faces.new(verts): couldn't create the new face, internal error"); + return NULL; + } - return BPy_BMVert_CreatePyObject(bm, v); + if (py_vert_example) { + BM_elem_attrs_copy(py_vert_example->bm, bm, py_vert_example->v, v); } + + return BPy_BMVert_CreatePyObject(bm, v); } /* Edge Seq @@ -2242,49 +2218,48 @@ static PyObject *bpy_bmedgeseq_new(BPy_BMElemSeq *self, PyObject *args) if (!PyArg_ParseTuple(args, "O|O!:edges.new", &vert_seq, &BPy_BMEdge_Type, &py_edge_example)) { return NULL; } - else { - BMesh *bm = self->bm; - BMEdge *e; - BMVert **vert_array = NULL; - Py_ssize_t vert_seq_len; /* always 2 */ - PyObject *ret = NULL; - if (py_edge_example) { - BPY_BM_CHECK_OBJ(py_edge_example); - } + BMesh *bm = self->bm; + BMEdge *e; + BMVert **vert_array = NULL; + Py_ssize_t vert_seq_len; /* always 2 */ + PyObject *ret = NULL; - vert_array = BPy_BMElem_PySeq_As_Array( - &bm, vert_seq, 2, 2, &vert_seq_len, BM_VERT, true, true, "edges.new(...)"); + if (py_edge_example) { + BPY_BM_CHECK_OBJ(py_edge_example); + } - if (vert_array == NULL) { - return NULL; - } + vert_array = BPy_BMElem_PySeq_As_Array( + &bm, vert_seq, 2, 2, &vert_seq_len, BM_VERT, true, true, "edges.new(...)"); - if (BM_edge_exists(vert_array[0], vert_array[1])) { - PyErr_SetString(PyExc_ValueError, "edges.new(): this edge exists"); - goto cleanup; - } + if (vert_array == NULL) { + return NULL; + } - e = BM_edge_create(bm, vert_array[0], vert_array[1], NULL, BM_CREATE_NOP); + if (BM_edge_exists(vert_array[0], vert_array[1])) { + PyErr_SetString(PyExc_ValueError, "edges.new(): this edge exists"); + goto cleanup; + } - if (e == NULL) { - PyErr_SetString(PyExc_ValueError, - "faces.new(verts): couldn't create the new face, internal error"); - goto cleanup; - } + e = BM_edge_create(bm, vert_array[0], vert_array[1], NULL, BM_CREATE_NOP); - if (py_edge_example) { - BM_elem_attrs_copy(py_edge_example->bm, bm, py_edge_example->e, e); - } + if (e == NULL) { + PyErr_SetString(PyExc_ValueError, + "faces.new(verts): couldn't create the new face, internal error"); + goto cleanup; + } - ret = BPy_BMEdge_CreatePyObject(bm, e); + if (py_edge_example) { + BM_elem_attrs_copy(py_edge_example->bm, bm, py_edge_example->e, e); + } - cleanup: - if (vert_array) { - PyMem_FREE(vert_array); - } - return ret; + ret = BPy_BMEdge_CreatePyObject(bm, e); + +cleanup: + if (vert_array) { + PyMem_FREE(vert_array); } + return ret; } /* Face Seq @@ -2310,58 +2285,57 @@ static PyObject *bpy_bmfaceseq_new(BPy_BMElemSeq *self, PyObject *args) if (!PyArg_ParseTuple(args, "O|O!:faces.new", &vert_seq, &BPy_BMFace_Type, &py_face_example)) { return NULL; } - else { - BMesh *bm = self->bm; - Py_ssize_t vert_seq_len; - BMVert **vert_array = NULL; + BMesh *bm = self->bm; + Py_ssize_t vert_seq_len; - PyObject *ret = NULL; + BMVert **vert_array = NULL; - BMFace *f_new; + PyObject *ret = NULL; - if (py_face_example) { - BPY_BM_CHECK_OBJ(py_face_example); - } + BMFace *f_new; - vert_array = BPy_BMElem_PySeq_As_Array( - &bm, vert_seq, 3, PY_SSIZE_T_MAX, &vert_seq_len, BM_VERT, true, true, "faces.new(...)"); + if (py_face_example) { + BPY_BM_CHECK_OBJ(py_face_example); + } - if (vert_array == NULL) { - return NULL; - } + vert_array = BPy_BMElem_PySeq_As_Array( + &bm, vert_seq, 3, PY_SSIZE_T_MAX, &vert_seq_len, BM_VERT, true, true, "faces.new(...)"); - /* check if the face exists */ - if (BM_face_exists(vert_array, vert_seq_len) != NULL) { - PyErr_SetString(PyExc_ValueError, "faces.new(verts): face already exists"); - goto cleanup; - } + if (vert_array == NULL) { + return NULL; + } - /* Go ahead and make the face! - * --------------------------- */ + /* check if the face exists */ + if (BM_face_exists(vert_array, vert_seq_len) != NULL) { + PyErr_SetString(PyExc_ValueError, "faces.new(verts): face already exists"); + goto cleanup; + } - f_new = BM_face_create_verts(bm, - vert_array, - vert_seq_len, - py_face_example ? py_face_example->f : NULL, - BM_CREATE_NOP, - true); + /* Go ahead and make the face! + * --------------------------- */ - if (UNLIKELY(f_new == NULL)) { - PyErr_SetString(PyExc_ValueError, - "faces.new(verts): couldn't create the new face, internal error"); - goto cleanup; - } + f_new = BM_face_create_verts(bm, + vert_array, + vert_seq_len, + py_face_example ? py_face_example->f : NULL, + BM_CREATE_NOP, + true); - ret = BPy_BMFace_CreatePyObject(bm, f_new); + if (UNLIKELY(f_new == NULL)) { + PyErr_SetString(PyExc_ValueError, + "faces.new(verts): couldn't create the new face, internal error"); + goto cleanup; + } - /* pass through */ - cleanup: - if (vert_array) { - PyMem_FREE(vert_array); - } - return ret; + ret = BPy_BMFace_CreatePyObject(bm, f_new); + + /* pass through */ +cleanup: + if (vert_array) { + PyMem_FREE(vert_array); } + return ret; } /* Elem Seq @@ -2378,16 +2352,15 @@ static PyObject *bpy_bmvertseq_remove(BPy_BMElemSeq *self, BPy_BMVert *value) if (!BPy_BMVert_Check(value)) { return NULL; } - else { - BMesh *bm = self->bm; - BPY_BM_CHECK_SOURCE_OBJ(bm, "verts.remove(vert)", value); + BMesh *bm = self->bm; - BM_vert_kill(bm, value->v); - bpy_bm_generic_invalidate((BPy_BMGeneric *)value); + BPY_BM_CHECK_SOURCE_OBJ(bm, "verts.remove(vert)", value); - Py_RETURN_NONE; - } + BM_vert_kill(bm, value->v); + bpy_bm_generic_invalidate((BPy_BMGeneric *)value); + + Py_RETURN_NONE; } PyDoc_STRVAR(bpy_bmedgeseq_remove_doc, @@ -2401,16 +2374,15 @@ static PyObject *bpy_bmedgeseq_remove(BPy_BMElemSeq *self, BPy_BMEdge *value) if (!BPy_BMEdge_Check(value)) { return NULL; } - else { - BMesh *bm = self->bm; - BPY_BM_CHECK_SOURCE_OBJ(bm, "edges.remove(edges)", value); + BMesh *bm = self->bm; - BM_edge_kill(bm, value->e); - bpy_bm_generic_invalidate((BPy_BMGeneric *)value); + BPY_BM_CHECK_SOURCE_OBJ(bm, "edges.remove(edges)", value); - Py_RETURN_NONE; - } + BM_edge_kill(bm, value->e); + bpy_bm_generic_invalidate((BPy_BMGeneric *)value); + + Py_RETURN_NONE; } PyDoc_STRVAR(bpy_bmfaceseq_remove_doc, @@ -2424,16 +2396,15 @@ static PyObject *bpy_bmfaceseq_remove(BPy_BMElemSeq *self, BPy_BMFace *value) if (!BPy_BMFace_Check(value)) { return NULL; } - else { - BMesh *bm = self->bm; - BPY_BM_CHECK_SOURCE_OBJ(bm, "faces.remove(face)", value); + BMesh *bm = self->bm; - BM_face_kill(bm, value->f); - bpy_bm_generic_invalidate((BPy_BMGeneric *)value); + BPY_BM_CHECK_SOURCE_OBJ(bm, "faces.remove(face)", value); - Py_RETURN_NONE; - } + BM_face_kill(bm, value->f); + bpy_bm_generic_invalidate((BPy_BMGeneric *)value); + + Py_RETURN_NONE; } PyDoc_STRVAR(bpy_bmedgeseq_get__method_doc, @@ -2456,31 +2427,30 @@ static PyObject *bpy_bmedgeseq_get__method(BPy_BMElemSeq *self, PyObject *args) if (!PyArg_ParseTuple(args, "O|O:edges.get", &vert_seq, &fallback)) { return NULL; } - else { - BMesh *bm = self->bm; - BMEdge *e; - BMVert **vert_array = NULL; - Py_ssize_t vert_seq_len; /* always 2 */ - PyObject *ret = NULL; - vert_array = BPy_BMElem_PySeq_As_Array( - &bm, vert_seq, 2, 2, &vert_seq_len, BM_VERT, true, true, "edges.get(...)"); + BMesh *bm = self->bm; + BMEdge *e; + BMVert **vert_array = NULL; + Py_ssize_t vert_seq_len; /* always 2 */ + PyObject *ret = NULL; - if (vert_array == NULL) { - return NULL; - } + vert_array = BPy_BMElem_PySeq_As_Array( + &bm, vert_seq, 2, 2, &vert_seq_len, BM_VERT, true, true, "edges.get(...)"); - if ((e = BM_edge_exists(vert_array[0], vert_array[1]))) { - ret = BPy_BMEdge_CreatePyObject(bm, e); - } - else { - ret = fallback; - Py_INCREF(ret); - } + if (vert_array == NULL) { + return NULL; + } - PyMem_FREE(vert_array); - return ret; + if ((e = BM_edge_exists(vert_array[0], vert_array[1]))) { + ret = BPy_BMEdge_CreatePyObject(bm, e); + } + else { + ret = fallback; + Py_INCREF(ret); } + + PyMem_FREE(vert_array); + return ret; } PyDoc_STRVAR(bpy_bmfaceseq_get__method_doc, @@ -2503,32 +2473,31 @@ static PyObject *bpy_bmfaceseq_get__method(BPy_BMElemSeq *self, PyObject *args) if (!PyArg_ParseTuple(args, "O|O:faces.get", &vert_seq, &fallback)) { return NULL; } - else { - BMesh *bm = self->bm; - BMFace *f = NULL; - BMVert **vert_array = NULL; - Py_ssize_t vert_seq_len; - PyObject *ret = NULL; - vert_array = BPy_BMElem_PySeq_As_Array( - &bm, vert_seq, 1, PY_SSIZE_T_MAX, &vert_seq_len, BM_VERT, true, true, "faces.get(...)"); + BMesh *bm = self->bm; + BMFace *f = NULL; + BMVert **vert_array = NULL; + Py_ssize_t vert_seq_len; + PyObject *ret = NULL; - if (vert_array == NULL) { - return NULL; - } + vert_array = BPy_BMElem_PySeq_As_Array( + &bm, vert_seq, 1, PY_SSIZE_T_MAX, &vert_seq_len, BM_VERT, true, true, "faces.get(...)"); - f = BM_face_exists(vert_array, vert_seq_len); - if (f != NULL) { - ret = BPy_BMFace_CreatePyObject(bm, f); - } - else { - ret = fallback; - Py_INCREF(ret); - } + if (vert_array == NULL) { + return NULL; + } - PyMem_FREE(vert_array); - return ret; + f = BM_face_exists(vert_array, vert_seq_len); + if (f != NULL) { + ret = BPy_BMFace_CreatePyObject(bm, f); } + else { + ret = fallback; + Py_INCREF(ret); + } + + PyMem_FREE(vert_array); + return ret; } PyDoc_STRVAR( @@ -2651,12 +2620,11 @@ static int bpy_bmelemseq_sort_cmp_by_keys_ascending(const void *index1_v, if (keys[*index1] < keys[*index2]) { return -1; } - else if (keys[*index1] > keys[*index2]) { + if (keys[*index1] > keys[*index2]) { return 1; } - else { - return 0; - } + + return 0; } static int bpy_bmelemseq_sort_cmp_by_keys_descending(const void *index1_v, @@ -3260,54 +3228,51 @@ static PyObject *bpy_bmelemseq_subscript(BPy_BMElemSeq *self, PyObject *key) } return bpy_bmelemseq_subscript_int(self, i); } - else if (PySlice_Check(key)) { + if (PySlice_Check(key)) { PySliceObject *key_slice = (PySliceObject *)key; Py_ssize_t step = 1; if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) { return NULL; } - else if (step != 1) { + if (step != 1) { PyErr_SetString(PyExc_TypeError, "BMElemSeq[slice]: slice steps not supported"); return NULL; } - else if (key_slice->start == Py_None && key_slice->stop == Py_None) { + if (key_slice->start == Py_None && key_slice->stop == Py_None) { return bpy_bmelemseq_subscript_slice(self, 0, PY_SSIZE_T_MAX); } - else { - Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; - /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ - if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) { - return NULL; - } - if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) { - return NULL; - } + Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; - if (start < 0 || stop < 0) { - /* only get the length for negative values */ - Py_ssize_t len = bpy_bmelemseq_length(self); - if (start < 0) { - start += len; - } - if (stop < 0) { - stop += len; - } - } + /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ + if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) { + return NULL; + } + if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) { + return NULL; + } - if (stop - start <= 0) { - return PyList_New(0); + if (start < 0 || stop < 0) { + /* only get the length for negative values */ + Py_ssize_t len = bpy_bmelemseq_length(self); + if (start < 0) { + start += len; } - else { - return bpy_bmelemseq_subscript_slice(self, start, stop); + if (stop < 0) { + stop += len; } } + + if (stop - start <= 0) { + return PyList_New(0); + } + + return bpy_bmelemseq_subscript_slice(self, start, stop); } - else { - PyErr_SetString(PyExc_AttributeError, "BMElemSeq[key]: invalid key, key must be an int"); - return NULL; - } + + PyErr_SetString(PyExc_AttributeError, "BMElemSeq[key]: invalid key, key must be an int"); + return NULL; } static int bpy_bmelemseq_contains(BPy_BMElemSeq *self, PyObject *value) @@ -3395,9 +3360,8 @@ static PyObject *bpy_bmiter_next(BPy_BMIter *self) PyErr_SetNone(PyExc_StopIteration); return NULL; } - else { - return (PyObject *)BPy_BMElem_CreatePyObject(self->bm, ele); - } + + return (PyObject *)BPy_BMElem_CreatePyObject(self->bm, ele); } /* Dealloc Functions @@ -3532,9 +3496,8 @@ static PyObject *bpy_bmesh_repr(BPy_BMesh *self) bm->totface, bm->totloop); } - else { - return PyUnicode_FromFormat("<BMesh dead at %p>", self); - } + + return PyUnicode_FromFormat("<BMesh dead at %p>", self); } static PyObject *bpy_bmvert_repr(BPy_BMVert *self) @@ -3545,9 +3508,8 @@ static PyObject *bpy_bmvert_repr(BPy_BMVert *self) BMVert *v = self->v; return PyUnicode_FromFormat("<BMVert(%p), index=%d>", v, BM_elem_index_get(v)); } - else { - return PyUnicode_FromFormat("<BMVert dead at %p>", self); - } + + return PyUnicode_FromFormat("<BMVert dead at %p>", self); } static PyObject *bpy_bmedge_repr(BPy_BMEdge *self) @@ -3564,9 +3526,8 @@ static PyObject *bpy_bmedge_repr(BPy_BMEdge *self) e->v2, BM_elem_index_get(e->v2)); } - else { - return PyUnicode_FromFormat("<BMEdge dead at %p>", self); - } + + return PyUnicode_FromFormat("<BMEdge dead at %p>", self); } static PyObject *bpy_bmface_repr(BPy_BMFace *self) @@ -3578,9 +3539,8 @@ static PyObject *bpy_bmface_repr(BPy_BMFace *self) return PyUnicode_FromFormat( "<BMFace(%p), index=%d, totverts=%d>", f, BM_elem_index_get(f), f->len); } - else { - return PyUnicode_FromFormat("<BMFace dead at %p>", self); - } + + return PyUnicode_FromFormat("<BMFace dead at %p>", self); } static PyObject *bpy_bmloop_repr(BPy_BMLoop *self) @@ -3599,9 +3559,8 @@ static PyObject *bpy_bmloop_repr(BPy_BMLoop *self) l->f, BM_elem_index_get(l->f)); } - else { - return PyUnicode_FromFormat("<BMLoop dead at %p>", self); - } + + return PyUnicode_FromFormat("<BMLoop dead at %p>", self); } /* Types @@ -4054,12 +4013,10 @@ int bpy_bm_generic_valid_check(BPy_BMGeneric *self) return 0; } - else { - PyErr_Format(PyExc_ReferenceError, - "BMesh data of type %.200s has been removed", - Py_TYPE(self)->tp_name); - return -1; - } + + PyErr_Format( + PyExc_ReferenceError, "BMesh data of type %.200s has been removed", Py_TYPE(self)->tp_name); + return -1; } int bpy_bm_generic_valid_check_source(BMesh *bm_source, @@ -4079,16 +4036,15 @@ int bpy_bm_generic_valid_check_source(BMesh *bm_source, if (UNLIKELY(ret == -1)) { break; } - else { - if (UNLIKELY(py_bm_elem->bm != bm_source)) { - /* could give more info here */ - PyErr_Format(PyExc_ValueError, - "%.200s: BMesh data of type %.200s is from another mesh", - error_prefix, - Py_TYPE(py_bm_elem)->tp_name); - ret = -1; - break; - } + + if (UNLIKELY(py_bm_elem->bm != bm_source)) { + /* could give more info here */ + PyErr_Format(PyExc_ValueError, + "%.200s: BMesh data of type %.200s is from another mesh", + error_prefix, + Py_TYPE(py_bm_elem)->tp_name); + ret = -1; + break; } } } diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c index 8615da653ae..51616030d30 100644 --- a/source/blender/python/bmesh/bmesh_py_types_customdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c @@ -67,10 +67,9 @@ static CustomDataLayer *bpy_bmlayeritem_get(BPy_BMLayerItem *self) if (index_absolute != -1) { return &data->layers[index_absolute]; } - else { - PyErr_SetString(PyExc_RuntimeError, "layer has become invalid"); - return NULL; - } + + PyErr_SetString(PyExc_RuntimeError, "layer has become invalid"); + return NULL; } /* py-type definitions @@ -142,9 +141,8 @@ static PyObject *bpy_bmlayercollection_active_get(BPy_BMLayerItem *self, void *U if (index != -1) { return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index); } - else { - Py_RETURN_NONE; - } + + Py_RETURN_NONE; } PyDoc_STRVAR( @@ -169,9 +167,8 @@ static PyObject *bpy_bmlayeritem_name_get(BPy_BMLayerItem *self, void *UNUSED(fl if (layer) { return PyUnicode_FromString(layer->name); } - else { - return NULL; - } + + return NULL; } static PyGetSetDef bpy_bmlayeraccess_vert_getseters[] = { @@ -617,16 +614,15 @@ static PyObject *bpy_bmlayercollection_get(BPy_BMLayerCollection *self, PyObject if (!PyArg_ParseTuple(args, "s|O:get", &key, &def)) { return NULL; } - else { - CustomData *data; - int index; - data = bpy_bm_customdata_get(self->bm, self->htype); - index = CustomData_get_named_layer(data, self->type, key); /* type relative */ + CustomData *data; + int index; - if (index != -1) { - return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index); - } + data = bpy_bm_customdata_get(self->bm, self->htype); + index = CustomData_get_named_layer(data, self->type, key); /* type relative */ + + if (index != -1) { + return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index); } return Py_INCREF_RET(def); @@ -689,10 +685,9 @@ static PyObject *bpy_bmlayercollection_subscript_str(BPy_BMLayerCollection *self if (index != -1) { return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index); } - else { - PyErr_Format(PyExc_KeyError, "BMLayerCollection[key]: key \"%.200s\" not found", keyname); - return NULL; - } + + PyErr_Format(PyExc_KeyError, "BMLayerCollection[key]: key \"%.200s\" not found", keyname); + return NULL; } static PyObject *bpy_bmlayercollection_subscript_int(BPy_BMLayerCollection *self, int keynum) @@ -750,62 +745,58 @@ static PyObject *bpy_bmlayercollection_subscript(BPy_BMLayerCollection *self, Py if (PyUnicode_Check(key)) { return bpy_bmlayercollection_subscript_str(self, _PyUnicode_AsString(key)); } - else if (PyIndex_Check(key)) { + if (PyIndex_Check(key)) { Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) { return NULL; } return bpy_bmlayercollection_subscript_int(self, i); } - else if (PySlice_Check(key)) { + if (PySlice_Check(key)) { PySliceObject *key_slice = (PySliceObject *)key; Py_ssize_t step = 1; if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) { return NULL; } - else if (step != 1) { + if (step != 1) { PyErr_SetString(PyExc_TypeError, "BMLayerCollection[slice]: slice steps not supported"); return NULL; } - else if (key_slice->start == Py_None && key_slice->stop == Py_None) { + if (key_slice->start == Py_None && key_slice->stop == Py_None) { return bpy_bmlayercollection_subscript_slice(self, 0, PY_SSIZE_T_MAX); } - else { - Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; - /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ - if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) { - return NULL; - } - if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) { - return NULL; - } + Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; - if (start < 0 || stop < 0) { - /* only get the length for negative values */ - Py_ssize_t len = bpy_bmlayercollection_length(self); - if (start < 0) { - start += len; - } - if (stop < 0) { - stop += len; - } - } + /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ + if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) { + return NULL; + } + if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) { + return NULL; + } - if (stop - start <= 0) { - return PyTuple_New(0); + if (start < 0 || stop < 0) { + /* only get the length for negative values */ + Py_ssize_t len = bpy_bmlayercollection_length(self); + if (start < 0) { + start += len; } - else { - return bpy_bmlayercollection_subscript_slice(self, start, stop); + if (stop < 0) { + stop += len; } } + + if (stop - start <= 0) { + return PyTuple_New(0); + } + + return bpy_bmlayercollection_subscript_slice(self, start, stop); } - else { - PyErr_SetString(PyExc_AttributeError, - "BMLayerCollection[key]: invalid key, key must be an int"); - return NULL; - } + + PyErr_SetString(PyExc_AttributeError, "BMLayerCollection[key]: invalid key, key must be an int"); + return NULL; } static int bpy_bmlayercollection_contains(BPy_BMLayerCollection *self, PyObject *value) @@ -1024,11 +1015,11 @@ static void *bpy_bmlayeritem_ptr_get(BPy_BMElem *py_ele, BPy_BMLayerItem *py_lay PyErr_SetString(PyExc_AttributeError, "BMElem[key]: invalid key, must be a BMLayerItem"); return NULL; } - else if (UNLIKELY(py_ele->bm != py_layer->bm)) { + if (UNLIKELY(py_ele->bm != py_layer->bm)) { PyErr_SetString(PyExc_ValueError, "BMElem[layer]: layer is from another mesh"); return NULL; } - else if (UNLIKELY(ele->head.htype != py_layer->htype)) { + if (UNLIKELY(ele->head.htype != py_layer->htype)) { char namestr_1[32], namestr_2[32]; PyErr_Format(PyExc_ValueError, "Layer/Element type mismatch, expected %.200s got layer type %.200s", @@ -1046,9 +1037,8 @@ static void *bpy_bmlayeritem_ptr_get(BPy_BMElem *py_ele, BPy_BMLayerItem *py_lay PyErr_SetString(PyExc_KeyError, "BMElem[key]: layer not found"); return NULL; } - else { - return value; - } + + return value; } /** diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.c b/source/blender/python/bmesh/bmesh_py_types_meshdata.c index 82b6cf5c3d5..f42348975c9 100644 --- a/source/blender/python/bmesh/bmesh_py_types_meshdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.c @@ -65,9 +65,8 @@ static int bpy_bmloopuv_uv_set(BPy_BMLoopUV *self, PyObject *value, void *UNUSED copy_v2_v2(self->data->uv, tvec); return 0; } - else { - return -1; - } + + return -1; } PyDoc_STRVAR(bpy_bmloopuv_flag__pin_uv_doc, "UV pin state.\n\n:type: boolean"); @@ -136,10 +135,9 @@ int BPy_BMLoopUV_AssignPyObject(struct MLoopUV *mloopuv, PyObject *value) PyErr_Format(PyExc_TypeError, "expected BMLoopUV, not a %.200s", Py_TYPE(value)->tp_name); return -1; } - else { - *((MLoopUV *)mloopuv) = *(((BPy_BMLoopUV *)value)->data); - return 0; - } + + *((MLoopUV *)mloopuv) = *(((BPy_BMLoopUV *)value)->data); + return 0; } PyObject *BPy_BMLoopUV_CreatePyObject(struct MLoopUV *mloopuv) @@ -174,9 +172,8 @@ static int bpy_bmvertskin_radius_set(BPy_BMVertSkin *self, PyObject *value, void copy_v2_v2(self->data->radius, tvec); return 0; } - else { - return -1; - } + + return -1; } PyDoc_STRVAR(bpy_bmvertskin_flag__use_root_doc, @@ -251,10 +248,9 @@ int BPy_BMVertSkin_AssignPyObject(struct MVertSkin *mvertskin, PyObject *value) PyErr_Format(PyExc_TypeError, "expected BMVertSkin, not a %.200s", Py_TYPE(value)->tp_name); return -1; } - else { - *((MVertSkin *)mvertskin) = *(((BPy_BMVertSkin *)value)->data); - return 0; - } + + *((MVertSkin *)mvertskin) = *(((BPy_BMVertSkin *)value)->data); + return 0; } PyObject *BPy_BMVertSkin_CreatePyObject(struct MVertSkin *mvertskin) @@ -351,9 +347,8 @@ int BPy_BMLoopColor_AssignPyObject(struct MLoopCol *mloopcol, PyObject *value) mloopcol_from_float(mloopcol, tvec); return 0; } - else { - return -1; - } + + return -1; } PyObject *BPy_BMLoopColor_CreatePyObject(struct MLoopCol *data) @@ -416,25 +411,22 @@ static PyObject *bpy_bmdeformvert_subscript(BPy_BMDeformVert *self, PyObject *ke if (i == -1 && PyErr_Occurred()) { return NULL; } - else { - MDeformWeight *dw = BKE_defvert_find_index(self->data, i); - if (dw == NULL) { - PyErr_SetString(PyExc_KeyError, - "BMDeformVert[key] = x: " - "key not found"); - return NULL; - } - else { - return PyFloat_FromDouble(dw->weight); - } + MDeformWeight *dw = BKE_defvert_find_index(self->data, i); + + if (dw == NULL) { + PyErr_SetString(PyExc_KeyError, + "BMDeformVert[key] = x: " + "key not found"); + return NULL; } + + return PyFloat_FromDouble(dw->weight); } - else { - PyErr_Format( - PyExc_TypeError, "BMDeformVert keys must be integers, not %.200s", Py_TYPE(key)->tp_name); - return NULL; - } + + PyErr_Format( + PyExc_TypeError, "BMDeformVert keys must be integers, not %.200s", Py_TYPE(key)->tp_name); + return NULL; } static int bpy_bmdeformvert_ass_subscript(BPy_BMDeformVert *self, PyObject *key, PyObject *value) @@ -455,18 +447,17 @@ static int bpy_bmdeformvert_ass_subscript(BPy_BMDeformVert *self, PyObject *key, "weight keys can't be negative"); return -1; } - else { - MDeformWeight *dw = BKE_defvert_ensure_index(self->data, i); - const float f = PyFloat_AsDouble(value); - if (f == -1 && PyErr_Occurred()) { // parsed key not a number - PyErr_SetString(PyExc_TypeError, - "BMDeformVert[key] = x: " - "assigned value not a number"); - return -1; - } - - dw->weight = clamp_f(f, 0.0f, 1.0f); + + MDeformWeight *dw = BKE_defvert_ensure_index(self->data, i); + const float f = PyFloat_AsDouble(value); + if (f == -1 && PyErr_Occurred()) { // parsed key not a number + PyErr_SetString(PyExc_TypeError, + "BMDeformVert[key] = x: " + "assigned value not a number"); + return -1; } + + dw->weight = clamp_f(f, 0.0f, 1.0f); } else { /* del dvert[group_index] */ @@ -482,11 +473,10 @@ static int bpy_bmdeformvert_ass_subscript(BPy_BMDeformVert *self, PyObject *key, return 0; } - else { - PyErr_Format( - PyExc_TypeError, "BMDeformVert keys must be integers, not %.200s", Py_TYPE(key)->tp_name); - return -1; - } + + PyErr_Format( + PyExc_TypeError, "BMDeformVert keys must be integers, not %.200s", Py_TYPE(key)->tp_name); + return -1; } static int bpy_bmdeformvert_contains(BPy_BMDeformVert *self, PyObject *value) @@ -616,16 +606,14 @@ static PyObject *bpy_bmdeformvert_get(BPy_BMDeformVert *self, PyObject *args) if (!PyArg_ParseTuple(args, "i|O:get", &key, &def)) { return NULL; } - else { - MDeformWeight *dw = BKE_defvert_find_index(self->data, key); - if (dw) { - return PyFloat_FromDouble(dw->weight); - } - else { - return Py_INCREF_RET(def); - } + MDeformWeight *dw = BKE_defvert_find_index(self->data, key); + + if (dw) { + return PyFloat_FromDouble(dw->weight); } + + return Py_INCREF_RET(def); } PyDoc_STRVAR(bpy_bmdeformvert_clear_doc, @@ -675,13 +663,12 @@ int BPy_BMDeformVert_AssignPyObject(struct MDeformVert *dvert, PyObject *value) PyErr_Format(PyExc_TypeError, "expected BMDeformVert, not a %.200s", Py_TYPE(value)->tp_name); return -1; } - else { - MDeformVert *dvert_src = ((BPy_BMDeformVert *)value)->data; - if (LIKELY(dvert != dvert_src)) { - BKE_defvert_copy(dvert, dvert_src); - } - return 0; + + MDeformVert *dvert_src = ((BPy_BMDeformVert *)value)->data; + if (LIKELY(dvert != dvert_src)) { + BKE_defvert_copy(dvert, dvert_src); } + return 0; } PyObject *BPy_BMDeformVert_CreatePyObject(struct MDeformVert *dvert) diff --git a/source/blender/python/bmesh/bmesh_py_types_select.c b/source/blender/python/bmesh/bmesh_py_types_select.c index 5e064453a04..d69668341ff 100644 --- a/source/blender/python/bmesh/bmesh_py_types_select.c +++ b/source/blender/python/bmesh/bmesh_py_types_select.c @@ -51,9 +51,8 @@ static PyObject *bpy_bmeditselseq_active_get(BPy_BMEditSelSeq *self, void *UNUSE if ((ese = self->bm->selected.last)) { return BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head); } - else { - Py_RETURN_NONE; - } + + Py_RETURN_NONE; } static PyGetSetDef bpy_bmeditselseq_getseters[] = { @@ -196,10 +195,9 @@ static PyObject *bpy_bmeditselseq_subscript_int(BPy_BMEditSelSeq *self, int keyn if (ese) { return BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head); } - else { - PyErr_Format(PyExc_IndexError, "BMElemSeq[index]: index %d out of range", keynum); - return NULL; - } + + PyErr_Format(PyExc_IndexError, "BMElemSeq[index]: index %d out of range", keynum); + return NULL; } static PyObject *bpy_bmeditselseq_subscript_slice(BPy_BMEditSelSeq *self, @@ -254,54 +252,51 @@ static PyObject *bpy_bmeditselseq_subscript(BPy_BMEditSelSeq *self, PyObject *ke } return bpy_bmeditselseq_subscript_int(self, i); } - else if (PySlice_Check(key)) { + if (PySlice_Check(key)) { PySliceObject *key_slice = (PySliceObject *)key; Py_ssize_t step = 1; if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) { return NULL; } - else if (step != 1) { + if (step != 1) { PyErr_SetString(PyExc_TypeError, "BMElemSeq[slice]: slice steps not supported"); return NULL; } - else if (key_slice->start == Py_None && key_slice->stop == Py_None) { + if (key_slice->start == Py_None && key_slice->stop == Py_None) { return bpy_bmeditselseq_subscript_slice(self, 0, PY_SSIZE_T_MAX); } - else { - Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; - /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ - if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) { - return NULL; - } - if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) { - return NULL; - } + Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; - if (start < 0 || stop < 0) { - /* only get the length for negative values */ - Py_ssize_t len = bpy_bmeditselseq_length(self); - if (start < 0) { - start += len; - } - if (stop < 0) { - stop += len; - } - } + /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ + if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) { + return NULL; + } + if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) { + return NULL; + } - if (stop - start <= 0) { - return PyList_New(0); + if (start < 0 || stop < 0) { + /* only get the length for negative values */ + Py_ssize_t len = bpy_bmeditselseq_length(self); + if (start < 0) { + start += len; } - else { - return bpy_bmeditselseq_subscript_slice(self, start, stop); + if (stop < 0) { + stop += len; } } + + if (stop - start <= 0) { + return PyList_New(0); + } + + return bpy_bmeditselseq_subscript_slice(self, start, stop); } - else { - PyErr_SetString(PyExc_AttributeError, "BMElemSeq[key]: invalid key, key must be an int"); - return NULL; - } + + PyErr_SetString(PyExc_AttributeError, "BMElemSeq[key]: invalid key, key must be an int"); + return NULL; } static int bpy_bmeditselseq_contains(BPy_BMEditSelSeq *self, PyObject *value) @@ -358,10 +353,9 @@ static PyObject *bpy_bmeditseliter_next(BPy_BMEditSelIter *self) PyErr_SetNone(PyExc_StopIteration); return NULL; } - else { - self->ese = ese->next; - return (PyObject *)BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head); - } + + self->ese = ese->next; + return (PyObject *)BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head); } PyTypeObject BPy_BMEditSelSeq_Type; diff --git a/source/blender/python/bmesh/bmesh_py_utils.c b/source/blender/python/bmesh/bmesh_py_utils.c index 9b207693e37..eab9ab226e4 100644 --- a/source/blender/python/bmesh/bmesh_py_utils.c +++ b/source/blender/python/bmesh/bmesh_py_utils.c @@ -91,11 +91,10 @@ static PyObject *bpy_bm_utils_vert_collapse_edge(PyObject *UNUSED(self), PyObjec if (e_new) { return BPy_BMEdge_CreatePyObject(bm, e_new); } - else { - PyErr_SetString(PyExc_ValueError, - "vert_collapse_edge(vert, edge): no new edge created, internal error"); - return NULL; - } + + PyErr_SetString(PyExc_ValueError, + "vert_collapse_edge(vert, edge): no new edge created, internal error"); + return NULL; } PyDoc_STRVAR(bpy_bm_utils_vert_collapse_faces_doc, @@ -158,11 +157,10 @@ static PyObject *bpy_bm_utils_vert_collapse_faces(PyObject *UNUSED(self), PyObje if (e_new) { return BPy_BMEdge_CreatePyObject(bm, e_new); } - else { - PyErr_SetString(PyExc_ValueError, - "vert_collapse_faces(vert, edge): no new edge created, internal error"); - return NULL; - } + + PyErr_SetString(PyExc_ValueError, + "vert_collapse_faces(vert, edge): no new edge created, internal error"); + return NULL; } PyDoc_STRVAR(bpy_bm_utils_vert_dissolve_doc, @@ -360,11 +358,10 @@ static PyObject *bpy_bm_utils_edge_split(PyObject *UNUSED(self), PyObject *args) ret, BPy_BMEdge_CreatePyObject(bm, e_new), BPy_BMVert_CreatePyObject(bm, v_new)); return ret; } - else { - PyErr_SetString(PyExc_ValueError, - "edge_split(edge, vert): couldn't split the edge, internal error"); - return NULL; - } + + PyErr_SetString(PyExc_ValueError, + "edge_split(edge, vert): couldn't split the edge, internal error"); + return NULL; } PyDoc_STRVAR(bpy_bm_utils_edge_rotate_doc, @@ -401,9 +398,8 @@ static PyObject *bpy_bm_utils_edge_rotate(PyObject *UNUSED(self), PyObject *args if (e_new) { return BPy_BMEdge_CreatePyObject(bm, e_new); } - else { - Py_RETURN_NONE; - } + + Py_RETURN_NONE; } PyDoc_STRVAR( @@ -534,10 +530,9 @@ static PyObject *bpy_bm_utils_face_split(PyObject *UNUSED(self), PyObject *args, ret, BPy_BMFace_CreatePyObject(bm, f_new), BPy_BMLoop_CreatePyObject(bm, l_new)); return ret; } - else { - PyErr_SetString(PyExc_ValueError, "face_split(...): couldn't split the face, internal error"); - return NULL; - } + + PyErr_SetString(PyExc_ValueError, "face_split(...): couldn't split the face, internal error"); + return NULL; } PyDoc_STRVAR(bpy_bm_utils_face_split_edgenet_doc, @@ -617,11 +612,10 @@ static PyObject *bpy_bm_utils_face_split_edgenet(PyObject *UNUSED(self), } return ret; } - else { - PyErr_SetString(PyExc_ValueError, - "face_split_edgenet(...): couldn't split the face, internal error"); - return NULL; - } + + PyErr_SetString(PyExc_ValueError, + "face_split_edgenet(...): couldn't split the face, internal error"); + return NULL; } PyDoc_STRVAR(bpy_bm_utils_face_join_doc, @@ -664,9 +658,8 @@ static PyObject *bpy_bm_utils_face_join(PyObject *UNUSED(self), PyObject *args) if (f_new) { return BPy_BMFace_CreatePyObject(bm, f_new); } - else { - Py_RETURN_NONE; - } + + Py_RETURN_NONE; } PyDoc_STRVAR( @@ -721,9 +714,8 @@ static PyObject *bpy_bm_utils_face_vert_separate(PyObject *UNUSED(self), PyObjec if (v_new != v_old) { return BPy_BMVert_CreatePyObject(bm, v_new); } - else { - Py_RETURN_NONE; - } + + Py_RETURN_NONE; } PyDoc_STRVAR(bpy_bm_utils_face_flip_doc, @@ -782,9 +774,8 @@ static PyObject *bpy_bm_utils_loop_separate(PyObject *UNUSED(self), BPy_BMLoop * if (v_new != v_old) { return BPy_BMVert_CreatePyObject(bm, v_new); } - else { - Py_RETURN_NONE; - } + + Py_RETURN_NONE; } static struct PyMethodDef BPy_BM_utils_methods[] = { diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c index 2ad2794c76f..405541554c9 100644 --- a/source/blender/python/generic/bgl.c +++ b/source/blender/python/generic/bgl.c @@ -415,10 +415,9 @@ typedef struct BufferOrOffset { if (ret_str) { \ return PyUnicode_FromString((const char *)ret_str); \ } \ - else { \ - PyErr_SetString(PyExc_AttributeError, "could not get opengl string"); \ - return NULL; \ - } +\ + PyErr_SetString(PyExc_AttributeError, "could not get opengl string"); \ + return NULL; /** \} */ @@ -705,7 +704,7 @@ static int BGL_BufferOrOffsetConverter(PyObject *object, BufferOrOffset *buffer) buffer->offset = NULL; return 1; } - else if (PyNumber_Check(object)) { + if (PyNumber_Check(object)) { Py_ssize_t offset = PyNumber_AsSsize_t(object, PyExc_IndexError); if (offset == -1 && PyErr_Occurred()) { return 0; @@ -715,15 +714,14 @@ static int BGL_BufferOrOffsetConverter(PyObject *object, BufferOrOffset *buffer) buffer->offset = (void *)offset; return 1; } - else if (PyObject_TypeCheck(object, &BGL_bufferType)) { + if (PyObject_TypeCheck(object, &BGL_bufferType)) { buffer->buffer = (Buffer *)object; buffer->offset = NULL; return 1; } - else { - PyErr_SetString(PyExc_TypeError, "expected a bgl.Buffer or None"); - return 0; - } + + PyErr_SetString(PyExc_TypeError, "expected a bgl.Buffer or None"); + return 0; } #define MAX_DIMENSIONS 256 @@ -766,7 +764,7 @@ static PyObject *Buffer_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject "too many dimensions, max is " STRINGIFY(MAX_DIMENSIONS)); return NULL; } - else if (ndimensions < 1) { + if (ndimensions < 1) { PyErr_SetString(PyExc_AttributeError, "sequence must have at least one dimension"); return NULL; } @@ -913,9 +911,8 @@ static int Buffer_ass_item(Buffer *self, int i, PyObject *v) Py_DECREF(row); return ret; } - else { - return -1; - } + + return -1; } switch (self->type) { @@ -996,7 +993,7 @@ static PyObject *Buffer_subscript(Buffer *self, PyObject *item) } return Buffer_item(self, i); } - else if (PySlice_Check(item)) { + if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; if (PySlice_GetIndicesEx(item, self->dimensions[0], &start, &stop, &step, &slicelength) < 0) { @@ -1006,19 +1003,17 @@ static PyObject *Buffer_subscript(Buffer *self, PyObject *item) if (slicelength <= 0) { return PyTuple_New(0); } - else if (step == 1) { + if (step == 1) { return Buffer_slice(self, start, stop); } - else { - PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors"); - return NULL; - } - } - else { - PyErr_Format( - PyExc_TypeError, "buffer indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + + PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors"); return NULL; } + + PyErr_Format( + PyExc_TypeError, "buffer indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + return NULL; } static int Buffer_ass_subscript(Buffer *self, PyObject *item, PyObject *value) @@ -1033,7 +1028,7 @@ static int Buffer_ass_subscript(Buffer *self, PyObject *item, PyObject *value) } return Buffer_ass_item(self, i, value); } - else if (PySlice_Check(item)) { + if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; if (PySlice_GetIndicesEx(item, self->dimensions[0], &start, &stop, &step, &slicelength) < 0) { @@ -1043,16 +1038,14 @@ static int Buffer_ass_subscript(Buffer *self, PyObject *item, PyObject *value) if (step == 1) { return Buffer_ass_slice(self, start, stop, value); } - else { - PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors"); - return -1; - } - } - else { - PyErr_Format( - PyExc_TypeError, "buffer indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + + PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors"); return -1; } + + PyErr_Format( + PyExc_TypeError, "buffer indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + return -1; } static void Buffer_dealloc(Buffer *self) @@ -1442,24 +1435,10 @@ static void py_module_dict_add_method(PyObject *submodule, } } -PyObject *BPyInit_bgl(void) -{ - PyObject *submodule, *dict; - submodule = PyModule_Create(&BGL_module_def); - dict = PyModule_GetDict(submodule); - - if (PyType_Ready(&BGL_bufferType) < 0) { - return NULL; /* should never happen */ - } - - PyModule_AddObject(submodule, "Buffer", (PyObject *)&BGL_bufferType); - Py_INCREF((PyObject *)&BGL_bufferType); - /* needed since some function pointers won't be NULL */ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Waddress" #endif - #define PY_MOD_ADD_METHOD(func) \ { \ static PyMethodDef method_def = {"gl" #func, Method_##func, METH_VARARGS}; \ @@ -1467,788 +1446,790 @@ PyObject *BPyInit_bgl(void) } \ ((void)0) +static void init_bgl_version_1_0_methods(PyObject *submodule, PyObject *dict) +{ /* GL_VERSION_1_0 */ - { - PY_MOD_ADD_METHOD(BlendFunc); - PY_MOD_ADD_METHOD(Clear); - PY_MOD_ADD_METHOD(ClearColor); - PY_MOD_ADD_METHOD(ClearDepth); - PY_MOD_ADD_METHOD(ClearStencil); - PY_MOD_ADD_METHOD(ColorMask); - PY_MOD_ADD_METHOD(CullFace); - PY_MOD_ADD_METHOD(DepthFunc); - PY_MOD_ADD_METHOD(DepthMask); - PY_MOD_ADD_METHOD(DepthRange); - PY_MOD_ADD_METHOD(Disable); - PY_MOD_ADD_METHOD(DrawBuffer); - PY_MOD_ADD_METHOD(Enable); - PY_MOD_ADD_METHOD(Finish); - PY_MOD_ADD_METHOD(Flush); - PY_MOD_ADD_METHOD(FrontFace); - PY_MOD_ADD_METHOD(GetBooleanv); - PY_MOD_ADD_METHOD(GetDoublev); - PY_MOD_ADD_METHOD(GetError); - PY_MOD_ADD_METHOD(GetFloatv); - PY_MOD_ADD_METHOD(GetIntegerv); - PY_MOD_ADD_METHOD(GetString); - PY_MOD_ADD_METHOD(GetTexImage); - PY_MOD_ADD_METHOD(GetTexLevelParameterfv); - PY_MOD_ADD_METHOD(GetTexLevelParameteriv); - PY_MOD_ADD_METHOD(GetTexParameterfv); - PY_MOD_ADD_METHOD(GetTexParameteriv); - PY_MOD_ADD_METHOD(Hint); - PY_MOD_ADD_METHOD(IsEnabled); - PY_MOD_ADD_METHOD(LineWidth); - PY_MOD_ADD_METHOD(LogicOp); - PY_MOD_ADD_METHOD(PixelStoref); - PY_MOD_ADD_METHOD(PixelStorei); - PY_MOD_ADD_METHOD(PointSize); - PY_MOD_ADD_METHOD(PolygonMode); - PY_MOD_ADD_METHOD(ReadBuffer); - PY_MOD_ADD_METHOD(ReadPixels); - PY_MOD_ADD_METHOD(Scissor); - PY_MOD_ADD_METHOD(StencilFunc); - PY_MOD_ADD_METHOD(StencilMask); - PY_MOD_ADD_METHOD(StencilOp); - PY_MOD_ADD_METHOD(TexImage1D); - PY_MOD_ADD_METHOD(TexImage2D); - PY_MOD_ADD_METHOD(TexParameterf); - PY_MOD_ADD_METHOD(TexParameterfv); - PY_MOD_ADD_METHOD(TexParameteri); - PY_MOD_ADD_METHOD(TexParameteriv); - PY_MOD_ADD_METHOD(Viewport); - } - + PY_MOD_ADD_METHOD(BlendFunc); + PY_MOD_ADD_METHOD(Clear); + PY_MOD_ADD_METHOD(ClearColor); + PY_MOD_ADD_METHOD(ClearDepth); + PY_MOD_ADD_METHOD(ClearStencil); + PY_MOD_ADD_METHOD(ColorMask); + PY_MOD_ADD_METHOD(CullFace); + PY_MOD_ADD_METHOD(DepthFunc); + PY_MOD_ADD_METHOD(DepthMask); + PY_MOD_ADD_METHOD(DepthRange); + PY_MOD_ADD_METHOD(Disable); + PY_MOD_ADD_METHOD(DrawBuffer); + PY_MOD_ADD_METHOD(Enable); + PY_MOD_ADD_METHOD(Finish); + PY_MOD_ADD_METHOD(Flush); + PY_MOD_ADD_METHOD(FrontFace); + PY_MOD_ADD_METHOD(GetBooleanv); + PY_MOD_ADD_METHOD(GetDoublev); + PY_MOD_ADD_METHOD(GetError); + PY_MOD_ADD_METHOD(GetFloatv); + PY_MOD_ADD_METHOD(GetIntegerv); + PY_MOD_ADD_METHOD(GetString); + PY_MOD_ADD_METHOD(GetTexImage); + PY_MOD_ADD_METHOD(GetTexLevelParameterfv); + PY_MOD_ADD_METHOD(GetTexLevelParameteriv); + PY_MOD_ADD_METHOD(GetTexParameterfv); + PY_MOD_ADD_METHOD(GetTexParameteriv); + PY_MOD_ADD_METHOD(Hint); + PY_MOD_ADD_METHOD(IsEnabled); + PY_MOD_ADD_METHOD(LineWidth); + PY_MOD_ADD_METHOD(LogicOp); + PY_MOD_ADD_METHOD(PixelStoref); + PY_MOD_ADD_METHOD(PixelStorei); + PY_MOD_ADD_METHOD(PointSize); + PY_MOD_ADD_METHOD(PolygonMode); + PY_MOD_ADD_METHOD(ReadBuffer); + PY_MOD_ADD_METHOD(ReadPixels); + PY_MOD_ADD_METHOD(Scissor); + PY_MOD_ADD_METHOD(StencilFunc); + PY_MOD_ADD_METHOD(StencilMask); + PY_MOD_ADD_METHOD(StencilOp); + PY_MOD_ADD_METHOD(TexImage1D); + PY_MOD_ADD_METHOD(TexImage2D); + PY_MOD_ADD_METHOD(TexParameterf); + PY_MOD_ADD_METHOD(TexParameterfv); + PY_MOD_ADD_METHOD(TexParameteri); + PY_MOD_ADD_METHOD(TexParameteriv); + PY_MOD_ADD_METHOD(Viewport); +} +static void init_bgl_version_1_1_methods(PyObject *submodule, PyObject *dict) +{ /* GL_VERSION_1_1 */ - { - PY_MOD_ADD_METHOD(BindTexture); - PY_MOD_ADD_METHOD(CopyTexImage1D); - PY_MOD_ADD_METHOD(CopyTexImage2D); - PY_MOD_ADD_METHOD(CopyTexSubImage1D); - PY_MOD_ADD_METHOD(CopyTexSubImage2D); - PY_MOD_ADD_METHOD(DeleteTextures); - PY_MOD_ADD_METHOD(DrawArrays); - PY_MOD_ADD_METHOD(DrawElements); - PY_MOD_ADD_METHOD(GenTextures); - PY_MOD_ADD_METHOD(IsTexture); - PY_MOD_ADD_METHOD(PolygonOffset); - PY_MOD_ADD_METHOD(TexSubImage1D); - PY_MOD_ADD_METHOD(TexSubImage2D); - } - + PY_MOD_ADD_METHOD(BindTexture); + PY_MOD_ADD_METHOD(CopyTexImage1D); + PY_MOD_ADD_METHOD(CopyTexImage2D); + PY_MOD_ADD_METHOD(CopyTexSubImage1D); + PY_MOD_ADD_METHOD(CopyTexSubImage2D); + PY_MOD_ADD_METHOD(DeleteTextures); + PY_MOD_ADD_METHOD(DrawArrays); + PY_MOD_ADD_METHOD(DrawElements); + PY_MOD_ADD_METHOD(GenTextures); + PY_MOD_ADD_METHOD(IsTexture); + PY_MOD_ADD_METHOD(PolygonOffset); + PY_MOD_ADD_METHOD(TexSubImage1D); + PY_MOD_ADD_METHOD(TexSubImage2D); +} +static void init_bgl_version_1_2_methods(PyObject *submodule, PyObject *dict) +{ /* GL_VERSION_1_2 */ - { - PY_MOD_ADD_METHOD(CopyTexSubImage3D); - PY_MOD_ADD_METHOD(DrawRangeElements); - PY_MOD_ADD_METHOD(TexImage3D); - PY_MOD_ADD_METHOD(TexSubImage3D); - } - + PY_MOD_ADD_METHOD(CopyTexSubImage3D); + PY_MOD_ADD_METHOD(DrawRangeElements); + PY_MOD_ADD_METHOD(TexImage3D); + PY_MOD_ADD_METHOD(TexSubImage3D); +} +static void init_bgl_version_1_3_methods(PyObject *submodule, PyObject *dict) +{ /* GL_VERSION_1_3 */ - { - PY_MOD_ADD_METHOD(ActiveTexture); - PY_MOD_ADD_METHOD(CompressedTexImage1D); - PY_MOD_ADD_METHOD(CompressedTexImage2D); - PY_MOD_ADD_METHOD(CompressedTexImage3D); - PY_MOD_ADD_METHOD(CompressedTexSubImage1D); - PY_MOD_ADD_METHOD(CompressedTexSubImage2D); - PY_MOD_ADD_METHOD(CompressedTexSubImage3D); - PY_MOD_ADD_METHOD(GetCompressedTexImage); - PY_MOD_ADD_METHOD(SampleCoverage); - } - + PY_MOD_ADD_METHOD(ActiveTexture); + PY_MOD_ADD_METHOD(CompressedTexImage1D); + PY_MOD_ADD_METHOD(CompressedTexImage2D); + PY_MOD_ADD_METHOD(CompressedTexImage3D); + PY_MOD_ADD_METHOD(CompressedTexSubImage1D); + PY_MOD_ADD_METHOD(CompressedTexSubImage2D); + PY_MOD_ADD_METHOD(CompressedTexSubImage3D); + PY_MOD_ADD_METHOD(GetCompressedTexImage); + PY_MOD_ADD_METHOD(SampleCoverage); +} +static void init_bgl_version_1_4_methods(PyObject *submodule, PyObject *dict) +{ /* GL_VERSION_1_4 */ - { - PY_MOD_ADD_METHOD(BlendColor); - PY_MOD_ADD_METHOD(BlendEquation); - } - - /* GL_VERSION_1_5 */ - { - PY_MOD_ADD_METHOD(BeginQuery); - PY_MOD_ADD_METHOD(BindBuffer); - PY_MOD_ADD_METHOD(BufferData); - PY_MOD_ADD_METHOD(BufferSubData); - PY_MOD_ADD_METHOD(DeleteBuffers); - PY_MOD_ADD_METHOD(DeleteQueries); - PY_MOD_ADD_METHOD(EndQuery); - PY_MOD_ADD_METHOD(GenBuffers); - PY_MOD_ADD_METHOD(GenQueries); - PY_MOD_ADD_METHOD(GetBufferParameteriv); - PY_MOD_ADD_METHOD(GetBufferPointerv); - PY_MOD_ADD_METHOD(GetBufferSubData); - PY_MOD_ADD_METHOD(GetQueryObjectiv); - PY_MOD_ADD_METHOD(GetQueryObjectuiv); - PY_MOD_ADD_METHOD(GetQueryiv); - PY_MOD_ADD_METHOD(IsBuffer); - PY_MOD_ADD_METHOD(IsQuery); - PY_MOD_ADD_METHOD(MapBuffer); - PY_MOD_ADD_METHOD(UnmapBuffer); - } - + PY_MOD_ADD_METHOD(BlendColor); + PY_MOD_ADD_METHOD(BlendEquation); +} +static void init_bgl_version_1_5_methods(PyObject *submodule, PyObject *dict) +/* GL_VERSION_1_5 */ +{ + PY_MOD_ADD_METHOD(BeginQuery); + PY_MOD_ADD_METHOD(BindBuffer); + PY_MOD_ADD_METHOD(BufferData); + PY_MOD_ADD_METHOD(BufferSubData); + PY_MOD_ADD_METHOD(DeleteBuffers); + PY_MOD_ADD_METHOD(DeleteQueries); + PY_MOD_ADD_METHOD(EndQuery); + PY_MOD_ADD_METHOD(GenBuffers); + PY_MOD_ADD_METHOD(GenQueries); + PY_MOD_ADD_METHOD(GetBufferParameteriv); + PY_MOD_ADD_METHOD(GetBufferPointerv); + PY_MOD_ADD_METHOD(GetBufferSubData); + PY_MOD_ADD_METHOD(GetQueryObjectiv); + PY_MOD_ADD_METHOD(GetQueryObjectuiv); + PY_MOD_ADD_METHOD(GetQueryiv); + PY_MOD_ADD_METHOD(IsBuffer); + PY_MOD_ADD_METHOD(IsQuery); + PY_MOD_ADD_METHOD(MapBuffer); + PY_MOD_ADD_METHOD(UnmapBuffer); +} +static void init_bgl_version_2_0_methods(PyObject *submodule, PyObject *dict) +{ /* GL_VERSION_2_0 */ - { - PY_MOD_ADD_METHOD(AttachShader); - PY_MOD_ADD_METHOD(BindAttribLocation); - PY_MOD_ADD_METHOD(BlendEquationSeparate); - PY_MOD_ADD_METHOD(CompileShader); - PY_MOD_ADD_METHOD(CreateProgram); - PY_MOD_ADD_METHOD(CreateShader); - PY_MOD_ADD_METHOD(DeleteProgram); - PY_MOD_ADD_METHOD(DeleteShader); - PY_MOD_ADD_METHOD(DetachShader); - PY_MOD_ADD_METHOD(DisableVertexAttribArray); - PY_MOD_ADD_METHOD(DrawBuffers); - PY_MOD_ADD_METHOD(EnableVertexAttribArray); - PY_MOD_ADD_METHOD(GetActiveAttrib); - PY_MOD_ADD_METHOD(GetActiveUniform); - PY_MOD_ADD_METHOD(GetAttachedShaders); - PY_MOD_ADD_METHOD(GetAttribLocation); - PY_MOD_ADD_METHOD(GetProgramInfoLog); - PY_MOD_ADD_METHOD(GetProgramiv); - PY_MOD_ADD_METHOD(GetShaderInfoLog); - PY_MOD_ADD_METHOD(GetShaderSource); - PY_MOD_ADD_METHOD(GetShaderiv); - PY_MOD_ADD_METHOD(GetUniformLocation); - PY_MOD_ADD_METHOD(GetUniformfv); - PY_MOD_ADD_METHOD(GetUniformiv); - PY_MOD_ADD_METHOD(GetVertexAttribPointerv); - PY_MOD_ADD_METHOD(GetVertexAttribdv); - PY_MOD_ADD_METHOD(GetVertexAttribfv); - PY_MOD_ADD_METHOD(GetVertexAttribiv); - PY_MOD_ADD_METHOD(IsProgram); - PY_MOD_ADD_METHOD(IsShader); - PY_MOD_ADD_METHOD(LinkProgram); - PY_MOD_ADD_METHOD(ShaderSource); - PY_MOD_ADD_METHOD(StencilFuncSeparate); - PY_MOD_ADD_METHOD(StencilMaskSeparate); - PY_MOD_ADD_METHOD(StencilOpSeparate); - PY_MOD_ADD_METHOD(Uniform1f); - PY_MOD_ADD_METHOD(Uniform1fv); - PY_MOD_ADD_METHOD(Uniform1i); - PY_MOD_ADD_METHOD(Uniform1iv); - PY_MOD_ADD_METHOD(Uniform2f); - PY_MOD_ADD_METHOD(Uniform2fv); - PY_MOD_ADD_METHOD(Uniform2i); - PY_MOD_ADD_METHOD(Uniform2iv); - PY_MOD_ADD_METHOD(Uniform3f); - PY_MOD_ADD_METHOD(Uniform3fv); - PY_MOD_ADD_METHOD(Uniform3i); - PY_MOD_ADD_METHOD(Uniform3iv); - PY_MOD_ADD_METHOD(Uniform4f); - PY_MOD_ADD_METHOD(Uniform4fv); - PY_MOD_ADD_METHOD(Uniform4i); - PY_MOD_ADD_METHOD(Uniform4iv); - PY_MOD_ADD_METHOD(UniformMatrix2fv); - PY_MOD_ADD_METHOD(UniformMatrix3fv); - PY_MOD_ADD_METHOD(UniformMatrix4fv); - PY_MOD_ADD_METHOD(UseProgram); - PY_MOD_ADD_METHOD(ValidateProgram); - PY_MOD_ADD_METHOD(VertexAttrib1d); - PY_MOD_ADD_METHOD(VertexAttrib1dv); - PY_MOD_ADD_METHOD(VertexAttrib1f); - PY_MOD_ADD_METHOD(VertexAttrib1fv); - PY_MOD_ADD_METHOD(VertexAttrib1s); - PY_MOD_ADD_METHOD(VertexAttrib1sv); - PY_MOD_ADD_METHOD(VertexAttrib2d); - PY_MOD_ADD_METHOD(VertexAttrib2dv); - PY_MOD_ADD_METHOD(VertexAttrib2f); - PY_MOD_ADD_METHOD(VertexAttrib2fv); - PY_MOD_ADD_METHOD(VertexAttrib2s); - PY_MOD_ADD_METHOD(VertexAttrib2sv); - PY_MOD_ADD_METHOD(VertexAttrib3d); - PY_MOD_ADD_METHOD(VertexAttrib3dv); - PY_MOD_ADD_METHOD(VertexAttrib3f); - PY_MOD_ADD_METHOD(VertexAttrib3fv); - PY_MOD_ADD_METHOD(VertexAttrib3s); - PY_MOD_ADD_METHOD(VertexAttrib3sv); - PY_MOD_ADD_METHOD(VertexAttrib4Nbv); - PY_MOD_ADD_METHOD(VertexAttrib4Niv); - PY_MOD_ADD_METHOD(VertexAttrib4Nsv); - PY_MOD_ADD_METHOD(VertexAttrib4Nub); - PY_MOD_ADD_METHOD(VertexAttrib4Nubv); - PY_MOD_ADD_METHOD(VertexAttrib4Nuiv); - PY_MOD_ADD_METHOD(VertexAttrib4Nusv); - PY_MOD_ADD_METHOD(VertexAttrib4bv); - PY_MOD_ADD_METHOD(VertexAttrib4d); - PY_MOD_ADD_METHOD(VertexAttrib4dv); - PY_MOD_ADD_METHOD(VertexAttrib4f); - PY_MOD_ADD_METHOD(VertexAttrib4fv); - PY_MOD_ADD_METHOD(VertexAttrib4iv); - PY_MOD_ADD_METHOD(VertexAttrib4s); - PY_MOD_ADD_METHOD(VertexAttrib4sv); - PY_MOD_ADD_METHOD(VertexAttrib4ubv); - PY_MOD_ADD_METHOD(VertexAttrib4uiv); - PY_MOD_ADD_METHOD(VertexAttrib4usv); - PY_MOD_ADD_METHOD(VertexAttribPointer); - } - + PY_MOD_ADD_METHOD(AttachShader); + PY_MOD_ADD_METHOD(BindAttribLocation); + PY_MOD_ADD_METHOD(BlendEquationSeparate); + PY_MOD_ADD_METHOD(CompileShader); + PY_MOD_ADD_METHOD(CreateProgram); + PY_MOD_ADD_METHOD(CreateShader); + PY_MOD_ADD_METHOD(DeleteProgram); + PY_MOD_ADD_METHOD(DeleteShader); + PY_MOD_ADD_METHOD(DetachShader); + PY_MOD_ADD_METHOD(DisableVertexAttribArray); + PY_MOD_ADD_METHOD(DrawBuffers); + PY_MOD_ADD_METHOD(EnableVertexAttribArray); + PY_MOD_ADD_METHOD(GetActiveAttrib); + PY_MOD_ADD_METHOD(GetActiveUniform); + PY_MOD_ADD_METHOD(GetAttachedShaders); + PY_MOD_ADD_METHOD(GetAttribLocation); + PY_MOD_ADD_METHOD(GetProgramInfoLog); + PY_MOD_ADD_METHOD(GetProgramiv); + PY_MOD_ADD_METHOD(GetShaderInfoLog); + PY_MOD_ADD_METHOD(GetShaderSource); + PY_MOD_ADD_METHOD(GetShaderiv); + PY_MOD_ADD_METHOD(GetUniformLocation); + PY_MOD_ADD_METHOD(GetUniformfv); + PY_MOD_ADD_METHOD(GetUniformiv); + PY_MOD_ADD_METHOD(GetVertexAttribPointerv); + PY_MOD_ADD_METHOD(GetVertexAttribdv); + PY_MOD_ADD_METHOD(GetVertexAttribfv); + PY_MOD_ADD_METHOD(GetVertexAttribiv); + PY_MOD_ADD_METHOD(IsProgram); + PY_MOD_ADD_METHOD(IsShader); + PY_MOD_ADD_METHOD(LinkProgram); + PY_MOD_ADD_METHOD(ShaderSource); + PY_MOD_ADD_METHOD(StencilFuncSeparate); + PY_MOD_ADD_METHOD(StencilMaskSeparate); + PY_MOD_ADD_METHOD(StencilOpSeparate); + PY_MOD_ADD_METHOD(Uniform1f); + PY_MOD_ADD_METHOD(Uniform1fv); + PY_MOD_ADD_METHOD(Uniform1i); + PY_MOD_ADD_METHOD(Uniform1iv); + PY_MOD_ADD_METHOD(Uniform2f); + PY_MOD_ADD_METHOD(Uniform2fv); + PY_MOD_ADD_METHOD(Uniform2i); + PY_MOD_ADD_METHOD(Uniform2iv); + PY_MOD_ADD_METHOD(Uniform3f); + PY_MOD_ADD_METHOD(Uniform3fv); + PY_MOD_ADD_METHOD(Uniform3i); + PY_MOD_ADD_METHOD(Uniform3iv); + PY_MOD_ADD_METHOD(Uniform4f); + PY_MOD_ADD_METHOD(Uniform4fv); + PY_MOD_ADD_METHOD(Uniform4i); + PY_MOD_ADD_METHOD(Uniform4iv); + PY_MOD_ADD_METHOD(UniformMatrix2fv); + PY_MOD_ADD_METHOD(UniformMatrix3fv); + PY_MOD_ADD_METHOD(UniformMatrix4fv); + PY_MOD_ADD_METHOD(UseProgram); + PY_MOD_ADD_METHOD(ValidateProgram); + PY_MOD_ADD_METHOD(VertexAttrib1d); + PY_MOD_ADD_METHOD(VertexAttrib1dv); + PY_MOD_ADD_METHOD(VertexAttrib1f); + PY_MOD_ADD_METHOD(VertexAttrib1fv); + PY_MOD_ADD_METHOD(VertexAttrib1s); + PY_MOD_ADD_METHOD(VertexAttrib1sv); + PY_MOD_ADD_METHOD(VertexAttrib2d); + PY_MOD_ADD_METHOD(VertexAttrib2dv); + PY_MOD_ADD_METHOD(VertexAttrib2f); + PY_MOD_ADD_METHOD(VertexAttrib2fv); + PY_MOD_ADD_METHOD(VertexAttrib2s); + PY_MOD_ADD_METHOD(VertexAttrib2sv); + PY_MOD_ADD_METHOD(VertexAttrib3d); + PY_MOD_ADD_METHOD(VertexAttrib3dv); + PY_MOD_ADD_METHOD(VertexAttrib3f); + PY_MOD_ADD_METHOD(VertexAttrib3fv); + PY_MOD_ADD_METHOD(VertexAttrib3s); + PY_MOD_ADD_METHOD(VertexAttrib3sv); + PY_MOD_ADD_METHOD(VertexAttrib4Nbv); + PY_MOD_ADD_METHOD(VertexAttrib4Niv); + PY_MOD_ADD_METHOD(VertexAttrib4Nsv); + PY_MOD_ADD_METHOD(VertexAttrib4Nub); + PY_MOD_ADD_METHOD(VertexAttrib4Nubv); + PY_MOD_ADD_METHOD(VertexAttrib4Nuiv); + PY_MOD_ADD_METHOD(VertexAttrib4Nusv); + PY_MOD_ADD_METHOD(VertexAttrib4bv); + PY_MOD_ADD_METHOD(VertexAttrib4d); + PY_MOD_ADD_METHOD(VertexAttrib4dv); + PY_MOD_ADD_METHOD(VertexAttrib4f); + PY_MOD_ADD_METHOD(VertexAttrib4fv); + PY_MOD_ADD_METHOD(VertexAttrib4iv); + PY_MOD_ADD_METHOD(VertexAttrib4s); + PY_MOD_ADD_METHOD(VertexAttrib4sv); + PY_MOD_ADD_METHOD(VertexAttrib4ubv); + PY_MOD_ADD_METHOD(VertexAttrib4uiv); + PY_MOD_ADD_METHOD(VertexAttrib4usv); + PY_MOD_ADD_METHOD(VertexAttribPointer); +} +static void init_bgl_version_2_1_methods(PyObject *submodule, PyObject *dict) +{ /* GL_VERSION_2_1 */ - { - PY_MOD_ADD_METHOD(UniformMatrix2x3fv); - PY_MOD_ADD_METHOD(UniformMatrix2x4fv); - PY_MOD_ADD_METHOD(UniformMatrix3x2fv); - PY_MOD_ADD_METHOD(UniformMatrix3x4fv); - PY_MOD_ADD_METHOD(UniformMatrix4x2fv); - PY_MOD_ADD_METHOD(UniformMatrix4x3fv); - } - + PY_MOD_ADD_METHOD(UniformMatrix2x3fv); + PY_MOD_ADD_METHOD(UniformMatrix2x4fv); + PY_MOD_ADD_METHOD(UniformMatrix3x2fv); + PY_MOD_ADD_METHOD(UniformMatrix3x4fv); + PY_MOD_ADD_METHOD(UniformMatrix4x2fv); + PY_MOD_ADD_METHOD(UniformMatrix4x3fv); +} +static void init_bgl_version_3_0_methods(PyObject *submodule, PyObject *dict) +{ /* GL_VERSION_3_0 */ - { - PY_MOD_ADD_METHOD(BindFramebuffer); - PY_MOD_ADD_METHOD(BindRenderbuffer); - PY_MOD_ADD_METHOD(BindVertexArray); - PY_MOD_ADD_METHOD(BlitFramebuffer); - PY_MOD_ADD_METHOD(CheckFramebufferStatus); - PY_MOD_ADD_METHOD(DeleteFramebuffers); - PY_MOD_ADD_METHOD(DeleteRenderbuffers); - PY_MOD_ADD_METHOD(DeleteVertexArrays); - PY_MOD_ADD_METHOD(FramebufferRenderbuffer); - PY_MOD_ADD_METHOD(GenFramebuffers); - PY_MOD_ADD_METHOD(GenRenderbuffers); - PY_MOD_ADD_METHOD(GenVertexArrays); - PY_MOD_ADD_METHOD(GetStringi); - PY_MOD_ADD_METHOD(IsVertexArray); - PY_MOD_ADD_METHOD(RenderbufferStorage); - PY_MOD_ADD_METHOD(VertexAttribIPointer); - } - + PY_MOD_ADD_METHOD(BindFramebuffer); + PY_MOD_ADD_METHOD(BindRenderbuffer); + PY_MOD_ADD_METHOD(BindVertexArray); + PY_MOD_ADD_METHOD(BlitFramebuffer); + PY_MOD_ADD_METHOD(CheckFramebufferStatus); + PY_MOD_ADD_METHOD(DeleteFramebuffers); + PY_MOD_ADD_METHOD(DeleteRenderbuffers); + PY_MOD_ADD_METHOD(DeleteVertexArrays); + PY_MOD_ADD_METHOD(FramebufferRenderbuffer); + PY_MOD_ADD_METHOD(GenFramebuffers); + PY_MOD_ADD_METHOD(GenRenderbuffers); + PY_MOD_ADD_METHOD(GenVertexArrays); + PY_MOD_ADD_METHOD(GetStringi); + PY_MOD_ADD_METHOD(IsVertexArray); + PY_MOD_ADD_METHOD(RenderbufferStorage); + PY_MOD_ADD_METHOD(VertexAttribIPointer); +} +static void init_bgl_version_3_1_methods(PyObject *submodule, PyObject *dict) +{ /* GL_VERSION_3_1 */ - { - PY_MOD_ADD_METHOD(BindBufferBase); - PY_MOD_ADD_METHOD(BindBufferRange); - PY_MOD_ADD_METHOD(GetActiveUniformBlockName); - PY_MOD_ADD_METHOD(GetActiveUniformBlockiv); - PY_MOD_ADD_METHOD(GetActiveUniformName); - PY_MOD_ADD_METHOD(GetActiveUniformsiv); - PY_MOD_ADD_METHOD(GetIntegeri_v); - PY_MOD_ADD_METHOD(GetUniformBlockIndex); - PY_MOD_ADD_METHOD(GetUniformIndices); - PY_MOD_ADD_METHOD(UniformBlockBinding); - } - + PY_MOD_ADD_METHOD(BindBufferBase); + PY_MOD_ADD_METHOD(BindBufferRange); + PY_MOD_ADD_METHOD(GetActiveUniformBlockName); + PY_MOD_ADD_METHOD(GetActiveUniformBlockiv); + PY_MOD_ADD_METHOD(GetActiveUniformName); + PY_MOD_ADD_METHOD(GetActiveUniformsiv); + PY_MOD_ADD_METHOD(GetIntegeri_v); + PY_MOD_ADD_METHOD(GetUniformBlockIndex); + PY_MOD_ADD_METHOD(GetUniformIndices); + PY_MOD_ADD_METHOD(UniformBlockBinding); +} +static void init_bgl_version_3_2_methods(PyObject *submodule, PyObject *dict) +{ /* GL_VERSION_3_2 */ - { - PY_MOD_ADD_METHOD(FramebufferTexture); - PY_MOD_ADD_METHOD(GetBufferParameteri64v); - PY_MOD_ADD_METHOD(GetInteger64i_v); - PY_MOD_ADD_METHOD(GetMultisamplefv); - PY_MOD_ADD_METHOD(SampleMaski); - PY_MOD_ADD_METHOD(TexImage2DMultisample); - PY_MOD_ADD_METHOD(TexImage3DMultisample); - } - + PY_MOD_ADD_METHOD(FramebufferTexture); + PY_MOD_ADD_METHOD(GetBufferParameteri64v); + PY_MOD_ADD_METHOD(GetInteger64i_v); + PY_MOD_ADD_METHOD(GetMultisamplefv); + PY_MOD_ADD_METHOD(SampleMaski); + PY_MOD_ADD_METHOD(TexImage2DMultisample); + PY_MOD_ADD_METHOD(TexImage3DMultisample); +} +static void init_bgl_version_3_3_methods(PyObject *UNUSED(submodule), PyObject *UNUSED(dict)) +{ /* GL_VERSION_3_3 */ - { - } +} #define PY_DICT_ADD_INT(x) py_module_dict_add_int(dict, #x, x) #define PY_DICT_ADD_INT64(x) py_module_dict_add_int64(dict, #x, x) +static void init_bgl_version_1_1_constants(PyObject *dict) +{ /* GL_VERSION_1_1 */ - { - PY_DICT_ADD_INT(GL_ALPHA); - PY_DICT_ADD_INT(GL_ALWAYS); - PY_DICT_ADD_INT(GL_AND); - PY_DICT_ADD_INT(GL_AND_INVERTED); - PY_DICT_ADD_INT(GL_AND_REVERSE); - PY_DICT_ADD_INT(GL_BACK); - PY_DICT_ADD_INT(GL_BACK_LEFT); - PY_DICT_ADD_INT(GL_BACK_RIGHT); - PY_DICT_ADD_INT(GL_BLEND); - PY_DICT_ADD_INT(GL_BLEND_DST); - PY_DICT_ADD_INT(GL_BLEND_SRC); - PY_DICT_ADD_INT(GL_BLUE); - PY_DICT_ADD_INT(GL_BYTE); - PY_DICT_ADD_INT(GL_CCW); - PY_DICT_ADD_INT(GL_CLEAR); - PY_DICT_ADD_INT(GL_COLOR); - PY_DICT_ADD_INT(GL_COLOR_BUFFER_BIT); - PY_DICT_ADD_INT(GL_COLOR_CLEAR_VALUE); - PY_DICT_ADD_INT(GL_COLOR_LOGIC_OP); - PY_DICT_ADD_INT(GL_COLOR_WRITEMASK); - PY_DICT_ADD_INT(GL_COPY); - PY_DICT_ADD_INT(GL_COPY_INVERTED); - PY_DICT_ADD_INT(GL_CULL_FACE); - PY_DICT_ADD_INT(GL_CULL_FACE_MODE); - PY_DICT_ADD_INT(GL_CW); - PY_DICT_ADD_INT(GL_DECR); - PY_DICT_ADD_INT(GL_DEPTH); - PY_DICT_ADD_INT(GL_DEPTH_BUFFER_BIT); - PY_DICT_ADD_INT(GL_DEPTH_CLEAR_VALUE); - PY_DICT_ADD_INT(GL_DEPTH_COMPONENT); - PY_DICT_ADD_INT(GL_DEPTH_FUNC); - PY_DICT_ADD_INT(GL_DEPTH_RANGE); - PY_DICT_ADD_INT(GL_DEPTH_TEST); - PY_DICT_ADD_INT(GL_DEPTH_WRITEMASK); - PY_DICT_ADD_INT(GL_DITHER); - PY_DICT_ADD_INT(GL_DONT_CARE); - PY_DICT_ADD_INT(GL_DOUBLE); - PY_DICT_ADD_INT(GL_DOUBLEBUFFER); - PY_DICT_ADD_INT(GL_DRAW_BUFFER); - PY_DICT_ADD_INT(GL_DST_ALPHA); - PY_DICT_ADD_INT(GL_DST_COLOR); - PY_DICT_ADD_INT(GL_EQUAL); - PY_DICT_ADD_INT(GL_EQUIV); - PY_DICT_ADD_INT(GL_EXTENSIONS); - PY_DICT_ADD_INT(GL_FALSE); - PY_DICT_ADD_INT(GL_FASTEST); - PY_DICT_ADD_INT(GL_FILL); - PY_DICT_ADD_INT(GL_FLOAT); - PY_DICT_ADD_INT(GL_FRONT); - PY_DICT_ADD_INT(GL_FRONT_AND_BACK); - PY_DICT_ADD_INT(GL_FRONT_FACE); - PY_DICT_ADD_INT(GL_FRONT_LEFT); - PY_DICT_ADD_INT(GL_FRONT_RIGHT); - PY_DICT_ADD_INT(GL_GEQUAL); - PY_DICT_ADD_INT(GL_GREATER); - PY_DICT_ADD_INT(GL_GREEN); - PY_DICT_ADD_INT(GL_INCR); - PY_DICT_ADD_INT(GL_INT); - PY_DICT_ADD_INT(GL_INVALID_ENUM); - PY_DICT_ADD_INT(GL_INVALID_OPERATION); - PY_DICT_ADD_INT(GL_INVALID_VALUE); - PY_DICT_ADD_INT(GL_INVERT); - PY_DICT_ADD_INT(GL_KEEP); - PY_DICT_ADD_INT(GL_LEFT); - PY_DICT_ADD_INT(GL_LEQUAL); - PY_DICT_ADD_INT(GL_LESS); - PY_DICT_ADD_INT(GL_LINE); - PY_DICT_ADD_INT(GL_LINEAR); - PY_DICT_ADD_INT(GL_LINEAR_MIPMAP_LINEAR); - PY_DICT_ADD_INT(GL_LINEAR_MIPMAP_NEAREST); - PY_DICT_ADD_INT(GL_LINES); - PY_DICT_ADD_INT(GL_LINE_LOOP); - PY_DICT_ADD_INT(GL_LINE_SMOOTH); - PY_DICT_ADD_INT(GL_LINE_SMOOTH_HINT); - PY_DICT_ADD_INT(GL_LINE_STRIP); - PY_DICT_ADD_INT(GL_LINE_WIDTH); - PY_DICT_ADD_INT(GL_LINE_WIDTH_GRANULARITY); - PY_DICT_ADD_INT(GL_LINE_WIDTH_RANGE); - PY_DICT_ADD_INT(GL_LOGIC_OP_MODE); - PY_DICT_ADD_INT(GL_MAX_TEXTURE_SIZE); - PY_DICT_ADD_INT(GL_MAX_VIEWPORT_DIMS); - PY_DICT_ADD_INT(GL_NAND); - PY_DICT_ADD_INT(GL_NEAREST); - PY_DICT_ADD_INT(GL_NEAREST_MIPMAP_LINEAR); - PY_DICT_ADD_INT(GL_NEAREST_MIPMAP_NEAREST); - PY_DICT_ADD_INT(GL_NEVER); - PY_DICT_ADD_INT(GL_NICEST); - PY_DICT_ADD_INT(GL_NONE); - PY_DICT_ADD_INT(GL_NOOP); - PY_DICT_ADD_INT(GL_NOR); - PY_DICT_ADD_INT(GL_NOTEQUAL); - PY_DICT_ADD_INT(GL_NO_ERROR); - PY_DICT_ADD_INT(GL_ONE); - PY_DICT_ADD_INT(GL_ONE_MINUS_DST_ALPHA); - PY_DICT_ADD_INT(GL_ONE_MINUS_DST_COLOR); - PY_DICT_ADD_INT(GL_ONE_MINUS_SRC_ALPHA); - PY_DICT_ADD_INT(GL_ONE_MINUS_SRC_COLOR); - PY_DICT_ADD_INT(GL_OR); - PY_DICT_ADD_INT(GL_OR_INVERTED); - PY_DICT_ADD_INT(GL_OR_REVERSE); - PY_DICT_ADD_INT(GL_OUT_OF_MEMORY); - PY_DICT_ADD_INT(GL_PACK_ALIGNMENT); - PY_DICT_ADD_INT(GL_PACK_LSB_FIRST); - PY_DICT_ADD_INT(GL_PACK_ROW_LENGTH); - PY_DICT_ADD_INT(GL_PACK_SKIP_PIXELS); - PY_DICT_ADD_INT(GL_PACK_SKIP_ROWS); - PY_DICT_ADD_INT(GL_PACK_SWAP_BYTES); - PY_DICT_ADD_INT(GL_POINT); - PY_DICT_ADD_INT(GL_POINTS); - PY_DICT_ADD_INT(GL_POINT_SIZE); - PY_DICT_ADD_INT(GL_POLYGON_MODE); - PY_DICT_ADD_INT(GL_POLYGON_OFFSET_FACTOR); - PY_DICT_ADD_INT(GL_POLYGON_OFFSET_FILL); - PY_DICT_ADD_INT(GL_POLYGON_OFFSET_LINE); - PY_DICT_ADD_INT(GL_POLYGON_OFFSET_POINT); - PY_DICT_ADD_INT(GL_POLYGON_OFFSET_UNITS); - PY_DICT_ADD_INT(GL_POLYGON_SMOOTH); - PY_DICT_ADD_INT(GL_POLYGON_SMOOTH_HINT); - PY_DICT_ADD_INT(GL_PROXY_TEXTURE_1D); - PY_DICT_ADD_INT(GL_PROXY_TEXTURE_2D); - PY_DICT_ADD_INT(GL_R3_G3_B2); - PY_DICT_ADD_INT(GL_READ_BUFFER); - PY_DICT_ADD_INT(GL_RED); - PY_DICT_ADD_INT(GL_RENDERER); - PY_DICT_ADD_INT(GL_REPEAT); - PY_DICT_ADD_INT(GL_REPLACE); - PY_DICT_ADD_INT(GL_RGB); - PY_DICT_ADD_INT(GL_RGB10); - PY_DICT_ADD_INT(GL_RGB10_A2); - PY_DICT_ADD_INT(GL_RGB12); - PY_DICT_ADD_INT(GL_RGB16); - PY_DICT_ADD_INT(GL_RGB4); - PY_DICT_ADD_INT(GL_RGB5); - PY_DICT_ADD_INT(GL_RGB5_A1); - PY_DICT_ADD_INT(GL_RGB8); - PY_DICT_ADD_INT(GL_RGBA); - PY_DICT_ADD_INT(GL_RGBA12); - PY_DICT_ADD_INT(GL_RGBA16); - PY_DICT_ADD_INT(GL_RGBA2); - PY_DICT_ADD_INT(GL_RGBA4); - PY_DICT_ADD_INT(GL_RGBA8); - PY_DICT_ADD_INT(GL_RIGHT); - PY_DICT_ADD_INT(GL_SCISSOR_BOX); - PY_DICT_ADD_INT(GL_SCISSOR_TEST); - PY_DICT_ADD_INT(GL_SET); - PY_DICT_ADD_INT(GL_SHORT); - PY_DICT_ADD_INT(GL_SRC_ALPHA); - PY_DICT_ADD_INT(GL_SRC_ALPHA_SATURATE); - PY_DICT_ADD_INT(GL_SRC_COLOR); - PY_DICT_ADD_INT(GL_STENCIL); - PY_DICT_ADD_INT(GL_STENCIL_BUFFER_BIT); - PY_DICT_ADD_INT(GL_STENCIL_CLEAR_VALUE); - PY_DICT_ADD_INT(GL_STENCIL_FAIL); - PY_DICT_ADD_INT(GL_STENCIL_FUNC); - PY_DICT_ADD_INT(GL_STENCIL_INDEX); - PY_DICT_ADD_INT(GL_STENCIL_PASS_DEPTH_FAIL); - PY_DICT_ADD_INT(GL_STENCIL_PASS_DEPTH_PASS); - PY_DICT_ADD_INT(GL_STENCIL_REF); - PY_DICT_ADD_INT(GL_STENCIL_TEST); - PY_DICT_ADD_INT(GL_STENCIL_VALUE_MASK); - PY_DICT_ADD_INT(GL_STENCIL_WRITEMASK); - PY_DICT_ADD_INT(GL_STEREO); - PY_DICT_ADD_INT(GL_SUBPIXEL_BITS); - PY_DICT_ADD_INT(GL_TEXTURE); - PY_DICT_ADD_INT(GL_TEXTURE_1D); - PY_DICT_ADD_INT(GL_TEXTURE_2D); - PY_DICT_ADD_INT(GL_TEXTURE_ALPHA_SIZE); - PY_DICT_ADD_INT(GL_TEXTURE_BINDING_1D); - PY_DICT_ADD_INT(GL_TEXTURE_BINDING_2D); - PY_DICT_ADD_INT(GL_TEXTURE_BLUE_SIZE); - PY_DICT_ADD_INT(GL_TEXTURE_BORDER_COLOR); - PY_DICT_ADD_INT(GL_TEXTURE_GREEN_SIZE); - PY_DICT_ADD_INT(GL_TEXTURE_HEIGHT); - PY_DICT_ADD_INT(GL_TEXTURE_INTERNAL_FORMAT); - PY_DICT_ADD_INT(GL_TEXTURE_MAG_FILTER); - PY_DICT_ADD_INT(GL_TEXTURE_MIN_FILTER); - PY_DICT_ADD_INT(GL_TEXTURE_RED_SIZE); - PY_DICT_ADD_INT(GL_TEXTURE_WIDTH); - PY_DICT_ADD_INT(GL_TEXTURE_WRAP_S); - PY_DICT_ADD_INT(GL_TEXTURE_WRAP_T); - PY_DICT_ADD_INT(GL_TRIANGLES); - PY_DICT_ADD_INT(GL_TRIANGLE_FAN); - PY_DICT_ADD_INT(GL_TRIANGLE_STRIP); - PY_DICT_ADD_INT(GL_TRUE); - PY_DICT_ADD_INT(GL_UNPACK_ALIGNMENT); - PY_DICT_ADD_INT(GL_UNPACK_LSB_FIRST); - PY_DICT_ADD_INT(GL_UNPACK_ROW_LENGTH); - PY_DICT_ADD_INT(GL_UNPACK_SKIP_PIXELS); - PY_DICT_ADD_INT(GL_UNPACK_SKIP_ROWS); - PY_DICT_ADD_INT(GL_UNPACK_SWAP_BYTES); - PY_DICT_ADD_INT(GL_UNSIGNED_BYTE); - PY_DICT_ADD_INT(GL_UNSIGNED_INT); - PY_DICT_ADD_INT(GL_UNSIGNED_SHORT); - PY_DICT_ADD_INT(GL_VENDOR); - PY_DICT_ADD_INT(GL_VERSION); - PY_DICT_ADD_INT(GL_VIEWPORT); - PY_DICT_ADD_INT(GL_XOR); - PY_DICT_ADD_INT(GL_ZERO); - } - + PY_DICT_ADD_INT(GL_ALPHA); + PY_DICT_ADD_INT(GL_ALWAYS); + PY_DICT_ADD_INT(GL_AND); + PY_DICT_ADD_INT(GL_AND_INVERTED); + PY_DICT_ADD_INT(GL_AND_REVERSE); + PY_DICT_ADD_INT(GL_BACK); + PY_DICT_ADD_INT(GL_BACK_LEFT); + PY_DICT_ADD_INT(GL_BACK_RIGHT); + PY_DICT_ADD_INT(GL_BLEND); + PY_DICT_ADD_INT(GL_BLEND_DST); + PY_DICT_ADD_INT(GL_BLEND_SRC); + PY_DICT_ADD_INT(GL_BLUE); + PY_DICT_ADD_INT(GL_BYTE); + PY_DICT_ADD_INT(GL_CCW); + PY_DICT_ADD_INT(GL_CLEAR); + PY_DICT_ADD_INT(GL_COLOR); + PY_DICT_ADD_INT(GL_COLOR_BUFFER_BIT); + PY_DICT_ADD_INT(GL_COLOR_CLEAR_VALUE); + PY_DICT_ADD_INT(GL_COLOR_LOGIC_OP); + PY_DICT_ADD_INT(GL_COLOR_WRITEMASK); + PY_DICT_ADD_INT(GL_COPY); + PY_DICT_ADD_INT(GL_COPY_INVERTED); + PY_DICT_ADD_INT(GL_CULL_FACE); + PY_DICT_ADD_INT(GL_CULL_FACE_MODE); + PY_DICT_ADD_INT(GL_CW); + PY_DICT_ADD_INT(GL_DECR); + PY_DICT_ADD_INT(GL_DEPTH); + PY_DICT_ADD_INT(GL_DEPTH_BUFFER_BIT); + PY_DICT_ADD_INT(GL_DEPTH_CLEAR_VALUE); + PY_DICT_ADD_INT(GL_DEPTH_COMPONENT); + PY_DICT_ADD_INT(GL_DEPTH_FUNC); + PY_DICT_ADD_INT(GL_DEPTH_RANGE); + PY_DICT_ADD_INT(GL_DEPTH_TEST); + PY_DICT_ADD_INT(GL_DEPTH_WRITEMASK); + PY_DICT_ADD_INT(GL_DITHER); + PY_DICT_ADD_INT(GL_DONT_CARE); + PY_DICT_ADD_INT(GL_DOUBLE); + PY_DICT_ADD_INT(GL_DOUBLEBUFFER); + PY_DICT_ADD_INT(GL_DRAW_BUFFER); + PY_DICT_ADD_INT(GL_DST_ALPHA); + PY_DICT_ADD_INT(GL_DST_COLOR); + PY_DICT_ADD_INT(GL_EQUAL); + PY_DICT_ADD_INT(GL_EQUIV); + PY_DICT_ADD_INT(GL_EXTENSIONS); + PY_DICT_ADD_INT(GL_FALSE); + PY_DICT_ADD_INT(GL_FASTEST); + PY_DICT_ADD_INT(GL_FILL); + PY_DICT_ADD_INT(GL_FLOAT); + PY_DICT_ADD_INT(GL_FRONT); + PY_DICT_ADD_INT(GL_FRONT_AND_BACK); + PY_DICT_ADD_INT(GL_FRONT_FACE); + PY_DICT_ADD_INT(GL_FRONT_LEFT); + PY_DICT_ADD_INT(GL_FRONT_RIGHT); + PY_DICT_ADD_INT(GL_GEQUAL); + PY_DICT_ADD_INT(GL_GREATER); + PY_DICT_ADD_INT(GL_GREEN); + PY_DICT_ADD_INT(GL_INCR); + PY_DICT_ADD_INT(GL_INT); + PY_DICT_ADD_INT(GL_INVALID_ENUM); + PY_DICT_ADD_INT(GL_INVALID_OPERATION); + PY_DICT_ADD_INT(GL_INVALID_VALUE); + PY_DICT_ADD_INT(GL_INVERT); + PY_DICT_ADD_INT(GL_KEEP); + PY_DICT_ADD_INT(GL_LEFT); + PY_DICT_ADD_INT(GL_LEQUAL); + PY_DICT_ADD_INT(GL_LESS); + PY_DICT_ADD_INT(GL_LINE); + PY_DICT_ADD_INT(GL_LINEAR); + PY_DICT_ADD_INT(GL_LINEAR_MIPMAP_LINEAR); + PY_DICT_ADD_INT(GL_LINEAR_MIPMAP_NEAREST); + PY_DICT_ADD_INT(GL_LINES); + PY_DICT_ADD_INT(GL_LINE_LOOP); + PY_DICT_ADD_INT(GL_LINE_SMOOTH); + PY_DICT_ADD_INT(GL_LINE_SMOOTH_HINT); + PY_DICT_ADD_INT(GL_LINE_STRIP); + PY_DICT_ADD_INT(GL_LINE_WIDTH); + PY_DICT_ADD_INT(GL_LINE_WIDTH_GRANULARITY); + PY_DICT_ADD_INT(GL_LINE_WIDTH_RANGE); + PY_DICT_ADD_INT(GL_LOGIC_OP_MODE); + PY_DICT_ADD_INT(GL_MAX_TEXTURE_SIZE); + PY_DICT_ADD_INT(GL_MAX_VIEWPORT_DIMS); + PY_DICT_ADD_INT(GL_NAND); + PY_DICT_ADD_INT(GL_NEAREST); + PY_DICT_ADD_INT(GL_NEAREST_MIPMAP_LINEAR); + PY_DICT_ADD_INT(GL_NEAREST_MIPMAP_NEAREST); + PY_DICT_ADD_INT(GL_NEVER); + PY_DICT_ADD_INT(GL_NICEST); + PY_DICT_ADD_INT(GL_NONE); + PY_DICT_ADD_INT(GL_NOOP); + PY_DICT_ADD_INT(GL_NOR); + PY_DICT_ADD_INT(GL_NOTEQUAL); + PY_DICT_ADD_INT(GL_NO_ERROR); + PY_DICT_ADD_INT(GL_ONE); + PY_DICT_ADD_INT(GL_ONE_MINUS_DST_ALPHA); + PY_DICT_ADD_INT(GL_ONE_MINUS_DST_COLOR); + PY_DICT_ADD_INT(GL_ONE_MINUS_SRC_ALPHA); + PY_DICT_ADD_INT(GL_ONE_MINUS_SRC_COLOR); + PY_DICT_ADD_INT(GL_OR); + PY_DICT_ADD_INT(GL_OR_INVERTED); + PY_DICT_ADD_INT(GL_OR_REVERSE); + PY_DICT_ADD_INT(GL_OUT_OF_MEMORY); + PY_DICT_ADD_INT(GL_PACK_ALIGNMENT); + PY_DICT_ADD_INT(GL_PACK_LSB_FIRST); + PY_DICT_ADD_INT(GL_PACK_ROW_LENGTH); + PY_DICT_ADD_INT(GL_PACK_SKIP_PIXELS); + PY_DICT_ADD_INT(GL_PACK_SKIP_ROWS); + PY_DICT_ADD_INT(GL_PACK_SWAP_BYTES); + PY_DICT_ADD_INT(GL_POINT); + PY_DICT_ADD_INT(GL_POINTS); + PY_DICT_ADD_INT(GL_POINT_SIZE); + PY_DICT_ADD_INT(GL_POLYGON_MODE); + PY_DICT_ADD_INT(GL_POLYGON_OFFSET_FACTOR); + PY_DICT_ADD_INT(GL_POLYGON_OFFSET_FILL); + PY_DICT_ADD_INT(GL_POLYGON_OFFSET_LINE); + PY_DICT_ADD_INT(GL_POLYGON_OFFSET_POINT); + PY_DICT_ADD_INT(GL_POLYGON_OFFSET_UNITS); + PY_DICT_ADD_INT(GL_POLYGON_SMOOTH); + PY_DICT_ADD_INT(GL_POLYGON_SMOOTH_HINT); + PY_DICT_ADD_INT(GL_PROXY_TEXTURE_1D); + PY_DICT_ADD_INT(GL_PROXY_TEXTURE_2D); + PY_DICT_ADD_INT(GL_R3_G3_B2); + PY_DICT_ADD_INT(GL_READ_BUFFER); + PY_DICT_ADD_INT(GL_RED); + PY_DICT_ADD_INT(GL_RENDERER); + PY_DICT_ADD_INT(GL_REPEAT); + PY_DICT_ADD_INT(GL_REPLACE); + PY_DICT_ADD_INT(GL_RGB); + PY_DICT_ADD_INT(GL_RGB10); + PY_DICT_ADD_INT(GL_RGB10_A2); + PY_DICT_ADD_INT(GL_RGB12); + PY_DICT_ADD_INT(GL_RGB16); + PY_DICT_ADD_INT(GL_RGB4); + PY_DICT_ADD_INT(GL_RGB5); + PY_DICT_ADD_INT(GL_RGB5_A1); + PY_DICT_ADD_INT(GL_RGB8); + PY_DICT_ADD_INT(GL_RGBA); + PY_DICT_ADD_INT(GL_RGBA12); + PY_DICT_ADD_INT(GL_RGBA16); + PY_DICT_ADD_INT(GL_RGBA2); + PY_DICT_ADD_INT(GL_RGBA4); + PY_DICT_ADD_INT(GL_RGBA8); + PY_DICT_ADD_INT(GL_RIGHT); + PY_DICT_ADD_INT(GL_SCISSOR_BOX); + PY_DICT_ADD_INT(GL_SCISSOR_TEST); + PY_DICT_ADD_INT(GL_SET); + PY_DICT_ADD_INT(GL_SHORT); + PY_DICT_ADD_INT(GL_SRC_ALPHA); + PY_DICT_ADD_INT(GL_SRC_ALPHA_SATURATE); + PY_DICT_ADD_INT(GL_SRC_COLOR); + PY_DICT_ADD_INT(GL_STENCIL); + PY_DICT_ADD_INT(GL_STENCIL_BUFFER_BIT); + PY_DICT_ADD_INT(GL_STENCIL_CLEAR_VALUE); + PY_DICT_ADD_INT(GL_STENCIL_FAIL); + PY_DICT_ADD_INT(GL_STENCIL_FUNC); + PY_DICT_ADD_INT(GL_STENCIL_INDEX); + PY_DICT_ADD_INT(GL_STENCIL_PASS_DEPTH_FAIL); + PY_DICT_ADD_INT(GL_STENCIL_PASS_DEPTH_PASS); + PY_DICT_ADD_INT(GL_STENCIL_REF); + PY_DICT_ADD_INT(GL_STENCIL_TEST); + PY_DICT_ADD_INT(GL_STENCIL_VALUE_MASK); + PY_DICT_ADD_INT(GL_STENCIL_WRITEMASK); + PY_DICT_ADD_INT(GL_STEREO); + PY_DICT_ADD_INT(GL_SUBPIXEL_BITS); + PY_DICT_ADD_INT(GL_TEXTURE); + PY_DICT_ADD_INT(GL_TEXTURE_1D); + PY_DICT_ADD_INT(GL_TEXTURE_2D); + PY_DICT_ADD_INT(GL_TEXTURE_ALPHA_SIZE); + PY_DICT_ADD_INT(GL_TEXTURE_BINDING_1D); + PY_DICT_ADD_INT(GL_TEXTURE_BINDING_2D); + PY_DICT_ADD_INT(GL_TEXTURE_BLUE_SIZE); + PY_DICT_ADD_INT(GL_TEXTURE_BORDER_COLOR); + PY_DICT_ADD_INT(GL_TEXTURE_GREEN_SIZE); + PY_DICT_ADD_INT(GL_TEXTURE_HEIGHT); + PY_DICT_ADD_INT(GL_TEXTURE_INTERNAL_FORMAT); + PY_DICT_ADD_INT(GL_TEXTURE_MAG_FILTER); + PY_DICT_ADD_INT(GL_TEXTURE_MIN_FILTER); + PY_DICT_ADD_INT(GL_TEXTURE_RED_SIZE); + PY_DICT_ADD_INT(GL_TEXTURE_WIDTH); + PY_DICT_ADD_INT(GL_TEXTURE_WRAP_S); + PY_DICT_ADD_INT(GL_TEXTURE_WRAP_T); + PY_DICT_ADD_INT(GL_TRIANGLES); + PY_DICT_ADD_INT(GL_TRIANGLE_FAN); + PY_DICT_ADD_INT(GL_TRIANGLE_STRIP); + PY_DICT_ADD_INT(GL_TRUE); + PY_DICT_ADD_INT(GL_UNPACK_ALIGNMENT); + PY_DICT_ADD_INT(GL_UNPACK_LSB_FIRST); + PY_DICT_ADD_INT(GL_UNPACK_ROW_LENGTH); + PY_DICT_ADD_INT(GL_UNPACK_SKIP_PIXELS); + PY_DICT_ADD_INT(GL_UNPACK_SKIP_ROWS); + PY_DICT_ADD_INT(GL_UNPACK_SWAP_BYTES); + PY_DICT_ADD_INT(GL_UNSIGNED_BYTE); + PY_DICT_ADD_INT(GL_UNSIGNED_INT); + PY_DICT_ADD_INT(GL_UNSIGNED_SHORT); + PY_DICT_ADD_INT(GL_VENDOR); + PY_DICT_ADD_INT(GL_VERSION); + PY_DICT_ADD_INT(GL_VIEWPORT); + PY_DICT_ADD_INT(GL_XOR); + PY_DICT_ADD_INT(GL_ZERO); +} +static void init_bgl_version_1_2_constants(PyObject *dict) +{ /* GL_VERSION_1_2 */ - { - PY_DICT_ADD_INT(GL_ALIASED_LINE_WIDTH_RANGE); - PY_DICT_ADD_INT(GL_BGR); - PY_DICT_ADD_INT(GL_BGRA); - PY_DICT_ADD_INT(GL_CLAMP_TO_EDGE); - PY_DICT_ADD_INT(GL_MAX_3D_TEXTURE_SIZE); - PY_DICT_ADD_INT(GL_MAX_ELEMENTS_INDICES); - PY_DICT_ADD_INT(GL_MAX_ELEMENTS_VERTICES); - PY_DICT_ADD_INT(GL_PACK_IMAGE_HEIGHT); - PY_DICT_ADD_INT(GL_PACK_SKIP_IMAGES); - PY_DICT_ADD_INT(GL_PROXY_TEXTURE_3D); - PY_DICT_ADD_INT(GL_SMOOTH_LINE_WIDTH_GRANULARITY); - PY_DICT_ADD_INT(GL_SMOOTH_LINE_WIDTH_RANGE); - PY_DICT_ADD_INT(GL_SMOOTH_POINT_SIZE_GRANULARITY); - PY_DICT_ADD_INT(GL_SMOOTH_POINT_SIZE_RANGE); - PY_DICT_ADD_INT(GL_TEXTURE_3D); - PY_DICT_ADD_INT(GL_TEXTURE_BASE_LEVEL); - PY_DICT_ADD_INT(GL_TEXTURE_BINDING_3D); - PY_DICT_ADD_INT(GL_TEXTURE_DEPTH); - PY_DICT_ADD_INT(GL_TEXTURE_MAX_LEVEL); - PY_DICT_ADD_INT(GL_TEXTURE_MAX_LOD); - PY_DICT_ADD_INT(GL_TEXTURE_MIN_LOD); - PY_DICT_ADD_INT(GL_TEXTURE_WRAP_R); - PY_DICT_ADD_INT(GL_UNPACK_IMAGE_HEIGHT); - PY_DICT_ADD_INT(GL_UNPACK_SKIP_IMAGES); - PY_DICT_ADD_INT(GL_UNSIGNED_BYTE_2_3_3_REV); - PY_DICT_ADD_INT(GL_UNSIGNED_BYTE_3_3_2); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_10_10_10_2); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_2_10_10_10_REV); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_8_8_8_8); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_8_8_8_8_REV); - PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_1_5_5_5_REV); - PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_4_4_4_4); - PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_4_4_4_4_REV); - PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_5_5_5_1); - PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_5_6_5); - PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_5_6_5_REV); - } - + PY_DICT_ADD_INT(GL_ALIASED_LINE_WIDTH_RANGE); + PY_DICT_ADD_INT(GL_BGR); + PY_DICT_ADD_INT(GL_BGRA); + PY_DICT_ADD_INT(GL_CLAMP_TO_EDGE); + PY_DICT_ADD_INT(GL_MAX_3D_TEXTURE_SIZE); + PY_DICT_ADD_INT(GL_MAX_ELEMENTS_INDICES); + PY_DICT_ADD_INT(GL_MAX_ELEMENTS_VERTICES); + PY_DICT_ADD_INT(GL_PACK_IMAGE_HEIGHT); + PY_DICT_ADD_INT(GL_PACK_SKIP_IMAGES); + PY_DICT_ADD_INT(GL_PROXY_TEXTURE_3D); + PY_DICT_ADD_INT(GL_SMOOTH_LINE_WIDTH_GRANULARITY); + PY_DICT_ADD_INT(GL_SMOOTH_LINE_WIDTH_RANGE); + PY_DICT_ADD_INT(GL_SMOOTH_POINT_SIZE_GRANULARITY); + PY_DICT_ADD_INT(GL_SMOOTH_POINT_SIZE_RANGE); + PY_DICT_ADD_INT(GL_TEXTURE_3D); + PY_DICT_ADD_INT(GL_TEXTURE_BASE_LEVEL); + PY_DICT_ADD_INT(GL_TEXTURE_BINDING_3D); + PY_DICT_ADD_INT(GL_TEXTURE_DEPTH); + PY_DICT_ADD_INT(GL_TEXTURE_MAX_LEVEL); + PY_DICT_ADD_INT(GL_TEXTURE_MAX_LOD); + PY_DICT_ADD_INT(GL_TEXTURE_MIN_LOD); + PY_DICT_ADD_INT(GL_TEXTURE_WRAP_R); + PY_DICT_ADD_INT(GL_UNPACK_IMAGE_HEIGHT); + PY_DICT_ADD_INT(GL_UNPACK_SKIP_IMAGES); + PY_DICT_ADD_INT(GL_UNSIGNED_BYTE_2_3_3_REV); + PY_DICT_ADD_INT(GL_UNSIGNED_BYTE_3_3_2); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_10_10_10_2); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_2_10_10_10_REV); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_8_8_8_8); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_8_8_8_8_REV); + PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_1_5_5_5_REV); + PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_4_4_4_4); + PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_4_4_4_4_REV); + PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_5_5_5_1); + PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_5_6_5); + PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_5_6_5_REV); +} +static void init_bgl_version_1_3_constants(PyObject *dict) +{ /* GL_VERSION_1_3 */ - { - PY_DICT_ADD_INT(GL_ACTIVE_TEXTURE); - PY_DICT_ADD_INT(GL_CLAMP_TO_BORDER); - PY_DICT_ADD_INT(GL_COMPRESSED_RGB); - PY_DICT_ADD_INT(GL_COMPRESSED_RGBA); - PY_DICT_ADD_INT(GL_COMPRESSED_TEXTURE_FORMATS); - PY_DICT_ADD_INT(GL_MAX_CUBE_MAP_TEXTURE_SIZE); - PY_DICT_ADD_INT(GL_MULTISAMPLE); - PY_DICT_ADD_INT(GL_NUM_COMPRESSED_TEXTURE_FORMATS); - PY_DICT_ADD_INT(GL_PROXY_TEXTURE_CUBE_MAP); - PY_DICT_ADD_INT(GL_SAMPLES); - PY_DICT_ADD_INT(GL_SAMPLE_ALPHA_TO_COVERAGE); - PY_DICT_ADD_INT(GL_SAMPLE_ALPHA_TO_ONE); - PY_DICT_ADD_INT(GL_SAMPLE_BUFFERS); - PY_DICT_ADD_INT(GL_SAMPLE_COVERAGE); - PY_DICT_ADD_INT(GL_SAMPLE_COVERAGE_INVERT); - PY_DICT_ADD_INT(GL_SAMPLE_COVERAGE_VALUE); - PY_DICT_ADD_INT(GL_TEXTURE0); - PY_DICT_ADD_INT(GL_TEXTURE1); - PY_DICT_ADD_INT(GL_TEXTURE10); - PY_DICT_ADD_INT(GL_TEXTURE11); - PY_DICT_ADD_INT(GL_TEXTURE12); - PY_DICT_ADD_INT(GL_TEXTURE13); - PY_DICT_ADD_INT(GL_TEXTURE14); - PY_DICT_ADD_INT(GL_TEXTURE15); - PY_DICT_ADD_INT(GL_TEXTURE16); - PY_DICT_ADD_INT(GL_TEXTURE17); - PY_DICT_ADD_INT(GL_TEXTURE18); - PY_DICT_ADD_INT(GL_TEXTURE19); - PY_DICT_ADD_INT(GL_TEXTURE2); - PY_DICT_ADD_INT(GL_TEXTURE20); - PY_DICT_ADD_INT(GL_TEXTURE21); - PY_DICT_ADD_INT(GL_TEXTURE22); - PY_DICT_ADD_INT(GL_TEXTURE23); - PY_DICT_ADD_INT(GL_TEXTURE24); - PY_DICT_ADD_INT(GL_TEXTURE25); - PY_DICT_ADD_INT(GL_TEXTURE26); - PY_DICT_ADD_INT(GL_TEXTURE27); - PY_DICT_ADD_INT(GL_TEXTURE28); - PY_DICT_ADD_INT(GL_TEXTURE29); - PY_DICT_ADD_INT(GL_TEXTURE3); - PY_DICT_ADD_INT(GL_TEXTURE30); - PY_DICT_ADD_INT(GL_TEXTURE31); - PY_DICT_ADD_INT(GL_TEXTURE4); - PY_DICT_ADD_INT(GL_TEXTURE5); - PY_DICT_ADD_INT(GL_TEXTURE6); - PY_DICT_ADD_INT(GL_TEXTURE7); - PY_DICT_ADD_INT(GL_TEXTURE8); - PY_DICT_ADD_INT(GL_TEXTURE9); - PY_DICT_ADD_INT(GL_TEXTURE_BINDING_CUBE_MAP); - PY_DICT_ADD_INT(GL_TEXTURE_COMPRESSED); - PY_DICT_ADD_INT(GL_TEXTURE_COMPRESSED_IMAGE_SIZE); - PY_DICT_ADD_INT(GL_TEXTURE_COMPRESSION_HINT); - PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP); - PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X); - PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y); - PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z); - PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_POSITIVE_X); - PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y); - PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z); - } - + PY_DICT_ADD_INT(GL_ACTIVE_TEXTURE); + PY_DICT_ADD_INT(GL_CLAMP_TO_BORDER); + PY_DICT_ADD_INT(GL_COMPRESSED_RGB); + PY_DICT_ADD_INT(GL_COMPRESSED_RGBA); + PY_DICT_ADD_INT(GL_COMPRESSED_TEXTURE_FORMATS); + PY_DICT_ADD_INT(GL_MAX_CUBE_MAP_TEXTURE_SIZE); + PY_DICT_ADD_INT(GL_MULTISAMPLE); + PY_DICT_ADD_INT(GL_NUM_COMPRESSED_TEXTURE_FORMATS); + PY_DICT_ADD_INT(GL_PROXY_TEXTURE_CUBE_MAP); + PY_DICT_ADD_INT(GL_SAMPLES); + PY_DICT_ADD_INT(GL_SAMPLE_ALPHA_TO_COVERAGE); + PY_DICT_ADD_INT(GL_SAMPLE_ALPHA_TO_ONE); + PY_DICT_ADD_INT(GL_SAMPLE_BUFFERS); + PY_DICT_ADD_INT(GL_SAMPLE_COVERAGE); + PY_DICT_ADD_INT(GL_SAMPLE_COVERAGE_INVERT); + PY_DICT_ADD_INT(GL_SAMPLE_COVERAGE_VALUE); + PY_DICT_ADD_INT(GL_TEXTURE0); + PY_DICT_ADD_INT(GL_TEXTURE1); + PY_DICT_ADD_INT(GL_TEXTURE10); + PY_DICT_ADD_INT(GL_TEXTURE11); + PY_DICT_ADD_INT(GL_TEXTURE12); + PY_DICT_ADD_INT(GL_TEXTURE13); + PY_DICT_ADD_INT(GL_TEXTURE14); + PY_DICT_ADD_INT(GL_TEXTURE15); + PY_DICT_ADD_INT(GL_TEXTURE16); + PY_DICT_ADD_INT(GL_TEXTURE17); + PY_DICT_ADD_INT(GL_TEXTURE18); + PY_DICT_ADD_INT(GL_TEXTURE19); + PY_DICT_ADD_INT(GL_TEXTURE2); + PY_DICT_ADD_INT(GL_TEXTURE20); + PY_DICT_ADD_INT(GL_TEXTURE21); + PY_DICT_ADD_INT(GL_TEXTURE22); + PY_DICT_ADD_INT(GL_TEXTURE23); + PY_DICT_ADD_INT(GL_TEXTURE24); + PY_DICT_ADD_INT(GL_TEXTURE25); + PY_DICT_ADD_INT(GL_TEXTURE26); + PY_DICT_ADD_INT(GL_TEXTURE27); + PY_DICT_ADD_INT(GL_TEXTURE28); + PY_DICT_ADD_INT(GL_TEXTURE29); + PY_DICT_ADD_INT(GL_TEXTURE3); + PY_DICT_ADD_INT(GL_TEXTURE30); + PY_DICT_ADD_INT(GL_TEXTURE31); + PY_DICT_ADD_INT(GL_TEXTURE4); + PY_DICT_ADD_INT(GL_TEXTURE5); + PY_DICT_ADD_INT(GL_TEXTURE6); + PY_DICT_ADD_INT(GL_TEXTURE7); + PY_DICT_ADD_INT(GL_TEXTURE8); + PY_DICT_ADD_INT(GL_TEXTURE9); + PY_DICT_ADD_INT(GL_TEXTURE_BINDING_CUBE_MAP); + PY_DICT_ADD_INT(GL_TEXTURE_COMPRESSED); + PY_DICT_ADD_INT(GL_TEXTURE_COMPRESSED_IMAGE_SIZE); + PY_DICT_ADD_INT(GL_TEXTURE_COMPRESSION_HINT); + PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP); + PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X); + PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y); + PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z); + PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_POSITIVE_X); + PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y); + PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z); +} +static void init_bgl_version_1_4_constants(PyObject *dict) +{ /* GL_VERSION_1_4 */ - { - PY_DICT_ADD_INT(GL_BLEND_DST_ALPHA); - PY_DICT_ADD_INT(GL_BLEND_DST_RGB); - PY_DICT_ADD_INT(GL_BLEND_SRC_ALPHA); - PY_DICT_ADD_INT(GL_BLEND_SRC_RGB); - PY_DICT_ADD_INT(GL_CONSTANT_ALPHA); - PY_DICT_ADD_INT(GL_CONSTANT_COLOR); - PY_DICT_ADD_INT(GL_DECR_WRAP); - PY_DICT_ADD_INT(GL_DEPTH_COMPONENT16); - PY_DICT_ADD_INT(GL_DEPTH_COMPONENT24); - PY_DICT_ADD_INT(GL_DEPTH_COMPONENT32); - PY_DICT_ADD_INT(GL_FUNC_ADD); - PY_DICT_ADD_INT(GL_FUNC_REVERSE_SUBTRACT); - PY_DICT_ADD_INT(GL_FUNC_SUBTRACT); - PY_DICT_ADD_INT(GL_INCR_WRAP); - PY_DICT_ADD_INT(GL_MAX); - PY_DICT_ADD_INT(GL_MAX_TEXTURE_LOD_BIAS); - PY_DICT_ADD_INT(GL_MIN); - PY_DICT_ADD_INT(GL_MIRRORED_REPEAT); - PY_DICT_ADD_INT(GL_ONE_MINUS_CONSTANT_ALPHA); - PY_DICT_ADD_INT(GL_ONE_MINUS_CONSTANT_COLOR); - PY_DICT_ADD_INT(GL_POINT_FADE_THRESHOLD_SIZE); - PY_DICT_ADD_INT(GL_TEXTURE_COMPARE_FUNC); - PY_DICT_ADD_INT(GL_TEXTURE_COMPARE_MODE); - PY_DICT_ADD_INT(GL_TEXTURE_DEPTH_SIZE); - PY_DICT_ADD_INT(GL_TEXTURE_LOD_BIAS); - } - + PY_DICT_ADD_INT(GL_BLEND_DST_ALPHA); + PY_DICT_ADD_INT(GL_BLEND_DST_RGB); + PY_DICT_ADD_INT(GL_BLEND_SRC_ALPHA); + PY_DICT_ADD_INT(GL_BLEND_SRC_RGB); + PY_DICT_ADD_INT(GL_CONSTANT_ALPHA); + PY_DICT_ADD_INT(GL_CONSTANT_COLOR); + PY_DICT_ADD_INT(GL_DECR_WRAP); + PY_DICT_ADD_INT(GL_DEPTH_COMPONENT16); + PY_DICT_ADD_INT(GL_DEPTH_COMPONENT24); + PY_DICT_ADD_INT(GL_DEPTH_COMPONENT32); + PY_DICT_ADD_INT(GL_FUNC_ADD); + PY_DICT_ADD_INT(GL_FUNC_REVERSE_SUBTRACT); + PY_DICT_ADD_INT(GL_FUNC_SUBTRACT); + PY_DICT_ADD_INT(GL_INCR_WRAP); + PY_DICT_ADD_INT(GL_MAX); + PY_DICT_ADD_INT(GL_MAX_TEXTURE_LOD_BIAS); + PY_DICT_ADD_INT(GL_MIN); + PY_DICT_ADD_INT(GL_MIRRORED_REPEAT); + PY_DICT_ADD_INT(GL_ONE_MINUS_CONSTANT_ALPHA); + PY_DICT_ADD_INT(GL_ONE_MINUS_CONSTANT_COLOR); + PY_DICT_ADD_INT(GL_POINT_FADE_THRESHOLD_SIZE); + PY_DICT_ADD_INT(GL_TEXTURE_COMPARE_FUNC); + PY_DICT_ADD_INT(GL_TEXTURE_COMPARE_MODE); + PY_DICT_ADD_INT(GL_TEXTURE_DEPTH_SIZE); + PY_DICT_ADD_INT(GL_TEXTURE_LOD_BIAS); +} +static void init_bgl_version_1_5_constants(PyObject *dict) +{ /* GL_VERSION_1_5 */ - { - PY_DICT_ADD_INT(GL_ARRAY_BUFFER); - PY_DICT_ADD_INT(GL_ARRAY_BUFFER_BINDING); - PY_DICT_ADD_INT(GL_BUFFER_ACCESS); - PY_DICT_ADD_INT(GL_BUFFER_MAPPED); - PY_DICT_ADD_INT(GL_BUFFER_MAP_POINTER); - PY_DICT_ADD_INT(GL_BUFFER_SIZE); - PY_DICT_ADD_INT(GL_BUFFER_USAGE); - PY_DICT_ADD_INT(GL_CURRENT_QUERY); - PY_DICT_ADD_INT(GL_DYNAMIC_COPY); - PY_DICT_ADD_INT(GL_DYNAMIC_DRAW); - PY_DICT_ADD_INT(GL_DYNAMIC_READ); - PY_DICT_ADD_INT(GL_ELEMENT_ARRAY_BUFFER); - PY_DICT_ADD_INT(GL_ELEMENT_ARRAY_BUFFER_BINDING); - PY_DICT_ADD_INT(GL_QUERY_COUNTER_BITS); - PY_DICT_ADD_INT(GL_QUERY_RESULT); - PY_DICT_ADD_INT(GL_QUERY_RESULT_AVAILABLE); - PY_DICT_ADD_INT(GL_READ_ONLY); - PY_DICT_ADD_INT(GL_READ_WRITE); - PY_DICT_ADD_INT(GL_SAMPLES_PASSED); - PY_DICT_ADD_INT(GL_STATIC_COPY); - PY_DICT_ADD_INT(GL_STATIC_DRAW); - PY_DICT_ADD_INT(GL_STATIC_READ); - PY_DICT_ADD_INT(GL_STREAM_COPY); - PY_DICT_ADD_INT(GL_STREAM_DRAW); - PY_DICT_ADD_INT(GL_STREAM_READ); - PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING); - PY_DICT_ADD_INT(GL_WRITE_ONLY); - } - + PY_DICT_ADD_INT(GL_ARRAY_BUFFER); + PY_DICT_ADD_INT(GL_ARRAY_BUFFER_BINDING); + PY_DICT_ADD_INT(GL_BUFFER_ACCESS); + PY_DICT_ADD_INT(GL_BUFFER_MAPPED); + PY_DICT_ADD_INT(GL_BUFFER_MAP_POINTER); + PY_DICT_ADD_INT(GL_BUFFER_SIZE); + PY_DICT_ADD_INT(GL_BUFFER_USAGE); + PY_DICT_ADD_INT(GL_CURRENT_QUERY); + PY_DICT_ADD_INT(GL_DYNAMIC_COPY); + PY_DICT_ADD_INT(GL_DYNAMIC_DRAW); + PY_DICT_ADD_INT(GL_DYNAMIC_READ); + PY_DICT_ADD_INT(GL_ELEMENT_ARRAY_BUFFER); + PY_DICT_ADD_INT(GL_ELEMENT_ARRAY_BUFFER_BINDING); + PY_DICT_ADD_INT(GL_QUERY_COUNTER_BITS); + PY_DICT_ADD_INT(GL_QUERY_RESULT); + PY_DICT_ADD_INT(GL_QUERY_RESULT_AVAILABLE); + PY_DICT_ADD_INT(GL_READ_ONLY); + PY_DICT_ADD_INT(GL_READ_WRITE); + PY_DICT_ADD_INT(GL_SAMPLES_PASSED); + PY_DICT_ADD_INT(GL_STATIC_COPY); + PY_DICT_ADD_INT(GL_STATIC_DRAW); + PY_DICT_ADD_INT(GL_STATIC_READ); + PY_DICT_ADD_INT(GL_STREAM_COPY); + PY_DICT_ADD_INT(GL_STREAM_DRAW); + PY_DICT_ADD_INT(GL_STREAM_READ); + PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING); + PY_DICT_ADD_INT(GL_WRITE_ONLY); +} +static void init_bgl_version_2_0_constants(PyObject *dict) +{ /* GL_VERSION_2_0 */ - { - PY_DICT_ADD_INT(GL_ACTIVE_ATTRIBUTES); - PY_DICT_ADD_INT(GL_ACTIVE_ATTRIBUTE_MAX_LENGTH); - PY_DICT_ADD_INT(GL_ACTIVE_UNIFORMS); - PY_DICT_ADD_INT(GL_ACTIVE_UNIFORM_MAX_LENGTH); - PY_DICT_ADD_INT(GL_ATTACHED_SHADERS); - PY_DICT_ADD_INT(GL_BLEND_EQUATION_ALPHA); - PY_DICT_ADD_INT(GL_BLEND_EQUATION_RGB); - PY_DICT_ADD_INT(GL_BOOL); - PY_DICT_ADD_INT(GL_BOOL_VEC2); - PY_DICT_ADD_INT(GL_BOOL_VEC3); - PY_DICT_ADD_INT(GL_BOOL_VEC4); - PY_DICT_ADD_INT(GL_COMPILE_STATUS); - PY_DICT_ADD_INT(GL_CURRENT_PROGRAM); - PY_DICT_ADD_INT(GL_CURRENT_VERTEX_ATTRIB); - PY_DICT_ADD_INT(GL_DELETE_STATUS); - PY_DICT_ADD_INT(GL_DRAW_BUFFER0); - PY_DICT_ADD_INT(GL_DRAW_BUFFER1); - PY_DICT_ADD_INT(GL_DRAW_BUFFER10); - PY_DICT_ADD_INT(GL_DRAW_BUFFER11); - PY_DICT_ADD_INT(GL_DRAW_BUFFER12); - PY_DICT_ADD_INT(GL_DRAW_BUFFER13); - PY_DICT_ADD_INT(GL_DRAW_BUFFER14); - PY_DICT_ADD_INT(GL_DRAW_BUFFER15); - PY_DICT_ADD_INT(GL_DRAW_BUFFER2); - PY_DICT_ADD_INT(GL_DRAW_BUFFER3); - PY_DICT_ADD_INT(GL_DRAW_BUFFER4); - PY_DICT_ADD_INT(GL_DRAW_BUFFER5); - PY_DICT_ADD_INT(GL_DRAW_BUFFER6); - PY_DICT_ADD_INT(GL_DRAW_BUFFER7); - PY_DICT_ADD_INT(GL_DRAW_BUFFER8); - PY_DICT_ADD_INT(GL_DRAW_BUFFER9); - PY_DICT_ADD_INT(GL_FLOAT_MAT2); - PY_DICT_ADD_INT(GL_FLOAT_MAT3); - PY_DICT_ADD_INT(GL_FLOAT_MAT4); - PY_DICT_ADD_INT(GL_FLOAT_VEC2); - PY_DICT_ADD_INT(GL_FLOAT_VEC3); - PY_DICT_ADD_INT(GL_FLOAT_VEC4); - PY_DICT_ADD_INT(GL_FRAGMENT_SHADER); - PY_DICT_ADD_INT(GL_FRAGMENT_SHADER_DERIVATIVE_HINT); - PY_DICT_ADD_INT(GL_INFO_LOG_LENGTH); - PY_DICT_ADD_INT(GL_INT_VEC2); - PY_DICT_ADD_INT(GL_INT_VEC3); - PY_DICT_ADD_INT(GL_INT_VEC4); - PY_DICT_ADD_INT(GL_LINK_STATUS); - PY_DICT_ADD_INT(GL_LOWER_LEFT); - PY_DICT_ADD_INT(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS); - PY_DICT_ADD_INT(GL_MAX_DRAW_BUFFERS); - PY_DICT_ADD_INT(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS); - PY_DICT_ADD_INT(GL_MAX_TEXTURE_IMAGE_UNITS); - PY_DICT_ADD_INT(GL_MAX_VARYING_FLOATS); - PY_DICT_ADD_INT(GL_MAX_VERTEX_ATTRIBS); - PY_DICT_ADD_INT(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS); - PY_DICT_ADD_INT(GL_MAX_VERTEX_UNIFORM_COMPONENTS); - PY_DICT_ADD_INT(GL_POINT_SPRITE_COORD_ORIGIN); - PY_DICT_ADD_INT(GL_SAMPLER_1D); - PY_DICT_ADD_INT(GL_SAMPLER_1D_SHADOW); - PY_DICT_ADD_INT(GL_SAMPLER_2D); - PY_DICT_ADD_INT(GL_SAMPLER_2D_SHADOW); - PY_DICT_ADD_INT(GL_SAMPLER_3D); - PY_DICT_ADD_INT(GL_SAMPLER_CUBE); - PY_DICT_ADD_INT(GL_SHADER_SOURCE_LENGTH); - PY_DICT_ADD_INT(GL_SHADER_TYPE); - PY_DICT_ADD_INT(GL_SHADING_LANGUAGE_VERSION); - PY_DICT_ADD_INT(GL_STENCIL_BACK_FAIL); - PY_DICT_ADD_INT(GL_STENCIL_BACK_FUNC); - PY_DICT_ADD_INT(GL_STENCIL_BACK_PASS_DEPTH_FAIL); - PY_DICT_ADD_INT(GL_STENCIL_BACK_PASS_DEPTH_PASS); - PY_DICT_ADD_INT(GL_STENCIL_BACK_REF); - PY_DICT_ADD_INT(GL_STENCIL_BACK_VALUE_MASK); - PY_DICT_ADD_INT(GL_STENCIL_BACK_WRITEMASK); - PY_DICT_ADD_INT(GL_UPPER_LEFT); - PY_DICT_ADD_INT(GL_VALIDATE_STATUS); - PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_ENABLED); - PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED); - PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_POINTER); - PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_SIZE); - PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_STRIDE); - PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_TYPE); - PY_DICT_ADD_INT(GL_VERTEX_PROGRAM_POINT_SIZE); - PY_DICT_ADD_INT(GL_VERTEX_SHADER); - } - + PY_DICT_ADD_INT(GL_ACTIVE_ATTRIBUTES); + PY_DICT_ADD_INT(GL_ACTIVE_ATTRIBUTE_MAX_LENGTH); + PY_DICT_ADD_INT(GL_ACTIVE_UNIFORMS); + PY_DICT_ADD_INT(GL_ACTIVE_UNIFORM_MAX_LENGTH); + PY_DICT_ADD_INT(GL_ATTACHED_SHADERS); + PY_DICT_ADD_INT(GL_BLEND_EQUATION_ALPHA); + PY_DICT_ADD_INT(GL_BLEND_EQUATION_RGB); + PY_DICT_ADD_INT(GL_BOOL); + PY_DICT_ADD_INT(GL_BOOL_VEC2); + PY_DICT_ADD_INT(GL_BOOL_VEC3); + PY_DICT_ADD_INT(GL_BOOL_VEC4); + PY_DICT_ADD_INT(GL_COMPILE_STATUS); + PY_DICT_ADD_INT(GL_CURRENT_PROGRAM); + PY_DICT_ADD_INT(GL_CURRENT_VERTEX_ATTRIB); + PY_DICT_ADD_INT(GL_DELETE_STATUS); + PY_DICT_ADD_INT(GL_DRAW_BUFFER0); + PY_DICT_ADD_INT(GL_DRAW_BUFFER1); + PY_DICT_ADD_INT(GL_DRAW_BUFFER10); + PY_DICT_ADD_INT(GL_DRAW_BUFFER11); + PY_DICT_ADD_INT(GL_DRAW_BUFFER12); + PY_DICT_ADD_INT(GL_DRAW_BUFFER13); + PY_DICT_ADD_INT(GL_DRAW_BUFFER14); + PY_DICT_ADD_INT(GL_DRAW_BUFFER15); + PY_DICT_ADD_INT(GL_DRAW_BUFFER2); + PY_DICT_ADD_INT(GL_DRAW_BUFFER3); + PY_DICT_ADD_INT(GL_DRAW_BUFFER4); + PY_DICT_ADD_INT(GL_DRAW_BUFFER5); + PY_DICT_ADD_INT(GL_DRAW_BUFFER6); + PY_DICT_ADD_INT(GL_DRAW_BUFFER7); + PY_DICT_ADD_INT(GL_DRAW_BUFFER8); + PY_DICT_ADD_INT(GL_DRAW_BUFFER9); + PY_DICT_ADD_INT(GL_FLOAT_MAT2); + PY_DICT_ADD_INT(GL_FLOAT_MAT3); + PY_DICT_ADD_INT(GL_FLOAT_MAT4); + PY_DICT_ADD_INT(GL_FLOAT_VEC2); + PY_DICT_ADD_INT(GL_FLOAT_VEC3); + PY_DICT_ADD_INT(GL_FLOAT_VEC4); + PY_DICT_ADD_INT(GL_FRAGMENT_SHADER); + PY_DICT_ADD_INT(GL_FRAGMENT_SHADER_DERIVATIVE_HINT); + PY_DICT_ADD_INT(GL_INFO_LOG_LENGTH); + PY_DICT_ADD_INT(GL_INT_VEC2); + PY_DICT_ADD_INT(GL_INT_VEC3); + PY_DICT_ADD_INT(GL_INT_VEC4); + PY_DICT_ADD_INT(GL_LINK_STATUS); + PY_DICT_ADD_INT(GL_LOWER_LEFT); + PY_DICT_ADD_INT(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS); + PY_DICT_ADD_INT(GL_MAX_DRAW_BUFFERS); + PY_DICT_ADD_INT(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS); + PY_DICT_ADD_INT(GL_MAX_TEXTURE_IMAGE_UNITS); + PY_DICT_ADD_INT(GL_MAX_VARYING_FLOATS); + PY_DICT_ADD_INT(GL_MAX_VERTEX_ATTRIBS); + PY_DICT_ADD_INT(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS); + PY_DICT_ADD_INT(GL_MAX_VERTEX_UNIFORM_COMPONENTS); + PY_DICT_ADD_INT(GL_POINT_SPRITE_COORD_ORIGIN); + PY_DICT_ADD_INT(GL_SAMPLER_1D); + PY_DICT_ADD_INT(GL_SAMPLER_1D_SHADOW); + PY_DICT_ADD_INT(GL_SAMPLER_2D); + PY_DICT_ADD_INT(GL_SAMPLER_2D_SHADOW); + PY_DICT_ADD_INT(GL_SAMPLER_3D); + PY_DICT_ADD_INT(GL_SAMPLER_CUBE); + PY_DICT_ADD_INT(GL_SHADER_SOURCE_LENGTH); + PY_DICT_ADD_INT(GL_SHADER_TYPE); + PY_DICT_ADD_INT(GL_SHADING_LANGUAGE_VERSION); + PY_DICT_ADD_INT(GL_STENCIL_BACK_FAIL); + PY_DICT_ADD_INT(GL_STENCIL_BACK_FUNC); + PY_DICT_ADD_INT(GL_STENCIL_BACK_PASS_DEPTH_FAIL); + PY_DICT_ADD_INT(GL_STENCIL_BACK_PASS_DEPTH_PASS); + PY_DICT_ADD_INT(GL_STENCIL_BACK_REF); + PY_DICT_ADD_INT(GL_STENCIL_BACK_VALUE_MASK); + PY_DICT_ADD_INT(GL_STENCIL_BACK_WRITEMASK); + PY_DICT_ADD_INT(GL_UPPER_LEFT); + PY_DICT_ADD_INT(GL_VALIDATE_STATUS); + PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_ENABLED); + PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED); + PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_POINTER); + PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_SIZE); + PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_STRIDE); + PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_TYPE); + PY_DICT_ADD_INT(GL_VERTEX_PROGRAM_POINT_SIZE); + PY_DICT_ADD_INT(GL_VERTEX_SHADER); +} +static void init_bgl_version_2_1_constants(PyObject *dict) +{ /* GL_VERSION_2_1 */ - { - PY_DICT_ADD_INT(GL_COMPRESSED_SRGB); - PY_DICT_ADD_INT(GL_COMPRESSED_SRGB_ALPHA); - PY_DICT_ADD_INT(GL_FLOAT_MAT2x3); - PY_DICT_ADD_INT(GL_FLOAT_MAT2x4); - PY_DICT_ADD_INT(GL_FLOAT_MAT3x2); - PY_DICT_ADD_INT(GL_FLOAT_MAT3x4); - PY_DICT_ADD_INT(GL_FLOAT_MAT4x2); - PY_DICT_ADD_INT(GL_FLOAT_MAT4x3); - PY_DICT_ADD_INT(GL_PIXEL_PACK_BUFFER); - PY_DICT_ADD_INT(GL_PIXEL_PACK_BUFFER_BINDING); - PY_DICT_ADD_INT(GL_PIXEL_UNPACK_BUFFER); - PY_DICT_ADD_INT(GL_PIXEL_UNPACK_BUFFER_BINDING); - PY_DICT_ADD_INT(GL_SRGB); - PY_DICT_ADD_INT(GL_SRGB8); - PY_DICT_ADD_INT(GL_SRGB8_ALPHA8); - PY_DICT_ADD_INT(GL_SRGB_ALPHA); - } - + PY_DICT_ADD_INT(GL_COMPRESSED_SRGB); + PY_DICT_ADD_INT(GL_COMPRESSED_SRGB_ALPHA); + PY_DICT_ADD_INT(GL_FLOAT_MAT2x3); + PY_DICT_ADD_INT(GL_FLOAT_MAT2x4); + PY_DICT_ADD_INT(GL_FLOAT_MAT3x2); + PY_DICT_ADD_INT(GL_FLOAT_MAT3x4); + PY_DICT_ADD_INT(GL_FLOAT_MAT4x2); + PY_DICT_ADD_INT(GL_FLOAT_MAT4x3); + PY_DICT_ADD_INT(GL_PIXEL_PACK_BUFFER); + PY_DICT_ADD_INT(GL_PIXEL_PACK_BUFFER_BINDING); + PY_DICT_ADD_INT(GL_PIXEL_UNPACK_BUFFER); + PY_DICT_ADD_INT(GL_PIXEL_UNPACK_BUFFER_BINDING); + PY_DICT_ADD_INT(GL_SRGB); + PY_DICT_ADD_INT(GL_SRGB8); + PY_DICT_ADD_INT(GL_SRGB8_ALPHA8); + PY_DICT_ADD_INT(GL_SRGB_ALPHA); +} +static void init_bgl_version_3_0_constants(PyObject *dict) +{ /* GL_VERSION_3_0 */ - { - PY_DICT_ADD_INT(GL_BGRA_INTEGER); - PY_DICT_ADD_INT(GL_BGR_INTEGER); - PY_DICT_ADD_INT(GL_BLUE_INTEGER); - PY_DICT_ADD_INT(GL_BUFFER_ACCESS_FLAGS); - PY_DICT_ADD_INT(GL_BUFFER_MAP_LENGTH); - PY_DICT_ADD_INT(GL_BUFFER_MAP_OFFSET); - PY_DICT_ADD_INT(GL_CLAMP_READ_COLOR); - PY_DICT_ADD_INT(GL_CLIP_DISTANCE0); - PY_DICT_ADD_INT(GL_CLIP_DISTANCE1); - PY_DICT_ADD_INT(GL_CLIP_DISTANCE2); - PY_DICT_ADD_INT(GL_CLIP_DISTANCE3); - PY_DICT_ADD_INT(GL_CLIP_DISTANCE4); - PY_DICT_ADD_INT(GL_CLIP_DISTANCE5); + PY_DICT_ADD_INT(GL_BGRA_INTEGER); + PY_DICT_ADD_INT(GL_BGR_INTEGER); + PY_DICT_ADD_INT(GL_BLUE_INTEGER); + PY_DICT_ADD_INT(GL_BUFFER_ACCESS_FLAGS); + PY_DICT_ADD_INT(GL_BUFFER_MAP_LENGTH); + PY_DICT_ADD_INT(GL_BUFFER_MAP_OFFSET); + PY_DICT_ADD_INT(GL_CLAMP_READ_COLOR); + PY_DICT_ADD_INT(GL_CLIP_DISTANCE0); + PY_DICT_ADD_INT(GL_CLIP_DISTANCE1); + PY_DICT_ADD_INT(GL_CLIP_DISTANCE2); + PY_DICT_ADD_INT(GL_CLIP_DISTANCE3); + PY_DICT_ADD_INT(GL_CLIP_DISTANCE4); + PY_DICT_ADD_INT(GL_CLIP_DISTANCE5); #if 0 PY_DICT_ADD_INT(GL_CLIP_DISTANCE6); PY_DICT_ADD_INT(GL_CLIP_DISTANCE7); #endif - PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT0); - PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT1); - PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT2); - PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT3); - PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT4); - PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT5); - PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT6); - PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT7); - PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT8); - PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT9); - PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT10); - PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT11); - PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT12); - PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT13); - PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT14); - PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT15); + PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT0); + PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT1); + PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT2); + PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT3); + PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT4); + PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT5); + PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT6); + PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT7); + PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT8); + PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT9); + PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT10); + PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT11); + PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT12); + PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT13); + PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT14); + PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT15); #if 0 PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT16); PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT17); @@ -2267,346 +2248,384 @@ PyObject *BPyInit_bgl(void) PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT30); PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT31); #endif - PY_DICT_ADD_INT(GL_COMPARE_REF_TO_TEXTURE); - PY_DICT_ADD_INT(GL_COMPRESSED_RED); - PY_DICT_ADD_INT(GL_COMPRESSED_RED_RGTC1); - PY_DICT_ADD_INT(GL_COMPRESSED_RG); - PY_DICT_ADD_INT(GL_COMPRESSED_RG_RGTC2); - PY_DICT_ADD_INT(GL_COMPRESSED_SIGNED_RED_RGTC1); - PY_DICT_ADD_INT(GL_COMPRESSED_SIGNED_RG_RGTC2); - PY_DICT_ADD_INT(GL_CONTEXT_FLAGS); - PY_DICT_ADD_INT(GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT); - PY_DICT_ADD_INT(GL_DEPTH24_STENCIL8); - PY_DICT_ADD_INT(GL_DEPTH32F_STENCIL8); - PY_DICT_ADD_INT(GL_DEPTH_ATTACHMENT); - PY_DICT_ADD_INT(GL_DEPTH_COMPONENT32F); - PY_DICT_ADD_INT(GL_DEPTH_STENCIL); - PY_DICT_ADD_INT(GL_DEPTH_STENCIL_ATTACHMENT); - PY_DICT_ADD_INT(GL_DRAW_FRAMEBUFFER); - PY_DICT_ADD_INT(GL_DRAW_FRAMEBUFFER_BINDING); - PY_DICT_ADD_INT(GL_FIXED_ONLY); - PY_DICT_ADD_INT(GL_FLOAT_32_UNSIGNED_INT_24_8_REV); - PY_DICT_ADD_INT(GL_FRAMEBUFFER); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_BINDING); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_COMPLETE); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_DEFAULT); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_SRGB); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_UNDEFINED); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_UNSUPPORTED); - PY_DICT_ADD_INT(GL_GREEN_INTEGER); - PY_DICT_ADD_INT(GL_HALF_FLOAT); - PY_DICT_ADD_INT(GL_INDEX); - PY_DICT_ADD_INT(GL_INTERLEAVED_ATTRIBS); - PY_DICT_ADD_INT(GL_INT_SAMPLER_1D); - PY_DICT_ADD_INT(GL_INT_SAMPLER_1D_ARRAY); - PY_DICT_ADD_INT(GL_INT_SAMPLER_2D); - PY_DICT_ADD_INT(GL_INT_SAMPLER_2D_ARRAY); - PY_DICT_ADD_INT(GL_INT_SAMPLER_3D); - PY_DICT_ADD_INT(GL_INT_SAMPLER_CUBE); - PY_DICT_ADD_INT(GL_INVALID_FRAMEBUFFER_OPERATION); - PY_DICT_ADD_INT(GL_MAJOR_VERSION); - PY_DICT_ADD_INT(GL_MAP_FLUSH_EXPLICIT_BIT); - PY_DICT_ADD_INT(GL_MAP_INVALIDATE_BUFFER_BIT); - PY_DICT_ADD_INT(GL_MAP_INVALIDATE_RANGE_BIT); - PY_DICT_ADD_INT(GL_MAP_READ_BIT); - PY_DICT_ADD_INT(GL_MAP_UNSYNCHRONIZED_BIT); - PY_DICT_ADD_INT(GL_MAP_WRITE_BIT); - PY_DICT_ADD_INT(GL_MAX_ARRAY_TEXTURE_LAYERS); - PY_DICT_ADD_INT(GL_MAX_CLIP_DISTANCES); - PY_DICT_ADD_INT(GL_MAX_COLOR_ATTACHMENTS); - PY_DICT_ADD_INT(GL_MAX_PROGRAM_TEXEL_OFFSET); - PY_DICT_ADD_INT(GL_MAX_RENDERBUFFER_SIZE); - PY_DICT_ADD_INT(GL_MAX_SAMPLES); - PY_DICT_ADD_INT(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS); - PY_DICT_ADD_INT(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS); - PY_DICT_ADD_INT(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS); - PY_DICT_ADD_INT(GL_MAX_VARYING_COMPONENTS); - PY_DICT_ADD_INT(GL_MINOR_VERSION); - PY_DICT_ADD_INT(GL_MIN_PROGRAM_TEXEL_OFFSET); - PY_DICT_ADD_INT(GL_NUM_EXTENSIONS); - PY_DICT_ADD_INT(GL_PRIMITIVES_GENERATED); - PY_DICT_ADD_INT(GL_PROXY_TEXTURE_1D_ARRAY); - PY_DICT_ADD_INT(GL_PROXY_TEXTURE_2D_ARRAY); - PY_DICT_ADD_INT(GL_QUERY_BY_REGION_NO_WAIT); - PY_DICT_ADD_INT(GL_QUERY_BY_REGION_WAIT); - PY_DICT_ADD_INT(GL_QUERY_NO_WAIT); - PY_DICT_ADD_INT(GL_QUERY_WAIT); - PY_DICT_ADD_INT(GL_R11F_G11F_B10F); - PY_DICT_ADD_INT(GL_R16); - PY_DICT_ADD_INT(GL_R16F); - PY_DICT_ADD_INT(GL_R16I); - PY_DICT_ADD_INT(GL_R16UI); - PY_DICT_ADD_INT(GL_R32F); - PY_DICT_ADD_INT(GL_R32I); - PY_DICT_ADD_INT(GL_R32UI); - PY_DICT_ADD_INT(GL_R8); - PY_DICT_ADD_INT(GL_R8I); - PY_DICT_ADD_INT(GL_R8UI); - PY_DICT_ADD_INT(GL_RASTERIZER_DISCARD); - PY_DICT_ADD_INT(GL_READ_FRAMEBUFFER); - PY_DICT_ADD_INT(GL_READ_FRAMEBUFFER_BINDING); - PY_DICT_ADD_INT(GL_RED_INTEGER); - PY_DICT_ADD_INT(GL_RENDERBUFFER); - PY_DICT_ADD_INT(GL_RENDERBUFFER_ALPHA_SIZE); - PY_DICT_ADD_INT(GL_RENDERBUFFER_BINDING); - PY_DICT_ADD_INT(GL_RENDERBUFFER_BLUE_SIZE); - PY_DICT_ADD_INT(GL_RENDERBUFFER_DEPTH_SIZE); - PY_DICT_ADD_INT(GL_RENDERBUFFER_GREEN_SIZE); - PY_DICT_ADD_INT(GL_RENDERBUFFER_HEIGHT); - PY_DICT_ADD_INT(GL_RENDERBUFFER_INTERNAL_FORMAT); - PY_DICT_ADD_INT(GL_RENDERBUFFER_RED_SIZE); - PY_DICT_ADD_INT(GL_RENDERBUFFER_SAMPLES); - PY_DICT_ADD_INT(GL_RENDERBUFFER_STENCIL_SIZE); - PY_DICT_ADD_INT(GL_RENDERBUFFER_WIDTH); - PY_DICT_ADD_INT(GL_RG); - PY_DICT_ADD_INT(GL_RG16); - PY_DICT_ADD_INT(GL_RG16F); - PY_DICT_ADD_INT(GL_RG16I); - PY_DICT_ADD_INT(GL_RG16UI); - PY_DICT_ADD_INT(GL_RG32F); - PY_DICT_ADD_INT(GL_RG32I); - PY_DICT_ADD_INT(GL_RG32UI); - PY_DICT_ADD_INT(GL_RG8); - PY_DICT_ADD_INT(GL_RG8I); - PY_DICT_ADD_INT(GL_RG8UI); - PY_DICT_ADD_INT(GL_RGB16F); - PY_DICT_ADD_INT(GL_RGB16I); - PY_DICT_ADD_INT(GL_RGB16UI); - PY_DICT_ADD_INT(GL_RGB32F); - PY_DICT_ADD_INT(GL_RGB32I); - PY_DICT_ADD_INT(GL_RGB32UI); - PY_DICT_ADD_INT(GL_RGB8I); - PY_DICT_ADD_INT(GL_RGB8UI); - PY_DICT_ADD_INT(GL_RGB9_E5); - PY_DICT_ADD_INT(GL_RGBA16F); - PY_DICT_ADD_INT(GL_RGBA16I); - PY_DICT_ADD_INT(GL_RGBA16UI); - PY_DICT_ADD_INT(GL_RGBA32F); - PY_DICT_ADD_INT(GL_RGBA32I); - PY_DICT_ADD_INT(GL_RGBA32UI); - PY_DICT_ADD_INT(GL_RGBA8I); - PY_DICT_ADD_INT(GL_RGBA8UI); - PY_DICT_ADD_INT(GL_RGBA_INTEGER); - PY_DICT_ADD_INT(GL_RGB_INTEGER); - PY_DICT_ADD_INT(GL_RG_INTEGER); - PY_DICT_ADD_INT(GL_SAMPLER_1D_ARRAY); - PY_DICT_ADD_INT(GL_SAMPLER_1D_ARRAY_SHADOW); - PY_DICT_ADD_INT(GL_SAMPLER_2D_ARRAY); - PY_DICT_ADD_INT(GL_SAMPLER_2D_ARRAY_SHADOW); - PY_DICT_ADD_INT(GL_SAMPLER_CUBE_SHADOW); - PY_DICT_ADD_INT(GL_SEPARATE_ATTRIBS); - PY_DICT_ADD_INT(GL_STENCIL_ATTACHMENT); - PY_DICT_ADD_INT(GL_STENCIL_INDEX1); - PY_DICT_ADD_INT(GL_STENCIL_INDEX16); - PY_DICT_ADD_INT(GL_STENCIL_INDEX4); - PY_DICT_ADD_INT(GL_STENCIL_INDEX8); - PY_DICT_ADD_INT(GL_TEXTURE_1D_ARRAY); - PY_DICT_ADD_INT(GL_TEXTURE_2D_ARRAY); - PY_DICT_ADD_INT(GL_TEXTURE_ALPHA_TYPE); - PY_DICT_ADD_INT(GL_TEXTURE_BINDING_1D_ARRAY); - PY_DICT_ADD_INT(GL_TEXTURE_BINDING_2D_ARRAY); - PY_DICT_ADD_INT(GL_TEXTURE_BLUE_TYPE); - PY_DICT_ADD_INT(GL_TEXTURE_DEPTH_TYPE); - PY_DICT_ADD_INT(GL_TEXTURE_GREEN_TYPE); - PY_DICT_ADD_INT(GL_TEXTURE_RED_TYPE); - PY_DICT_ADD_INT(GL_TEXTURE_SHARED_SIZE); - PY_DICT_ADD_INT(GL_TEXTURE_STENCIL_SIZE); - PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER); - PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING); - PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER_MODE); - PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER_SIZE); - PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER_START); - PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); - PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_VARYINGS); - PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_10F_11F_11F_REV); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_24_8); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_5_9_9_9_REV); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_1D); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_1D_ARRAY); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D_ARRAY); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_3D); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_CUBE); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_VEC2); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_VEC3); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_VEC4); - PY_DICT_ADD_INT(GL_UNSIGNED_NORMALIZED); - PY_DICT_ADD_INT(GL_VERTEX_ARRAY_BINDING); - PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_INTEGER); - } - + PY_DICT_ADD_INT(GL_COMPARE_REF_TO_TEXTURE); + PY_DICT_ADD_INT(GL_COMPRESSED_RED); + PY_DICT_ADD_INT(GL_COMPRESSED_RED_RGTC1); + PY_DICT_ADD_INT(GL_COMPRESSED_RG); + PY_DICT_ADD_INT(GL_COMPRESSED_RG_RGTC2); + PY_DICT_ADD_INT(GL_COMPRESSED_SIGNED_RED_RGTC1); + PY_DICT_ADD_INT(GL_COMPRESSED_SIGNED_RG_RGTC2); + PY_DICT_ADD_INT(GL_CONTEXT_FLAGS); + PY_DICT_ADD_INT(GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT); + PY_DICT_ADD_INT(GL_DEPTH24_STENCIL8); + PY_DICT_ADD_INT(GL_DEPTH32F_STENCIL8); + PY_DICT_ADD_INT(GL_DEPTH_ATTACHMENT); + PY_DICT_ADD_INT(GL_DEPTH_COMPONENT32F); + PY_DICT_ADD_INT(GL_DEPTH_STENCIL); + PY_DICT_ADD_INT(GL_DEPTH_STENCIL_ATTACHMENT); + PY_DICT_ADD_INT(GL_DRAW_FRAMEBUFFER); + PY_DICT_ADD_INT(GL_DRAW_FRAMEBUFFER_BINDING); + PY_DICT_ADD_INT(GL_FIXED_ONLY); + PY_DICT_ADD_INT(GL_FLOAT_32_UNSIGNED_INT_24_8_REV); + PY_DICT_ADD_INT(GL_FRAMEBUFFER); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_BINDING); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_COMPLETE); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_DEFAULT); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_SRGB); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_UNDEFINED); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_UNSUPPORTED); + PY_DICT_ADD_INT(GL_GREEN_INTEGER); + PY_DICT_ADD_INT(GL_HALF_FLOAT); + PY_DICT_ADD_INT(GL_INDEX); + PY_DICT_ADD_INT(GL_INTERLEAVED_ATTRIBS); + PY_DICT_ADD_INT(GL_INT_SAMPLER_1D); + PY_DICT_ADD_INT(GL_INT_SAMPLER_1D_ARRAY); + PY_DICT_ADD_INT(GL_INT_SAMPLER_2D); + PY_DICT_ADD_INT(GL_INT_SAMPLER_2D_ARRAY); + PY_DICT_ADD_INT(GL_INT_SAMPLER_3D); + PY_DICT_ADD_INT(GL_INT_SAMPLER_CUBE); + PY_DICT_ADD_INT(GL_INVALID_FRAMEBUFFER_OPERATION); + PY_DICT_ADD_INT(GL_MAJOR_VERSION); + PY_DICT_ADD_INT(GL_MAP_FLUSH_EXPLICIT_BIT); + PY_DICT_ADD_INT(GL_MAP_INVALIDATE_BUFFER_BIT); + PY_DICT_ADD_INT(GL_MAP_INVALIDATE_RANGE_BIT); + PY_DICT_ADD_INT(GL_MAP_READ_BIT); + PY_DICT_ADD_INT(GL_MAP_UNSYNCHRONIZED_BIT); + PY_DICT_ADD_INT(GL_MAP_WRITE_BIT); + PY_DICT_ADD_INT(GL_MAX_ARRAY_TEXTURE_LAYERS); + PY_DICT_ADD_INT(GL_MAX_CLIP_DISTANCES); + PY_DICT_ADD_INT(GL_MAX_COLOR_ATTACHMENTS); + PY_DICT_ADD_INT(GL_MAX_PROGRAM_TEXEL_OFFSET); + PY_DICT_ADD_INT(GL_MAX_RENDERBUFFER_SIZE); + PY_DICT_ADD_INT(GL_MAX_SAMPLES); + PY_DICT_ADD_INT(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS); + PY_DICT_ADD_INT(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS); + PY_DICT_ADD_INT(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS); + PY_DICT_ADD_INT(GL_MAX_VARYING_COMPONENTS); + PY_DICT_ADD_INT(GL_MINOR_VERSION); + PY_DICT_ADD_INT(GL_MIN_PROGRAM_TEXEL_OFFSET); + PY_DICT_ADD_INT(GL_NUM_EXTENSIONS); + PY_DICT_ADD_INT(GL_PRIMITIVES_GENERATED); + PY_DICT_ADD_INT(GL_PROXY_TEXTURE_1D_ARRAY); + PY_DICT_ADD_INT(GL_PROXY_TEXTURE_2D_ARRAY); + PY_DICT_ADD_INT(GL_QUERY_BY_REGION_NO_WAIT); + PY_DICT_ADD_INT(GL_QUERY_BY_REGION_WAIT); + PY_DICT_ADD_INT(GL_QUERY_NO_WAIT); + PY_DICT_ADD_INT(GL_QUERY_WAIT); + PY_DICT_ADD_INT(GL_R11F_G11F_B10F); + PY_DICT_ADD_INT(GL_R16); + PY_DICT_ADD_INT(GL_R16F); + PY_DICT_ADD_INT(GL_R16I); + PY_DICT_ADD_INT(GL_R16UI); + PY_DICT_ADD_INT(GL_R32F); + PY_DICT_ADD_INT(GL_R32I); + PY_DICT_ADD_INT(GL_R32UI); + PY_DICT_ADD_INT(GL_R8); + PY_DICT_ADD_INT(GL_R8I); + PY_DICT_ADD_INT(GL_R8UI); + PY_DICT_ADD_INT(GL_RASTERIZER_DISCARD); + PY_DICT_ADD_INT(GL_READ_FRAMEBUFFER); + PY_DICT_ADD_INT(GL_READ_FRAMEBUFFER_BINDING); + PY_DICT_ADD_INT(GL_RED_INTEGER); + PY_DICT_ADD_INT(GL_RENDERBUFFER); + PY_DICT_ADD_INT(GL_RENDERBUFFER_ALPHA_SIZE); + PY_DICT_ADD_INT(GL_RENDERBUFFER_BINDING); + PY_DICT_ADD_INT(GL_RENDERBUFFER_BLUE_SIZE); + PY_DICT_ADD_INT(GL_RENDERBUFFER_DEPTH_SIZE); + PY_DICT_ADD_INT(GL_RENDERBUFFER_GREEN_SIZE); + PY_DICT_ADD_INT(GL_RENDERBUFFER_HEIGHT); + PY_DICT_ADD_INT(GL_RENDERBUFFER_INTERNAL_FORMAT); + PY_DICT_ADD_INT(GL_RENDERBUFFER_RED_SIZE); + PY_DICT_ADD_INT(GL_RENDERBUFFER_SAMPLES); + PY_DICT_ADD_INT(GL_RENDERBUFFER_STENCIL_SIZE); + PY_DICT_ADD_INT(GL_RENDERBUFFER_WIDTH); + PY_DICT_ADD_INT(GL_RG); + PY_DICT_ADD_INT(GL_RG16); + PY_DICT_ADD_INT(GL_RG16F); + PY_DICT_ADD_INT(GL_RG16I); + PY_DICT_ADD_INT(GL_RG16UI); + PY_DICT_ADD_INT(GL_RG32F); + PY_DICT_ADD_INT(GL_RG32I); + PY_DICT_ADD_INT(GL_RG32UI); + PY_DICT_ADD_INT(GL_RG8); + PY_DICT_ADD_INT(GL_RG8I); + PY_DICT_ADD_INT(GL_RG8UI); + PY_DICT_ADD_INT(GL_RGB16F); + PY_DICT_ADD_INT(GL_RGB16I); + PY_DICT_ADD_INT(GL_RGB16UI); + PY_DICT_ADD_INT(GL_RGB32F); + PY_DICT_ADD_INT(GL_RGB32I); + PY_DICT_ADD_INT(GL_RGB32UI); + PY_DICT_ADD_INT(GL_RGB8I); + PY_DICT_ADD_INT(GL_RGB8UI); + PY_DICT_ADD_INT(GL_RGB9_E5); + PY_DICT_ADD_INT(GL_RGBA16F); + PY_DICT_ADD_INT(GL_RGBA16I); + PY_DICT_ADD_INT(GL_RGBA16UI); + PY_DICT_ADD_INT(GL_RGBA32F); + PY_DICT_ADD_INT(GL_RGBA32I); + PY_DICT_ADD_INT(GL_RGBA32UI); + PY_DICT_ADD_INT(GL_RGBA8I); + PY_DICT_ADD_INT(GL_RGBA8UI); + PY_DICT_ADD_INT(GL_RGBA_INTEGER); + PY_DICT_ADD_INT(GL_RGB_INTEGER); + PY_DICT_ADD_INT(GL_RG_INTEGER); + PY_DICT_ADD_INT(GL_SAMPLER_1D_ARRAY); + PY_DICT_ADD_INT(GL_SAMPLER_1D_ARRAY_SHADOW); + PY_DICT_ADD_INT(GL_SAMPLER_2D_ARRAY); + PY_DICT_ADD_INT(GL_SAMPLER_2D_ARRAY_SHADOW); + PY_DICT_ADD_INT(GL_SAMPLER_CUBE_SHADOW); + PY_DICT_ADD_INT(GL_SEPARATE_ATTRIBS); + PY_DICT_ADD_INT(GL_STENCIL_ATTACHMENT); + PY_DICT_ADD_INT(GL_STENCIL_INDEX1); + PY_DICT_ADD_INT(GL_STENCIL_INDEX16); + PY_DICT_ADD_INT(GL_STENCIL_INDEX4); + PY_DICT_ADD_INT(GL_STENCIL_INDEX8); + PY_DICT_ADD_INT(GL_TEXTURE_1D_ARRAY); + PY_DICT_ADD_INT(GL_TEXTURE_2D_ARRAY); + PY_DICT_ADD_INT(GL_TEXTURE_ALPHA_TYPE); + PY_DICT_ADD_INT(GL_TEXTURE_BINDING_1D_ARRAY); + PY_DICT_ADD_INT(GL_TEXTURE_BINDING_2D_ARRAY); + PY_DICT_ADD_INT(GL_TEXTURE_BLUE_TYPE); + PY_DICT_ADD_INT(GL_TEXTURE_DEPTH_TYPE); + PY_DICT_ADD_INT(GL_TEXTURE_GREEN_TYPE); + PY_DICT_ADD_INT(GL_TEXTURE_RED_TYPE); + PY_DICT_ADD_INT(GL_TEXTURE_SHARED_SIZE); + PY_DICT_ADD_INT(GL_TEXTURE_STENCIL_SIZE); + PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER); + PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING); + PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER_MODE); + PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER_SIZE); + PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER_START); + PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); + PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_VARYINGS); + PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_10F_11F_11F_REV); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_24_8); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_5_9_9_9_REV); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_1D); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_1D_ARRAY); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D_ARRAY); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_3D); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_CUBE); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_VEC2); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_VEC3); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_VEC4); + PY_DICT_ADD_INT(GL_UNSIGNED_NORMALIZED); + PY_DICT_ADD_INT(GL_VERTEX_ARRAY_BINDING); + PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_INTEGER); +} +static void init_bgl_version_3_1_constants(PyObject *dict) +{ /* GL_VERSION_3_1 */ - { - PY_DICT_ADD_INT(GL_ACTIVE_UNIFORM_BLOCKS); - PY_DICT_ADD_INT(GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH); - PY_DICT_ADD_INT(GL_COPY_READ_BUFFER); - PY_DICT_ADD_INT(GL_COPY_WRITE_BUFFER); - PY_DICT_ADD_INT(GL_INT_SAMPLER_2D_RECT); - PY_DICT_ADD_INT(GL_INT_SAMPLER_BUFFER); - PY_DICT_ADD_INT(GL_INVALID_INDEX); - PY_DICT_ADD_INT(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS); - PY_DICT_ADD_INT(GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS); - PY_DICT_ADD_INT(GL_MAX_COMBINED_UNIFORM_BLOCKS); - PY_DICT_ADD_INT(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS); - PY_DICT_ADD_INT(GL_MAX_FRAGMENT_UNIFORM_BLOCKS); - PY_DICT_ADD_INT(GL_MAX_GEOMETRY_UNIFORM_BLOCKS); - PY_DICT_ADD_INT(GL_MAX_RECTANGLE_TEXTURE_SIZE); - PY_DICT_ADD_INT(GL_MAX_TEXTURE_BUFFER_SIZE); - PY_DICT_ADD_INT(GL_MAX_UNIFORM_BLOCK_SIZE); - PY_DICT_ADD_INT(GL_MAX_UNIFORM_BUFFER_BINDINGS); - PY_DICT_ADD_INT(GL_MAX_VERTEX_UNIFORM_BLOCKS); - PY_DICT_ADD_INT(GL_PRIMITIVE_RESTART); - PY_DICT_ADD_INT(GL_PRIMITIVE_RESTART_INDEX); - PY_DICT_ADD_INT(GL_PROXY_TEXTURE_RECTANGLE); - PY_DICT_ADD_INT(GL_R16_SNORM); - PY_DICT_ADD_INT(GL_R8_SNORM); - PY_DICT_ADD_INT(GL_RG16_SNORM); - PY_DICT_ADD_INT(GL_RG8_SNORM); - PY_DICT_ADD_INT(GL_RGB16_SNORM); - PY_DICT_ADD_INT(GL_RGB8_SNORM); - PY_DICT_ADD_INT(GL_RGBA16_SNORM); - PY_DICT_ADD_INT(GL_RGBA8_SNORM); - PY_DICT_ADD_INT(GL_SAMPLER_2D_RECT); - PY_DICT_ADD_INT(GL_SAMPLER_2D_RECT_SHADOW); - PY_DICT_ADD_INT(GL_SAMPLER_BUFFER); - PY_DICT_ADD_INT(GL_SIGNED_NORMALIZED); - PY_DICT_ADD_INT(GL_TEXTURE_BINDING_BUFFER); - PY_DICT_ADD_INT(GL_TEXTURE_BINDING_RECTANGLE); - PY_DICT_ADD_INT(GL_TEXTURE_BUFFER); - PY_DICT_ADD_INT(GL_TEXTURE_BUFFER_DATA_STORE_BINDING); - PY_DICT_ADD_INT(GL_TEXTURE_RECTANGLE); - PY_DICT_ADD_INT(GL_UNIFORM_ARRAY_STRIDE); - PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS); - PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES); - PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_BINDING); - PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_DATA_SIZE); - PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_INDEX); - PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_NAME_LENGTH); - PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER); - PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER); - PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER); - PY_DICT_ADD_INT(GL_UNIFORM_BUFFER); - PY_DICT_ADD_INT(GL_UNIFORM_BUFFER_BINDING); - PY_DICT_ADD_INT(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT); - PY_DICT_ADD_INT(GL_UNIFORM_BUFFER_SIZE); - PY_DICT_ADD_INT(GL_UNIFORM_BUFFER_START); - PY_DICT_ADD_INT(GL_UNIFORM_IS_ROW_MAJOR); - PY_DICT_ADD_INT(GL_UNIFORM_MATRIX_STRIDE); - PY_DICT_ADD_INT(GL_UNIFORM_NAME_LENGTH); - PY_DICT_ADD_INT(GL_UNIFORM_OFFSET); - PY_DICT_ADD_INT(GL_UNIFORM_SIZE); - PY_DICT_ADD_INT(GL_UNIFORM_TYPE); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D_RECT); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_BUFFER); - } + PY_DICT_ADD_INT(GL_ACTIVE_UNIFORM_BLOCKS); + PY_DICT_ADD_INT(GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH); + PY_DICT_ADD_INT(GL_COPY_READ_BUFFER); + PY_DICT_ADD_INT(GL_COPY_WRITE_BUFFER); + PY_DICT_ADD_INT(GL_INT_SAMPLER_2D_RECT); + PY_DICT_ADD_INT(GL_INT_SAMPLER_BUFFER); + PY_DICT_ADD_INT(GL_INVALID_INDEX); + PY_DICT_ADD_INT(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS); + PY_DICT_ADD_INT(GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS); + PY_DICT_ADD_INT(GL_MAX_COMBINED_UNIFORM_BLOCKS); + PY_DICT_ADD_INT(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS); + PY_DICT_ADD_INT(GL_MAX_FRAGMENT_UNIFORM_BLOCKS); + PY_DICT_ADD_INT(GL_MAX_GEOMETRY_UNIFORM_BLOCKS); + PY_DICT_ADD_INT(GL_MAX_RECTANGLE_TEXTURE_SIZE); + PY_DICT_ADD_INT(GL_MAX_TEXTURE_BUFFER_SIZE); + PY_DICT_ADD_INT(GL_MAX_UNIFORM_BLOCK_SIZE); + PY_DICT_ADD_INT(GL_MAX_UNIFORM_BUFFER_BINDINGS); + PY_DICT_ADD_INT(GL_MAX_VERTEX_UNIFORM_BLOCKS); + PY_DICT_ADD_INT(GL_PRIMITIVE_RESTART); + PY_DICT_ADD_INT(GL_PRIMITIVE_RESTART_INDEX); + PY_DICT_ADD_INT(GL_PROXY_TEXTURE_RECTANGLE); + PY_DICT_ADD_INT(GL_R16_SNORM); + PY_DICT_ADD_INT(GL_R8_SNORM); + PY_DICT_ADD_INT(GL_RG16_SNORM); + PY_DICT_ADD_INT(GL_RG8_SNORM); + PY_DICT_ADD_INT(GL_RGB16_SNORM); + PY_DICT_ADD_INT(GL_RGB8_SNORM); + PY_DICT_ADD_INT(GL_RGBA16_SNORM); + PY_DICT_ADD_INT(GL_RGBA8_SNORM); + PY_DICT_ADD_INT(GL_SAMPLER_2D_RECT); + PY_DICT_ADD_INT(GL_SAMPLER_2D_RECT_SHADOW); + PY_DICT_ADD_INT(GL_SAMPLER_BUFFER); + PY_DICT_ADD_INT(GL_SIGNED_NORMALIZED); + PY_DICT_ADD_INT(GL_TEXTURE_BINDING_BUFFER); + PY_DICT_ADD_INT(GL_TEXTURE_BINDING_RECTANGLE); + PY_DICT_ADD_INT(GL_TEXTURE_BUFFER); + PY_DICT_ADD_INT(GL_TEXTURE_BUFFER_DATA_STORE_BINDING); + PY_DICT_ADD_INT(GL_TEXTURE_RECTANGLE); + PY_DICT_ADD_INT(GL_UNIFORM_ARRAY_STRIDE); + PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS); + PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES); + PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_BINDING); + PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_DATA_SIZE); + PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_INDEX); + PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_NAME_LENGTH); + PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER); + PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER); + PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER); + PY_DICT_ADD_INT(GL_UNIFORM_BUFFER); + PY_DICT_ADD_INT(GL_UNIFORM_BUFFER_BINDING); + PY_DICT_ADD_INT(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT); + PY_DICT_ADD_INT(GL_UNIFORM_BUFFER_SIZE); + PY_DICT_ADD_INT(GL_UNIFORM_BUFFER_START); + PY_DICT_ADD_INT(GL_UNIFORM_IS_ROW_MAJOR); + PY_DICT_ADD_INT(GL_UNIFORM_MATRIX_STRIDE); + PY_DICT_ADD_INT(GL_UNIFORM_NAME_LENGTH); + PY_DICT_ADD_INT(GL_UNIFORM_OFFSET); + PY_DICT_ADD_INT(GL_UNIFORM_SIZE); + PY_DICT_ADD_INT(GL_UNIFORM_TYPE); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D_RECT); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_BUFFER); +} +static void init_bgl_version_3_2_constants(PyObject *dict) +/* GL_VERSION_3_2 */ +{ + PY_DICT_ADD_INT(GL_ALREADY_SIGNALED); + PY_DICT_ADD_INT(GL_CONDITION_SATISFIED); + PY_DICT_ADD_INT(GL_CONTEXT_COMPATIBILITY_PROFILE_BIT); + PY_DICT_ADD_INT(GL_CONTEXT_CORE_PROFILE_BIT); + PY_DICT_ADD_INT(GL_CONTEXT_PROFILE_MASK); + PY_DICT_ADD_INT(GL_DEPTH_CLAMP); + PY_DICT_ADD_INT(GL_FIRST_VERTEX_CONVENTION); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_LAYERED); + PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS); + PY_DICT_ADD_INT(GL_GEOMETRY_INPUT_TYPE); + PY_DICT_ADD_INT(GL_GEOMETRY_OUTPUT_TYPE); + PY_DICT_ADD_INT(GL_GEOMETRY_SHADER); + PY_DICT_ADD_INT(GL_GEOMETRY_VERTICES_OUT); + PY_DICT_ADD_INT(GL_INT_SAMPLER_2D_MULTISAMPLE); + PY_DICT_ADD_INT(GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY); + PY_DICT_ADD_INT(GL_LAST_VERTEX_CONVENTION); + PY_DICT_ADD_INT(GL_LINES_ADJACENCY); + PY_DICT_ADD_INT(GL_LINE_STRIP_ADJACENCY); + PY_DICT_ADD_INT(GL_MAX_COLOR_TEXTURE_SAMPLES); + PY_DICT_ADD_INT(GL_MAX_DEPTH_TEXTURE_SAMPLES); + PY_DICT_ADD_INT(GL_MAX_FRAGMENT_INPUT_COMPONENTS); + PY_DICT_ADD_INT(GL_MAX_GEOMETRY_INPUT_COMPONENTS); + PY_DICT_ADD_INT(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS); + PY_DICT_ADD_INT(GL_MAX_GEOMETRY_OUTPUT_VERTICES); + PY_DICT_ADD_INT(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS); + PY_DICT_ADD_INT(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS); + PY_DICT_ADD_INT(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS); + PY_DICT_ADD_INT(GL_MAX_INTEGER_SAMPLES); + PY_DICT_ADD_INT(GL_MAX_SAMPLE_MASK_WORDS); + PY_DICT_ADD_INT(GL_MAX_SERVER_WAIT_TIMEOUT); + PY_DICT_ADD_INT(GL_MAX_VERTEX_OUTPUT_COMPONENTS); + PY_DICT_ADD_INT(GL_OBJECT_TYPE); + PY_DICT_ADD_INT(GL_PROGRAM_POINT_SIZE); + PY_DICT_ADD_INT(GL_PROVOKING_VERTEX); + PY_DICT_ADD_INT(GL_PROXY_TEXTURE_2D_MULTISAMPLE); + PY_DICT_ADD_INT(GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY); + PY_DICT_ADD_INT(GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION); + PY_DICT_ADD_INT(GL_SAMPLER_2D_MULTISAMPLE); + PY_DICT_ADD_INT(GL_SAMPLER_2D_MULTISAMPLE_ARRAY); + PY_DICT_ADD_INT(GL_SAMPLE_MASK); + PY_DICT_ADD_INT(GL_SAMPLE_MASK_VALUE); + PY_DICT_ADD_INT(GL_SAMPLE_POSITION); + PY_DICT_ADD_INT(GL_SIGNALED); + PY_DICT_ADD_INT(GL_SYNC_CONDITION); + PY_DICT_ADD_INT(GL_SYNC_FENCE); + PY_DICT_ADD_INT(GL_SYNC_FLAGS); + PY_DICT_ADD_INT(GL_SYNC_FLUSH_COMMANDS_BIT); + PY_DICT_ADD_INT(GL_SYNC_GPU_COMMANDS_COMPLETE); + PY_DICT_ADD_INT(GL_SYNC_STATUS); + PY_DICT_ADD_INT(GL_TEXTURE_2D_MULTISAMPLE); + PY_DICT_ADD_INT(GL_TEXTURE_2D_MULTISAMPLE_ARRAY); + PY_DICT_ADD_INT(GL_TEXTURE_BINDING_2D_MULTISAMPLE); + PY_DICT_ADD_INT(GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY); + PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_SEAMLESS); + PY_DICT_ADD_INT(GL_TEXTURE_FIXED_SAMPLE_LOCATIONS); + PY_DICT_ADD_INT(GL_TEXTURE_SAMPLES); + PY_DICT_ADD_INT(GL_TIMEOUT_EXPIRED); + PY_DICT_ADD_INT64(GL_TIMEOUT_IGNORED); + PY_DICT_ADD_INT(GL_TRIANGLES_ADJACENCY); + PY_DICT_ADD_INT(GL_TRIANGLE_STRIP_ADJACENCY); + PY_DICT_ADD_INT(GL_UNSIGNALED); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE); + PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY); + PY_DICT_ADD_INT(GL_WAIT_FAILED); +} +static void init_bgl_version_3_3_constants(PyObject *dict) +{ + /* GL_VERSION_3_3 */ + PY_DICT_ADD_INT(GL_ANY_SAMPLES_PASSED); + PY_DICT_ADD_INT(GL_INT_2_10_10_10_REV); + PY_DICT_ADD_INT(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS); + PY_DICT_ADD_INT(GL_ONE_MINUS_SRC1_ALPHA); + PY_DICT_ADD_INT(GL_ONE_MINUS_SRC1_COLOR); + PY_DICT_ADD_INT(GL_RGB10_A2UI); + PY_DICT_ADD_INT(GL_SAMPLER_BINDING); + PY_DICT_ADD_INT(GL_SRC1_COLOR); + PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_A); + PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_B); + PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_G); + PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_R); + PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_RGBA); + PY_DICT_ADD_INT(GL_TIMESTAMP); + PY_DICT_ADD_INT(GL_TIME_ELAPSED); + PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_DIVISOR); +} - /* GL_VERSION_3_2 */ - { - PY_DICT_ADD_INT(GL_ALREADY_SIGNALED); - PY_DICT_ADD_INT(GL_CONDITION_SATISFIED); - PY_DICT_ADD_INT(GL_CONTEXT_COMPATIBILITY_PROFILE_BIT); - PY_DICT_ADD_INT(GL_CONTEXT_CORE_PROFILE_BIT); - PY_DICT_ADD_INT(GL_CONTEXT_PROFILE_MASK); - PY_DICT_ADD_INT(GL_DEPTH_CLAMP); - PY_DICT_ADD_INT(GL_FIRST_VERTEX_CONVENTION); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_LAYERED); - PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS); - PY_DICT_ADD_INT(GL_GEOMETRY_INPUT_TYPE); - PY_DICT_ADD_INT(GL_GEOMETRY_OUTPUT_TYPE); - PY_DICT_ADD_INT(GL_GEOMETRY_SHADER); - PY_DICT_ADD_INT(GL_GEOMETRY_VERTICES_OUT); - PY_DICT_ADD_INT(GL_INT_SAMPLER_2D_MULTISAMPLE); - PY_DICT_ADD_INT(GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY); - PY_DICT_ADD_INT(GL_LAST_VERTEX_CONVENTION); - PY_DICT_ADD_INT(GL_LINES_ADJACENCY); - PY_DICT_ADD_INT(GL_LINE_STRIP_ADJACENCY); - PY_DICT_ADD_INT(GL_MAX_COLOR_TEXTURE_SAMPLES); - PY_DICT_ADD_INT(GL_MAX_DEPTH_TEXTURE_SAMPLES); - PY_DICT_ADD_INT(GL_MAX_FRAGMENT_INPUT_COMPONENTS); - PY_DICT_ADD_INT(GL_MAX_GEOMETRY_INPUT_COMPONENTS); - PY_DICT_ADD_INT(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS); - PY_DICT_ADD_INT(GL_MAX_GEOMETRY_OUTPUT_VERTICES); - PY_DICT_ADD_INT(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS); - PY_DICT_ADD_INT(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS); - PY_DICT_ADD_INT(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS); - PY_DICT_ADD_INT(GL_MAX_INTEGER_SAMPLES); - PY_DICT_ADD_INT(GL_MAX_SAMPLE_MASK_WORDS); - PY_DICT_ADD_INT(GL_MAX_SERVER_WAIT_TIMEOUT); - PY_DICT_ADD_INT(GL_MAX_VERTEX_OUTPUT_COMPONENTS); - PY_DICT_ADD_INT(GL_OBJECT_TYPE); - PY_DICT_ADD_INT(GL_PROGRAM_POINT_SIZE); - PY_DICT_ADD_INT(GL_PROVOKING_VERTEX); - PY_DICT_ADD_INT(GL_PROXY_TEXTURE_2D_MULTISAMPLE); - PY_DICT_ADD_INT(GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY); - PY_DICT_ADD_INT(GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION); - PY_DICT_ADD_INT(GL_SAMPLER_2D_MULTISAMPLE); - PY_DICT_ADD_INT(GL_SAMPLER_2D_MULTISAMPLE_ARRAY); - PY_DICT_ADD_INT(GL_SAMPLE_MASK); - PY_DICT_ADD_INT(GL_SAMPLE_MASK_VALUE); - PY_DICT_ADD_INT(GL_SAMPLE_POSITION); - PY_DICT_ADD_INT(GL_SIGNALED); - PY_DICT_ADD_INT(GL_SYNC_CONDITION); - PY_DICT_ADD_INT(GL_SYNC_FENCE); - PY_DICT_ADD_INT(GL_SYNC_FLAGS); - PY_DICT_ADD_INT(GL_SYNC_FLUSH_COMMANDS_BIT); - PY_DICT_ADD_INT(GL_SYNC_GPU_COMMANDS_COMPLETE); - PY_DICT_ADD_INT(GL_SYNC_STATUS); - PY_DICT_ADD_INT(GL_TEXTURE_2D_MULTISAMPLE); - PY_DICT_ADD_INT(GL_TEXTURE_2D_MULTISAMPLE_ARRAY); - PY_DICT_ADD_INT(GL_TEXTURE_BINDING_2D_MULTISAMPLE); - PY_DICT_ADD_INT(GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY); - PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_SEAMLESS); - PY_DICT_ADD_INT(GL_TEXTURE_FIXED_SAMPLE_LOCATIONS); - PY_DICT_ADD_INT(GL_TEXTURE_SAMPLES); - PY_DICT_ADD_INT(GL_TIMEOUT_EXPIRED); - PY_DICT_ADD_INT64(GL_TIMEOUT_IGNORED); - PY_DICT_ADD_INT(GL_TRIANGLES_ADJACENCY); - PY_DICT_ADD_INT(GL_TRIANGLE_STRIP_ADJACENCY); - PY_DICT_ADD_INT(GL_UNSIGNALED); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE); - PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY); - PY_DICT_ADD_INT(GL_WAIT_FAILED); - } +PyObject *BPyInit_bgl(void) +{ + PyObject *submodule, *dict; + submodule = PyModule_Create(&BGL_module_def); + dict = PyModule_GetDict(submodule); - /* GL_VERSION_3_3 */ - { - PY_DICT_ADD_INT(GL_ANY_SAMPLES_PASSED); - PY_DICT_ADD_INT(GL_INT_2_10_10_10_REV); - PY_DICT_ADD_INT(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS); - PY_DICT_ADD_INT(GL_ONE_MINUS_SRC1_ALPHA); - PY_DICT_ADD_INT(GL_ONE_MINUS_SRC1_COLOR); - PY_DICT_ADD_INT(GL_RGB10_A2UI); - PY_DICT_ADD_INT(GL_SAMPLER_BINDING); - PY_DICT_ADD_INT(GL_SRC1_COLOR); - PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_A); - PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_B); - PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_G); - PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_R); - PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_RGBA); - PY_DICT_ADD_INT(GL_TIMESTAMP); - PY_DICT_ADD_INT(GL_TIME_ELAPSED); - PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_DIVISOR); + if (PyType_Ready(&BGL_bufferType) < 0) { + return NULL; /* should never happen */ } + PyModule_AddObject(submodule, "Buffer", (PyObject *)&BGL_bufferType); + Py_INCREF((PyObject *)&BGL_bufferType); + + init_bgl_version_1_0_methods(submodule, dict); + init_bgl_version_1_1_methods(submodule, dict); + init_bgl_version_1_2_methods(submodule, dict); + init_bgl_version_1_3_methods(submodule, dict); + init_bgl_version_1_4_methods(submodule, dict); + init_bgl_version_1_5_methods(submodule, dict); + init_bgl_version_2_0_methods(submodule, dict); + init_bgl_version_2_1_methods(submodule, dict); + init_bgl_version_3_0_methods(submodule, dict); + init_bgl_version_3_1_methods(submodule, dict); + init_bgl_version_3_2_methods(submodule, dict); + init_bgl_version_3_3_methods(submodule, dict); + + init_bgl_version_1_1_constants(dict); + init_bgl_version_1_2_constants(dict); + init_bgl_version_1_3_constants(dict); + init_bgl_version_1_4_constants(dict); + init_bgl_version_1_5_constants(dict); + init_bgl_version_2_0_constants(dict); + init_bgl_version_2_1_constants(dict); + init_bgl_version_3_0_constants(dict); + init_bgl_version_3_1_constants(dict); + init_bgl_version_3_2_constants(dict); + init_bgl_version_3_3_constants(dict); + return submodule; } diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c index cabeeba18b9..615ce514a3e 100644 --- a/source/blender/python/generic/idprop_py_api.c +++ b/source/blender/python/generic/idprop_py_api.c @@ -51,13 +51,12 @@ static PyObject *idprop_py_from_idp_string(const IDProperty *prop) if (prop->subtype == IDP_STRING_SUB_BYTE) { return PyBytes_FromStringAndSize(IDP_String(prop), prop->len); } - else { + #ifdef USE_STRING_COERCE - return PyC_UnicodeFromByteAndSize(IDP_Array(prop), prop->len - 1); + return PyC_UnicodeFromByteAndSize(IDP_Array(prop), prop->len - 1); #else - return PyUnicode_FromStringAndSize(IDP_String(prop), prop->len - 1); + return PyUnicode_FromStringAndSize(IDP_String(prop), prop->len - 1); #endif - } } static PyObject *idprop_py_from_idp_int(const IDProperty *prop) @@ -479,10 +478,10 @@ static IDProperty *idp_from_PySequence_Buffer(const char *name, Py_buffer *buffe /* should never happen as the type has been checked before */ return NULL; } - else { - val.array.type = id_type; - val.array.len = buffer->len / buffer->itemsize; - } + + val.array.type = id_type; + val.array.len = buffer->len / buffer->itemsize; + prop = IDP_New(IDP_ARRAY, &val, name); memcpy(IDP_Array(prop), buffer->buf, buffer->len); return prop; @@ -576,17 +575,15 @@ static IDProperty *idp_from_PySequence(const char *name, PyObject *ob) PyBuffer_Release(&buffer); return prop; } - else { - PyObject *ob_seq_fast = PySequence_Fast(ob, "py -> idprop"); - if (ob_seq_fast != NULL) { - IDProperty *prop = idp_from_PySequence_Fast(name, ob_seq_fast); - Py_DECREF(ob_seq_fast); - return prop; - } - else { - return NULL; - } + + PyObject *ob_seq_fast = PySequence_Fast(ob, "py -> idprop"); + if (ob_seq_fast != NULL) { + IDProperty *prop = idp_from_PySequence_Fast(name, ob_seq_fast); + Py_DECREF(ob_seq_fast); + return prop; } + + return NULL; } static IDProperty *idp_from_PyMapping(const char *name, PyObject *ob) @@ -641,29 +638,28 @@ static IDProperty *idp_from_PyObject(PyObject *name_obj, PyObject *ob) if (PyFloat_Check(ob)) { return idp_from_PyFloat(name, ob); } - else if (PyLong_Check(ob)) { + if (PyLong_Check(ob)) { return idp_from_PyLong(name, ob); } - else if (PyUnicode_Check(ob)) { + if (PyUnicode_Check(ob)) { return idp_from_PyUnicode(name, ob); } - else if (PyBytes_Check(ob)) { + if (PyBytes_Check(ob)) { return idp_from_PyBytes(name, ob); } - else if (PySequence_Check(ob)) { + if (PySequence_Check(ob)) { return idp_from_PySequence(name, ob); } - else if (ob == Py_None || pyrna_id_CheckPyObject(ob)) { + if (ob == Py_None || pyrna_id_CheckPyObject(ob)) { return idp_from_DatablockPointer(name, ob); } - else if (PyMapping_Check(ob)) { + if (PyMapping_Check(ob)) { return idp_from_PyMapping(name, ob); } - else { - PyErr_Format( - PyExc_TypeError, "invalid id-property type %.200s not supported", Py_TYPE(ob)->tp_name); - return NULL; - } + + PyErr_Format( + PyExc_TypeError, "invalid id-property type %.200s not supported", Py_TYPE(ob)->tp_name); + return NULL; } /** \} */ @@ -736,21 +732,19 @@ int BPy_Wrap_SetMapItem(IDProperty *prop, PyObject *key, PyObject *val) IDP_FreeFromGroup(prop, pkey); return 0; } - else { - PyErr_SetString(PyExc_KeyError, "property not found in group"); - return -1; - } + + PyErr_SetString(PyExc_KeyError, "property not found in group"); + return -1; } - else { - bool ok; - ok = BPy_IDProperty_Map_ValidateAndCreate(key, prop, val); - if (ok == false) { - return -1; - } + bool ok; - return 0; + ok = BPy_IDProperty_Map_ValidateAndCreate(key, prop, val); + if (ok == false) { + return -1; } + + return 0; } static int BPy_IDGroup_Map_SetItem(BPy_IDProperty *self, PyObject *key, PyObject *val) @@ -1485,7 +1479,7 @@ static PyObject *BPy_IDArray_subscript(BPy_IDArray *self, PyObject *item) } return BPy_IDArray_GetItem(self, i); } - else if (PySlice_Check(item)) { + if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; if (PySlice_GetIndicesEx(item, self->prop->len, &start, &stop, &step, &slicelength) < 0) { @@ -1495,21 +1489,19 @@ static PyObject *BPy_IDArray_subscript(BPy_IDArray *self, PyObject *item) if (slicelength <= 0) { return PyTuple_New(0); } - else if (step == 1) { + if (step == 1) { return BPy_IDArray_slice(self, start, stop); } - else { - PyErr_SetString(PyExc_TypeError, "slice steps not supported with vectors"); - return NULL; - } - } - else { - PyErr_Format(PyExc_TypeError, - "vector indices must be integers, not %.200s", - __func__, - Py_TYPE(item)->tp_name); + + PyErr_SetString(PyExc_TypeError, "slice steps not supported with vectors"); return NULL; } + + PyErr_Format(PyExc_TypeError, + "vector indices must be integers, not %.200s", + __func__, + Py_TYPE(item)->tp_name); + return NULL; } static int BPy_IDArray_ass_subscript(BPy_IDArray *self, PyObject *item, PyObject *value) @@ -1524,7 +1516,7 @@ static int BPy_IDArray_ass_subscript(BPy_IDArray *self, PyObject *item, PyObject } return BPy_IDArray_SetItem(self, i, value); } - else if (PySlice_Check(item)) { + if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; if (PySlice_GetIndicesEx(item, self->prop->len, &start, &stop, &step, &slicelength) < 0) { @@ -1534,16 +1526,14 @@ static int BPy_IDArray_ass_subscript(BPy_IDArray *self, PyObject *item, PyObject if (step == 1) { return BPy_IDArray_ass_slice(self, start, stop, value); } - else { - PyErr_SetString(PyExc_TypeError, "slice steps not supported with vectors"); - return -1; - } - } - else { - PyErr_Format( - PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + + PyErr_SetString(PyExc_TypeError, "slice steps not supported with vectors"); return -1; } + + PyErr_Format( + PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + return -1; } static PyMappingMethods BPy_IDArray_AsMapping = { @@ -1709,14 +1699,12 @@ static PyObject *BPy_Group_Iter_Next(BPy_IDGroup_Iter *self) BPy_IDGroup_WrapData(self->group->id, cur, self->group->prop)); return ret; } - else { - return PyUnicode_FromString(cur->name); - } - } - else { - PyErr_SetNone(PyExc_StopIteration); - return NULL; + + return PyUnicode_FromString(cur->name); } + + PyErr_SetNone(PyExc_StopIteration); + return NULL; } PyTypeObject BPy_IDGroup_Iter_Type = { diff --git a/source/blender/python/generic/imbuf_py_api.c b/source/blender/python/generic/imbuf_py_api.c index 8a02638786d..3536236754e 100644 --- a/source/blender/python/generic/imbuf_py_api.c +++ b/source/blender/python/generic/imbuf_py_api.c @@ -57,11 +57,10 @@ static int py_imbuf_valid_check(Py_ImBuf *self) if (LIKELY(self->ibuf)) { return 0; } - else { - PyErr_Format( - PyExc_ReferenceError, "ImBuf data of type %.200s has been freed", Py_TYPE(self)->tp_name); - return -1; - } + + PyErr_Format( + PyExc_ReferenceError, "ImBuf data of type %.200s has been freed", Py_TYPE(self)->tp_name); + return -1; } #define PY_IMBUF_CHECK_OBJ(obj) \ @@ -324,9 +323,8 @@ static PyObject *py_imbuf_repr(Py_ImBuf *self) return PyUnicode_FromFormat( "<imbuf: address=%p, filepath='%s', size=(%d, %d)>", ibuf, ibuf->name, ibuf->x, ibuf->y); } - else { - return PyUnicode_FromString("<imbuf: address=0x0>"); - } + + return PyUnicode_FromString("<imbuf: address=0x0>"); } static Py_hash_t py_imbuf_hash(Py_ImBuf *self) diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index 37ed96bcaa0..caae5c4e122 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -51,6 +51,10 @@ # include "BLI_math_base.h" /* isfinite() */ #endif +/* -------------------------------------------------------------------- */ +/** \name Fast Python to C Array Conversion for Primitive Types + * \{ */ + /* array utility function */ int PyC_AsArray_FAST(void *array, PyObject *value_fast, @@ -137,11 +141,12 @@ int PyC_AsArray(void *array, return ret; } +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Typed Tuple Packing * * \note See #PyC_Tuple_Pack_* macros that take multiple arguments. - * * \{ */ /* array utility function */ @@ -192,6 +197,10 @@ PyObject *PyC_Tuple_PackArray_Bool(const bool *array, uint len) /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Tuple/List Filling + * \{ */ + /** * Caller needs to ensure tuple is uninitialized. * Handy for filling a tuple with None for eg. @@ -218,6 +227,12 @@ void PyC_List_Fill(PyObject *list, PyObject *value) } } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Bool/Enum Argument Parsing + * \{ */ + /** * Use with PyArg_ParseTuple's "O&" formatting. * @@ -274,8 +289,16 @@ int PyC_CheckArgs_DeepCopy(PyObject *args) return PyArg_ParseTuple(args, "|O!:__deepcopy__", &PyDict_Type, &dummy_pydict) != 0; } +/** \} */ + #ifndef MATH_STANDALONE +/* -------------------------------------------------------------------- */ +/** \name Simple Printing (for debugging) + * + * These are useful to run directly from a debugger to be able to inspect the state. + * \{ */ + /* for debugging */ void PyC_ObSpit(const char *name, PyObject *var) { @@ -352,12 +375,11 @@ void PyC_StackSpit(void) fprintf(stderr, "python line lookup failed, interpreter inactive\n"); return; } - else { - /* lame but handy */ - PyGILState_STATE gilstate = PyGILState_Ensure(); - PyRun_SimpleString("__import__('traceback').print_stack()"); - PyGILState_Release(gilstate); - } + + /* lame but handy */ + PyGILState_STATE gilstate = PyGILState_Ensure(); + PyRun_SimpleString("__import__('traceback').print_stack()"); + PyGILState_Release(gilstate); } void PyC_StackPrint(/* FILE */ void *fp) @@ -374,6 +396,12 @@ void PyC_StackPrint(/* FILE */ void *fp) } } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Access Current Frame File Name & Line Number + * \{ */ + void PyC_FileAndNum(const char **r_filename, int *r_lineno) { PyFrameObject *frame; @@ -433,6 +461,12 @@ void PyC_FileAndNum_Safe(const char **r_filename, int *r_lineno) PyC_FileAndNum(r_filename, r_lineno); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Object Access Utilities + * \{ */ + /* Would be nice if python had this built in */ PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...) { @@ -461,6 +495,12 @@ PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...) return item; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Frozen Set Creation + * \{ */ + PyObject *PyC_FrozenSetFromStrings(const char **strings) { const char **str; @@ -477,6 +517,12 @@ PyObject *PyC_FrozenSetFromStrings(const char **strings) return ret; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Exception Utilities + * \{ */ + /** * Similar to #PyErr_Format(), * @@ -542,6 +588,12 @@ void PyC_Err_PrintWithFunc(PyObject *py_func) _PyUnicode_AsString(((PyFunctionObject *)py_func)->func_name)); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Exception Buffer Access + * \{ */ + /* returns the exception string as a new PyUnicode object, depends on external traceback module */ # if 0 @@ -648,7 +700,7 @@ error_cleanup: PyObject *PyC_ExceptionBuffer_Simple(void) { - PyObject *string_io_buf; + PyObject *string_io_buf = NULL; PyObject *error_type, *error_value, *error_traceback; @@ -662,7 +714,19 @@ PyObject *PyC_ExceptionBuffer_Simple(void) return NULL; } - string_io_buf = PyObject_Str(error_value); + if (PyErr_GivenExceptionMatches(error_type, PyExc_SyntaxError)) { + /* Special exception for syntax errors, + * in these cases the full error is verbose and not very useful, + * just use the initial text so we know what the error is. */ + if (PyTuple_CheckExact(error_value) && PyTuple_GET_SIZE(error_value) >= 1) { + string_io_buf = PyObject_Str(PyTuple_GET_ITEM(error_value, 0)); + } + } + + if (string_io_buf == NULL) { + string_io_buf = PyObject_Str(error_value); + } + /* Python does this too */ if (UNLIKELY(string_io_buf == NULL)) { string_io_buf = PyUnicode_FromFormat("<unprintable %s object>", Py_TYPE(error_value)->tp_name); @@ -675,6 +739,14 @@ PyObject *PyC_ExceptionBuffer_Simple(void) return string_io_buf; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Unicode Conversion + * + * In some cases we need to coerce strings, avoid doing this inline. + * \{ */ + /* string conversion, escape non-unicode chars, coerce must be set to NULL */ const char *PyC_UnicodeAsByteAndSize(PyObject *py_str, Py_ssize_t *size, PyObject **coerce) { @@ -687,22 +759,20 @@ const char *PyC_UnicodeAsByteAndSize(PyObject *py_str, Py_ssize_t *size, PyObjec * chars since blender doesn't limit this */ return result; } - else { - PyErr_Clear(); - if (PyBytes_Check(py_str)) { - *size = PyBytes_GET_SIZE(py_str); - return PyBytes_AS_STRING(py_str); - } - else if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) { - *size = PyBytes_GET_SIZE(*coerce); - return PyBytes_AS_STRING(*coerce); - } - else { - /* leave error raised from EncodeFS */ - return NULL; - } + PyErr_Clear(); + + if (PyBytes_Check(py_str)) { + *size = PyBytes_GET_SIZE(py_str); + return PyBytes_AS_STRING(py_str); } + if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) { + *size = PyBytes_GET_SIZE(*coerce); + return PyBytes_AS_STRING(*coerce); + } + + /* leave error raised from EncodeFS */ + return NULL; } const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce) @@ -716,20 +786,18 @@ const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce) * chars since blender doesn't limit this. */ return result; } - else { - PyErr_Clear(); - if (PyBytes_Check(py_str)) { - return PyBytes_AS_STRING(py_str); - } - else if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) { - return PyBytes_AS_STRING(*coerce); - } - else { - /* leave error raised from EncodeFS */ - return NULL; - } + PyErr_Clear(); + + if (PyBytes_Check(py_str)) { + return PyBytes_AS_STRING(py_str); } + if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) { + return PyBytes_AS_STRING(*coerce); + } + + /* leave error raised from EncodeFS */ + return NULL; } PyObject *PyC_UnicodeFromByteAndSize(const char *str, Py_ssize_t size) @@ -740,12 +808,11 @@ PyObject *PyC_UnicodeFromByteAndSize(const char *str, Py_ssize_t size) * chars since blender doesn't limit this */ return result; } - else { - PyErr_Clear(); - /* this means paths will always be accessible once converted, on all OS's */ - result = PyUnicode_DecodeFSDefaultAndSize(str, size); - return result; - } + + PyErr_Clear(); + /* this means paths will always be accessible once converted, on all OS's */ + result = PyUnicode_DecodeFSDefaultAndSize(str, size); + return result; } PyObject *PyC_UnicodeFromByte(const char *str) @@ -753,6 +820,12 @@ PyObject *PyC_UnicodeFromByte(const char *str) return PyC_UnicodeFromByteAndSize(str, strlen(str)); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Name Space Creation/Manipulation + * \{ */ + /***************************************************************************** * Description: This function creates a new Python dictionary object. * note: dict is owned by sys.modules["__main__"] module, reference is borrowed @@ -818,8 +891,18 @@ void PyC_MainModule_Restore(PyObject *main_mod) Py_XDECREF(main_mod); } -/* Must be called before Py_Initialize, - * expects output of BKE_appdir_folder_id(BLENDER_PYTHON, NULL). */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name #Py_SetPythonHome Wrapper + * \{ */ + +/** + * - Must be called before #Py_Initialize. + * - Expects output of `BKE_appdir_folder_id(BLENDER_PYTHON, NULL)`. + * - Note that the `PYTHONPATH` environment variable isn't reliable, see T31506. + Use #Py_SetPythonHome instead. + */ void PyC_SetHomePath(const char *py_path_bundle) { if (py_path_bundle == NULL) { @@ -838,24 +921,14 @@ void PyC_SetHomePath(const char *py_path_bundle) /* OSX allow file/directory names to contain : character (represented as / in the Finder) * but current Python lib (release 3.1.1) doesn't handle these correctly */ if (strchr(py_path_bundle, ':')) { - printf( - "Warning : Blender application is located in a path containing : or / chars\ - \nThis may make python import function fail\n"); - } -# endif - -# if 0 /* disable for now [#31506] - campbell */ -# ifdef _WIN32 - /* cmake/MSVC debug build crashes without this, why only - * in this case is unknown.. */ - { - /*BLI_setenv("PYTHONPATH", py_path_bundle)*/; + fprintf(stderr, + "Warning! Blender application is located in a path containing ':' or '/' chars\n" + "This may make python import function fail\n"); } -# endif # endif { - static wchar_t py_path_bundle_wchar[1024]; + wchar_t py_path_bundle_wchar[1024]; /* Can't use this, on linux gives bug: #23018, * TODO: try LANG="en_US.UTF-8" /usr/bin/blender, suggested 2008 */ @@ -875,6 +948,12 @@ bool PyC_IsInterpreterActive(void) return (PyThreadState_GetDict() != NULL); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name #Py_SetPythonHome Wrapper + * \{ */ + /* Would be nice if python had this built in * See: https://wiki.blender.org/wiki/Tools/Debugging/PyFromC */ @@ -1051,15 +1130,22 @@ void *PyC_RNA_AsPointer(PyObject *value, const char *type_name) return result; } - else { - PyErr_Format(PyExc_TypeError, - "expected '%.200s' type found '%.200s' instead", - type_name, - Py_TYPE(value)->tp_name); - return NULL; - } + + PyErr_Format(PyExc_TypeError, + "expected '%.200s' type found '%.200s' instead", + type_name, + Py_TYPE(value)->tp_name); + return NULL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Flag Set Utilities (#PyC_FlagSet) + * + * Convert to/from Python set of strings to an int flag. + * \{ */ + PyObject *PyC_FlagSet_AsString(PyC_FlagSet *item) { PyObject *py_items = PyList_New(0); @@ -1160,6 +1246,12 @@ PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag) return ret; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Run String (Evaluate to Primitive Types) + * \{ */ + /** * \return success * @@ -1323,6 +1415,8 @@ bool PyC_RunString_AsString(const char *imports[], return PyC_RunString_AsStringAndSize(imports, expr, filename, r_value, &value_size); } +/** \} */ + #endif /* #ifndef MATH_STANDALONE */ /* -------------------------------------------------------------------- */ @@ -1410,6 +1504,12 @@ uint32_t PyC_Long_AsU32(PyObject *value) * PyC_Long_AsU64 */ +#ifdef __GNUC__ +# pragma warning(pop) +#endif + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Py_buffer Utils * @@ -1486,9 +1586,3 @@ bool PyC_StructFmt_type_is_bool(char format) } /** \} */ - -#ifdef __GNUC__ -# pragma warning(pop) -#endif - -/** \} */ diff --git a/source/blender/python/gpu/gpu_py_api.c b/source/blender/python/gpu/gpu_py_api.c index 1379c0e557a..da7674eb7f9 100644 --- a/source/blender/python/gpu/gpu_py_api.c +++ b/source/blender/python/gpu/gpu_py_api.c @@ -43,9 +43,9 @@ /** \name Utils to invalidate functions * \{ */ -bool bpygpu_is_initialized_or_error(void) +bool bpygpu_is_init_or_error(void) { - if (!GPU_is_initialized()) { + if (!GPU_is_init()) { PyErr_SetString(PyExc_SystemError, "GPU functions for drawing are not available in background mode"); diff --git a/source/blender/python/gpu/gpu_py_api.h b/source/blender/python/gpu/gpu_py_api.h index 2360bba1f5d..b8f0cde129f 100644 --- a/source/blender/python/gpu/gpu_py_api.h +++ b/source/blender/python/gpu/gpu_py_api.h @@ -24,14 +24,14 @@ int bpygpu_ParsePrimType(PyObject *o, void *p); PyObject *BPyInit_gpu(void); -bool bpygpu_is_initialized_or_error(void); +bool bpygpu_is_init_or_error(void); #define BPYGPU_IS_INIT_OR_ERROR_OBJ \ - if (UNLIKELY(!bpygpu_is_initialized_or_error())) { \ + if (UNLIKELY(!bpygpu_is_init_or_error())) { \ return NULL; \ } \ ((void)0) #define BPYGPU_IS_INIT_OR_ERROR_INT \ - if (UNLIKELY(!bpygpu_is_initialized_or_error())) { \ + if (UNLIKELY(!bpygpu_is_init_or_error())) { \ return -1; \ } \ ((void)0) diff --git a/source/blender/python/gpu/gpu_py_batch.c b/source/blender/python/gpu/gpu_py_batch.c index b3df991cf12..01bccc57c7a 100644 --- a/source/blender/python/gpu/gpu_py_batch.c +++ b/source/blender/python/gpu/gpu_py_batch.c @@ -184,8 +184,7 @@ static PyObject *bpygpu_Batch_program_set(BPyGPUBatch *self, BPyGPUShader *py_sh } GPUShader *shader = py_shader->shader; - GPU_batch_program_set( - self->batch, GPU_shader_get_program(shader), GPU_shader_get_interface(shader)); + GPU_batch_set_shader(self->batch, shader); #ifdef USE_GPU_PY_REFERENCES /* Remove existing user (if any), hold new user. */ @@ -223,15 +222,13 @@ static PyObject *bpygpu_Batch_draw(BPyGPUBatch *self, PyObject *args) if (!PyArg_ParseTuple(args, "|O!:GPUBatch.draw", &BPyGPUShader_Type, &py_program)) { return NULL; } - else if (py_program == NULL) { + if (py_program == NULL) { if (!bpygpu_batch_is_program_or_error(self)) { return NULL; } } else if (self->batch->program != GPU_shader_get_program(py_program->shader)) { - GPU_batch_program_set(self->batch, - GPU_shader_get_program(py_program->shader), - GPU_shader_get_interface(py_program->shader)); + GPU_batch_set_shader(self->batch, py_program->shader); } GPU_batch_draw(self->batch); diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c index dde1d13477f..cdbd3bc0b9c 100644 --- a/source/blender/python/intern/bpy_app_handlers.c +++ b/source/blender/python/intern/bpy_app_handlers.c @@ -118,22 +118,20 @@ static PyObject *bpy_app_handlers_persistent_new(PyTypeObject *UNUSED(type), "get the dictionary from the function passed"); return NULL; } - else { - /* set id */ - if (*dict_ptr == NULL) { - *dict_ptr = PyDict_New(); - } - PyDict_SetItemString(*dict_ptr, PERMINENT_CB_ID, Py_None); + /* set id */ + if (*dict_ptr == NULL) { + *dict_ptr = PyDict_New(); } + PyDict_SetItemString(*dict_ptr, PERMINENT_CB_ID, Py_None); + Py_INCREF(value); return value; } - else { - PyErr_SetString(PyExc_ValueError, "bpy.app.handlers.persistent expected a function"); - return NULL; - } + + PyErr_SetString(PyExc_ValueError, "bpy.app.handlers.persistent expected a function"); + return NULL; } /* dummy type because decorators can't be PyCFunctions */ diff --git a/source/blender/python/intern/bpy_capi_utils.c b/source/blender/python/intern/bpy_capi_utils.c index 89ef2f40a30..27eea80f1f6 100644 --- a/source/blender/python/intern/bpy_capi_utils.c +++ b/source/blender/python/intern/bpy_capi_utils.c @@ -97,7 +97,10 @@ void BPy_reports_write_stdout(const ReportList *reports, const char *header) } } -bool BPy_errors_to_report_ex(ReportList *reports, const bool use_full, const bool use_location) +bool BPy_errors_to_report_ex(ReportList *reports, + const char *error_prefix, + const bool use_full, + const bool use_location) { PyObject *pystring; @@ -124,40 +127,38 @@ bool BPy_errors_to_report_ex(ReportList *reports, const bool use_full, const boo return 0; } + if (error_prefix == NULL) { + /* Not very helpful, better than nothing. */ + error_prefix = "Python"; + } + if (use_location) { const char *filename; int lineno; - PyObject *pystring_format; /* workaround, see below */ - const char *cstring; - PyC_FileAndNum(&filename, &lineno); if (filename == NULL) { filename = "<unknown location>"; } -#if 0 /* ARG!. workaround for a bug in blenders use of vsnprintf */ BKE_reportf(reports, RPT_ERROR, - "%s\nlocation: %s:%d\n", + TIP_("%s: %s\nlocation: %s:%d\n"), + error_prefix, _PyUnicode_AsString(pystring), filename, lineno); -#else - pystring_format = PyUnicode_FromFormat( - TIP_("%s\nlocation: %s:%d\n"), _PyUnicode_AsString(pystring), filename, lineno); - - cstring = _PyUnicode_AsString(pystring_format); - BKE_report(reports, RPT_ERROR, cstring); - - /* not exactly needed. just for testing */ - fprintf(stderr, TIP_("%s\nlocation: %s:%d\n"), cstring, filename, lineno); - Py_DECREF(pystring_format); /* workaround */ -#endif + /* Not exactly needed. Useful for developers tracking down issues. */ + fprintf(stderr, + TIP_("%s: %s\nlocation: %s:%d\n"), + error_prefix, + _PyUnicode_AsString(pystring), + filename, + lineno); } else { - BKE_report(reports, RPT_ERROR, _PyUnicode_AsString(pystring)); + BKE_reportf(reports, RPT_ERROR, "%s: %s", error_prefix, _PyUnicode_AsString(pystring)); } Py_DECREF(pystring); @@ -166,5 +167,5 @@ bool BPy_errors_to_report_ex(ReportList *reports, const bool use_full, const boo bool BPy_errors_to_report(ReportList *reports) { - return BPy_errors_to_report_ex(reports, true, true); + return BPy_errors_to_report_ex(reports, NULL, true, true); } diff --git a/source/blender/python/intern/bpy_capi_utils.h b/source/blender/python/intern/bpy_capi_utils.h index c021ec14933..861b23190a2 100644 --- a/source/blender/python/intern/bpy_capi_utils.h +++ b/source/blender/python/intern/bpy_capi_utils.h @@ -42,8 +42,10 @@ char *BPy_enum_as_string(const struct EnumPropertyItem *item); short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const bool clear); void BPy_reports_write_stdout(const struct ReportList *reports, const char *header); bool BPy_errors_to_report_ex(struct ReportList *reports, + const char *error_prefix, const bool use_full, const bool use_location); +bool BPy_errors_to_report_brief_with_prefix(struct ReportList *reports, const char *error_prefix); bool BPy_errors_to_report(struct ReportList *reports); /* TODO - find a better solution! */ diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c index 5e2162c9e2d..7fb4b0c469c 100644 --- a/source/blender/python/intern/bpy_driver.c +++ b/source/blender/python/intern/bpy_driver.c @@ -83,9 +83,8 @@ int bpy_pydriver_create_dict(void) if (d == NULL) { return -1; } - else { - bpy_pydriver_Dict = d; - } + + bpy_pydriver_Dict = d; /* import some modules: builtins, bpy, math, (Blender.noise)*/ PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins()); @@ -411,8 +410,10 @@ static PyObject *bpy_pydriver_depsgraph_as_pyobject(struct Depsgraph *depsgraph) return pyrna_struct_CreatePyObject(&depsgraph_ptr); } -/* Adds a variable 'depsgraph' to the driver variables. This can then be used to obtain evaluated - * datablocks, and the current view layer and scene. See T75553. */ +/** + * Adds a variable 'depsgraph' to the driver variables. This can then be used to obtain evaluated + * data-blocks, and the current view layer and scene. See T75553. + */ static void bpy_pydriver_namespace_add_depsgraph(PyObject *driver_vars, struct Depsgraph *depsgraph) { @@ -428,17 +429,18 @@ static void bpy_pydriver_namespace_add_depsgraph(PyObject *driver_vars, } } -/* This evals py driver expressions, 'expr' is a Python expression that - * should evaluate to a float number, which is returned. +/** + * This evaluates Python driver expressions, `driver_orig->expression` + * is a Python expression that should evaluate to a float number, which is returned. * * (old)note: PyGILState_Ensure() isn't always called because python can call * the bake operator which intern starts a thread which calls scene update - * which does a driver update. to avoid a deadlock check PyC_IsInterpreterActive() - * if PyGILState_Ensure() is needed - see [#27683] + * which does a driver update. to avoid a deadlock check #PyC_IsInterpreterActive() + * if #PyGILState_Ensure() is needed, see T27683. * - * (new)note: checking if python is running is not threadsafe [#28114] + * (new)note: checking if python is running is not thread-safe T28114 * now release the GIL on python operator execution instead, using - * PyEval_SaveThread() / PyEval_RestoreThread() so we don't lock up blender. + * #PyEval_SaveThread() / #PyEval_RestoreThread() so we don't lock up blender. * * For copy-on-write we always cache expressions and write errors in the * original driver, otherwise these would get freed while editing. Due to @@ -677,11 +679,8 @@ float BPY_driver_exec(struct PathResolvedRNA *anim_rna, if (isfinite(result)) { return (float)result; } - else { - fprintf(stderr, - "\tBPY_driver_eval() - driver '%s' evaluates to '%f'\n", - driver->expression, - result); - return 0.0f; - } + + fprintf( + stderr, "\tBPY_driver_eval() - driver '%s' evaluates to '%f'\n", driver->expression, result); + return 0.0f; } diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 4fbe2db3ecd..c311041e4cb 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -258,11 +258,13 @@ void BPY_python_start(int argc, const char **argv) PyThreadState *py_tstate = NULL; const char *py_path_bundle = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, NULL); - /* not essential but nice to set our name */ - static wchar_t program_path_wchar[FILE_MAX]; /* python holds a reference */ - BLI_strncpy_wchar_from_utf8( - program_path_wchar, BKE_appdir_program_path(), ARRAY_SIZE(program_path_wchar)); - Py_SetProgramName(program_path_wchar); + /* Not essential but nice to set our name. */ + { + const char *program_path = BKE_appdir_program_path(); + wchar_t program_path_wchar[FILE_MAX]; + BLI_strncpy_wchar_from_utf8(program_path_wchar, program_path, ARRAY_SIZE(program_path_wchar)); + Py_SetProgramName(program_path_wchar); + } /* must run before python initializes */ PyImport_ExtendInittab(bpy_internal_modules); @@ -621,8 +623,11 @@ void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr) /** * \return success */ -bool BPY_execute_string_as_number( - bContext *C, const char *imports[], const char *expr, const bool verbose, double *r_value) +bool BPY_execute_string_as_number(bContext *C, + const char *imports[], + const char *expr, + const char *report_prefix, + double *r_value) { PyGILState_STATE gilstate; bool ok = true; @@ -641,8 +646,8 @@ bool BPY_execute_string_as_number( ok = PyC_RunString_AsNumber(imports, expr, "<expr as number>", r_value); if (ok == false) { - if (verbose) { - BPy_errors_to_report_ex(CTX_wm_reports(C), false, false); + if (report_prefix != NULL) { + BPy_errors_to_report_ex(CTX_wm_reports(C), report_prefix, false, false); } else { PyErr_Clear(); @@ -660,7 +665,7 @@ bool BPY_execute_string_as_number( bool BPY_execute_string_as_string_and_size(bContext *C, const char *imports[], const char *expr, - const bool verbose, + const char *report_prefix, char **r_value, size_t *r_value_size) { @@ -678,8 +683,8 @@ bool BPY_execute_string_as_string_and_size(bContext *C, ok = PyC_RunString_AsStringAndSize(imports, expr, "<expr as str>", r_value, r_value_size); if (ok == false) { - if (verbose) { - BPy_errors_to_report_ex(CTX_wm_reports(C), false, false); + if (report_prefix != NULL) { + BPy_errors_to_report_ex(CTX_wm_reports(C), false, false, report_prefix); } else { PyErr_Clear(); @@ -691,12 +696,15 @@ bool BPY_execute_string_as_string_and_size(bContext *C, return ok; } -bool BPY_execute_string_as_string( - bContext *C, const char *imports[], const char *expr, const bool verbose, char **r_value) +bool BPY_execute_string_as_string(bContext *C, + const char *imports[], + const char *expr, + const char *report_prefix, + char **r_value) { size_t value_dummy_size; return BPY_execute_string_as_string_and_size( - C, imports, expr, verbose, r_value, &value_dummy_size); + C, imports, expr, report_prefix, r_value, &value_dummy_size); } /** @@ -704,8 +712,11 @@ bool BPY_execute_string_as_string( * * \return success */ -bool BPY_execute_string_as_intptr( - bContext *C, const char *imports[], const char *expr, const bool verbose, intptr_t *r_value) +bool BPY_execute_string_as_intptr(bContext *C, + const char *imports[], + const char *expr, + const char *report_prefix, + intptr_t *r_value) { BLI_assert(r_value && expr); PyGILState_STATE gilstate; @@ -721,8 +732,8 @@ bool BPY_execute_string_as_intptr( ok = PyC_RunString_AsIntPtr(imports, expr, "<expr as intptr>", r_value); if (ok == false) { - if (verbose) { - BPy_errors_to_report_ex(CTX_wm_reports(C), false, false); + if (report_prefix != NULL) { + BPy_errors_to_report_ex(CTX_wm_reports(C), report_prefix, false, false); } else { PyErr_Clear(); @@ -916,8 +927,11 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult * /* TODO, reloading the module isn't functional at the moment. */ static void bpy_module_free(void *mod); + +/* Defined in 'creator.c' when building as a Python module. */ extern int main_python_enter(int argc, const char **argv); extern void main_python_exit(void); + static struct PyModuleDef bpy_proxy_def = { PyModuleDef_HEAD_INIT, "bpy", /* m_name */ diff --git a/source/blender/python/intern/bpy_library_load.c b/source/blender/python/intern/bpy_library_load.c index 05cbc9af601..bcf13b1d88f 100644 --- a/source/blender/python/intern/bpy_library_load.c +++ b/source/blender/python/intern/bpy_library_load.c @@ -244,21 +244,20 @@ static PyObject *bpy_lib_enter(BPy_Library *self) } return NULL; } - else { - int i = 0, code; - while ((code = BKE_idtype_idcode_iter_step(&i))) { - if (BKE_idtype_idcode_is_linkable(code)) { - const char *name_plural = BKE_idtype_idcode_to_name_plural(code); - PyObject *str = PyUnicode_FromString(name_plural); - PyObject *item; - - PyDict_SetItem(self->dict, str, item = PyList_New(0)); - Py_DECREF(item); - PyDict_SetItem(from_dict, str, item = _bpy_names(self, code)); - Py_DECREF(item); - - Py_DECREF(str); - } + + int i = 0, code; + while ((code = BKE_idtype_idcode_iter_step(&i))) { + if (BKE_idtype_idcode_is_linkable(code)) { + const char *name_plural = BKE_idtype_idcode_to_name_plural(code); + PyObject *str = PyUnicode_FromString(name_plural); + PyObject *item; + + PyDict_SetItem(self->dict, str, item = PyList_New(0)); + Py_DECREF(item); + PyDict_SetItem(from_dict, str, item = _bpy_names(self, code)); + Py_DECREF(item); + + Py_DECREF(str); } } @@ -393,65 +392,64 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args)) BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false); return NULL; } - else { - Library *lib = mainl->curlib; /* newly added lib, assign before append end */ - BLO_library_link_end(mainl, &(self->blo_handle), self->flag, NULL, NULL, NULL, NULL); - BLO_blendhandle_close(self->blo_handle); - self->blo_handle = NULL; - GHash *old_to_new_ids = BLI_ghash_ptr_new(__func__); + Library *lib = mainl->curlib; /* newly added lib, assign before append end */ + BLO_library_link_end(mainl, &(self->blo_handle), self->flag, NULL, NULL, NULL, NULL); + BLO_blendhandle_close(self->blo_handle); + self->blo_handle = NULL; - /* copied from wm_operator.c */ - { - /* mark all library linked objects to be updated */ - BKE_main_lib_objects_recalc_all(bmain); + GHash *old_to_new_ids = BLI_ghash_ptr_new(__func__); - /* append, rather than linking */ - if (do_append) { - BKE_library_make_local(bmain, lib, old_to_new_ids, true, false); - } + /* copied from wm_operator.c */ + { + /* mark all library linked objects to be updated */ + BKE_main_lib_objects_recalc_all(bmain); + + /* append, rather than linking */ + if (do_append) { + BKE_library_make_local(bmain, lib, old_to_new_ids, true, false); } + } - BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false); + BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false); - /* finally swap the capsules for real bpy objects - * important since BLO_library_append_end initializes NodeTree types used by srna->refine */ + /* finally swap the capsules for real bpy objects + * important since BLO_library_append_end initializes NodeTree types used by srna->refine */ #ifdef USE_RNA_DATABLOCKS - { - int idcode_step = 0, idcode; - while ((idcode = BKE_idtype_idcode_iter_step(&idcode_step))) { - if (BKE_idtype_idcode_is_linkable(idcode) && (idcode != ID_WS || do_append)) { - const char *name_plural = BKE_idtype_idcode_to_name_plural(idcode); - PyObject *ls = PyDict_GetItemString(self->dict, name_plural); - if (ls && PyList_Check(ls)) { - Py_ssize_t size = PyList_GET_SIZE(ls); - Py_ssize_t i; - PyObject *item; - - for (i = 0; i < size; i++) { - item = PyList_GET_ITEM(ls, i); - if (PyCapsule_CheckExact(item)) { - PointerRNA id_ptr; - ID *id; - - id = PyCapsule_GetPointer(item, NULL); - id = BLI_ghash_lookup_default(old_to_new_ids, id, id); - Py_DECREF(item); - - RNA_id_pointer_create(id, &id_ptr); - item = pyrna_struct_CreatePyObject(&id_ptr); - PyList_SET_ITEM(ls, i, item); - } + { + int idcode_step = 0, idcode; + while ((idcode = BKE_idtype_idcode_iter_step(&idcode_step))) { + if (BKE_idtype_idcode_is_linkable(idcode) && (idcode != ID_WS || do_append)) { + const char *name_plural = BKE_idtype_idcode_to_name_plural(idcode); + PyObject *ls = PyDict_GetItemString(self->dict, name_plural); + if (ls && PyList_Check(ls)) { + Py_ssize_t size = PyList_GET_SIZE(ls); + Py_ssize_t i; + PyObject *item; + + for (i = 0; i < size; i++) { + item = PyList_GET_ITEM(ls, i); + if (PyCapsule_CheckExact(item)) { + PointerRNA id_ptr; + ID *id; + + id = PyCapsule_GetPointer(item, NULL); + id = BLI_ghash_lookup_default(old_to_new_ids, id, id); + Py_DECREF(item); + + RNA_id_pointer_create(id, &id_ptr); + item = pyrna_struct_CreatePyObject(&id_ptr); + PyList_SET_ITEM(ls, i, item); } } } } } + } #endif /* USE_RNA_DATABLOCKS */ - BLI_ghash_free(old_to_new_ids, NULL, NULL); - Py_RETURN_NONE; - } + BLI_ghash_free(old_to_new_ids, NULL, NULL); + Py_RETURN_NONE; } static PyObject *bpy_lib_dir(BPy_Library *self) diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index 830acd987d9..66c67ca061c 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -1408,9 +1408,8 @@ static bool py_long_as_int(PyObject *py_long, int *r_int) *r_int = (int)PyLong_AS_LONG(py_long); return true; } - else { - return false; - } + + return false; } #if 0 @@ -1716,16 +1715,15 @@ static int bpy_prop_callback_check(PyObject *py_func, const char *keyword, int a Py_TYPE(py_func)->tp_name); return -1; } - else { - PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func); - if (f_code->co_argcount != argcount) { - PyErr_Format(PyExc_TypeError, - "%s keyword: expected a function taking %d arguments, not %d", - keyword, - argcount, - f_code->co_argcount); - return -1; - } + + PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func); + if (f_code->co_argcount != argcount) { + PyErr_Format(PyExc_TypeError, + "%s keyword: expected a function taking %d arguments, not %d", + keyword, + argcount, + f_code->co_argcount); + return -1; } } @@ -1981,7 +1979,7 @@ static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop, Py_DECREF(args); \ return ret; \ } \ - else if (PyTuple_GET_SIZE(args) > 1) { \ + if (PyTuple_GET_SIZE(args) > 1) { \ PyErr_SetString(PyExc_ValueError, "all args must be keywords"); \ return NULL; \ } \ @@ -3537,7 +3535,7 @@ static PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw Py_DECREF(args); return ret; } - else if (PyTuple_GET_SIZE(args) > 1) { + if (PyTuple_GET_SIZE(args) > 1) { PyErr_SetString(PyExc_ValueError, "expected one positional arg, one keyword arg"); return NULL; } @@ -3546,27 +3544,27 @@ static PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw if (srna == NULL && PyErr_Occurred()) { return NULL; /* self's type was compatible but error getting the srna */ } - else if (srna == NULL) { + if (srna == NULL) { PyErr_SetString(PyExc_TypeError, "RemoveProperty(): struct rna not available for this type"); return NULL; } - else { - const char *id = NULL; - static const char *_keywords[] = { - "attr", - NULL, - }; - static _PyArg_Parser _parser = {"s:RemoveProperty", _keywords, 0}; - if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &id)) { - return NULL; - } + const char *id = NULL; - if (RNA_def_property_free_identifier(srna, id) != 1) { - PyErr_Format(PyExc_TypeError, "RemoveProperty(): '%s' not a defined dynamic property", id); - return NULL; - } + static const char *_keywords[] = { + "attr", + NULL, + }; + static _PyArg_Parser _parser = {"s:RemoveProperty", _keywords, 0}; + if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &id)) { + return NULL; + } + + if (RNA_def_property_free_identifier(srna, id) != 1) { + PyErr_Format(PyExc_TypeError, "RemoveProperty(): '%s' not a defined dynamic property", id); + return NULL; } + Py_RETURN_NONE; } diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 893832b61b6..955a24bc880 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -987,24 +987,23 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self) PyErr_SetString(PyExc_RuntimeError, "could not use property type, internal error"); return NULL; } - else { - /* This should never fail. */ - int len = -1; - char *c = type_fmt; - while ((*c++ = tolower(*type_id++))) { - } + /* This should never fail. */ + int len = -1; + char *c = type_fmt; - if (type == PROP_COLLECTION) { - len = pyrna_prop_collection_length(self); - } - else if (RNA_property_array_check(self->prop)) { - len = pyrna_prop_array_length((BPy_PropertyArrayRNA *)self); - } + while ((*c++ = tolower(*type_id++))) { + } - if (len != -1) { - sprintf(--c, "[%d]", len); - } + if (type == PROP_COLLECTION) { + len = pyrna_prop_collection_length(self); + } + else if (RNA_property_array_check(self->prop)) { + len = pyrna_prop_array_length((BPy_PropertyArrayRNA *)self); + } + + if (len != -1) { + sprintf(--c, "[%d]", len); } /* If a pointer, try to print name of pointer target too. */ @@ -1246,17 +1245,16 @@ static int pyrna_string_to_enum( Py_TYPE(item)->tp_name); return -1; } - else { - if (!RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, r_value)) { - const char *enum_str = pyrna_enum_as_string(ptr, prop); - PyErr_Format(PyExc_TypeError, - "%.200s enum \"%.200s\" not found in (%s)", - error_prefix, - param, - enum_str); - MEM_freeN((void *)enum_str); - return -1; - } + + if (!RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, r_value)) { + const char *enum_str = pyrna_enum_as_string(ptr, prop); + PyErr_Format(PyExc_TypeError, + "%.200s enum \"%.200s\" not found in (%s)", + error_prefix, + param, + enum_str); + MEM_freeN((void *)enum_str); + return -1; } return 0; @@ -1715,14 +1713,14 @@ static int pyrna_py_to_prop( Py_TYPE(value)->tp_name); return -1; } + + if (data) { + *((bool *)data) = param; + } else { - if (data) { - *((bool *)data) = param; - } - else { - RNA_property_boolean_set(ptr, prop, param); - } + RNA_property_boolean_set(ptr, prop, param); } + break; } case PROP_INT: { @@ -1737,7 +1735,7 @@ static int pyrna_py_to_prop( RNA_property_identifier(prop)); return -1; } - else if (param == -1 && PyErr_Occurred()) { + if (param == -1 && PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s expected an int type, not %.200s", error_prefix, @@ -1746,16 +1744,16 @@ static int pyrna_py_to_prop( Py_TYPE(value)->tp_name); return -1; } + + int param_i = (int)param; + if (data) { + RNA_property_int_clamp(ptr, prop, ¶m_i); + *((int *)data) = param_i; + } else { - int param_i = (int)param; - if (data) { - RNA_property_int_clamp(ptr, prop, ¶m_i); - *((int *)data) = param_i; - } - else { - RNA_property_int_set(ptr, prop, param_i); - } + RNA_property_int_set(ptr, prop, param_i); } + break; } case PROP_FLOAT: { @@ -1769,15 +1767,15 @@ static int pyrna_py_to_prop( Py_TYPE(value)->tp_name); return -1; } + + if (data) { + RNA_property_float_clamp(ptr, prop, (float *)¶m); + *((float *)data) = param; + } else { - if (data) { - RNA_property_float_clamp(ptr, prop, (float *)¶m); - *((float *)data) = param; - } - else { - RNA_property_float_set(ptr, prop, param); - } + RNA_property_float_set(ptr, prop, param); } + break; } case PROP_STRING: { @@ -1835,19 +1833,18 @@ static int pyrna_py_to_prop( return -1; } - else { - if (data) { - if (RNA_property_flag(prop) & PROP_THICK_WRAP) { - BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop)); - } - else { - *((char **)data) = (char *)param; - } + + if (data) { + if (RNA_property_flag(prop) & PROP_THICK_WRAP) { + BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop)); } else { - RNA_property_string_set_bytes(ptr, prop, param, PyBytes_Size(value)); + *((char **)data) = (char *)param; } } + else { + RNA_property_string_set_bytes(ptr, prop, param, PyBytes_Size(value)); + } } else { /* Unicode String. */ @@ -1886,22 +1883,22 @@ static int pyrna_py_to_prop( return -1; } - else { - /* Same as bytes. */ - /* XXX, this is suspect, but needed for function calls, - * need to see if there's a better way. */ - if (data) { - if (RNA_property_flag(prop) & PROP_THICK_WRAP) { - BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop)); - } - else { - *((char **)data) = (char *)param; - } + + /* Same as bytes. */ + /* XXX, this is suspect, but needed for function calls, + * need to see if there's a better way. */ + if (data) { + if (RNA_property_flag(prop) & PROP_THICK_WRAP) { + BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop)); } else { - RNA_property_string_set(ptr, prop, param); + *((char **)data) = (char *)param; } } + else { + RNA_property_string_set(ptr, prop, param); + } + #ifdef USE_STRING_COERCE Py_XDECREF(value_coerce); #endif /* USE_STRING_COERCE */ @@ -1971,7 +1968,7 @@ static int pyrna_py_to_prop( PointerRNA opptr = RNA_property_pointer_get(ptr, prop); return pyrna_pydict_to_props(&opptr, value, false, error_prefix); } - else if (base_type == &RNA_GizmoProperties) { + if (base_type == &RNA_GizmoProperties) { PointerRNA opptr = RNA_property_pointer_get(ptr, prop); return pyrna_pydict_to_props(&opptr, value, false, error_prefix); } @@ -2008,7 +2005,7 @@ static int pyrna_py_to_prop( Py_XDECREF(value_new); return -1; } - else if ((flag & PROP_NEVER_NULL) && value == Py_None) { + if ((flag & PROP_NEVER_NULL) && value == Py_None) { PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s does not support a 'None' assignment %.200s type", error_prefix, @@ -2018,8 +2015,8 @@ static int pyrna_py_to_prop( Py_XDECREF(value_new); return -1; } - else if ((value != Py_None) && ((flag & PROP_ID_SELF_CHECK) && - ptr->owner_id == ((BPy_StructRNA *)value)->ptr.owner_id)) { + if ((value != Py_None) && ((flag & PROP_ID_SELF_CHECK) && + ptr->owner_id == ((BPy_StructRNA *)value)->ptr.owner_id)) { PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s ID type does not support assignment to itself", error_prefix, @@ -2028,85 +2025,84 @@ static int pyrna_py_to_prop( Py_XDECREF(value_new); return -1; } - else { - BPy_StructRNA *param = (BPy_StructRNA *)value; - bool raise_error = false; - if (data) { - if (flag_parameter & PARM_RNAPTR) { - if (flag & PROP_THICK_WRAP) { - if (value == Py_None) { - memset(data, 0, sizeof(PointerRNA)); - } - else if (RNA_struct_is_a(param->ptr.type, ptr_type)) { - *((PointerRNA *)data) = param->ptr; - } - else { - raise_error = true; - } + BPy_StructRNA *param = (BPy_StructRNA *)value; + bool raise_error = false; + if (data) { + + if (flag_parameter & PARM_RNAPTR) { + if (flag & PROP_THICK_WRAP) { + if (value == Py_None) { + memset(data, 0, sizeof(PointerRNA)); + } + else if (RNA_struct_is_a(param->ptr.type, ptr_type)) { + *((PointerRNA *)data) = param->ptr; } else { - /* For function calls, we sometimes want to pass the 'ptr' directly, - * but watch out that it remains valid! - * We could possibly support this later if needed. */ - BLI_assert(value_new == NULL); - if (value == Py_None) { - *((void **)data) = NULL; - } - else if (RNA_struct_is_a(param->ptr.type, ptr_type)) { - *((PointerRNA **)data) = ¶m->ptr; - } - else { - raise_error = true; - } + raise_error = true; } } - else if (value == Py_None) { - *((void **)data) = NULL; - } - else if (RNA_struct_is_a(param->ptr.type, ptr_type)) { - *((void **)data) = param->ptr.data; - } else { - raise_error = true; + /* For function calls, we sometimes want to pass the 'ptr' directly, + * but watch out that it remains valid! + * We could possibly support this later if needed. */ + BLI_assert(value_new == NULL); + if (value == Py_None) { + *((void **)data) = NULL; + } + else if (RNA_struct_is_a(param->ptr.type, ptr_type)) { + *((PointerRNA **)data) = ¶m->ptr; + } + else { + raise_error = true; + } } } + else if (value == Py_None) { + *((void **)data) = NULL; + } + else if (RNA_struct_is_a(param->ptr.type, ptr_type)) { + *((void **)data) = param->ptr.data; + } else { - /* Data == NULL, assign to RNA. */ - if (value == Py_None || RNA_struct_is_a(param->ptr.type, ptr_type)) { - ReportList reports; - BKE_reports_init(&reports, RPT_STORE); - RNA_property_pointer_set( - ptr, prop, value == Py_None ? PointerRNA_NULL : param->ptr, &reports); - int err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true)); - if (err == -1) { - Py_XDECREF(value_new); - return -1; - } - } - else { - raise_error = true; + raise_error = true; + } + } + else { + /* Data == NULL, assign to RNA. */ + if (value == Py_None || RNA_struct_is_a(param->ptr.type, ptr_type)) { + ReportList reports; + BKE_reports_init(&reports, RPT_STORE); + RNA_property_pointer_set( + ptr, prop, value == Py_None ? PointerRNA_NULL : param->ptr, &reports); + int err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true)); + if (err == -1) { + Py_XDECREF(value_new); + return -1; } } + else { + raise_error = true; + } + } - if (raise_error) { - if (pyrna_struct_validity_check(param) == -1) { - /* Error set. */ - } - else { - PointerRNA tmp; - RNA_pointer_create(NULL, ptr_type, NULL, &tmp); - PyErr_Format(PyExc_TypeError, - "%.200s %.200s.%.200s expected a %.200s type, not %.200s", - error_prefix, - RNA_struct_identifier(ptr->type), - RNA_property_identifier(prop), - RNA_struct_identifier(tmp.type), - RNA_struct_identifier(param->ptr.type)); - } - Py_XDECREF(value_new); - return -1; + if (raise_error) { + if (pyrna_struct_validity_check(param) == -1) { + /* Error set. */ } + else { + PointerRNA tmp; + RNA_pointer_create(NULL, ptr_type, NULL, &tmp); + PyErr_Format(PyExc_TypeError, + "%.200s %.200s.%.200s expected a %.200s type, not %.200s", + error_prefix, + RNA_struct_identifier(ptr->type), + RNA_property_identifier(prop), + RNA_struct_identifier(tmp.type), + RNA_struct_identifier(param->ptr.type)); + } + Py_XDECREF(value_new); + return -1; } Py_XDECREF(value_new); @@ -2295,9 +2291,8 @@ static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self) if (RNA_property_array_dimension(&self->ptr, self->prop, NULL) > 1) { return RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim); } - else { - return RNA_property_array_length(&self->ptr, self->prop); - } + + return RNA_property_array_length(&self->ptr, self->prop); } static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self) @@ -2356,25 +2351,24 @@ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_s if (RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum_abs, &newptr)) { return pyrna_struct_CreatePyObject(&newptr); } - else { - const int len = RNA_property_collection_length(&self->ptr, self->prop); - if (keynum_abs >= len) { - PyErr_Format(PyExc_IndexError, - "bpy_prop_collection[index]: " - "index %d out of range, size %d", - keynum, - len); - } - else { - PyErr_Format(PyExc_RuntimeError, - "bpy_prop_collection[index]: internal error, " - "valid index %d given in %d sized collection, but value not found", - keynum_abs, - len); - } - return NULL; + const int len = RNA_property_collection_length(&self->ptr, self->prop); + if (keynum_abs >= len) { + PyErr_Format(PyExc_IndexError, + "bpy_prop_collection[index]: " + "index %d out of range, size %d", + keynum, + len); + } + else { + PyErr_Format(PyExc_RuntimeError, + "bpy_prop_collection[index]: internal error, " + "valid index %d given in %d sized collection, but value not found", + keynum_abs, + len); } + + return NULL; } /* Values type must have been already checked. */ @@ -2473,79 +2467,76 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel PyTuple_GET_SIZE(key)); return -1; } - else if (self->ptr.type != &RNA_BlendData) { + if (self->ptr.type != &RNA_BlendData) { PyErr_Format(PyExc_KeyError, "%s: is only valid for bpy.data collections, not %.200s", err_prefix, RNA_struct_identifier(self->ptr.type)); return -1; } - else if ((keyname = _PyUnicode_AsString(PyTuple_GET_ITEM(key, 0))) == NULL) { + if ((keyname = _PyUnicode_AsString(PyTuple_GET_ITEM(key, 0))) == NULL) { PyErr_Format(PyExc_KeyError, "%s: id must be a string, not %.200s", err_prefix, Py_TYPE(PyTuple_GET_ITEM(key, 0))->tp_name); return -1; } - else { - PyObject *keylib = PyTuple_GET_ITEM(key, 1); - Library *lib; - bool found = false; - - if (keylib == Py_None) { - lib = NULL; - } - else if (PyUnicode_Check(keylib)) { - Main *bmain = self->ptr.data; - const char *keylib_str = _PyUnicode_AsString(keylib); - lib = BLI_findstring(&bmain->libraries, keylib_str, offsetof(Library, filepath)); - if (lib == NULL) { - if (err_not_found) { - PyErr_Format(PyExc_KeyError, - "%s: lib name '%.240s' " - "does not reference a valid library", - err_prefix, - keylib_str); - return -1; - } - else { - return 0; - } + + PyObject *keylib = PyTuple_GET_ITEM(key, 1); + Library *lib; + bool found = false; + + if (keylib == Py_None) { + lib = NULL; + } + else if (PyUnicode_Check(keylib)) { + Main *bmain = self->ptr.data; + const char *keylib_str = _PyUnicode_AsString(keylib); + lib = BLI_findstring(&bmain->libraries, keylib_str, offsetof(Library, filepath)); + if (lib == NULL) { + if (err_not_found) { + PyErr_Format(PyExc_KeyError, + "%s: lib name '%.240s' " + "does not reference a valid library", + err_prefix, + keylib_str); + return -1; } + + return 0; } - else { - PyErr_Format(PyExc_KeyError, - "%s: lib must be a string or None, not %.200s", - err_prefix, - Py_TYPE(keylib)->tp_name); - return -1; - } + } + else { + PyErr_Format(PyExc_KeyError, + "%s: lib must be a string or None, not %.200s", + err_prefix, + Py_TYPE(keylib)->tp_name); + return -1; + } - /* lib is either a valid pointer or NULL, - * either way can do direct comparison with id.lib */ + /* lib is either a valid pointer or NULL, + * either way can do direct comparison with id.lib */ - RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { - ID *id = itemptr.data; /* Always an ID. */ - if (id->lib == lib && (STREQLEN(keyname, id->name + 2, sizeof(id->name) - 2))) { - found = true; - if (r_ptr) { - *r_ptr = itemptr; - } - break; + RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { + ID *id = itemptr.data; /* Always an ID. */ + if (id->lib == lib && (STREQLEN(keyname, id->name + 2, sizeof(id->name) - 2))) { + found = true; + if (r_ptr) { + *r_ptr = itemptr; } + break; } - RNA_PROP_END; + } + RNA_PROP_END; - /* We may want to fail silently as with collection.get(). */ - if ((found == false) && err_not_found) { - /* Only runs for getitem access so use fixed string. */ - PyErr_SetString(PyExc_KeyError, "bpy_prop_collection[key, lib]: not found"); - return -1; - } - else { - return found; /* 1 / 0, no exception. */ - } + /* We may want to fail silently as with collection.get(). */ + if ((found == false) && err_not_found) { + /* Only runs for getitem access so use fixed string. */ + PyErr_SetString(PyExc_KeyError, "bpy_prop_collection[key, lib]: not found"); + return -1; } + + return found; /* 1 / 0, no exception. */ } static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self, @@ -2560,9 +2551,8 @@ static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *s if (contains == 1) { return pyrna_struct_CreatePyObject(&ptr); } - else { - return NULL; - } + + return NULL; } static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, @@ -2707,7 +2697,7 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject if (PyUnicode_Check(key)) { return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key)); } - else if (PyIndex_Check(key)) { + if (PyIndex_Check(key)) { Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) { return NULL; @@ -2715,62 +2705,59 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject return pyrna_prop_collection_subscript_int(self, i); } - else if (PySlice_Check(key)) { + if (PySlice_Check(key)) { PySliceObject *key_slice = (PySliceObject *)key; Py_ssize_t step = 1; if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) { return NULL; } - else if (step != 1) { + if (step != 1) { PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported"); return NULL; } - else if (key_slice->start == Py_None && key_slice->stop == Py_None) { + if (key_slice->start == Py_None && key_slice->stop == Py_None) { return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX); } - else { - Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; - /* Avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ - if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) { - return NULL; - } - if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) { - return NULL; - } + Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; - if (start < 0 || stop < 0) { - /* Only get the length for negative values. */ - Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop); - if (start < 0) { - start += len; - } - if (stop < 0) { - stop += len; - } - } + /* Avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ + if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) { + return NULL; + } + if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) { + return NULL; + } - if (stop - start <= 0) { - return PyList_New(0); + if (start < 0 || stop < 0) { + /* Only get the length for negative values. */ + Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop); + if (start < 0) { + start += len; } - else { - return pyrna_prop_collection_subscript_slice(self, start, stop); + if (stop < 0) { + stop += len; } } + + if (stop - start <= 0) { + return PyList_New(0); + } + + return pyrna_prop_collection_subscript_slice(self, start, stop); } - else if (PyTuple_Check(key)) { + if (PyTuple_Check(key)) { /* Special case, for ID datablocks we. */ return pyrna_prop_collection_subscript_str_lib_pair( self, key, "bpy_prop_collection[id, lib]", true); } - else { - PyErr_Format(PyExc_TypeError, - "bpy_prop_collection[key]: invalid key, " - "must be a string or an int, not %.200s", - Py_TYPE(key)->tp_name); - return NULL; - } + + PyErr_Format(PyExc_TypeError, + "bpy_prop_collection[key]: invalid key, " + "must be a string or an int, not %.200s", + Py_TYPE(key)->tp_name); + return NULL; } /* generic check to see if a PyObject is compatible with a collection @@ -2786,18 +2773,17 @@ static int pyrna_prop_collection_type_check(BPy_PropertyRNA *self, PyObject *val "this collection doesn't support None assignment"); return -1; } - else { - return 0; /* None is OK. */ - } + + return 0; /* None is OK. */ } - else if (BPy_StructRNA_Check(value) == 0) { + if (BPy_StructRNA_Check(value) == 0) { PyErr_Format(PyExc_TypeError, "bpy_prop_collection[key] = value: invalid, " "expected a StructRNA type or None, not a %.200s", Py_TYPE(value)->tp_name); return -1; } - else if ((prop_srna = RNA_property_pointer_type(&self->ptr, self->prop))) { + if ((prop_srna = RNA_property_pointer_type(&self->ptr, self->prop))) { StructRNA *value_srna = ((BPy_StructRNA *)value)->ptr.type; if (RNA_struct_is_a(value_srna, prop_srna) == 0) { PyErr_Format(PyExc_TypeError, @@ -2807,9 +2793,8 @@ static int pyrna_prop_collection_type_check(BPy_PropertyRNA *self, PyObject *val RNA_struct_identifier(value_srna)); return -1; } - else { - return 0; /* OK, this is the correct type! */ - } + + return 0; /* OK, this is the correct type! */ } PyErr_Format(PyExc_TypeError, @@ -2831,7 +2816,7 @@ static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self, PyErr_SetString(PyExc_TypeError, "del bpy_prop_collection[key]: not supported"); return -1; } - else if (pyrna_prop_collection_type_check(self, value) == -1) { + if (pyrna_prop_collection_type_check(self, value) == -1) { return -1; /* Exception is set. */ } @@ -2895,13 +2880,12 @@ static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self, } } #endif - else { - PyErr_Format(PyExc_TypeError, - "bpy_prop_collection[key]: invalid key, " - "must be a string or an int, not %.200s", - Py_TYPE(key)->tp_name); - return -1; - } + + PyErr_Format(PyExc_TypeError, + "bpy_prop_collection[key]: invalid key, " + "must be a string or an int, not %.200s", + Py_TYPE(key)->tp_name); + return -1; } static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject *key) @@ -2921,43 +2905,40 @@ static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject } return pyrna_prop_array_subscript_int(self, i); } - else if (PySlice_Check(key)) { + if (PySlice_Check(key)) { Py_ssize_t step = 1; PySliceObject *key_slice = (PySliceObject *)key; if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) { return NULL; } - else if (step != 1) { + if (step != 1) { PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported"); return NULL; } - else if (key_slice->start == Py_None && key_slice->stop == Py_None) { + if (key_slice->start == Py_None && key_slice->stop == Py_None) { /* Note: no significant advantage with optimizing [:] slice as with collections, * but include here for consistency with collection slice func */ Py_ssize_t len = (Py_ssize_t)pyrna_prop_array_length(self); return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len); } - else { - int len = pyrna_prop_array_length(self); - Py_ssize_t start, stop, slicelength; - if (PySlice_GetIndicesEx(key, len, &start, &stop, &step, &slicelength) < 0) { - return NULL; - } + int len = pyrna_prop_array_length(self); + Py_ssize_t start, stop, slicelength; - if (slicelength <= 0) { - return PyTuple_New(0); - } - else { - return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len); - } + if (PySlice_GetIndicesEx(key, len, &start, &stop, &step, &slicelength) < 0) { + return NULL; } + + if (slicelength <= 0) { + return PyTuple_New(0); + } + + return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len); } - else { - PyErr_SetString(PyExc_AttributeError, "bpy_prop_array[key]: invalid key, key must be an int"); - return NULL; - } + + PyErr_SetString(PyExc_AttributeError, "bpy_prop_array[key]: invalid key, key must be an int"); + return NULL; } /** @@ -2972,7 +2953,7 @@ static PyObject *prop_subscript_ass_array_slice__as_seq_fast(PyObject *value, in "element in assignment is not a sequence type"))) { return NULL; } - else if (PySequence_Fast_GET_SIZE(value_fast) != length) { + if (PySequence_Fast_GET_SIZE(value_fast) != length) { Py_DECREF(value_fast); PyErr_SetString(PyExc_ValueError, "bpy_prop_array[slice] = value: " @@ -2980,9 +2961,8 @@ static PyObject *prop_subscript_ass_array_slice__as_seq_fast(PyObject *value, in return NULL; } - else { - return value_fast; - } + + return value_fast; } static int prop_subscript_ass_array_slice__float_recursive( @@ -3005,17 +2985,16 @@ static int prop_subscript_ass_array_slice__float_recursive( } return index; } - else { - BLI_assert(totdim == 1); - const float min = range[0], max = range[1]; - int i; - for (i = 0; i != length; i++) { - float v = PyFloat_AsDouble(value_items[i]); - CLAMP(v, min, max); - value[i] = v; - } - return i; + + BLI_assert(totdim == 1); + const float min = range[0], max = range[1]; + int i; + for (i = 0; i != length; i++) { + float v = PyFloat_AsDouble(value_items[i]); + CLAMP(v, min, max); + value[i] = v; } + return i; } static int prop_subscript_ass_array_slice__int_recursive( @@ -3038,17 +3017,16 @@ static int prop_subscript_ass_array_slice__int_recursive( } return index; } - else { - BLI_assert(totdim == 1); - const int min = range[0], max = range[1]; - int i; - for (i = 0; i != length; i++) { - int v = PyLong_AsLong(value_items[i]); - CLAMP(v, min, max); - value[i] = v; - } - return i; + + BLI_assert(totdim == 1); + const int min = range[0], max = range[1]; + int i; + for (i = 0; i != length; i++) { + int v = PyLong_AsLong(value_items[i]); + CLAMP(v, min, max); + value[i] = v; } + return i; } static int prop_subscript_ass_array_slice__bool_recursive(PyObject **value_items, @@ -3073,15 +3051,14 @@ static int prop_subscript_ass_array_slice__bool_recursive(PyObject **value_items } return index; } - else { - BLI_assert(totdim == 1); - int i; - for (i = 0; i != length; i++) { - int v = PyLong_AsLong(value_items[i]); - value[i] = v; - } - return i; + + BLI_assert(totdim == 1); + int i; + for (i = 0; i != length; i++) { + int v = PyLong_AsLong(value_items[i]); + value[i] = v; } + return i; } /* Could call `pyrna_py_to_prop_array_index(self, i, value)` in a loop, but it is slow. */ @@ -3364,23 +3341,21 @@ static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key) return pyrna_prop_collection_subscript_str_lib_pair_ptr( self, key, "(id, lib) in bpy_prop_collection", false, NULL); } - else { - - /* Key in dict style check. */ - const char *keyname = _PyUnicode_AsString(key); - if (keyname == NULL) { - PyErr_SetString(PyExc_TypeError, - "bpy_prop_collection.__contains__: expected a string or a tuple of strings"); - return -1; - } + /* Key in dict style check. */ + const char *keyname = _PyUnicode_AsString(key); - if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) { - return 1; - } + if (keyname == NULL) { + PyErr_SetString(PyExc_TypeError, + "bpy_prop_collection.__contains__: expected a string or a tuple of strings"); + return -1; + } - return 0; + if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) { + return 1; } + + return 0; } static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value) @@ -3821,30 +3796,25 @@ static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args) path); return NULL; } - else { - return pyrna_array_index(&r_ptr, r_prop, index); - } + + return pyrna_array_index(&r_ptr, r_prop, index); } - else { - if (coerce == Py_False) { - return pyrna_prop_CreatePyObject(&r_ptr, r_prop); - } - else { - return pyrna_prop_to_py(&r_ptr, r_prop); - } + + if (coerce == Py_False) { + return pyrna_prop_CreatePyObject(&r_ptr, r_prop); } + + return pyrna_prop_to_py(&r_ptr, r_prop); } - else { - return pyrna_struct_CreatePyObject(&r_ptr); - } - } - else { - PyErr_Format(PyExc_ValueError, - "%.200s.path_resolve(\"%.200s\") could not be resolved", - RNA_struct_identifier(self->ptr.type), - path); - return NULL; + + return pyrna_struct_CreatePyObject(&r_ptr); } + + PyErr_Format(PyExc_ValueError, + "%.200s.path_resolve(\"%.200s\") could not be resolved", + RNA_struct_identifier(self->ptr.type), + path); + return NULL; } PyDoc_STRVAR(pyrna_struct_path_from_id_doc, @@ -3954,22 +3924,21 @@ static PyObject *pyrna_prop_as_bytes(BPy_PropertyRNA *self) RNA_property_identifier(self->prop)); return NULL; } - else { - PyObject *ret; - char buf_fixed[256], *buf; - int buf_len; - buf = RNA_property_string_get_alloc( - &self->ptr, self->prop, buf_fixed, sizeof(buf_fixed), &buf_len); + PyObject *ret; + char buf_fixed[256], *buf; + int buf_len; - ret = PyBytes_FromStringAndSize(buf, buf_len); + buf = RNA_property_string_get_alloc( + &self->ptr, self->prop, buf_fixed, sizeof(buf_fixed), &buf_len); - if (buf_fixed != buf) { - MEM_freeN(buf); - } + ret = PyBytes_FromStringAndSize(buf, buf_len); - return ret; + if (buf_fixed != buf) { + MEM_freeN(buf); } + + return ret; } PyDoc_STRVAR(pyrna_prop_update_doc, @@ -4478,7 +4447,7 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject PyErr_SetString(PyExc_AttributeError, "bpy_struct: __setattr__ must be a string"); return -1; } - else if (name[0] != '_' && (prop = RNA_struct_find_property(&self->ptr, name))) { + if (name[0] != '_' && (prop = RNA_struct_find_property(&self->ptr, name))) { if (!RNA_property_editable_flag(&self->ptr, prop)) { PyErr_Format(PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" from \"%.200s\" is read-only", @@ -4497,22 +4466,21 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject name); return -1; } - else { - PointerRNA newptr; - ListBase newlb; - short newtype; - int done = CTX_data_get(C, name, &newptr, &newlb, &newtype); + PointerRNA newptr; + ListBase newlb; + short newtype; - if (done == 1) { - PyErr_Format( - PyExc_AttributeError, "bpy_struct: Context property \"%.200s\" is read-only", name); - BLI_freelistN(&newlb); - return -1; - } + int done = CTX_data_get(C, name, &newptr, &newlb, &newtype); + if (done == 1) { + PyErr_Format( + PyExc_AttributeError, "bpy_struct: Context property \"%.200s\" is read-only", name); BLI_freelistN(&newlb); + return -1; } + + BLI_freelistN(&newlb); } /* pyrna_py_to_prop sets its own exceptions */ @@ -4523,9 +4491,8 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject } return pyrna_py_to_prop(&self->ptr, prop, NULL, value, "bpy_struct: item.attr = val:"); } - else { - return PyObject_GenericSetAttr((PyObject *)self, pyname, value); - } + + return PyObject_GenericSetAttr((PyObject *)self, pyname, value); } static PyObject *pyrna_prop_dir(BPy_PropertyRNA *self) @@ -4563,7 +4530,7 @@ static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject PyErr_SetString(PyExc_AttributeError, "bpy_prop_collection: __getattr__ must be a string"); return NULL; } - else if (name[0] != '_') { + if (name[0] != '_') { PyObject *ret; PropertyRNA *prop; FunctionRNA *func; @@ -4575,7 +4542,7 @@ static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject return ret; } - else if ((func = RNA_struct_find_function(r_ptr.type, name))) { + if ((func = RNA_struct_find_function(r_ptr.type, name))) { PyObject *self_collection = pyrna_struct_CreatePyObject(&r_ptr); ret = pyrna_func_to_py(&((BPy_DummyPointerRNA *)self_collection)->ptr, func); Py_DECREF(self_collection); @@ -4639,11 +4606,11 @@ static int pyrna_prop_collection_setattro(BPy_PropertyRNA *self, PyObject *pynam PyErr_SetString(PyExc_AttributeError, "bpy_prop: __setattr__ must be a string"); return -1; } - else if (value == NULL) { + if (value == NULL) { PyErr_SetString(PyExc_AttributeError, "bpy_prop: del not supported"); return -1; } - else if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { + if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { if ((prop = RNA_struct_find_property(&r_ptr, name))) { /* pyrna_py_to_prop sets its own exceptions. */ return pyrna_py_to_prop(&r_ptr, prop, NULL, value, "BPy_PropertyRNA - Attribute (setattr):"); @@ -4673,9 +4640,8 @@ static PyObject *pyrna_prop_collection_idprop_add(BPy_PropertyRNA *self) "bpy_prop_collection.add(): not supported for this collection"); return NULL; } - else { - return pyrna_struct_CreatePyObject(&r_ptr); - } + + return pyrna_struct_CreatePyObject(&r_ptr); } static PyObject *pyrna_prop_collection_idprop_remove(BPy_PropertyRNA *self, PyObject *value) @@ -5798,7 +5764,7 @@ static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject * Py_INCREF(base); return (PyObject *)base; } - else if (PyType_IsSubtype(Py_TYPE(base), &pyrna_struct_Type)) { + if (PyType_IsSubtype(Py_TYPE(base), &pyrna_struct_Type)) { /* this almost never runs, only when using user defined subclasses of built-in object. * this isn't common since it's NOT related to registerable subclasses. eg: * @@ -5826,10 +5792,9 @@ static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject * type->tp_name); return NULL; } - else { - PyErr_Format(PyExc_TypeError, "bpy_struct.__new__(type): expected a single argument"); - return NULL; - } + + PyErr_Format(PyExc_TypeError, "bpy_struct.__new__(type): expected a single argument"); + return NULL; } /* only needed for subtyping, so a new class gets a valid BPy_StructRNA @@ -5845,18 +5810,17 @@ static PyObject *pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *UN if (type == Py_TYPE(base)) { return Py_INCREF_RET((PyObject *)base); } - else if (PyType_IsSubtype(type, &pyrna_prop_Type)) { + if (PyType_IsSubtype(type, &pyrna_prop_Type)) { BPy_PropertyRNA *ret = (BPy_PropertyRNA *)type->tp_alloc(type, 0); ret->ptr = base->ptr; ret->prop = base->prop; return (PyObject *)ret; } - else { - PyErr_Format(PyExc_TypeError, - "bpy_prop.__new__(type): type '%.200s' is not a subtype of bpy_prop", - type->tp_name); - return NULL; - } + + PyErr_Format(PyExc_TypeError, + "bpy_prop.__new__(type): type '%.200s' is not a subtype of bpy_prop", + type->tp_name); + return NULL; } static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data) @@ -6192,9 +6156,8 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject err = -1; break; } - else { /* PyDict_GetItemString wont raise an error. */ - continue; - } + /* PyDict_GetItemString wont raise an error. */ + continue; } #ifdef DEBUG_STRING_FREE @@ -7131,25 +7094,24 @@ static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA * PyErr_SetNone(PyExc_StopIteration); return NULL; } - else { - BPy_StructRNA *pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&self->iter.ptr); + + BPy_StructRNA *pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&self->iter.ptr); # ifdef USE_PYRNA_STRUCT_REFERENCE - if (pyrna) { /* Unlikely, but may fail. */ - if ((PyObject *)pyrna != Py_None) { - /* hold a reference to the iterator since it may have - * allocated memory 'pyrna' needs. eg: introspecting dynamic enum's */ - /* TODO, we could have an api call to know if this is - * needed since most collections don't */ - pyrna_struct_reference_set(pyrna, (PyObject *)self); - } + if (pyrna) { /* Unlikely, but may fail. */ + if ((PyObject *)pyrna != Py_None) { + /* hold a reference to the iterator since it may have + * allocated memory 'pyrna' needs. eg: introspecting dynamic enum's */ + /* TODO, we could have an api call to know if this is + * needed since most collections don't */ + pyrna_struct_reference_set(pyrna, (PyObject *)self); } + } # endif /* !USE_PYRNA_STRUCT_REFERENCE */ - RNA_property_collection_next(&self->iter); + RNA_property_collection_next(&self->iter); - return (PyObject *)pyrna; - } + return (PyObject *)pyrna; } static void pyrna_prop_collection_iter_dealloc(BPy_PropertyCollectionIterRNA *self) @@ -7413,9 +7375,8 @@ static StructRNA *srna_from_ptr(PointerRNA *ptr) if (ptr->type == &RNA_Struct) { return ptr->data; } - else { - return ptr->type; - } + + return ptr->type; } /* Always returns a new ref, be sure to decref when done. */ @@ -7445,15 +7406,14 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr) Py_INCREF(pyrna); return (PyObject *)pyrna; } - else { - /* Existing users will need to use 'type_recast' method. */ - Py_DECREF(pyrna); - *instance = NULL; - /* Continue as if no instance was made. */ + + /* Existing users will need to use 'type_recast' method. */ + Py_DECREF(pyrna); + *instance = NULL; + /* Continue as if no instance was made. */ #if 0 /* No need to assign, will be written to next... */ pyrna = NULL; #endif - } } { @@ -7560,9 +7520,8 @@ PyObject *pyrna_id_CreatePyObject(ID *id) RNA_id_pointer_create(id, &ptr); return pyrna_struct_CreatePyObject(&ptr); } - else { - Py_RETURN_NONE; - } + + Py_RETURN_NONE; } bool pyrna_id_FromPyObject(PyObject *obj, ID **id) @@ -7571,10 +7530,9 @@ bool pyrna_id_FromPyObject(PyObject *obj, ID **id) *id = ((BPy_StructRNA *)obj)->ptr.owner_id; return true; } - else { - *id = NULL; - return false; - } + + *id = NULL; + return false; } bool pyrna_id_CheckPyObject(PyObject *obj) @@ -7869,30 +7827,29 @@ StructRNA *srna_from_self(PyObject *self, const char *error_prefix) if (self == NULL) { return NULL; } - else if (PyCapsule_CheckExact(self)) { + if (PyCapsule_CheckExact(self)) { return PyCapsule_GetPointer(self, NULL); } - else if (PyType_Check(self) == 0) { + if (PyType_Check(self) == 0) { return NULL; } - else { - /* These cases above not errors, they just mean the type was not compatible - * After this any errors will be raised in the script */ - PyObject *error_type, *error_value, *error_traceback; - StructRNA *srna; + /* These cases above not errors, they just mean the type was not compatible + * After this any errors will be raised in the script */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); - PyErr_Clear(); + PyObject *error_type, *error_value, *error_traceback; + StructRNA *srna; - srna = pyrna_struct_as_srna(self, false, error_prefix); + PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyErr_Clear(); - if (!PyErr_Occurred()) { - PyErr_Restore(error_type, error_value, error_traceback); - } + srna = pyrna_struct_as_srna(self, false, error_prefix); - return srna; + if (!PyErr_Occurred()) { + PyErr_Restore(error_type, error_value, error_traceback); } + + return srna; } static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item) diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c index 8aba2ae8598..ae19f89c348 100644 --- a/source/blender/python/intern/bpy_rna_anim.c +++ b/source/blender/python/intern/bpy_rna_anim.c @@ -181,24 +181,24 @@ static int pyrna_struct_anim_args_parse_no_resolve(PointerRNA *ptr, *r_path_full = path; return 0; } - else { - char *path_prefix = RNA_path_from_ID_to_struct(ptr); - if (path_prefix == NULL) { - PyErr_Format(PyExc_TypeError, - "%.200s could not make path for type %s", - error_prefix, - RNA_struct_identifier(ptr->type)); - return -1; - } - if (*path == '[') { - *r_path_full = BLI_string_joinN(path_prefix, path); - } - else { - *r_path_full = BLI_string_join_by_sep_charN('.', path_prefix, path); - } - MEM_freeN(path_prefix); + char *path_prefix = RNA_path_from_ID_to_struct(ptr); + if (path_prefix == NULL) { + PyErr_Format(PyExc_TypeError, + "%.200s could not make path for type %s", + error_prefix, + RNA_struct_identifier(ptr->type)); + return -1; + } + + if (*path == '[') { + *r_path_full = BLI_string_joinN(path_prefix, path); } + else { + *r_path_full = BLI_string_join_by_sep_charN('.', path_prefix, path); + } + MEM_freeN(path_prefix); + return 0; } @@ -383,33 +383,32 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb return PyBool_FromLong(result); } - else { - ID *id = self->ptr.owner_id; - ReportList reports; - bool result; - - BKE_reports_init(&reports, RPT_STORE); - - BLI_assert(BKE_id_is_in_global_main(id)); - result = (insert_keyframe(G_MAIN, - &reports, - id, - NULL, - group_name, - path_full, - index, - &anim_eval_context, - keytype, - NULL, - options) != 0); - MEM_freeN((void *)path_full); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) { - return NULL; - } - - return PyBool_FromLong(result); + ID *id = self->ptr.owner_id; + ReportList reports; + bool result; + + BKE_reports_init(&reports, RPT_STORE); + + BLI_assert(BKE_id_is_in_global_main(id)); + result = (insert_keyframe(G_MAIN, + &reports, + id, + NULL, + group_name, + path_full, + index, + &anim_eval_context, + keytype, + NULL, + options) != 0); + MEM_freeN((void *)path_full); + + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) { + return NULL; } + + return PyBool_FromLong(result); } char pyrna_struct_keyframe_delete_doc[] = @@ -453,7 +452,7 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb NULL) == -1) { return NULL; } - else if (self->ptr.type == &RNA_NlaStrip) { + if (self->ptr.type == &RNA_NlaStrip) { /* Handle special properties for NLA Strips, whose F-Curves are stored on the * strips themselves. These are stored separately or else the properties will * not have any effect. @@ -518,22 +517,21 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb return PyBool_FromLong(result); } - else { - bool result; - ReportList reports; - BKE_reports_init(&reports, RPT_STORE); + bool result; + ReportList reports; - result = (delete_keyframe( - G.main, &reports, self->ptr.owner_id, NULL, path_full, index, cfra) != 0); - MEM_freeN((void *)path_full); + BKE_reports_init(&reports, RPT_STORE); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) { - return NULL; - } + result = (delete_keyframe(G.main, &reports, self->ptr.owner_id, NULL, path_full, index, cfra) != + 0); + MEM_freeN((void *)path_full); - return PyBool_FromLong(result); + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) { + return NULL; } + + return PyBool_FromLong(result); } char pyrna_struct_driver_add_doc[] = @@ -563,60 +561,59 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args) &self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) == -1) { return NULL; } - else { - PyObject *ret = NULL; - ReportList reports; - int result; - BKE_reports_init(&reports, RPT_STORE); + PyObject *ret = NULL; + ReportList reports; + int result; - result = ANIM_add_driver(&reports, - (ID *)self->ptr.owner_id, - path_full, - index, - CREATEDRIVER_WITH_FMODIFIER, - DRIVER_TYPE_PYTHON); + BKE_reports_init(&reports, RPT_STORE); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) { - return NULL; - } + result = ANIM_add_driver(&reports, + (ID *)self->ptr.owner_id, + path_full, + index, + CREATEDRIVER_WITH_FMODIFIER, + DRIVER_TYPE_PYTHON); - if (result) { - ID *id = self->ptr.owner_id; - AnimData *adt = BKE_animdata_from_id(id); - FCurve *fcu; + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) { + return NULL; + } - PointerRNA tptr; + if (result) { + ID *id = self->ptr.owner_id; + AnimData *adt = BKE_animdata_from_id(id); + FCurve *fcu; - if (index == -1) { /* all, use a list */ - int i = 0; - ret = PyList_New(0); - while ((fcu = BKE_fcurve_find(&adt->drivers, path_full, i++))) { - RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr); - PyList_APPEND(ret, pyrna_struct_CreatePyObject(&tptr)); - } - } - else { - fcu = BKE_fcurve_find(&adt->drivers, path_full, index); + PointerRNA tptr; + + if (index == -1) { /* all, use a list */ + int i = 0; + ret = PyList_New(0); + while ((fcu = BKE_fcurve_find(&adt->drivers, path_full, i++))) { RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr); - ret = pyrna_struct_CreatePyObject(&tptr); + PyList_APPEND(ret, pyrna_struct_CreatePyObject(&tptr)); } - - bContext *context = BPy_GetContext(); - WM_event_add_notifier(BPy_GetContext(), NC_ANIMATION | ND_FCURVES_ORDER, NULL); - DEG_relations_tag_update(CTX_data_main(context)); } else { - /* XXX, should be handled by reports, */ - PyErr_SetString(PyExc_TypeError, - "bpy_struct.driver_add(): failed because of an internal error"); - return NULL; + fcu = BKE_fcurve_find(&adt->drivers, path_full, index); + RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr); + ret = pyrna_struct_CreatePyObject(&tptr); } - MEM_freeN((void *)path_full); - - return ret; + bContext *context = BPy_GetContext(); + WM_event_add_notifier(BPy_GetContext(), NC_ANIMATION | ND_FCURVES_ORDER, NULL); + DEG_relations_tag_update(CTX_data_main(context)); } + else { + /* XXX, should be handled by reports, */ + PyErr_SetString(PyExc_TypeError, + "bpy_struct.driver_add(): failed because of an internal error"); + return NULL; + } + + MEM_freeN((void *)path_full); + + return ret; } char pyrna_struct_driver_remove_doc[] = @@ -646,26 +643,25 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args) &self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) == -1) { return NULL; } - else { - short result; - ReportList reports; - BKE_reports_init(&reports, RPT_STORE); + short result; + ReportList reports; - result = ANIM_remove_driver(&reports, (ID *)self->ptr.owner_id, path_full, index, 0); + BKE_reports_init(&reports, RPT_STORE); - if (path != path_full) { - MEM_freeN((void *)path_full); - } + result = ANIM_remove_driver(&reports, (ID *)self->ptr.owner_id, path_full, index, 0); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) { - return NULL; - } - - bContext *context = BPy_GetContext(); - WM_event_add_notifier(context, NC_ANIMATION | ND_FCURVES_ORDER, NULL); - DEG_relations_tag_update(CTX_data_main(context)); + if (path != path_full) { + MEM_freeN((void *)path_full); + } - return PyBool_FromLong(result); + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) { + return NULL; } + + bContext *context = BPy_GetContext(); + WM_event_add_notifier(context, NC_ANIMATION | ND_FCURVES_ORDER, NULL); + DEG_relations_tag_update(CTX_data_main(context)); + + return PyBool_FromLong(result); } diff --git a/source/blender/python/intern/bpy_rna_array.c b/source/blender/python/intern/bpy_rna_array.c index 1e5b53b819e..66e07d556a6 100644 --- a/source/blender/python/intern/bpy_rna_array.c +++ b/source/blender/python/intern/bpy_rna_array.c @@ -180,7 +180,7 @@ static int validate_array_type(PyObject *seq, Py_TYPE(seq)->tp_name); return -1; } - else if ((seq_size != dimsize[dim]) && (is_dynamic == false)) { + if ((seq_size != dimsize[dim]) && (is_dynamic == false)) { PyErr_Format(PyExc_ValueError, "%s sequences of dimension %d should contain %d items, not %d", error_prefix, @@ -201,7 +201,7 @@ static int validate_array_type(PyObject *seq, i); return -1; } - else if (!check_item_type(item)) { + if (!check_item_type(item)) { Py_DECREF(item); #if 0 @@ -279,7 +279,7 @@ static int validate_array_length(PyObject *rvalue, RNA_property_identifier(prop)); return -1; } - else if ((RNA_property_flag(prop) & PROP_DYNAMIC) && lvalue_dim == 0) { + if ((RNA_property_flag(prop) & PROP_DYNAMIC) && lvalue_dim == 0) { if (RNA_property_array_length(ptr, prop) != tot) { #if 0 /* length is flexible */ @@ -382,7 +382,7 @@ static int validate_array(PyObject *rvalue, RNA_property_identifier(prop)); return -1; } - else if (totdim != 2) { + if (totdim != 2) { PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, matrix assign array with %d dimensions", error_prefix, @@ -391,7 +391,7 @@ static int validate_array(PyObject *rvalue, totdim); return -1; } - else if (pymat->num_col != dimsize[0] || pymat->num_row != dimsize[1]) { + if (pymat->num_col != dimsize[0] || pymat->num_row != dimsize[1]) { PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, matrix assign dimension size mismatch, " "is %dx%d, expected be %dx%d", @@ -404,10 +404,9 @@ static int validate_array(PyObject *rvalue, dimsize[1]); return -1; } - else { - *r_totitem = dimsize[0] * dimsize[1]; - return 0; - } + + *r_totitem = dimsize[0] * dimsize[1]; + return 0; } } #endif /* USE_MATHUTILS */ @@ -1017,31 +1016,31 @@ int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value) PyErr_Clear(); return 0; } - else { - float tmp[32]; - float *tmp_arr; - if (len * sizeof(float) > sizeof(tmp)) { - tmp_arr = PyMem_MALLOC(len * sizeof(float)); - } - else { - tmp_arr = tmp; - } + float tmp[32]; + float *tmp_arr; - RNA_property_float_get_array(ptr, prop, tmp_arr); + if (len * sizeof(float) > sizeof(tmp)) { + tmp_arr = PyMem_MALLOC(len * sizeof(float)); + } + else { + tmp_arr = tmp; + } - for (i = 0; i < len; i++) { - if (tmp_arr[i] == value_f) { - break; - } - } + RNA_property_float_get_array(ptr, prop, tmp_arr); - if (tmp_arr != tmp) { - PyMem_FREE(tmp_arr); + for (i = 0; i < len; i++) { + if (tmp_arr[i] == value_f) { + break; } + } - return i < len ? 1 : 0; + if (tmp_arr != tmp) { + PyMem_FREE(tmp_arr); } + + return i < len ? 1 : 0; + break; } case PROP_INT: { @@ -1050,31 +1049,31 @@ int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value) PyErr_Clear(); return 0; } - else { - int tmp[32]; - int *tmp_arr; - if (len * sizeof(int) > sizeof(tmp)) { - tmp_arr = PyMem_MALLOC(len * sizeof(int)); - } - else { - tmp_arr = tmp; - } + int tmp[32]; + int *tmp_arr; - RNA_property_int_get_array(ptr, prop, tmp_arr); + if (len * sizeof(int) > sizeof(tmp)) { + tmp_arr = PyMem_MALLOC(len * sizeof(int)); + } + else { + tmp_arr = tmp; + } - for (i = 0; i < len; i++) { - if (tmp_arr[i] == value_i) { - break; - } - } + RNA_property_int_get_array(ptr, prop, tmp_arr); - if (tmp_arr != tmp) { - PyMem_FREE(tmp_arr); + for (i = 0; i < len; i++) { + if (tmp_arr[i] == value_i) { + break; } + } - return i < len ? 1 : 0; + if (tmp_arr != tmp) { + PyMem_FREE(tmp_arr); } + + return i < len ? 1 : 0; + break; } case PROP_BOOLEAN: { @@ -1083,31 +1082,31 @@ int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value) PyErr_Clear(); return 0; } - else { - bool tmp[32]; - bool *tmp_arr; - if (len * sizeof(bool) > sizeof(tmp)) { - tmp_arr = PyMem_MALLOC(len * sizeof(bool)); - } - else { - tmp_arr = tmp; - } + bool tmp[32]; + bool *tmp_arr; - RNA_property_boolean_get_array(ptr, prop, tmp_arr); + if (len * sizeof(bool) > sizeof(tmp)) { + tmp_arr = PyMem_MALLOC(len * sizeof(bool)); + } + else { + tmp_arr = tmp; + } - for (i = 0; i < len; i++) { - if (tmp_arr[i] == value_i) { - break; - } - } + RNA_property_boolean_get_array(ptr, prop, tmp_arr); - if (tmp_arr != tmp) { - PyMem_FREE(tmp_arr); + for (i = 0; i < len; i++) { + if (tmp_arr[i] == value_i) { + break; } + } - return i < len ? 1 : 0; + if (tmp_arr != tmp) { + PyMem_FREE(tmp_arr); } + + return i < len ? 1 : 0; + break; } } diff --git a/source/blender/python/intern/bpy_rna_callback.c b/source/blender/python/intern/bpy_rna_callback.c index f9bcb8943f4..976b8a65ac7 100644 --- a/source/blender/python/intern/bpy_rna_callback.c +++ b/source/blender/python/intern/bpy_rna_callback.c @@ -317,10 +317,10 @@ PyObject *pyrna_callback_classmethod_add(PyObject *UNUSED(self), PyObject *args) error_prefix) == -1) { return NULL; } - else if (params.region_type_str && pyrna_enum_value_from_id(rna_enum_region_type_items, - params.region_type_str, - ¶ms.region_type, - error_prefix) == -1) { + if (params.region_type_str && pyrna_enum_value_from_id(rna_enum_region_type_items, + params.region_type_str, + ¶ms.region_type, + error_prefix) == -1) { return NULL; } @@ -352,29 +352,26 @@ PyObject *pyrna_callback_classmethod_add(PyObject *UNUSED(self), PyObject *args) region_draw_mode_items, params.event_str, ¶ms.event, error_prefix) == -1) { return NULL; } - else if (pyrna_enum_value_from_id(rna_enum_region_type_items, - params.region_type_str, - ¶ms.region_type, - error_prefix) == -1) { + if (pyrna_enum_value_from_id(rna_enum_region_type_items, + params.region_type_str, + ¶ms.region_type, + error_prefix) == -1) { return NULL; } - else { - const eSpace_Type spaceid = rna_Space_refine_reverse(srna); - if (spaceid == SPACE_EMPTY) { - PyErr_Format(PyExc_TypeError, "unknown space type '%.200s'", RNA_struct_identifier(srna)); - return NULL; - } - else { - SpaceType *st = BKE_spacetype_from_id(spaceid); - ARegionType *art = BKE_regiontype_from_id(st, params.region_type); - if (art == NULL) { - PyErr_Format( - PyExc_TypeError, "region type '%.200s' not in space", params.region_type_str); - return NULL; - } - handle = ED_region_draw_cb_activate(art, cb_region_draw, (void *)args, params.event); - } + + const eSpace_Type spaceid = rna_Space_refine_reverse(srna); + if (spaceid == SPACE_EMPTY) { + PyErr_Format(PyExc_TypeError, "unknown space type '%.200s'", RNA_struct_identifier(srna)); + return NULL; } + + SpaceType *st = BKE_spacetype_from_id(spaceid); + ARegionType *art = BKE_regiontype_from_id(st, params.region_type); + if (art == NULL) { + PyErr_Format(PyExc_TypeError, "region type '%.200s' not in space", params.region_type_str); + return NULL; + } + handle = ED_region_draw_cb_activate(art, cb_region_draw, (void *)args, params.event); } else { PyErr_SetString(PyExc_TypeError, "callback_add(): type does not support callbacks"); @@ -448,24 +445,21 @@ PyObject *pyrna_callback_classmethod_remove(PyObject *UNUSED(self), PyObject *ar error_prefix) == -1) { return NULL; } - else { - const eSpace_Type spaceid = rna_Space_refine_reverse(srna); - if (spaceid == SPACE_EMPTY) { - PyErr_Format(PyExc_TypeError, "unknown space type '%.200s'", RNA_struct_identifier(srna)); - return NULL; - } - else { - SpaceType *st = BKE_spacetype_from_id(spaceid); - ARegionType *art = BKE_regiontype_from_id(st, params.region_type); - if (art == NULL) { - PyErr_Format( - PyExc_TypeError, "region type '%.200s' not in space", params.region_type_str); - return NULL; - } - ED_region_draw_cb_exit(art, handle); - capsule_clear = true; - } + + const eSpace_Type spaceid = rna_Space_refine_reverse(srna); + if (spaceid == SPACE_EMPTY) { + PyErr_Format(PyExc_TypeError, "unknown space type '%.200s'", RNA_struct_identifier(srna)); + return NULL; } + + SpaceType *st = BKE_spacetype_from_id(spaceid); + ARegionType *art = BKE_regiontype_from_id(st, params.region_type); + if (art == NULL) { + PyErr_Format(PyExc_TypeError, "region type '%.200s' not in space", params.region_type_str); + return NULL; + } + ED_region_draw_cb_exit(art, handle); + capsule_clear = true; } else { PyErr_SetString(PyExc_TypeError, "callback_remove(): type does not support callbacks"); diff --git a/source/blender/python/intern/bpy_rna_gizmo.c b/source/blender/python/intern/bpy_rna_gizmo.c index aff81c68358..4ef718ef023 100644 --- a/source/blender/python/intern/bpy_rna_gizmo.c +++ b/source/blender/python/intern/bpy_rna_gizmo.c @@ -367,10 +367,10 @@ static PyObject *bpy_gizmo_target_get_value(PyObject *UNUSED(self), PyObject *ar WM_gizmo_target_property_float_get_array(gz, gz_prop, value); return PyC_Tuple_PackArray_F32(value, array_len); } - else { - float value = WM_gizmo_target_property_float_get(gz, gz_prop); - return PyFloat_FromDouble(value); - } + + float value = WM_gizmo_target_property_float_get(gz, gz_prop); + return PyFloat_FromDouble(value); + break; } default: { diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c index 5764db4e70c..308d2ef9618 100644 --- a/source/blender/python/mathutils/mathutils.c +++ b/source/blender/python/mathutils/mathutils.c @@ -249,42 +249,41 @@ int mathutils_array_parse_alloc(float **array, memcpy(*array, ((BaseMathObject *)value)->data, size * sizeof(float)); return size; } - else -#endif - { - PyObject *value_fast = NULL; - // *array = NULL; - int ret; - /* non list/tuple cases */ - if (!(value_fast = PySequence_Fast(value, error_prefix))) { - /* PySequence_Fast sets the error */ - return -1; - } +#endif - size = PySequence_Fast_GET_SIZE(value_fast); + PyObject *value_fast = NULL; + // *array = NULL; + int ret; - if (size < array_min) { - Py_DECREF(value_fast); - PyErr_Format(PyExc_ValueError, - "%.200s: sequence size is %d, expected > %d", - error_prefix, - size, - array_min); - return -1; - } + /* non list/tuple cases */ + if (!(value_fast = PySequence_Fast(value, error_prefix))) { + /* PySequence_Fast sets the error */ + return -1; + } - *array = PyMem_Malloc(size * sizeof(float)); + size = PySequence_Fast_GET_SIZE(value_fast); - ret = mathutils_array_parse_fast(*array, size, value_fast, error_prefix); + if (size < array_min) { Py_DECREF(value_fast); + PyErr_Format(PyExc_ValueError, + "%.200s: sequence size is %d, expected > %d", + error_prefix, + size, + array_min); + return -1; + } - if (ret == -1) { - PyMem_Free(*array); - } + *array = PyMem_Malloc(size * sizeof(float)); + + ret = mathutils_array_parse_fast(*array, size, value_fast, error_prefix); + Py_DECREF(value_fast); - return ret; + if (ret == -1) { + PyMem_Free(*array); } + + return ret; } /* parse an array of vectors */ @@ -482,45 +481,41 @@ int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) { return -1; } - else { - eulO_to_mat3(rmat, ((EulerObject *)value)->eul, ((EulerObject *)value)->order); - return 0; - } + + eulO_to_mat3(rmat, ((EulerObject *)value)->eul, ((EulerObject *)value)->order); + return 0; } - else if (QuaternionObject_Check(value)) { + if (QuaternionObject_Check(value)) { if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) { return -1; } - else { - float tquat[4]; - normalize_qt_qt(tquat, ((QuaternionObject *)value)->quat); - quat_to_mat3(rmat, tquat); - return 0; - } + + float tquat[4]; + normalize_qt_qt(tquat, ((QuaternionObject *)value)->quat); + quat_to_mat3(rmat, tquat); + return 0; } - else if (MatrixObject_Check(value)) { + if (MatrixObject_Check(value)) { if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) { return -1; } - else if (((MatrixObject *)value)->num_row < 3 || ((MatrixObject *)value)->num_col < 3) { + if (((MatrixObject *)value)->num_row < 3 || ((MatrixObject *)value)->num_col < 3) { PyErr_Format( PyExc_ValueError, "%.200s: matrix must have minimum 3x3 dimensions", error_prefix); return -1; } - else { - matrix_as_3x3(rmat, (MatrixObject *)value); - normalize_m3(rmat); - return 0; - } - } - else { - PyErr_Format(PyExc_TypeError, - "%.200s: expected a Euler, Quaternion or Matrix type, " - "found %.200s", - error_prefix, - Py_TYPE(value)->tp_name); - return -1; + + matrix_as_3x3(rmat, (MatrixObject *)value); + normalize_m3(rmat); + return 0; } + + PyErr_Format(PyExc_TypeError, + "%.200s: expected a Euler, Quaternion or Matrix type, " + "found %.200s", + error_prefix, + Py_TYPE(value)->tp_name); + return -1; } /* ----------------------------------MATRIX FUNCTIONS-------------------- */ diff --git a/source/blender/python/mathutils/mathutils_Color.c b/source/blender/python/mathutils/mathutils_Color.c index 08dede8ff78..6bffff467cd 100644 --- a/source/blender/python/mathutils/mathutils_Color.c +++ b/source/blender/python/mathutils/mathutils_Color.c @@ -347,7 +347,7 @@ static PyObject *Color_subscript(ColorObject *self, PyObject *item) } return Color_item(self, i); } - else if (PySlice_Check(item)) { + if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; if (PySlice_GetIndicesEx(item, COLOR_SIZE, &start, &stop, &step, &slicelength) < 0) { @@ -357,19 +357,17 @@ static PyObject *Color_subscript(ColorObject *self, PyObject *item) if (slicelength <= 0) { return PyTuple_New(0); } - else if (step == 1) { + if (step == 1) { return Color_slice(self, start, stop); } - else { - PyErr_SetString(PyExc_IndexError, "slice steps not supported with color"); - return NULL; - } - } - else { - PyErr_Format( - PyExc_TypeError, "color indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + + PyErr_SetString(PyExc_IndexError, "slice steps not supported with color"); return NULL; } + + PyErr_Format( + PyExc_TypeError, "color indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + return NULL; } static int Color_ass_subscript(ColorObject *self, PyObject *item, PyObject *value) @@ -384,7 +382,7 @@ static int Color_ass_subscript(ColorObject *self, PyObject *item, PyObject *valu } return Color_ass_item(self, i, value); } - else if (PySlice_Check(item)) { + if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; if (PySlice_GetIndicesEx(item, COLOR_SIZE, &start, &stop, &step, &slicelength) < 0) { @@ -394,16 +392,14 @@ static int Color_ass_subscript(ColorObject *self, PyObject *item, PyObject *valu if (step == 1) { return Color_ass_slice(self, start, stop, value); } - else { - PyErr_SetString(PyExc_IndexError, "slice steps not supported with color"); - return -1; - } - } - else { - PyErr_Format( - PyExc_TypeError, "color indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + + PyErr_SetString(PyExc_IndexError, "slice steps not supported with color"); return -1; } + + PyErr_Format( + PyExc_TypeError, "color indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + return -1; } /* -----------------PROTCOL DECLARATIONS-------------------------- */ diff --git a/source/blender/python/mathutils/mathutils_Euler.c b/source/blender/python/mathutils/mathutils_Euler.c index 7ece587e38f..ebc71706bef 100644 --- a/source/blender/python/mathutils/mathutils_Euler.c +++ b/source/blender/python/mathutils/mathutils_Euler.c @@ -558,7 +558,7 @@ static PyObject *Euler_subscript(EulerObject *self, PyObject *item) } return Euler_item(self, i); } - else if (PySlice_Check(item)) { + if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; if (PySlice_GetIndicesEx(item, EULER_SIZE, &start, &stop, &step, &slicelength) < 0) { @@ -568,19 +568,17 @@ static PyObject *Euler_subscript(EulerObject *self, PyObject *item) if (slicelength <= 0) { return PyTuple_New(0); } - else if (step == 1) { + if (step == 1) { return Euler_slice(self, start, stop); } - else { - PyErr_SetString(PyExc_IndexError, "slice steps not supported with eulers"); - return NULL; - } - } - else { - PyErr_Format( - PyExc_TypeError, "euler indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + + PyErr_SetString(PyExc_IndexError, "slice steps not supported with eulers"); return NULL; } + + PyErr_Format( + PyExc_TypeError, "euler indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + return NULL; } static int Euler_ass_subscript(EulerObject *self, PyObject *item, PyObject *value) @@ -595,7 +593,7 @@ static int Euler_ass_subscript(EulerObject *self, PyObject *item, PyObject *valu } return Euler_ass_item(self, i, value); } - else if (PySlice_Check(item)) { + if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; if (PySlice_GetIndicesEx(item, EULER_SIZE, &start, &stop, &step, &slicelength) < 0) { @@ -605,16 +603,14 @@ static int Euler_ass_subscript(EulerObject *self, PyObject *item, PyObject *valu if (step == 1) { return Euler_ass_slice(self, start, stop, value); } - else { - PyErr_SetString(PyExc_IndexError, "slice steps not supported with euler"); - return -1; - } - } - else { - PyErr_Format( - PyExc_TypeError, "euler indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + + PyErr_SetString(PyExc_IndexError, "slice steps not supported with euler"); return -1; } + + PyErr_Format( + PyExc_TypeError, "euler indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + return -1; } /* -----------------PROTCOL DECLARATIONS-------------------------- */ diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index 3e30c81c8c6..236bb1de29d 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -54,9 +54,8 @@ static int matrix_row_vector_check(MatrixObject *mat, VectorObject *vec, int row "owner matrix has been resized since this row vector was created"); return 0; } - else { - return 1; - } + + return 1; } static int matrix_col_vector_check(MatrixObject *mat, VectorObject *vec, int col) @@ -67,9 +66,8 @@ static int matrix_col_vector_check(MatrixObject *mat, VectorObject *vec, int col "owner matrix has been resized since this column vector was created"); return 0; } - else { - return 1; - } + + return 1; } /* ---------------------------------------------------------------------------- @@ -380,9 +378,8 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (Matrix_ass_slice((MatrixObject *)matrix, 0, INT_MAX, arg) == 0) { return matrix; } - else { /* matrix ok, slice assignment not */ - Py_DECREF(matrix); - } + /* matrix ok, slice assignment not */ + Py_DECREF(matrix); } } break; @@ -406,15 +403,13 @@ static PyObject *matrix__apply_to_copy(PyObject *(*matrix_func)(MatrixObject *), Py_DECREF(ret_dummy); return ret; } - else { /* error */ - Py_DECREF(ret); - return NULL; - } - } - else { - /* copy may fail if the read callback errors out */ + /* error */ + Py_DECREF(ret); return NULL; } + + /* copy may fail if the read callback errors out */ + return NULL; } /* when a matrix is 4x4 size but initialized as a 3x3, re-assign values for 4x4 */ @@ -512,10 +507,9 @@ static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args) "or a string in 'X', 'Y', 'Z'"); return NULL; } - else { - /* use the string */ - vec = NULL; - } + + /* use the string */ + vec = NULL; } angle = angle_wrap_rad(angle); @@ -1023,7 +1017,7 @@ static float matrix_determinant_internal(const MatrixObject *self) MATRIX_ITEM(self, 1, 0), MATRIX_ITEM(self, 1, 1)); } - else if (self->num_col == 3) { + if (self->num_col == 3) { return determinant_m3(MATRIX_ITEM(self, 0, 0), MATRIX_ITEM(self, 0, 1), MATRIX_ITEM(self, 0, 2), @@ -1034,9 +1028,8 @@ static float matrix_determinant_internal(const MatrixObject *self) MATRIX_ITEM(self, 2, 1), MATRIX_ITEM(self, 2, 2)); } - else { - return determinant_m4((float(*)[4])self->matrix); - } + + return determinant_m4((float(*)[4])self->matrix); } static void adjoint_matrix_n(float *mat_dst, const float *mat_src, const ushort dim) @@ -1094,9 +1087,8 @@ static bool matrix_invert_internal(const MatrixObject *self, float *r_mat) matrix_invert_with_det_n_internal(r_mat, self->matrix, det, self->num_col); return true; } - else { - return false; - } + + return false; } /** @@ -1475,9 +1467,8 @@ static bool matrix_invert_is_compat(const MatrixObject *self) "only square matrices are supported"); return false; } - else { - return true; - } + + return true; } static bool matrix_invert_args_check(const MatrixObject *self, PyObject *args, bool check_type) @@ -1605,10 +1596,9 @@ static PyObject *Matrix_inverted(MatrixObject *self, PyObject *args) Py_INCREF(fallback); return fallback; } - else { - matrix_invert_raise_degenerate(); - return NULL; - } + + matrix_invert_raise_degenerate(); + return NULL; } return Matrix_copy_notest(self, mat); @@ -2386,48 +2376,47 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va /* PySequence_Fast sets the error */ return -1; } - else { - PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast); - const int size = end - begin; - int row, col; - float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM]; - float vec[4]; - if (PySequence_Fast_GET_SIZE(value_fast) != size) { - Py_DECREF(value_fast); - PyErr_SetString(PyExc_ValueError, - "matrix[begin:end] = []: " - "size mismatch in slice assignment"); - return -1; - } + PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast); + const int size = end - begin; + int row, col; + float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM]; + float vec[4]; + + if (PySequence_Fast_GET_SIZE(value_fast) != size) { + Py_DECREF(value_fast); + PyErr_SetString(PyExc_ValueError, + "matrix[begin:end] = []: " + "size mismatch in slice assignment"); + return -1; + } - memcpy(mat, self->matrix, self->num_col * self->num_row * sizeof(float)); + memcpy(mat, self->matrix, self->num_col * self->num_row * sizeof(float)); - /* parse sub items */ - for (row = begin; row < end; row++) { - /* parse each sub sequence */ - PyObject *item = value_fast_items[row - begin]; + /* parse sub items */ + for (row = begin; row < end; row++) { + /* parse each sub sequence */ + PyObject *item = value_fast_items[row - begin]; - if (mathutils_array_parse( - vec, self->num_col, self->num_col, item, "matrix[begin:end] = value assignment") == - -1) { - Py_DECREF(value_fast); - return -1; - } + if (mathutils_array_parse( + vec, self->num_col, self->num_col, item, "matrix[begin:end] = value assignment") == + -1) { + Py_DECREF(value_fast); + return -1; + } - for (col = 0; col < self->num_col; col++) { - mat[col * self->num_row + row] = vec[col]; - } + for (col = 0; col < self->num_col; col++) { + mat[col * self->num_row + row] = vec[col]; } + } - Py_DECREF(value_fast); + Py_DECREF(value_fast); - /*parsed well - now set in matrix*/ - memcpy(self->matrix, mat, self->num_col * self->num_row * sizeof(float)); + /*parsed well - now set in matrix*/ + memcpy(self->matrix, mat, self->num_col * self->num_row * sizeof(float)); - (void)BaseMath_WriteCallback(self); - return 0; - } + (void)BaseMath_WriteCallback(self); + return 0; } /*------------------------NUMERIC PROTOCOLS---------------------- *------------------------obj + obj------------------------------*/ @@ -2540,7 +2529,7 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2) return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_TYPE(mat1)); } - else if (mat2) { + if (mat2) { /*FLOAT/INT * MATRIX */ if (((scalar = PyFloat_AsDouble(m1)) == -1.0f && PyErr_Occurred()) == 0) { return matrix_mul_float(mat2, scalar); @@ -2655,7 +2644,7 @@ static PyObject *Matrix_matmul(PyObject *m1, PyObject *m2) return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_TYPE(mat1)); } - else if (mat1) { + if (mat1) { /* MATRIX @ VECTOR */ if (VectorObject_Check(m2)) { VectorObject *vec2 = (VectorObject *)m2; @@ -2772,7 +2761,7 @@ static PyObject *Matrix_subscript(MatrixObject *self, PyObject *item) } return Matrix_item_row(self, i); } - else if (PySlice_Check(item)) { + if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; if (PySlice_GetIndicesEx(item, self->num_row, &start, &stop, &step, &slicelength) < 0) { @@ -2782,19 +2771,17 @@ static PyObject *Matrix_subscript(MatrixObject *self, PyObject *item) if (slicelength <= 0) { return PyTuple_New(0); } - else if (step == 1) { + if (step == 1) { return Matrix_slice(self, start, stop); } - else { - PyErr_SetString(PyExc_IndexError, "slice steps not supported with matrices"); - return NULL; - } - } - else { - PyErr_Format( - PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + + PyErr_SetString(PyExc_IndexError, "slice steps not supported with matrices"); return NULL; } + + PyErr_Format( + PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + return NULL; } static int Matrix_ass_subscript(MatrixObject *self, PyObject *item, PyObject *value) @@ -2809,7 +2796,7 @@ static int Matrix_ass_subscript(MatrixObject *self, PyObject *item, PyObject *va } return Matrix_ass_item_row(self, i, value); } - else if (PySlice_Check(item)) { + if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; if (PySlice_GetIndicesEx(item, self->num_row, &start, &stop, &step, &slicelength) < 0) { @@ -2819,16 +2806,14 @@ static int Matrix_ass_subscript(MatrixObject *self, PyObject *item, PyObject *va if (step == 1) { return Matrix_ass_slice(self, start, stop, value); } - else { - PyErr_SetString(PyExc_IndexError, "slice steps not supported with matrices"); - return -1; - } - } - else { - PyErr_Format( - PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + + PyErr_SetString(PyExc_IndexError, "slice steps not supported with matrices"); return -1; } + + PyErr_Format( + PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + return -1; } static PyMappingMethods Matrix_AsMapping = { @@ -2977,15 +2962,14 @@ static PyObject *Matrix_is_negative_get(MatrixObject *self, void *UNUSED(closure if (self->num_row == 4 && self->num_col == 4) { return PyBool_FromLong(is_negative_m4((float(*)[4])self->matrix)); } - else if (self->num_row == 3 && self->num_col == 3) { + if (self->num_row == 3 && self->num_col == 3) { return PyBool_FromLong(is_negative_m3((float(*)[3])self->matrix)); } - else { - PyErr_SetString(PyExc_AttributeError, - "Matrix.is_negative: " - "inappropriate matrix size - expects 3x3 or 4x4 matrix"); - return NULL; - } + + PyErr_SetString(PyExc_AttributeError, + "Matrix.is_negative: " + "inappropriate matrix size - expects 3x3 or 4x4 matrix"); + return NULL; } PyDoc_STRVAR(Matrix_is_orthogonal_doc, @@ -3000,15 +2984,14 @@ static PyObject *Matrix_is_orthogonal_get(MatrixObject *self, void *UNUSED(closu if (self->num_row == 4 && self->num_col == 4) { return PyBool_FromLong(is_orthonormal_m4((float(*)[4])self->matrix)); } - else if (self->num_row == 3 && self->num_col == 3) { + if (self->num_row == 3 && self->num_col == 3) { return PyBool_FromLong(is_orthonormal_m3((float(*)[3])self->matrix)); } - else { - PyErr_SetString(PyExc_AttributeError, - "Matrix.is_orthogonal: " - "inappropriate matrix size - expects 3x3 or 4x4 matrix"); - return NULL; - } + + PyErr_SetString(PyExc_AttributeError, + "Matrix.is_orthogonal: " + "inappropriate matrix size - expects 3x3 or 4x4 matrix"); + return NULL; } PyDoc_STRVAR(Matrix_is_orthogonal_axis_vectors_doc, @@ -3024,15 +3007,14 @@ static PyObject *Matrix_is_orthogonal_axis_vectors_get(MatrixObject *self, void if (self->num_row == 4 && self->num_col == 4) { return PyBool_FromLong(is_orthogonal_m4((float(*)[4])self->matrix)); } - else if (self->num_row == 3 && self->num_col == 3) { + if (self->num_row == 3 && self->num_col == 3) { return PyBool_FromLong(is_orthogonal_m3((float(*)[3])self->matrix)); } - else { - PyErr_SetString(PyExc_AttributeError, - "Matrix.is_orthogonal_axis_vectors: " - "inappropriate matrix size - expects 3x3 or 4x4 matrix"); - return NULL; - } + + PyErr_SetString(PyExc_AttributeError, + "Matrix.is_orthogonal_axis_vectors: " + "inappropriate matrix size - expects 3x3 or 4x4 matrix"); + return NULL; } /*****************************************************************************/ @@ -3478,14 +3460,13 @@ static PyObject *MatrixAccess_subscript(MatrixAccessObject *self, PyObject *item } return Matrix_item_row(matrix_user, i); } - else { /* MAT_ACCESS_ROW */ - if (i < 0) { - i += matrix_user->num_col; - } - return Matrix_item_col(matrix_user, i); + /* MAT_ACCESS_ROW */ + if (i < 0) { + i += matrix_user->num_col; } + return Matrix_item_col(matrix_user, i); } - else if (PySlice_Check(item)) { + if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; if (PySlice_GetIndicesEx(item, MatrixAccess_len(self), &start, &stop, &step, &slicelength) < @@ -3496,19 +3477,17 @@ static PyObject *MatrixAccess_subscript(MatrixAccessObject *self, PyObject *item if (slicelength <= 0) { return PyTuple_New(0); } - else if (step == 1) { + if (step == 1) { return MatrixAccess_slice(self, start, stop); } - else { - PyErr_SetString(PyExc_IndexError, "slice steps not supported with matrix accessors"); - return NULL; - } - } - else { - PyErr_Format( - PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + + PyErr_SetString(PyExc_IndexError, "slice steps not supported with matrix accessors"); return NULL; } + + PyErr_Format( + PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + return NULL; } static int MatrixAccess_ass_subscript(MatrixAccessObject *self, PyObject *item, PyObject *value) @@ -3527,19 +3506,17 @@ static int MatrixAccess_ass_subscript(MatrixAccessObject *self, PyObject *item, } return Matrix_ass_item_row(matrix_user, i, value); } - else { /* MAT_ACCESS_ROW */ - if (i < 0) { - i += matrix_user->num_col; - } - return Matrix_ass_item_col(matrix_user, i, value); + /* MAT_ACCESS_ROW */ + if (i < 0) { + i += matrix_user->num_col; } + return Matrix_ass_item_col(matrix_user, i, value); } /* TODO, slice */ - else { - PyErr_Format( - PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name); - return -1; - } + + PyErr_Format( + PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + return -1; } static PyObject *MatrixAccess_iter(MatrixAccessObject *self) diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c index 2b7761b7678..b0e6b330968 100644 --- a/source/blender/python/mathutils/mathutils_Quaternion.c +++ b/source/blender/python/mathutils/mathutils_Quaternion.c @@ -815,7 +815,7 @@ static PyObject *Quaternion_subscript(QuaternionObject *self, PyObject *item) } return Quaternion_item(self, i); } - else if (PySlice_Check(item)) { + if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; if (PySlice_GetIndicesEx(item, QUAT_SIZE, &start, &stop, &step, &slicelength) < 0) { @@ -825,20 +825,17 @@ static PyObject *Quaternion_subscript(QuaternionObject *self, PyObject *item) if (slicelength <= 0) { return PyTuple_New(0); } - else if (step == 1) { + if (step == 1) { return Quaternion_slice(self, start, stop); } - else { - PyErr_SetString(PyExc_IndexError, "slice steps not supported with quaternions"); - return NULL; - } - } - else { - PyErr_Format(PyExc_TypeError, - "quaternion indices must be integers, not %.200s", - Py_TYPE(item)->tp_name); + + PyErr_SetString(PyExc_IndexError, "slice steps not supported with quaternions"); return NULL; } + + PyErr_Format( + PyExc_TypeError, "quaternion indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + return NULL; } static int Quaternion_ass_subscript(QuaternionObject *self, PyObject *item, PyObject *value) @@ -853,7 +850,7 @@ static int Quaternion_ass_subscript(QuaternionObject *self, PyObject *item, PyOb } return Quaternion_ass_item(self, i, value); } - else if (PySlice_Check(item)) { + if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; if (PySlice_GetIndicesEx(item, QUAT_SIZE, &start, &stop, &step, &slicelength) < 0) { @@ -863,17 +860,14 @@ static int Quaternion_ass_subscript(QuaternionObject *self, PyObject *item, PyOb if (step == 1) { return Quaternion_ass_slice(self, start, stop, value); } - else { - PyErr_SetString(PyExc_IndexError, "slice steps not supported with quaternion"); - return -1; - } - } - else { - PyErr_Format(PyExc_TypeError, - "quaternion indices must be integers, not %.200s", - Py_TYPE(item)->tp_name); + + PyErr_SetString(PyExc_IndexError, "slice steps not supported with quaternion"); return -1; } + + PyErr_Format( + PyExc_TypeError, "quaternion indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + return -1; } /* ------------------------NUMERIC PROTOCOLS---------------------- */ @@ -967,7 +961,7 @@ static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2) return Quaternion_CreatePyObject(quat, Py_TYPE(q1)); } /* the only case this can happen (for a supported type is "FLOAT * QUAT") */ - else if (quat2) { /* FLOAT * QUAT */ + if (quat2) { /* FLOAT * QUAT */ if (((scalar = PyFloat_AsDouble(q1)) == -1.0f && PyErr_Occurred()) == 0) { return quat_mul_float(quat2, scalar); } @@ -1049,7 +1043,7 @@ static PyObject *Quaternion_matmul(PyObject *q1, PyObject *q2) mul_qt_qtqt(quat, quat1->quat, quat2->quat); return Quaternion_CreatePyObject(quat, Py_TYPE(q1)); } - else if (quat1) { + if (quat1) { /* QUAT @ VEC */ if (VectorObject_Check(q2)) { VectorObject *vec2 = (VectorObject *)q2; @@ -1384,10 +1378,9 @@ static PyObject *quat__apply_to_copy(PyObject *(*quat_func)(QuaternionObject *), Py_DECREF(ret_dummy); return ret; } - else { /* error */ - Py_DECREF(ret); - return NULL; - } + /* error */ + Py_DECREF(ret); + return NULL; } /* axis vector suffers from precision errors, use this function to ensure */ diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c index 4b47440a530..b30aafbf875 100644 --- a/source/blender/python/mathutils/mathutils_Vector.c +++ b/source/blender/python/mathutils/mathutils_Vector.c @@ -104,10 +104,9 @@ static PyObject *vec__apply_to_copy(PyObject *(*vec_func)(VectorObject *), Vecto Py_DECREF(ret_dummy); return (PyObject *)ret; } - else { /* error */ - Py_DECREF(ret); - return NULL; - } + /* error */ + Py_DECREF(ret); + return NULL; } /*-----------------------CLASS-METHODS----------------------------*/ @@ -1004,12 +1003,11 @@ static PyObject *Vector_angle(VectorObject *self, PyObject *args) Py_INCREF(fallback); return fallback; } - else { - PyErr_SetString(PyExc_ValueError, - "Vector.angle(other): " - "zero length vectors have no valid angle"); - return NULL; - } + + PyErr_SetString(PyExc_ValueError, + "Vector.angle(other): " + "zero length vectors have no valid angle"); + return NULL; } return PyFloat_FromDouble(saacos(dot / (sqrt(dot_self) * sqrt(dot_other)))); @@ -1059,12 +1057,11 @@ static PyObject *Vector_angle_signed(VectorObject *self, PyObject *args) Py_INCREF(fallback); return fallback; } - else { - PyErr_SetString(PyExc_ValueError, - "Vector.angle_signed(other): " - "zero length vectors have no valid angle"); - return NULL; - } + + PyErr_SetString(PyExc_ValueError, + "Vector.angle_signed(other): " + "zero length vectors have no valid angle"); + return NULL; } return PyFloat_FromDouble(angle_signed_v2v2(self->vec, tvec)); @@ -1238,12 +1235,11 @@ static PyObject *Vector_slerp(VectorObject *self, PyObject *args) Py_INCREF(fallback); return fallback; } - else { - PyErr_SetString(PyExc_ValueError, - "Vector.slerp(): " - "zero length vectors unsupported"); - return NULL; - } + + PyErr_SetString(PyExc_ValueError, + "Vector.slerp(): " + "zero length vectors unsupported"); + return NULL; } /* We have sane state, execute slerp */ @@ -1256,12 +1252,11 @@ static PyObject *Vector_slerp(VectorObject *self, PyObject *args) Py_INCREF(fallback); return fallback; } - else { - PyErr_SetString(PyExc_ValueError, - "Vector.slerp(): " - "opposite vectors unsupported"); - return NULL; - } + + PyErr_SetString(PyExc_ValueError, + "Vector.slerp(): " + "opposite vectors unsupported"); + return NULL; } interp_dot_slerp(fac, cosom, w); @@ -1785,7 +1780,7 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2) /* element-wise product */ return vector_mul_vec(vec1, vec2); } - else if (vec1) { + if (vec1) { if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* VEC * FLOAT */ return vector_mul_float(vec1, scalar); } @@ -1890,7 +1885,7 @@ static PyObject *Vector_matmul(PyObject *v1, PyObject *v2) /*dot product*/ return PyFloat_FromDouble(dot_vn_vn(vec1->vec, vec2->vec, vec1->size)); } - else if (vec1) { + if (vec1) { if (MatrixObject_Check(v2)) { /* VEC @ MATRIX */ float tvec[MAX_DIMENSIONS]; @@ -2039,9 +2034,8 @@ static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa if (comparison_type == Py_NE) { Py_RETURN_TRUE; } - else { - Py_RETURN_FALSE; - } + + Py_RETURN_FALSE; } vecA = (VectorObject *)objectA; vecB = (VectorObject *)objectB; @@ -2054,9 +2048,8 @@ static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa if (comparison_type == Py_NE) { Py_RETURN_TRUE; } - else { - Py_RETURN_FALSE; - } + + Py_RETURN_FALSE; } switch (comparison_type) { @@ -2107,9 +2100,8 @@ static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa if (result == 1) { Py_RETURN_TRUE; } - else { - Py_RETURN_FALSE; - } + + Py_RETURN_FALSE; } static Py_hash_t Vector_hash(VectorObject *self) @@ -2152,7 +2144,7 @@ static PyObject *Vector_subscript(VectorObject *self, PyObject *item) } return Vector_item(self, i); } - else if (PySlice_Check(item)) { + if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; if (PySlice_GetIndicesEx(item, self->size, &start, &stop, &step, &slicelength) < 0) { @@ -2162,19 +2154,17 @@ static PyObject *Vector_subscript(VectorObject *self, PyObject *item) if (slicelength <= 0) { return PyTuple_New(0); } - else if (step == 1) { + if (step == 1) { return Vector_slice(self, start, stop); } - else { - PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors"); - return NULL; - } - } - else { - PyErr_Format( - PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + + PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors"); return NULL; } + + PyErr_Format( + PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + return NULL; } static int Vector_ass_subscript(VectorObject *self, PyObject *item, PyObject *value) @@ -2189,7 +2179,7 @@ static int Vector_ass_subscript(VectorObject *self, PyObject *item, PyObject *va } return Vector_ass_item(self, i, value); } - else if (PySlice_Check(item)) { + if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; if (PySlice_GetIndicesEx(item, self->size, &start, &stop, &step, &slicelength) < 0) { @@ -2199,16 +2189,14 @@ static int Vector_ass_subscript(VectorObject *self, PyObject *item, PyObject *va if (step == 1) { return Vector_ass_slice(self, start, stop, value); } - else { - PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors"); - return -1; - } - } - else { - PyErr_Format( - PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + + PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors"); return -1; } + + PyErr_Format( + PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + return -1; } static PyMappingMethods Vector_AsMapping = { @@ -2523,9 +2511,8 @@ static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure if (BaseMath_WriteCallback(self) == -1) { return -1; } - else { - return 0; - } + + return 0; } #define _SWIZZLE1(a) ((a) | SWIZZLE_VALID_AXIS) diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c index 5a0dc7d6a5e..80a72696d77 100644 --- a/source/blender/python/mathutils/mathutils_bvhtree.c +++ b/source/blender/python/mathutils/mathutils_bvhtree.c @@ -914,16 +914,15 @@ static PyObject *C_BVHTree_FromPolygons(PyObject *UNUSED(cls), PyObject *args, P return bvhtree_CreatePyObject( tree, epsilon, coords, coords_len, tris, tris_len, orig_index, orig_normal); } - else { - if (coords) { - MEM_freeN(coords); - } - if (tris) { - MEM_freeN(tris); - } - return NULL; + if (coords) { + MEM_freeN(coords); + } + if (tris) { + MEM_freeN(tris); } + + return NULL; } #ifndef MATH_STANDALONE @@ -1053,55 +1052,48 @@ static Mesh *bvh_get_mesh(const char *funcname, funcname); return NULL; } - else { - *r_free_mesh = true; - return mesh_create_eval_final_render(depsgraph, scene, ob, &data_masks); - } + + *r_free_mesh = true; + return mesh_create_eval_final_render(depsgraph, scene, ob, &data_masks); } - else if (ob_eval != NULL) { + if (ob_eval != NULL) { if (use_cage) { return mesh_get_eval_deform(depsgraph, scene, ob_eval, &data_masks); } - else { - return mesh_get_eval_final(depsgraph, scene, ob_eval, &data_masks); - } + + return mesh_get_eval_final(depsgraph, scene, ob_eval, &data_masks); } - else { - PyErr_Format(PyExc_ValueError, - "%s(...): Cannot get evaluated data from given dependency graph / object pair", - funcname); + + PyErr_Format(PyExc_ValueError, + "%s(...): Cannot get evaluated data from given dependency graph / object pair", + funcname); + return NULL; + } + + /* !use_deform */ + if (use_render) { + if (use_cage) { + PyErr_Format( + PyExc_ValueError, + "%s(...): cage arg is unsupported when dependency graph evaluation mode is RENDER", + funcname); return NULL; } + + *r_free_mesh = true; + return mesh_create_eval_no_deform_render(depsgraph, scene, ob, &data_masks); } - else { - /* !use_deform */ - if (use_render) { - if (use_cage) { - PyErr_Format( - PyExc_ValueError, - "%s(...): cage arg is unsupported when dependency graph evaluation mode is RENDER", - funcname); - return NULL; - } - else { - *r_free_mesh = true; - return mesh_create_eval_no_deform_render(depsgraph, scene, ob, &data_masks); - } - } - else { - if (use_cage) { - PyErr_Format(PyExc_ValueError, - "%s(...): cage arg is unsupported when deform=False and dependency graph " - "evaluation mode is not RENDER", - funcname); - return NULL; - } - else { - *r_free_mesh = true; - return mesh_create_eval_no_deform(depsgraph, scene, ob, &data_masks); - } - } + + if (use_cage) { + PyErr_Format(PyExc_ValueError, + "%s(...): cage arg is unsupported when deform=False and dependency graph " + "evaluation mode is not RENDER", + funcname); + return NULL; } + + *r_free_mesh = true; + return mesh_create_eval_no_deform(depsgraph, scene, ob, &data_masks); } PyDoc_STRVAR(C_BVHTree_FromObject_doc, diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c index 93dbac32c19..37997e9f912 100644 --- a/source/blender/python/mathutils/mathutils_geometry.c +++ b/source/blender/python/mathutils/mathutils_geometry.c @@ -204,12 +204,11 @@ static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject /* collinear */ Py_RETURN_NONE; } - else { - tuple = PyTuple_New(2); - PyTuple_SET_ITEMS( - tuple, Vector_CreatePyObject(i1, len, NULL), Vector_CreatePyObject(i2, len, NULL)); - return tuple; - } + + tuple = PyTuple_New(2); + PyTuple_SET_ITEMS( + tuple, Vector_CreatePyObject(i1, len, NULL), Vector_CreatePyObject(i2, len, NULL)); + return tuple; } /* Line-Line intersection using algorithm from mathworld.wolfram.com */ @@ -466,9 +465,8 @@ static PyObject *M_Geometry_intersect_line_line_2d(PyObject *UNUSED(self), PyObj if (isect_seg_seg_v2_point(UNPACK4(lines), vi) == 1) { return Vector_CreatePyObject(vi, 2, NULL); } - else { - Py_RETURN_NONE; - } + + Py_RETURN_NONE; } PyDoc_STRVAR( @@ -519,9 +517,8 @@ static PyObject *M_Geometry_intersect_line_plane(PyObject *UNUSED(self), PyObjec if (isect_line_plane_v3(isect, line_a, line_b, plane_co, plane_no) == 1) { return Vector_CreatePyObject(isect, 3, NULL); } - else { - Py_RETURN_NONE; - } + + Py_RETURN_NONE; } PyDoc_STRVAR( @@ -637,43 +634,42 @@ static PyObject *M_Geometry_intersect_line_sphere(PyObject *UNUSED(self), PyObje -1)) == 0) { return NULL; } - else { - bool use_a = true; - bool use_b = true; - float lambda; - PyObject *ret = PyTuple_New(2); + bool use_a = true; + bool use_b = true; + float lambda; - switch (isect_line_sphere_v3(line_a, line_b, sphere_co, sphere_radius, isect_a, isect_b)) { - case 1: - if (!(!clip || (((lambda = line_point_factor_v3(isect_a, line_a, line_b)) >= 0.0f) && - (lambda <= 1.0f)))) { - use_a = false; - } - use_b = false; - break; - case 2: - if (!(!clip || (((lambda = line_point_factor_v3(isect_a, line_a, line_b)) >= 0.0f) && - (lambda <= 1.0f)))) { - use_a = false; - } - if (!(!clip || (((lambda = line_point_factor_v3(isect_b, line_a, line_b)) >= 0.0f) && - (lambda <= 1.0f)))) { - use_b = false; - } - break; - default: + PyObject *ret = PyTuple_New(2); + + switch (isect_line_sphere_v3(line_a, line_b, sphere_co, sphere_radius, isect_a, isect_b)) { + case 1: + if (!(!clip || (((lambda = line_point_factor_v3(isect_a, line_a, line_b)) >= 0.0f) && + (lambda <= 1.0f)))) { + use_a = false; + } + use_b = false; + break; + case 2: + if (!(!clip || (((lambda = line_point_factor_v3(isect_a, line_a, line_b)) >= 0.0f) && + (lambda <= 1.0f)))) { use_a = false; + } + if (!(!clip || (((lambda = line_point_factor_v3(isect_b, line_a, line_b)) >= 0.0f) && + (lambda <= 1.0f)))) { use_b = false; - break; - } + } + break; + default: + use_a = false; + use_b = false; + break; + } - PyTuple_SET_ITEMS(ret, - use_a ? Vector_CreatePyObject(isect_a, 3, NULL) : Py_INCREF_RET(Py_None), - use_b ? Vector_CreatePyObject(isect_b, 3, NULL) : Py_INCREF_RET(Py_None)); + PyTuple_SET_ITEMS(ret, + use_a ? Vector_CreatePyObject(isect_a, 3, NULL) : Py_INCREF_RET(Py_None), + use_b ? Vector_CreatePyObject(isect_b, 3, NULL) : Py_INCREF_RET(Py_None)); - return ret; - } + return ret; } /* keep in sync with M_Geometry_intersect_line_sphere */ @@ -723,43 +719,42 @@ static PyObject *M_Geometry_intersect_line_sphere_2d(PyObject *UNUSED(self), PyO -1)) == 0) { return NULL; } - else { - bool use_a = true; - bool use_b = true; - float lambda; - PyObject *ret = PyTuple_New(2); + bool use_a = true; + bool use_b = true; + float lambda; - switch (isect_line_sphere_v2(line_a, line_b, sphere_co, sphere_radius, isect_a, isect_b)) { - case 1: - if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a, line_b)) >= 0.0f) && - (lambda <= 1.0f)))) { - use_a = false; - } - use_b = false; - break; - case 2: - if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a, line_b)) >= 0.0f) && - (lambda <= 1.0f)))) { - use_a = false; - } - if (!(!clip || (((lambda = line_point_factor_v2(isect_b, line_a, line_b)) >= 0.0f) && - (lambda <= 1.0f)))) { - use_b = false; - } - break; - default: + PyObject *ret = PyTuple_New(2); + + switch (isect_line_sphere_v2(line_a, line_b, sphere_co, sphere_radius, isect_a, isect_b)) { + case 1: + if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a, line_b)) >= 0.0f) && + (lambda <= 1.0f)))) { + use_a = false; + } + use_b = false; + break; + case 2: + if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a, line_b)) >= 0.0f) && + (lambda <= 1.0f)))) { use_a = false; + } + if (!(!clip || (((lambda = line_point_factor_v2(isect_b, line_a, line_b)) >= 0.0f) && + (lambda <= 1.0f)))) { use_b = false; - break; - } + } + break; + default: + use_a = false; + use_b = false; + break; + } - PyTuple_SET_ITEMS(ret, - use_a ? Vector_CreatePyObject(isect_a, 2, NULL) : Py_INCREF_RET(Py_None), - use_b ? Vector_CreatePyObject(isect_b, 2, NULL) : Py_INCREF_RET(Py_None)); + PyTuple_SET_ITEMS(ret, + use_a ? Vector_CreatePyObject(isect_a, 2, NULL) : Py_INCREF_RET(Py_None), + use_b ? Vector_CreatePyObject(isect_b, 2, NULL) : Py_INCREF_RET(Py_None)); - return ret; - } + return ret; } PyDoc_STRVAR( @@ -849,9 +844,8 @@ static PyObject *M_Geometry_intersect_point_tri(PyObject *UNUSED(self), PyObject if (isect_point_tri_v3(pt, UNPACK3(tri), vi)) { return Vector_CreatePyObject(vi, 3, NULL); } - else { - Py_RETURN_NONE; - } + + Py_RETURN_NONE; } PyDoc_STRVAR(M_Geometry_closest_point_on_tri_doc, @@ -1094,88 +1088,84 @@ static PyObject *M_Geometry_points_in_planes(PyObject *UNUSED(self), PyObject *a (float **)&planes, 4, py_planes, "points_in_planes")) == -1) { return NULL; } - else { - /* note, this could be refactored into plain C easy - py bits are noted */ - const float eps = 0.0001f; - const uint len = (uint)planes_len; - uint i, j, k, l; - - float n1n2[3], n2n3[3], n3n1[3]; - float potentialVertex[3]; - char *planes_used = PyMem_Malloc(sizeof(char) * len); - - /* python */ - PyObject *py_verts = PyList_New(0); - PyObject *py_plane_index = PyList_New(0); - - memset(planes_used, 0, sizeof(char) * len); - - for (i = 0; i < len; i++) { - const float *N1 = planes[i]; - for (j = i + 1; j < len; j++) { - const float *N2 = planes[j]; - cross_v3_v3v3(n1n2, N1, N2); - if (len_squared_v3(n1n2) > eps) { - for (k = j + 1; k < len; k++) { - const float *N3 = planes[k]; - cross_v3_v3v3(n2n3, N2, N3); - if (len_squared_v3(n2n3) > eps) { - cross_v3_v3v3(n3n1, N3, N1); - if (len_squared_v3(n3n1) > eps) { - const float quotient = dot_v3v3(N1, n2n3); - if (fabsf(quotient) > eps) { - /** - * <pre> - * potentialVertex = ( - * (n2n3 * N1[3] + n3n1 * N2[3] + n1n2 * N3[3]) * - * (-1.0 / quotient)); - * </pre> - */ - const float quotient_ninv = -1.0f / quotient; - potentialVertex[0] = ((n2n3[0] * N1[3]) + (n3n1[0] * N2[3]) + - (n1n2[0] * N3[3])) * - quotient_ninv; - potentialVertex[1] = ((n2n3[1] * N1[3]) + (n3n1[1] * N2[3]) + - (n1n2[1] * N3[3])) * - quotient_ninv; - potentialVertex[2] = ((n2n3[2] * N1[3]) + (n3n1[2] * N2[3]) + - (n1n2[2] * N3[3])) * - quotient_ninv; - for (l = 0; l < len; l++) { - const float *NP = planes[l]; - if ((dot_v3v3(NP, potentialVertex) + NP[3]) > 0.000001f) { - break; - } - } - if (l == len) { /* ok */ - /* python */ - PyList_APPEND(py_verts, Vector_CreatePyObject(potentialVertex, 3, NULL)); - planes_used[i] = planes_used[j] = planes_used[k] = true; + /* note, this could be refactored into plain C easy - py bits are noted */ + const float eps = 0.0001f; + const uint len = (uint)planes_len; + uint i, j, k, l; + + float n1n2[3], n2n3[3], n3n1[3]; + float potentialVertex[3]; + char *planes_used = PyMem_Malloc(sizeof(char) * len); + + /* python */ + PyObject *py_verts = PyList_New(0); + PyObject *py_plane_index = PyList_New(0); + + memset(planes_used, 0, sizeof(char) * len); + + for (i = 0; i < len; i++) { + const float *N1 = planes[i]; + for (j = i + 1; j < len; j++) { + const float *N2 = planes[j]; + cross_v3_v3v3(n1n2, N1, N2); + if (len_squared_v3(n1n2) > eps) { + for (k = j + 1; k < len; k++) { + const float *N3 = planes[k]; + cross_v3_v3v3(n2n3, N2, N3); + if (len_squared_v3(n2n3) > eps) { + cross_v3_v3v3(n3n1, N3, N1); + if (len_squared_v3(n3n1) > eps) { + const float quotient = dot_v3v3(N1, n2n3); + if (fabsf(quotient) > eps) { + /** + * <pre> + * potentialVertex = ( + * (n2n3 * N1[3] + n3n1 * N2[3] + n1n2 * N3[3]) * + * (-1.0 / quotient)); + * </pre> + */ + const float quotient_ninv = -1.0f / quotient; + potentialVertex[0] = ((n2n3[0] * N1[3]) + (n3n1[0] * N2[3]) + (n1n2[0] * N3[3])) * + quotient_ninv; + potentialVertex[1] = ((n2n3[1] * N1[3]) + (n3n1[1] * N2[3]) + (n1n2[1] * N3[3])) * + quotient_ninv; + potentialVertex[2] = ((n2n3[2] * N1[3]) + (n3n1[2] * N2[3]) + (n1n2[2] * N3[3])) * + quotient_ninv; + for (l = 0; l < len; l++) { + const float *NP = planes[l]; + if ((dot_v3v3(NP, potentialVertex) + NP[3]) > 0.000001f) { + break; } } + + if (l == len) { /* ok */ + /* python */ + PyList_APPEND(py_verts, Vector_CreatePyObject(potentialVertex, 3, NULL)); + planes_used[i] = planes_used[j] = planes_used[k] = true; + } } } } } } } + } - PyMem_Free(planes); + PyMem_Free(planes); - /* now make a list of used planes */ - for (i = 0; i < len; i++) { - if (planes_used[i]) { - PyList_APPEND(py_plane_index, PyLong_FromLong(i)); - } + /* now make a list of used planes */ + for (i = 0; i < len; i++) { + if (planes_used[i]) { + PyList_APPEND(py_plane_index, PyLong_FromLong(i)); } - PyMem_Free(planes_used); + } + PyMem_Free(planes_used); - { - PyObject *ret = PyTuple_New(2); - PyTuple_SET_ITEMS(ret, py_verts, py_plane_index); - return ret; - } + { + PyObject *ret = PyTuple_New(2); + PyTuple_SET_ITEMS(ret, py_verts, py_plane_index); + return ret; } } @@ -1321,7 +1311,7 @@ static PyObject *M_Geometry_tessellate_polygon(PyObject *UNUSED(self), PyObject BKE_displist_free(&dispbase); /* possible some dl was allocated */ return NULL; } - else if (totpoints) { + if (totpoints) { /* now make the list to return */ BKE_displist_fill(&dispbase, &dispbase, is_2d ? ((const float[3]){0, 0, -1}) : NULL, false); diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 7b28728cfe7..188bdab316c 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -491,7 +491,7 @@ static float clipx_rctf(rctf *rf, float x1, float x2) rf->xmin = rf->xmax; return 0.0; } - else if (size != 0.0f) { + if (size != 0.0f) { return BLI_rctf_size_x(rf) / size; } return 1.0; @@ -514,7 +514,7 @@ static float clipy_rctf(rctf *rf, float y1, float y2) rf->ymin = rf->ymax; return 0.0; } - else if (size != 0.0f) { + if (size != 0.0f) { return BLI_rctf_size_y(rf) / size; } return 1.0; @@ -888,7 +888,7 @@ static void ewa_read_pixel_cb(void *userdata, int x, int y, float result[4]) static void ewa_eval(TexResult *texr, ImBuf *ibuf, float fx, float fy, afdata_t *AFD) { ReadEWAData data; - float uv[2] = {fx, fy}; + const float uv[2] = {fx, fy}; data.ibuf = ibuf; data.AFD = AFD; BLI_ewa_filter(ibuf->x, diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c index b30821a1b73..f12b425ee8b 100644 --- a/source/blender/render/intern/source/multires_bake.c +++ b/source/blender/render/intern/source/multires_bake.c @@ -157,7 +157,7 @@ static void init_bake_rast(MBakeRast *bake_rast, static void flush_pixel(const MResolvePixelData *data, const int x, const int y) { - float st[2] = {(x + 0.5f) / data->w, (y + 0.5f) / data->h}; + const float st[2] = {(x + 0.5f) / data->w, (y + 0.5f) / data->h}; const float *st0, *st1, *st2; const float *tang0, *tang1, *tang2; float no0[3], no1[3], no2[3]; diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index ade80898131..0fc389ecd93 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -281,9 +281,8 @@ RenderLayer *RE_GetRenderLayer(RenderResult *rr, const char *name) if (rr == NULL) { return NULL; } - else { - return BLI_findstring(&rr->layers, name, offsetof(RenderLayer, name)); - } + + return BLI_findstring(&rr->layers, name, offsetof(RenderLayer, name)); } bool RE_HasSingleLayer(Render *re) @@ -1655,9 +1654,8 @@ static bool check_valid_compositing_camera(Scene *scene, Object *camera_override return true; } - else { - return (camera_override != NULL || scene->camera != NULL); - } + + return (camera_override != NULL || scene->camera != NULL); } static bool check_valid_camera_multiview(Scene *scene, Object *camera, ReportList *reports) @@ -1755,7 +1753,7 @@ static bool node_tree_has_composite_output(bNodeTree *ntree) if (ELEM(node->type, CMP_NODE_COMPOSITE, CMP_NODE_OUTPUT_FILE)) { return true; } - else if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) { + if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) { if (node->id) { if (node_tree_has_composite_output((bNodeTree *)node->id)) { return true; @@ -1879,14 +1877,14 @@ const char *RE_GetActiveRenderView(Render *re) } /* evaluating scene options for general Blender render */ -static int render_initialize_from_main(Render *re, - const RenderData *rd, - Main *bmain, - Scene *scene, - ViewLayer *single_layer, - Object *camera_override, - int anim, - int anim_init) +static int render_init_from_main(Render *re, + const RenderData *rd, + Main *bmain, + Scene *scene, + ViewLayer *single_layer, + Object *camera_override, + int anim, + int anim_init) { int winx, winy; rcti disprect; @@ -2004,8 +2002,7 @@ void RE_RenderFrame(Render *re, scene->r.cfra = frame; - if (render_initialize_from_main( - re, &scene->r, bmain, scene, single_layer, camera_override, 0, 0)) { + if (render_init_from_main(re, &scene->r, bmain, scene, single_layer, camera_override, 0, 0)) { const RenderData rd = scene->r; MEM_reset_peak_memory(); @@ -2058,7 +2055,7 @@ void RE_RenderFrame(Render *re, void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, int render) { re->result_ok = 0; - if (render_initialize_from_main(re, &scene->r, bmain, scene, NULL, NULL, 0, 0)) { + if (render_init_from_main(re, &scene->r, bmain, scene, NULL, NULL, 0, 0)) { if (render) { do_render_3d(re); } @@ -2422,7 +2419,7 @@ void RE_RenderAnim(Render *re, (rd.im_format.views_format == R_IMF_VIEWS_INDIVIDUAL)); /* do not fully call for each frame, it initializes & pops output window */ - if (!render_initialize_from_main(re, &rd, bmain, scene, single_layer, camera_override, 0, 1)) { + if (!render_init_from_main(re, &rd, bmain, scene, single_layer, camera_override, 0, 1)) { return; } @@ -2501,15 +2498,14 @@ void RE_RenderAnim(Render *re, render_update_depsgraph(re); /* only border now, todo: camera lens. (ton) */ - render_initialize_from_main(re, &rd, bmain, scene, single_layer, camera_override, 1, 0); + render_init_from_main(re, &rd, bmain, scene, single_layer, camera_override, 1, 0); if (nfra != scene->r.cfra) { /* Skip this frame, but could update for physics and particles system. */ continue; } - else { - nfra += tfra; - } + + nfra += tfra; /* Touch/NoOverwrite options are only valid for image's */ if (is_movie == false) { @@ -2864,7 +2860,7 @@ RenderPass *RE_pass_find_by_name(volatile RenderLayer *rl, const char *name, con if (viewname == NULL || viewname[0] == '\0') { break; } - else if (STREQ(rp->view, viewname)) { + if (STREQ(rp->view, viewname)) { break; } } diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index 8daad33b477..db3ae8d8b5e 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -557,7 +557,7 @@ static float density_falloff(PointDensityRangeData *pdr, int index, float square } if (pdr->density_curve && dist != 0.0f) { - BKE_curvemapping_initialize(pdr->density_curve); + BKE_curvemapping_init(pdr->density_curve); density = BKE_curvemapping_evaluateF(pdr->density_curve, 0, density / dist) * dist; } @@ -868,7 +868,7 @@ void RE_point_density_minmax(struct Depsgraph *depsgraph, particle_system_minmax(depsgraph, scene, object, psys, pd->radius, r_min, r_max); } else { - float radius[3] = {pd->radius, pd->radius, pd->radius}; + const float radius[3] = {pd->radius, pd->radius, pd->radius}; BoundBox *bb = BKE_object_boundbox_get(object); if (bb != NULL) { diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index 4b74bfb3e5c..6299a86e25f 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -709,7 +709,7 @@ static int order_render_passes(const void *a, const void *b) if (passtype_a > passtype_b) { return 1; } - else if (passtype_a < passtype_b) { + if (passtype_a < passtype_b) { return 0; } } @@ -728,7 +728,7 @@ static int order_render_passes(const void *a, const void *b) if (STREQ(rpa->view, STEREO_LEFT_NAME)) { return 0; } - else if (STREQ(rpb->view, STEREO_LEFT_NAME)) { + if (STREQ(rpb->view, STEREO_LEFT_NAME)) { return 1; } @@ -736,7 +736,7 @@ static int order_render_passes(const void *a, const void *b) if (STREQ(rpa->view, STEREO_RIGHT_NAME)) { return 0; } - else if (STREQ(rpb->view, STEREO_RIGHT_NAME)) { + if (STREQ(rpb->view, STEREO_RIGHT_NAME)) { return 1; } @@ -930,9 +930,8 @@ bool RE_WriteRenderResult(ReportList *reports, if (!STREQ(view, viewname)) { continue; } - else { - viewname = ""; - } + + viewname = ""; } /* Skip compositing if only a single other layer is requested. */ @@ -993,9 +992,8 @@ bool RE_WriteRenderResult(ReportList *reports, if (!STREQ(view, viewname)) { continue; } - else { - viewname = ""; - } + + viewname = ""; } /* We only store RGBA passes as half float, for diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index b37eeed3681..e5c62dbd784 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -1381,20 +1381,19 @@ static int multitex_nodes_intern(Tex *tex, return rgbnor; } - else { - return multitex(tex, - texvec, - dxt, - dyt, - osatex, - texres, - thread, - which_output, - pool, - skip_load_image, - texnode_preview, - use_nodes); - } + + return multitex(tex, + texvec, + dxt, + dyt, + osatex, + texres, + thread, + which_output, + pool, + skip_load_image, + texnode_preview, + use_nodes); } /* this is called from the shader and texture nodes diff --git a/source/blender/simulation/CMakeLists.txt b/source/blender/simulation/CMakeLists.txt index 243b056db74..cbc6ee65303 100644 --- a/source/blender/simulation/CMakeLists.txt +++ b/source/blender/simulation/CMakeLists.txt @@ -43,7 +43,9 @@ set(SRC intern/implicit_eigen.cpp intern/particle_allocator.cc intern/particle_function.cc + intern/particle_mesh_emitter.cc intern/simulation_collect_influences.cc + intern/simulation_solver_influences.cc intern/simulation_solver.cc intern/simulation_update.cc @@ -52,7 +54,9 @@ set(SRC intern/implicit.h intern/particle_allocator.hh intern/particle_function.hh + intern/particle_mesh_emitter.hh intern/simulation_collect_influences.hh + intern/simulation_solver_influences.hh intern/simulation_solver.hh intern/time_interval.hh diff --git a/source/blender/simulation/SIM_simulation_update.hh b/source/blender/simulation/SIM_simulation_update.hh index 2c64fdec02e..7c2726f038e 100644 --- a/source/blender/simulation/SIM_simulation_update.hh +++ b/source/blender/simulation/SIM_simulation_update.hh @@ -26,4 +26,6 @@ void update_simulation_in_depsgraph(Depsgraph *depsgraph, Scene *scene_cow, Simulation *simulation_cow); -} +bool update_simulation_dependencies(Simulation *simulation); + +} // namespace blender::sim diff --git a/source/blender/simulation/intern/hair_volume.cpp b/source/blender/simulation/intern/hair_volume.cpp index c80ae69ce73..c24b7154d13 100644 --- a/source/blender/simulation/intern/hair_volume.cpp +++ b/source/blender/simulation/intern/hair_volume.cpp @@ -710,9 +710,8 @@ BLI_INLINE float hair_volume_density_divergence(float density, if (density > density_threshold && density > target_density) { return strength * logf(target_density / density); } - else { - return 0.0f; - } + + return 0.0f; } bool SIM_hair_volume_solve_divergence(HairGrid *grid, @@ -1030,14 +1029,13 @@ bool SIM_hair_volume_solve_divergence(HairGrid *grid, return true; } - else { - /* Clear result in case of error */ - for (i = 0, vert = grid->verts; i < num_cells; i++, vert++) { - zero_v3(vert->velocity_smooth); - } - return false; + /* Clear result in case of error */ + for (i = 0, vert = grid->verts; i < num_cells; i++, vert++) { + zero_v3(vert->velocity_smooth); } + + return false; } #if 0 /* XXX weighting is incorrect, disabled for now */ diff --git a/source/blender/simulation/intern/implicit_blender.c b/source/blender/simulation/intern/implicit_blender.c index 856572aa3f5..ccc26233e3a 100644 --- a/source/blender/simulation/intern/implicit_blender.c +++ b/source/blender/simulation/intern/implicit_blender.c @@ -98,7 +98,7 @@ DO_INLINE void mul_fvector_S(float to[3], const float from[3], float scalar) } /* simple v^T * v product ("outer product") */ /* STATUS: HAS TO BE verified (*should* work) */ -DO_INLINE void mul_fvectorT_fvector(float to[3][3], float vectorA[3], float vectorB[3]) +DO_INLINE void mul_fvectorT_fvector(float to[3][3], const float vectorA[3], const float vectorB[3]) { mul_fvector_S(to[0], vectorB, vectorA[0]); mul_fvector_S(to[1], vectorB, vectorA[1]); @@ -156,7 +156,7 @@ DO_INLINE void cp_lfvector(float (*to)[3], float (*from)[3], unsigned int verts) memcpy(to, from, verts * sizeof(lfVector)); } /* init long vector with float[3] */ -DO_INLINE void init_lfvector(float (*fLongVector)[3], float vector[3], unsigned int verts) +DO_INLINE void init_lfvector(float (*fLongVector)[3], const float vector[3], unsigned int verts) { unsigned int i = 0; for (i = 0; i < verts; i++) { @@ -360,7 +360,7 @@ static void print_bfmatrix(fmatrix3x3 *m) # endif /* copy 3x3 matrix */ -DO_INLINE void cp_fmatrix(float to[3][3], float from[3][3]) +DO_INLINE void cp_fmatrix(float to[3][3], const float from[3][3]) { // memcpy(to, from, sizeof (float) * 9); copy_v3_v3(to[0], from[0]); @@ -429,7 +429,7 @@ DO_INLINE void mul_fmatrix_S(float matrix[3][3], float scalar) /* a vector multiplied by a 3x3 matrix */ /* STATUS: verified */ -DO_INLINE void mul_fvector_fmatrix(float *to, const float *from, float matrix[3][3]) +DO_INLINE void mul_fvector_fmatrix(float *to, const float *from, const float matrix[3][3]) { to[0] = matrix[0][0] * from[0] + matrix[1][0] * from[1] + matrix[2][0] * from[2]; to[1] = matrix[0][1] * from[0] + matrix[1][1] * from[1] + matrix[2][1] * from[2]; @@ -438,14 +438,16 @@ DO_INLINE void mul_fvector_fmatrix(float *to, const float *from, float matrix[3] /* 3x3 matrix multiplied by a vector */ /* STATUS: verified */ -DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][3], float from[3]) +DO_INLINE void mul_fmatrix_fvector(float *to, const float matrix[3][3], const float from[3]) { to[0] = dot_v3v3(matrix[0], from); to[1] = dot_v3v3(matrix[1], from); to[2] = dot_v3v3(matrix[2], from); } /* 3x3 matrix addition with 3x3 matrix */ -DO_INLINE void add_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) +DO_INLINE void add_fmatrix_fmatrix(float to[3][3], + const float matrixA[3][3], + const float matrixB[3][3]) { add_v3_v3v3(to[0], matrixA[0], matrixB[0]); add_v3_v3v3(to[1], matrixA[1], matrixB[1]); @@ -453,14 +455,16 @@ DO_INLINE void add_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float ma } /* A -= B*x + C*y (3x3 matrix sub-addition with 3x3 matrix) */ DO_INLINE void subadd_fmatrixS_fmatrixS( - float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS) + float to[3][3], const float matrixA[3][3], float aS, const float matrixB[3][3], float bS) { VECSUBADDSS(to[0], matrixA[0], aS, matrixB[0], bS); VECSUBADDSS(to[1], matrixA[1], aS, matrixB[1], bS); VECSUBADDSS(to[2], matrixA[2], aS, matrixB[2], bS); } /* A = B - C (3x3 matrix subtraction with 3x3 matrix) */ -DO_INLINE void sub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) +DO_INLINE void sub_fmatrix_fmatrix(float to[3][3], + const float matrixA[3][3], + const float matrixB[3][3]) { sub_v3_v3v3(to[0], matrixA[0], matrixB[0]); sub_v3_v3v3(to[1], matrixA[1], matrixB[1]); @@ -471,14 +475,14 @@ DO_INLINE void sub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float ma ///////////////////////////////////////////////////////////////// /* 3x3 matrix multiplied+added by a vector */ /* STATUS: verified */ -DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][3], float from[3]) +DO_INLINE void muladd_fmatrix_fvector(float to[3], const float matrix[3][3], const float from[3]) { to[0] += dot_v3v3(matrix[0], from); to[1] += dot_v3v3(matrix[1], from); to[2] += dot_v3v3(matrix[2], from); } -DO_INLINE void muladd_fmatrixT_fvector(float to[3], float matrix[3][3], const float from[3]) +DO_INLINE void muladd_fmatrixT_fvector(float to[3], const float matrix[3][3], const float from[3]) { to[0] += matrix[0][0] * from[0] + matrix[1][0] * from[1] + matrix[2][0] * from[2]; to[1] += matrix[0][1] * from[0] + matrix[1][1] * from[1] + matrix[2][1] * from[2]; @@ -492,7 +496,7 @@ BLI_INLINE void outerproduct(float r[3][3], const float a[3], const float b[3]) mul_v3_v3fl(r[2], a, b[2]); } -BLI_INLINE void cross_m3_v3m3(float r[3][3], const float v[3], float m[3][3]) +BLI_INLINE void cross_m3_v3m3(float r[3][3], const float v[3], const float m[3][3]) { cross_v3_v3v3(r[0], v, m[0]); cross_v3_v3v3(r[1], v, m[1]); @@ -512,7 +516,7 @@ BLI_INLINE void cross_v3_identity(float r[3][3], const float v[3]) r[2][2] = 0.0f; } -BLI_INLINE void madd_m3_m3fl(float r[3][3], float m[3][3], float f) +BLI_INLINE void madd_m3_m3fl(float r[3][3], const float m[3][3], float f) { r[0][0] += m[0][0] * f; r[0][1] += m[0][1] * f; @@ -744,7 +748,10 @@ BLI_INLINE void root_to_world_v3(Implicit_Data *data, int index, float r[3], con mul_v3_m3v3(r, data->tfm[index].m, v); } -BLI_INLINE void world_to_root_m3(Implicit_Data *data, int index, float r[3][3], float m[3][3]) +BLI_INLINE void world_to_root_m3(Implicit_Data *data, + int index, + float r[3][3], + const float m[3][3]) { float trot[3][3]; copy_m3_m3(trot, data->tfm[index].m); @@ -752,7 +759,10 @@ BLI_INLINE void world_to_root_m3(Implicit_Data *data, int index, float r[3][3], mul_m3_m3m3(r, trot, m); } -BLI_INLINE void root_to_world_m3(Implicit_Data *data, int index, float r[3][3], float m[3][3]) +BLI_INLINE void root_to_world_m3(Implicit_Data *data, + int index, + float r[3][3], + const float m[3][3]) { mul_m3_m3m3(r, data->tfm[index].m, m); } @@ -1469,7 +1479,7 @@ void SIM_mass_spring_force_face_wind( Implicit_Data *data, int v1, int v2, int v3, const float (*winvec)[3]) { const float effector_scale = 0.02f; - int vs[3] = {v1, v2, v3}; + const int vs[3] = {v1, v2, v3}; float win[3], nor[3], area; float factor, base_force; float force[3]; @@ -1509,7 +1519,7 @@ void SIM_mass_spring_force_face_extern( Implicit_Data *data, int v1, int v2, int v3, const float (*forcevec)[3]) { const float effector_scale = 0.02f; - int vs[3] = {v1, v2, v3}; + const int vs[3] = {v1, v2, v3}; float nor[3], area; float factor, base_force[3]; float force[3][3]; @@ -1711,9 +1721,8 @@ BLI_INLINE float fbstar(float length, float L, float kb, float cb) if (tempfb_fl < fbstar_fl) { return fbstar_fl; } - else { - return tempfb_fl; - } + + return tempfb_fl; } // function to calculae bending spring force (taken from Choi & Co) @@ -1725,9 +1734,8 @@ BLI_INLINE float fbstar_jacobi(float length, float L, float kb, float cb) if (tempfb_fl < fbstar_fl) { return -cb; } - else { - return -kb * fbderiv(length, L); - } + + return -kb * fbderiv(length, L); } /* calculate elonglation */ @@ -1763,8 +1771,12 @@ BLI_INLINE bool spring_length(Implicit_Data *data, return true; } -BLI_INLINE void apply_spring( - Implicit_Data *data, int i, int j, const float f[3], float dfdx[3][3], float dfdv[3][3]) +BLI_INLINE void apply_spring(Implicit_Data *data, + int i, + int j, + const float f[3], + const float dfdx[3][3], + const float dfdv[3][3]) { int block_ij = SIM_mass_spring_add_block(data, i, j); @@ -1864,9 +1876,8 @@ bool SIM_mass_spring_force_spring_bending( return true; } - else { - return false; - } + + return false; } BLI_INLINE void poly_avg(lfVector *data, const int *inds, int len, float r_avg[3]) @@ -1902,7 +1913,7 @@ BLI_INLINE void edge_norm(lfVector *data, int i, int j, float r_dir[3]) normalize_v3(r_dir); } -BLI_INLINE float bend_angle(float dir_a[3], float dir_b[3], float dir_e[3]) +BLI_INLINE float bend_angle(const float dir_a[3], const float dir_b[3], const float dir_e[3]) { float cos, sin; float tmp[3]; @@ -2352,9 +2363,8 @@ bool SIM_mass_spring_force_spring_goal(Implicit_Data *data, return true; } - else { - return false; - } + + return false; } #endif /* IMPLICIT_SOLVER_BLENDER */ diff --git a/source/blender/simulation/intern/particle_allocator.cc b/source/blender/simulation/intern/particle_allocator.cc index eb1e998e63a..e47a6354d81 100644 --- a/source/blender/simulation/intern/particle_allocator.cc +++ b/source/blender/simulation/intern/particle_allocator.cc @@ -16,6 +16,8 @@ #include "particle_allocator.hh" +#include "BLI_rand.hh" + namespace blender::sim { AttributesAllocator::~AttributesAllocator() @@ -67,8 +69,15 @@ fn::MutableAttributesRef ParticleAllocator::allocate(int size) ids[pindex] = start_id + pindex; } } + else if (name == "Hash") { + MutableSpan<int> hashes = attributes.get<int>("Hash"); + RandomNumberGenerator rng(hash_seed_ ^ (uint32_t)next_id_); + for (int pindex : IndexRange(size)) { + hashes[pindex] = (int)rng.get_uint32(); + } + } else { - type.fill_uninitialized(info.default_of(i), attributes.get(i).buffer(), size); + type.fill_uninitialized(info.default_of(i), attributes.get(i).data(), size); } } return attributes; diff --git a/source/blender/simulation/intern/particle_allocator.hh b/source/blender/simulation/intern/particle_allocator.hh index ae23c8c8238..c0bbdb845d9 100644 --- a/source/blender/simulation/intern/particle_allocator.hh +++ b/source/blender/simulation/intern/particle_allocator.hh @@ -69,10 +69,11 @@ class ParticleAllocator : NonCopyable, NonMovable { private: AttributesAllocator attributes_allocator_; std::atomic<int> next_id_; + uint32_t hash_seed_; public: - ParticleAllocator(const fn::AttributesInfo &attributes_info, int next_id) - : attributes_allocator_(attributes_info), next_id_(next_id) + ParticleAllocator(const fn::AttributesInfo &attributes_info, int next_id, uint32_t hash_seed) + : attributes_allocator_(attributes_info), next_id_(next_id), hash_seed_(hash_seed) { } diff --git a/source/blender/simulation/intern/particle_function.cc b/source/blender/simulation/intern/particle_function.cc index 935ef7983d9..69977eb2054 100644 --- a/source/blender/simulation/intern/particle_function.cc +++ b/source/blender/simulation/intern/particle_function.cc @@ -49,19 +49,17 @@ ParticleFunction::ParticleFunction(const fn::MultiFunction *global_fn, } } -ParticleFunctionEvaluator::ParticleFunctionEvaluator( - const ParticleFunction &particle_fn, - const SimulationSolveContext &solve_context, - const ParticleChunkContext &particle_chunk_context) +ParticleFunctionEvaluator::ParticleFunctionEvaluator(const ParticleFunction &particle_fn, + const SimulationSolveContext &solve_context, + const ParticleChunkContext &particles) : particle_fn_(particle_fn), solve_context_(solve_context), - particle_chunk_context_(particle_chunk_context), - mask_(particle_chunk_context_.index_mask()), + particles_(particles), + mask_(particles_.index_mask), outputs_(particle_fn_.output_types_.size(), nullptr) { - global_context_.add_global_context("PersistentDataHandleMap", &solve_context_.handle_map()); - per_particle_context_.add_global_context("PersistentDataHandleMap", - &solve_context_.handle_map()); + global_context_.add_global_context("PersistentDataHandleMap", &solve_context_.handle_map); + per_particle_context_.add_global_context("PersistentDataHandleMap", &solve_context_.handle_map); } ParticleFunctionEvaluator::~ParticleFunctionEvaluator() @@ -92,8 +90,10 @@ void ParticleFunctionEvaluator::compute() fn::GVSpan ParticleFunctionEvaluator::get(int output_index, StringRef expected_name) const { #ifdef DEBUG - StringRef real_name = particle_fn_.output_names_[output_index]; - BLI_assert(expected_name == real_name); + if (expected_name != "") { + StringRef real_name = particle_fn_.output_names_[output_index]; + BLI_assert(expected_name == real_name); + } BLI_assert(is_computed_); #endif UNUSED_VARS_NDEBUG(expected_name); @@ -102,9 +102,8 @@ fn::GVSpan ParticleFunctionEvaluator::get(int output_index, StringRef expected_n if (particle_fn_.output_is_global_[output_index]) { return fn::GVSpan::FromSingleWithMaxSize(type, buffer); } - else { - return fn::GVSpan(fn::GSpan(type, buffer, mask_.min_array_size())); - } + + return fn::GVSpan(fn::GSpan(type, buffer, mask_.min_array_size())); } void ParticleFunctionEvaluator::compute_globals() @@ -116,8 +115,9 @@ void ParticleFunctionEvaluator::compute_globals() fn::MFParamsBuilder params(*particle_fn_.global_fn_, mask_.min_array_size()); /* Add input parameters. */ + ParticleFunctionInputContext input_context{solve_context_, particles_}; for (const ParticleFunctionInput *input : particle_fn_.global_inputs_) { - input->add_input(particle_chunk_context_.attributes(), params, resources_); + input->add_input(input_context, params, resources_); } /* Add output parameters. */ @@ -143,8 +143,9 @@ void ParticleFunctionEvaluator::compute_per_particle() fn::MFParamsBuilder params(*particle_fn_.per_particle_fn_, mask_.min_array_size()); /* Add input parameters. */ + ParticleFunctionInputContext input_context{solve_context_, particles_}; for (const ParticleFunctionInput *input : particle_fn_.per_particle_inputs_) { - input->add_input(particle_chunk_context_.attributes(), params, resources_); + input->add_input(input_context, params, resources_); } /* Add output parameters. */ diff --git a/source/blender/simulation/intern/particle_function.hh b/source/blender/simulation/intern/particle_function.hh index cc8ccbd8243..ead4e6f3c31 100644 --- a/source/blender/simulation/intern/particle_function.hh +++ b/source/blender/simulation/intern/particle_function.hh @@ -25,10 +25,15 @@ namespace blender::sim { +struct ParticleFunctionInputContext { + const SimulationSolveContext &solve_context; + const ParticleChunkContext &particles; +}; + class ParticleFunctionInput { public: virtual ~ParticleFunctionInput() = default; - virtual void add_input(fn::AttributesRef attributes, + virtual void add_input(ParticleFunctionInputContext &context, fn::MFParamsBuilder ¶ms, ResourceCollector &resources) const = 0; }; @@ -60,7 +65,7 @@ class ParticleFunctionEvaluator { ResourceCollector resources_; const ParticleFunction &particle_fn_; const SimulationSolveContext &solve_context_; - const ParticleChunkContext &particle_chunk_context_; + const ParticleChunkContext &particles_; IndexMask mask_; fn::MFContextBuilder global_context_; fn::MFContextBuilder per_particle_context_; @@ -70,13 +75,13 @@ class ParticleFunctionEvaluator { public: ParticleFunctionEvaluator(const ParticleFunction &particle_fn, const SimulationSolveContext &solve_context, - const ParticleChunkContext &particle_chunk_context); + const ParticleChunkContext &particles); ~ParticleFunctionEvaluator(); void compute(); - fn::GVSpan get(int output_index, StringRef expected_name) const; + fn::GVSpan get(int output_index, StringRef expected_name = "") const; - template<typename T> fn::VSpan<T> get(int output_index, StringRef expected_name) const + template<typename T> fn::VSpan<T> get(int output_index, StringRef expected_name = "") const { return this->get(output_index, expected_name).typed<T>(); } diff --git a/source/blender/simulation/intern/particle_mesh_emitter.cc b/source/blender/simulation/intern/particle_mesh_emitter.cc new file mode 100644 index 00000000000..26541d550eb --- /dev/null +++ b/source/blender/simulation/intern/particle_mesh_emitter.cc @@ -0,0 +1,362 @@ +/* + * 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. + */ + +#include "particle_mesh_emitter.hh" + +#include "BLI_float4x4.hh" +#include "BLI_rand.hh" +#include "BLI_vector_adaptor.hh" + +#include "BKE_mesh_runtime.h" + +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" + +namespace blender::sim { + +ParticleMeshEmitter::~ParticleMeshEmitter() = default; + +struct EmitterSettings { + Object *object; + float rate; +}; + +static BLI_NOINLINE void compute_birth_times(float rate, + TimeInterval emit_interval, + ParticleMeshEmitterSimulationState &state, + Vector<float> &r_birth_times) +{ + const float time_between_particles = 1.0f / rate; + int counter = 0; + while (true) { + counter++; + const float time_offset = counter * time_between_particles; + const float birth_time = state.last_birth_time + time_offset; + if (birth_time > emit_interval.stop()) { + break; + } + if (birth_time <= emit_interval.start()) { + continue; + } + r_birth_times.append(birth_time); + } +} + +static BLI_NOINLINE Span<MLoopTri> get_mesh_triangles(Mesh &mesh) +{ + const MLoopTri *triangles = BKE_mesh_runtime_looptri_ensure(&mesh); + int amount = BKE_mesh_runtime_looptri_len(&mesh); + return Span(triangles, amount); +} + +static BLI_NOINLINE void compute_triangle_areas(Mesh &mesh, + Span<MLoopTri> triangles, + MutableSpan<float> r_areas) +{ + assert_same_size(triangles, r_areas); + + for (int i : triangles.index_range()) { + const MLoopTri &tri = triangles[i]; + + const float3 v1 = mesh.mvert[mesh.mloop[tri.tri[0]].v].co; + const float3 v2 = mesh.mvert[mesh.mloop[tri.tri[1]].v].co; + const float3 v3 = mesh.mvert[mesh.mloop[tri.tri[2]].v].co; + + const float area = area_tri_v3(v1, v2, v3); + r_areas[i] = area; + } +} + +static BLI_NOINLINE void compute_triangle_weights(Mesh &mesh, + Span<MLoopTri> triangles, + MutableSpan<float> r_weights) +{ + assert_same_size(triangles, r_weights); + compute_triangle_areas(mesh, triangles, r_weights); +} + +static BLI_NOINLINE void compute_cumulative_distribution(Span<float> weights, + MutableSpan<float> r_cumulative_weights) +{ + BLI_assert(weights.size() + 1 == r_cumulative_weights.size()); + + r_cumulative_weights[0] = 0; + for (int i : weights.index_range()) { + r_cumulative_weights[i + 1] = r_cumulative_weights[i] + weights[i]; + } +} + +static void sample_cumulative_distribution_recursive(RandomNumberGenerator &rng, + int amount, + int start, + int one_after_end, + Span<float> cumulative_weights, + VectorAdaptor<int> &r_sampled_indices) +{ + BLI_assert(start <= one_after_end); + const int size = one_after_end - start; + if (size == 0) { + BLI_assert(amount == 0); + } + else if (amount == 0) { + return; + } + else if (size == 1) { + r_sampled_indices.append_n_times(start, amount); + } + else { + const int middle = start + size / 2; + const float left_weight = cumulative_weights[middle] - cumulative_weights[start]; + const float right_weight = cumulative_weights[one_after_end] - cumulative_weights[middle]; + BLI_assert(left_weight >= 0.0f && right_weight >= 0.0f); + const float weight_sum = left_weight + right_weight; + BLI_assert(weight_sum > 0.0f); + + const float left_factor = left_weight / weight_sum; + const float right_factor = right_weight / weight_sum; + + int left_amount = amount * left_factor; + int right_amount = amount * right_factor; + + if (left_amount + right_amount < amount) { + BLI_assert(left_amount + right_amount + 1 == amount); + const float weight_per_item = weight_sum / amount; + const float total_remaining_weight = weight_sum - + (left_amount + right_amount) * weight_per_item; + const float left_remaining_weight = left_weight - left_amount * weight_per_item; + const float left_remaining_factor = left_remaining_weight / total_remaining_weight; + if (rng.get_float() < left_remaining_factor) { + left_amount++; + } + else { + right_amount++; + } + } + + sample_cumulative_distribution_recursive( + rng, left_amount, start, middle, cumulative_weights, r_sampled_indices); + sample_cumulative_distribution_recursive( + rng, right_amount, middle, one_after_end, cumulative_weights, r_sampled_indices); + } +} + +static BLI_NOINLINE void sample_cumulative_distribution(RandomNumberGenerator &rng, + Span<float> cumulative_weights, + MutableSpan<int> r_samples) +{ + VectorAdaptor<int> sampled_indices(r_samples); + sample_cumulative_distribution_recursive(rng, + r_samples.size(), + 0, + cumulative_weights.size() - 1, + cumulative_weights, + sampled_indices); + BLI_assert(sampled_indices.is_full()); +} + +static BLI_NOINLINE bool sample_weighted_buckets(RandomNumberGenerator &rng, + Span<float> weights, + MutableSpan<int> r_samples) +{ + Array<float> cumulative_weights(weights.size() + 1); + compute_cumulative_distribution(weights, cumulative_weights); + + if (r_samples.size() > 0 && cumulative_weights.as_span().last() == 0.0f) { + /* All weights are zero. */ + return false; + } + + sample_cumulative_distribution(rng, cumulative_weights, r_samples); + return true; +} + +static BLI_NOINLINE void sample_looptris(RandomNumberGenerator &rng, + Mesh &mesh, + Span<MLoopTri> triangles, + Span<int> triangles_to_sample, + MutableSpan<float3> r_sampled_positions, + MutableSpan<float3> r_sampled_normals) +{ + assert_same_size(triangles_to_sample, r_sampled_positions, r_sampled_normals); + + MLoop *loops = mesh.mloop; + MVert *verts = mesh.mvert; + + for (uint i : triangles_to_sample.index_range()) { + const uint triangle_index = triangles_to_sample[i]; + const MLoopTri &triangle = triangles[triangle_index]; + + const float3 v1 = verts[loops[triangle.tri[0]].v].co; + const float3 v2 = verts[loops[triangle.tri[1]].v].co; + const float3 v3 = verts[loops[triangle.tri[2]].v].co; + + const float3 bary_coords = rng.get_barycentric_coordinates(); + + float3 position; + interp_v3_v3v3v3(position, v1, v2, v3, bary_coords); + + float3 normal; + normal_tri_v3(normal, v1, v2, v3); + + r_sampled_positions[i] = position; + r_sampled_normals[i] = normal; + } +} + +static BLI_NOINLINE bool compute_new_particle_attributes(ParticleEmitterContext &context, + EmitterSettings &settings, + ParticleMeshEmitterSimulationState &state, + Vector<float3> &r_positions, + Vector<float3> &r_velocities, + Vector<float> &r_birth_times) +{ + if (settings.object == nullptr) { + return false; + } + if (settings.rate <= 0.000001f) { + return false; + } + if (settings.object->type != OB_MESH) { + return false; + } + Mesh &mesh = *(Mesh *)settings.object->data; + if (mesh.totvert == 0) { + return false; + } + + const float start_time = context.emit_interval.start(); + const uint32_t seed = DefaultHash<StringRef>{}(state.head.name); + RandomNumberGenerator rng{(*(uint32_t *)&start_time) ^ seed}; + + compute_birth_times(settings.rate, context.emit_interval, state, r_birth_times); + const int particle_amount = r_birth_times.size(); + if (particle_amount == 0) { + return false; + } + + const float last_birth_time = r_birth_times.last(); + rng.shuffle(r_birth_times.as_mutable_span()); + + Span<MLoopTri> triangles = get_mesh_triangles(mesh); + if (triangles.is_empty()) { + return false; + } + + Array<float> triangle_weights(triangles.size()); + compute_triangle_weights(mesh, triangles, triangle_weights); + + Array<int> triangles_to_sample(particle_amount); + if (!sample_weighted_buckets(rng, triangle_weights, triangles_to_sample)) { + return false; + } + + r_positions.resize(particle_amount); + r_velocities.resize(particle_amount); + sample_looptris(rng, mesh, triangles, triangles_to_sample, r_positions, r_velocities); + + if (context.solve_context.dependency_animations.is_object_transform_changing(*settings.object)) { + Array<float4x4> local_to_world_matrices(particle_amount); + context.solve_context.dependency_animations.get_object_transforms( + *settings.object, r_birth_times, local_to_world_matrices); + + for (int i : IndexRange(particle_amount)) { + const float4x4 &position_to_world = local_to_world_matrices[i]; + const float4x4 normal_to_world = position_to_world.inverted_transposed_affine(); + r_positions[i] = position_to_world * r_positions[i]; + r_velocities[i] = normal_to_world * r_velocities[i]; + } + } + else { + const float4x4 position_to_world = settings.object->obmat; + const float4x4 normal_to_world = position_to_world.inverted_transposed_affine(); + for (int i : IndexRange(particle_amount)) { + r_positions[i] = position_to_world * r_positions[i]; + r_velocities[i] = normal_to_world * r_velocities[i]; + } + } + + for (int i : IndexRange(particle_amount)) { + r_velocities[i].normalize(); + } + + state.last_birth_time = last_birth_time; + return true; +} + +static BLI_NOINLINE EmitterSettings compute_settings(const fn::MultiFunction &inputs_fn, + ParticleEmitterContext &context) +{ + EmitterSettings parameters; + + fn::MFContextBuilder mf_context; + mf_context.add_global_context("PersistentDataHandleMap", &context.solve_context.handle_map); + + fn::MFParamsBuilder mf_params{inputs_fn, 1}; + bke::PersistentObjectHandle object_handle; + mf_params.add_uninitialized_single_output(&object_handle, "Object"); + mf_params.add_uninitialized_single_output(¶meters.rate, "Rate"); + + inputs_fn.call(IndexRange(1), mf_params, mf_context); + + parameters.object = context.solve_context.handle_map.lookup(object_handle); + return parameters; +} + +void ParticleMeshEmitter::emit(ParticleEmitterContext &context) const +{ + auto *state = context.lookup_state<ParticleMeshEmitterSimulationState>(own_state_name_); + if (state == nullptr) { + return; + } + + EmitterSettings settings = compute_settings(inputs_fn_, context); + + Vector<float3> new_positions; + Vector<float3> new_velocities; + Vector<float> new_birth_times; + + if (!compute_new_particle_attributes( + context, settings, *state, new_positions, new_velocities, new_birth_times)) { + return; + } + + for (StringRef name : particle_names_) { + ParticleAllocator *allocator = context.try_get_particle_allocator(name); + if (allocator == nullptr) { + continue; + } + + int amount = new_positions.size(); + fn::MutableAttributesRef attributes = allocator->allocate(amount); + + attributes.get<float3>("Position").copy_from(new_positions); + attributes.get<float3>("Velocity").copy_from(new_velocities); + attributes.get<float>("Birth Time").copy_from(new_birth_times); + + if (action_ != nullptr) { + ParticleChunkContext particles{ + *context.solve_context.state_map.lookup<ParticleSimulationState>(name), + IndexRange(amount), + attributes, + nullptr}; + ParticleActionContext action_context{context.solve_context, particles}; + action_->execute(action_context); + } + } +} + +} // namespace blender::sim diff --git a/source/blender/simulation/intern/particle_mesh_emitter.hh b/source/blender/simulation/intern/particle_mesh_emitter.hh new file mode 100644 index 00000000000..cdcf2a34e16 --- /dev/null +++ b/source/blender/simulation/intern/particle_mesh_emitter.hh @@ -0,0 +1,49 @@ +/* + * 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. + */ + +#pragma once + +#include "simulation_solver_influences.hh" + +#include "FN_multi_function.hh" + +namespace blender::sim { + +class ParticleMeshEmitter final : public ParticleEmitter { + private: + std::string own_state_name_; + Array<std::string> particle_names_; + const fn::MultiFunction &inputs_fn_; + const ParticleAction *action_; + + public: + ParticleMeshEmitter(std::string own_state_name, + Array<std::string> particle_names, + const fn::MultiFunction &inputs_fn, + const ParticleAction *action) + : own_state_name_(std::move(own_state_name)), + particle_names_(particle_names), + inputs_fn_(inputs_fn), + action_(action) + { + } + + ~ParticleMeshEmitter(); + + void emit(ParticleEmitterContext &context) const override; +}; + +} // namespace blender::sim diff --git a/source/blender/simulation/intern/simulation_collect_influences.cc b/source/blender/simulation/intern/simulation_collect_influences.cc index 764e587d157..818415e5d88 100644 --- a/source/blender/simulation/intern/simulation_collect_influences.cc +++ b/source/blender/simulation/intern/simulation_collect_influences.cc @@ -16,6 +16,7 @@ #include "simulation_collect_influences.hh" #include "particle_function.hh" +#include "particle_mesh_emitter.hh" #include "FN_attributes_ref.hh" #include "FN_multi_function_network_evaluation.hh" @@ -23,38 +24,125 @@ #include "NOD_node_tree_multi_function.hh" +#include "DEG_depsgraph_query.h" + +#include "BLI_hash.h" #include "BLI_rand.hh" +#include "BLI_set.hh" namespace blender::sim { +using fn::GVSpan; +using fn::MFContextBuilder; +using fn::MFDataType; +using fn::MFDummyNode; +using fn::MFFunctionNode; +using fn::MFInputSocket; +using fn::MFNetwork; +using fn::MFNetworkEvaluator; +using fn::MFNode; +using fn::MFOutputSocket; +using fn::MFParamsBuilder; +using fn::MFParamType; +using fn::MultiFunction; +using fn::VSpan; +using nodes::DerivedNodeTree; +using nodes::DInputSocket; +using nodes::DNode; +using nodes::DOutputSocket; +using nodes::DParentNode; +using nodes::MFNetworkTreeMap; +using nodes::NodeTreeRefMap; + struct DummyDataSources { - Map<const fn::MFOutputSocket *, std::string> particle_attributes; + Map<const MFOutputSocket *, std::string> particle_attributes; + Set<const MFOutputSocket *> simulation_time; + Set<const MFOutputSocket *> scene_time; }; extern "C" { void WM_clipboard_text_set(const char *buf, bool selection); } -static std::string dnode_to_path(const nodes::DNode &dnode) +static std::string dnode_to_path(const DNode &dnode) { std::string path; - for (const nodes::DParentNode *parent = dnode.parent(); parent; parent = parent->parent()) { + for (const DParentNode *parent = dnode.parent(); parent; parent = parent->parent()) { path = parent->node_ref().name() + "/" + path; } path = path + dnode.name(); return path; } -static Span<const nodes::DNode *> get_particle_simulation_nodes(const nodes::DerivedNodeTree &tree) +struct CollectContext : NonCopyable, NonMovable { + SimulationInfluences &influences; + RequiredStates &required_states; + ResourceCollector &resources; + MFNetworkTreeMap &network_map; + MFNetwork &network; + const DerivedNodeTree &tree; + + DummyDataSources data_sources; + Span<const DNode *> particle_simulation_nodes; + Map<const DNode *, std::string> node_paths; + + CollectContext(SimulationInfluences &influences, + RequiredStates &required_states, + ResourceCollector &resources, + MFNetworkTreeMap &network_map) + : influences(influences), + required_states(required_states), + resources(resources), + network_map(network_map), + network(network_map.network()), + tree(network_map.tree()) + { + particle_simulation_nodes = tree.nodes_by_type("SimulationNodeParticleSimulation"); + } +}; + +static const ParticleAction *create_particle_action(CollectContext &context, + const DOutputSocket &dsocket, + Span<StringRefNull> particle_names); + +static const ParticleAction *create_particle_action(CollectContext &context, + const DInputSocket &dsocket, + Span<StringRefNull> particle_names) +{ + BLI_assert(dsocket.bsocket()->type == SOCK_CONTROL_FLOW); + if (dsocket.linked_sockets().size() != 1) { + return nullptr; + } + return create_particle_action(context, *dsocket.linked_sockets()[0], particle_names); +} + +static StringRefNull get_identifier(CollectContext &context, const DNode &dnode) +{ + return context.node_paths.lookup_or_add_cb(&dnode, [&]() { return dnode_to_path(dnode); }); +} + +static Span<const DNode *> nodes_by_type(CollectContext &context, StringRefNull idname) { - return tree.nodes_by_type("SimulationNodeParticleSimulation"); + return context.tree.nodes_by_type(idname); +} + +static Array<StringRefNull> find_linked_particle_simulations(CollectContext &context, + const DOutputSocket &output_socket) +{ + VectorSet<StringRefNull> names; + for (const DInputSocket *target_socket : output_socket.linked_sockets()) { + if (target_socket->node().idname() == "SimulationNodeParticleSimulation") { + names.add(get_identifier(context, target_socket->node())); + } + } + return names.as_span(); } /* Returns true on success. */ -static bool compute_global_inputs(nodes::MFNetworkTreeMap &network_map, +static bool compute_global_inputs(MFNetworkTreeMap &network_map, ResourceCollector &resources, - Span<const fn::MFInputSocket *> sockets, - MutableSpan<fn::GMutableSpan> r_results) + Span<const MFInputSocket *> sockets, + MutableSpan<GMutableSpan> r_results) { int amount = sockets.size(); if (amount == 0) { @@ -65,28 +153,28 @@ static bool compute_global_inputs(nodes::MFNetworkTreeMap &network_map, return false; } - fn::MFNetworkEvaluator network_fn{{}, sockets}; - fn::MFParamsBuilder params{network_fn, 1}; + MFNetworkEvaluator network_fn{{}, sockets}; + MFParamsBuilder params{network_fn, 1}; for (int param_index : network_fn.param_indices()) { - fn::MFParamType param_type = network_fn.param_type(param_index); - BLI_assert(param_type.category() == fn::MFParamType::Category::SingleOutput); /* For now. */ - const fn::CPPType &type = param_type.data_type().single_type(); + MFParamType param_type = network_fn.param_type(param_index); + BLI_assert(param_type.category() == MFParamType::Category::SingleOutput); /* For now. */ + const CPPType &type = param_type.data_type().single_type(); void *buffer = resources.linear_allocator().allocate(type.size(), type.alignment()); resources.add(buffer, type.destruct_cb(), AT); - fn::GMutableSpan span{type, buffer, 1}; + GMutableSpan span{type, buffer, 1}; r_results[param_index] = span; params.add_uninitialized_single_output(span); } - fn::MFContextBuilder context; + MFContextBuilder context; network_fn.call(IndexRange(1), params, context); return true; } static std::optional<Array<std::string>> compute_global_string_inputs( - nodes::MFNetworkTreeMap &network_map, Span<const fn::MFInputSocket *> sockets) + MFNetworkTreeMap &network_map, Span<const MFInputSocket *> sockets) { ResourceCollector local_resources; - Array<fn::GMutableSpan> computed_values(sockets.size(), NoInitialization()); + Array<GMutableSpan> computed_values(sockets.size(), NoInitialization()); if (!compute_global_inputs(network_map, local_resources, sockets, computed_values)) { return {}; } @@ -98,107 +186,177 @@ static std::optional<Array<std::string>> compute_global_string_inputs( return strings; } -static void find_and_deduplicate_particle_attribute_nodes(nodes::MFNetworkTreeMap &network_map, - DummyDataSources &r_data_sources) +/** + * This will find all the particle attribute input nodes. Then it will compute the attribute names + * by evaluating the network (those names should not depend on per particle data). In the end, + * input nodes that access the same attribute are combined. + */ +static void prepare_particle_attribute_nodes(CollectContext &context) { - fn::MFNetwork &network = network_map.network(); - const nodes::DerivedNodeTree &tree = network_map.tree(); - - Span<const nodes::DNode *> attribute_dnodes = tree.nodes_by_type( - "SimulationNodeParticleAttribute"); + Span<const DNode *> attribute_dnodes = nodes_by_type(context, "SimulationNodeParticleAttribute"); - Vector<fn::MFInputSocket *> name_sockets; - for (const nodes::DNode *dnode : attribute_dnodes) { - fn::MFInputSocket &name_socket = network_map.lookup_dummy(dnode->input(0)); + Vector<MFInputSocket *> name_sockets; + for (const DNode *dnode : attribute_dnodes) { + MFInputSocket &name_socket = context.network_map.lookup_dummy(dnode->input(0)); name_sockets.append(&name_socket); } - std::optional<Array<std::string>> attribute_names = compute_global_string_inputs(network_map, - name_sockets); + std::optional<Array<std::string>> attribute_names = compute_global_string_inputs( + context.network_map, name_sockets); if (!attribute_names.has_value()) { return; } - Map<std::pair<std::string, fn::MFDataType>, Vector<fn::MFNode *>> - attribute_nodes_by_name_and_type; + MultiValueMap<std::pair<std::string, MFDataType>, MFNode *> attribute_nodes_by_name_and_type; for (int i : attribute_names->index_range()) { - attribute_nodes_by_name_and_type - .lookup_or_add_default( - {(*attribute_names)[i], name_sockets[i]->node().output(0).data_type()}) - .append(&name_sockets[i]->node()); + attribute_nodes_by_name_and_type.add( + {(*attribute_names)[i], name_sockets[i]->node().output(0).data_type()}, + &name_sockets[i]->node()); } - Map<const fn::MFOutputSocket *, std::string> attribute_inputs; + Map<const MFOutputSocket *, std::string> attribute_inputs; for (auto item : attribute_nodes_by_name_and_type.items()) { StringRef attribute_name = item.key.first; - fn::MFDataType data_type = item.key.second; - Span<fn::MFNode *> nodes = item.value; + MFDataType data_type = item.key.second; + Span<MFNode *> nodes = item.value; - fn::MFOutputSocket &new_attribute_socket = network.add_input( + MFOutputSocket &new_attribute_socket = context.network.add_input( "Attribute '" + attribute_name + "'", data_type); - for (fn::MFNode *node : nodes) { - network.relink(node->output(0), new_attribute_socket); + for (MFNode *node : nodes) { + context.network.relink(node->output(0), new_attribute_socket); } - network.remove(nodes); + context.network.remove(nodes); - r_data_sources.particle_attributes.add_new(&new_attribute_socket, attribute_name); + context.data_sources.particle_attributes.add_new(&new_attribute_socket, attribute_name); + } +} + +static void prepare_time_input_nodes(CollectContext &context) +{ + Span<const DNode *> time_input_dnodes = nodes_by_type(context, "SimulationNodeTime"); + Vector<const DNode *> simulation_time_inputs; + Vector<const DNode *> scene_time_inputs; + for (const DNode *dnode : time_input_dnodes) { + NodeSimInputTimeType type = (NodeSimInputTimeType)dnode->node_ref().bnode()->custom1; + switch (type) { + case NODE_SIM_INPUT_SIMULATION_TIME: { + simulation_time_inputs.append(dnode); + break; + } + case NODE_SIM_INPUT_SCENE_TIME: { + scene_time_inputs.append(dnode); + break; + } + } + } + + if (simulation_time_inputs.size() > 0) { + MFOutputSocket &new_socket = context.network.add_input("Simulation Time", + MFDataType::ForSingle<float>()); + for (const DNode *dnode : simulation_time_inputs) { + MFOutputSocket &old_socket = context.network_map.lookup_dummy(dnode->output(0)); + context.network.relink(old_socket, new_socket); + context.network.remove(old_socket.node()); + } + context.data_sources.simulation_time.add(&new_socket); + } + if (scene_time_inputs.size() > 0) { + MFOutputSocket &new_socket = context.network.add_input("Scene Time", + MFDataType::ForSingle<float>()); + for (const DNode *dnode : scene_time_inputs) { + MFOutputSocket &old_socket = context.network_map.lookup_dummy(dnode->output(0)); + context.network.relink(old_socket, new_socket); + context.network.remove(old_socket.node()); + } + context.data_sources.scene_time.add(&new_socket); } } class ParticleAttributeInput : public ParticleFunctionInput { private: std::string attribute_name_; - const fn::CPPType &attribute_type_; + const CPPType &attribute_type_; public: - ParticleAttributeInput(std::string attribute_name, const fn::CPPType &attribute_type) + ParticleAttributeInput(std::string attribute_name, const CPPType &attribute_type) : attribute_name_(std::move(attribute_name)), attribute_type_(attribute_type) { } - void add_input(fn::AttributesRef attributes, - fn::MFParamsBuilder ¶ms, + void add_input(ParticleFunctionInputContext &context, + MFParamsBuilder ¶ms, ResourceCollector &UNUSED(resources)) const override { - std::optional<fn::GSpan> span = attributes.try_get(attribute_name_, attribute_type_); + std::optional<GSpan> span = context.particles.attributes.try_get(attribute_name_, + attribute_type_); if (span.has_value()) { params.add_readonly_single_input(*span); } else { - params.add_readonly_single_input(fn::GVSpan::FromDefault(attribute_type_)); + params.add_readonly_single_input(GVSpan::FromDefault(attribute_type_)); } } }; +class SceneTimeInput : public ParticleFunctionInput { + void add_input(ParticleFunctionInputContext &context, + MFParamsBuilder ¶ms, + ResourceCollector &resources) const override + { + const float time = DEG_get_ctime(&context.solve_context.depsgraph); + float *time_ptr = &resources.construct<float>(AT, time); + params.add_readonly_single_input(time_ptr); + } +}; + +class SimulationTimeInput : public ParticleFunctionInput { + void add_input(ParticleFunctionInputContext &context, + MFParamsBuilder ¶ms, + ResourceCollector &resources) const override + { + /* TODO: Vary this per particle. */ + const float time = context.solve_context.solve_interval.stop(); + float *time_ptr = &resources.construct<float>(AT, time); + params.add_readonly_single_input(time_ptr); + } +}; + static const ParticleFunction *create_particle_function_for_inputs( - Span<const fn::MFInputSocket *> sockets_to_compute, - ResourceCollector &resources, - DummyDataSources &data_sources) + CollectContext &context, Span<const MFInputSocket *> sockets_to_compute) { BLI_assert(sockets_to_compute.size() >= 1); - const fn::MFNetwork &network = sockets_to_compute[0]->node().network(); + const MFNetwork &network = sockets_to_compute[0]->node().network(); - VectorSet<const fn::MFOutputSocket *> dummy_deps; - VectorSet<const fn::MFInputSocket *> unlinked_input_deps; + VectorSet<const MFOutputSocket *> dummy_deps; + VectorSet<const MFInputSocket *> unlinked_input_deps; network.find_dependencies(sockets_to_compute, dummy_deps, unlinked_input_deps); BLI_assert(unlinked_input_deps.size() == 0); Vector<const ParticleFunctionInput *> per_particle_inputs; - for (const fn::MFOutputSocket *socket : dummy_deps) { - const std::string *attribute_name = data_sources.particle_attributes.lookup_ptr(socket); - if (attribute_name == nullptr) { - return nullptr; + for (const MFOutputSocket *socket : dummy_deps) { + if (context.data_sources.particle_attributes.contains(socket)) { + const std::string *attribute_name = context.data_sources.particle_attributes.lookup_ptr( + socket); + if (attribute_name == nullptr) { + return nullptr; + } + per_particle_inputs.append(&context.resources.construct<ParticleAttributeInput>( + AT, *attribute_name, socket->data_type().single_type())); + } + else if (context.data_sources.scene_time.contains(socket)) { + per_particle_inputs.append(&context.resources.construct<SceneTimeInput>(AT)); + } + else if (context.data_sources.simulation_time.contains(socket)) { + per_particle_inputs.append(&context.resources.construct<SimulationTimeInput>(AT)); } - per_particle_inputs.append(&resources.construct<ParticleAttributeInput>( - AT, *attribute_name, socket->data_type().single_type())); } - const fn::MultiFunction &per_particle_fn = resources.construct<fn::MFNetworkEvaluator>( + const MultiFunction &per_particle_fn = context.resources.construct<MFNetworkEvaluator>( AT, dummy_deps.as_span(), sockets_to_compute); Array<bool> output_is_global(sockets_to_compute.size(), false); - const ParticleFunction &particle_fn = resources.construct<ParticleFunction>( + const ParticleFunction &particle_fn = context.resources.construct<ParticleFunction>( AT, nullptr, &per_particle_fn, @@ -209,6 +367,17 @@ static const ParticleFunction *create_particle_function_for_inputs( return &particle_fn; } +static const ParticleFunction *create_particle_function_for_inputs( + CollectContext &context, Span<const DInputSocket *> dsockets_to_compute) +{ + Vector<const MFInputSocket *> sockets_to_compute; + for (const DInputSocket *dsocket : dsockets_to_compute) { + const MFInputSocket &socket = context.network_map.lookup_dummy(*dsocket); + sockets_to_compute.append(&socket); + } + return create_particle_function_for_inputs(context, sockets_to_compute); +} + class ParticleFunctionForce : public ParticleForce { private: const ParticleFunction &particle_fn_; @@ -220,13 +389,12 @@ class ParticleFunctionForce : public ParticleForce { void add_force(ParticleForceContext &context) const override { - IndexMask mask = context.particle_chunk().index_mask(); - MutableSpan<float3> r_combined_force = context.force_dst(); + IndexMask mask = context.particles.index_mask; + MutableSpan<float3> r_combined_force = context.force_dst; - ParticleFunctionEvaluator evaluator{ - particle_fn_, context.solve_context(), context.particle_chunk()}; + ParticleFunctionEvaluator evaluator{particle_fn_, context.solve_context, context.particles}; evaluator.compute(); - fn::VSpan<float3> forces = evaluator.get<float3>(0, "Force"); + VSpan<float3> forces = evaluator.get<float3>(0, "Force"); for (int64_t i : mask) { r_combined_force[i] += forces[i]; @@ -234,218 +402,473 @@ class ParticleFunctionForce : public ParticleForce { } }; -static Vector<const ParticleForce *> create_forces_for_particle_simulation( - const nodes::DNode &simulation_node, - nodes::MFNetworkTreeMap &network_map, - ResourceCollector &resources, - DummyDataSources &data_sources) +static void create_forces_for_particle_simulation(CollectContext &context, + const DNode &simulation_node) { Vector<const ParticleForce *> forces; - for (const nodes::DOutputSocket *origin_socket : - simulation_node.input(2, "Forces").linked_sockets()) { - const nodes::DNode &origin_node = origin_socket->node(); + for (const DOutputSocket *origin_socket : simulation_node.input(2, "Forces").linked_sockets()) { + const DNode &origin_node = origin_socket->node(); if (origin_node.idname() != "SimulationNodeForce") { continue; } - const fn::MFInputSocket &force_socket = network_map.lookup_dummy( - origin_node.input(0, "Force")); - const ParticleFunction *particle_fn = create_particle_function_for_inputs( - {&force_socket}, resources, data_sources); + context, {&origin_node.input(0, "Force")}); if (particle_fn == nullptr) { continue; } - const ParticleForce &force = resources.construct<ParticleFunctionForce>(AT, *particle_fn); + const ParticleForce &force = context.resources.construct<ParticleFunctionForce>(AT, + *particle_fn); forces.append(&force); } - return forces; + + StringRef particle_name = get_identifier(context, simulation_node); + context.influences.particle_forces.add_multiple_as(particle_name, forces); +} + +static void collect_forces(CollectContext &context) +{ + for (const DNode *dnode : context.particle_simulation_nodes) { + create_forces_for_particle_simulation(context, *dnode); + } +} + +static ParticleEmitter *create_particle_emitter(CollectContext &context, const DNode &dnode) +{ + Array<StringRefNull> names = find_linked_particle_simulations(context, dnode.output(0)); + if (names.size() == 0) { + return nullptr; + } + + Array<const MFInputSocket *> input_sockets{2}; + for (int i : input_sockets.index_range()) { + input_sockets[i] = &context.network_map.lookup_dummy(dnode.input(i)); + } + + if (context.network.have_dummy_or_unlinked_dependencies(input_sockets)) { + return nullptr; + } + + MultiFunction &inputs_fn = context.resources.construct<MFNetworkEvaluator>( + AT, Span<const MFOutputSocket *>(), input_sockets.as_span()); + + const ParticleAction *birth_action = create_particle_action( + context, dnode.input(2, "Execute"), names); + + StringRefNull own_state_name = get_identifier(context, dnode); + context.required_states.add(own_state_name, SIM_TYPE_NAME_PARTICLE_MESH_EMITTER); + ParticleEmitter &emitter = context.resources.construct<ParticleMeshEmitter>( + AT, own_state_name, names.as_span(), inputs_fn, birth_action); + return &emitter; +} + +static void collect_emitters(CollectContext &context) +{ + for (const DNode *dnode : nodes_by_type(context, "SimulationNodeParticleMeshEmitter")) { + ParticleEmitter *emitter = create_particle_emitter(context, *dnode); + if (emitter != nullptr) { + context.influences.particle_emitters.append(emitter); + } + } } -static void collect_forces(nodes::MFNetworkTreeMap &network_map, - ResourceCollector &resources, - DummyDataSources &data_sources, - SimulationInfluences &r_influences) +static void collect_birth_events(CollectContext &context) { - for (const nodes::DNode *dnode : get_particle_simulation_nodes(network_map.tree())) { - std::string name = dnode_to_path(*dnode); - Vector<const ParticleForce *> forces = create_forces_for_particle_simulation( - *dnode, network_map, resources, data_sources); - r_influences.particle_forces.add_new(std::move(name), std::move(forces)); + for (const DNode *event_dnode : nodes_by_type(context, "SimulationNodeParticleBirthEvent")) { + const DInputSocket &execute_input = event_dnode->input(0); + if (execute_input.linked_sockets().size() != 1) { + continue; + } + + Array<StringRefNull> particle_names = find_linked_particle_simulations(context, + event_dnode->output(0)); + + const DOutputSocket &execute_source = *execute_input.linked_sockets()[0]; + const ParticleAction *action = create_particle_action(context, execute_source, particle_names); + if (action == nullptr) { + continue; + } + + for (StringRefNull particle_name : particle_names) { + context.influences.particle_birth_actions.add_as(particle_name, action); + } + } +} + +static void collect_time_step_events(CollectContext &context) +{ + for (const DNode *event_dnode : nodes_by_type(context, "SimulationNodeParticleTimeStepEvent")) { + const DInputSocket &execute_input = event_dnode->input(0); + Array<StringRefNull> particle_names = find_linked_particle_simulations(context, + event_dnode->output(0)); + + const ParticleAction *action = create_particle_action(context, execute_input, particle_names); + if (action == nullptr) { + continue; + } + + NodeSimParticleTimeStepEventType type = + (NodeSimParticleTimeStepEventType)event_dnode->node_ref().bnode()->custom1; + if (type == NODE_PARTICLE_TIME_STEP_EVENT_BEGIN) { + for (StringRefNull particle_name : particle_names) { + context.influences.particle_time_step_begin_actions.add_as(particle_name, action); + } + } + else { + for (StringRefNull particle_name : particle_names) { + context.influences.particle_time_step_end_actions.add_as(particle_name, action); + } + } } } -class MyBasicEmitter : public ParticleEmitter { +class SequenceParticleAction : public ParticleAction { private: - Array<std::string> names_; - std::string my_state_; - const fn::MultiFunction &inputs_fn_; - uint32_t seed_; + Vector<const ParticleAction *> actions_; public: - MyBasicEmitter(Array<std::string> names, - std::string my_state, - const fn::MultiFunction &inputs_fn, - uint32_t seed) - : names_(std::move(names)), - my_state_(std::move(my_state)), - inputs_fn_(inputs_fn), - seed_(seed) + SequenceParticleAction(Span<const ParticleAction *> actions) : actions_(std::move(actions)) { } - void emit(ParticleEmitterContext &context) const override + void execute(ParticleActionContext &context) const override { - auto *state = context.solve_context().state_map().lookup<ParticleMeshEmitterSimulationState>( - my_state_); - if (state == nullptr) { - return; + for (const ParticleAction *action : actions_) { + action->execute(context); } + } +}; - fn::MFContextBuilder mf_context; - mf_context.add_global_context("PersistentDataHandleMap", - &context.solve_context().handle_map()); +class SetParticleAttributeAction : public ParticleAction { + private: + std::string attribute_name_; + const CPPType &cpp_type_; + const ParticleFunction &inputs_fn_; - fn::MFParamsBuilder mf_params{inputs_fn_, 1}; - bke::PersistentObjectHandle object_handle; - float rate; - mf_params.add_uninitialized_single_output(&object_handle); - mf_params.add_uninitialized_single_output(&rate); - inputs_fn_.call(IndexRange(1), mf_params, mf_context); + public: + SetParticleAttributeAction(std::string attribute_name, + const CPPType &cpp_type, + const ParticleFunction &inputs_fn) + : attribute_name_(std::move(attribute_name)), cpp_type_(cpp_type), inputs_fn_(inputs_fn) + { + } - const Object *object = context.solve_context().handle_map().lookup(object_handle); - if (object == nullptr) { + void execute(ParticleActionContext &context) const override + { + std::optional<GMutableSpan> attribute_array = context.particles.attributes.try_get( + attribute_name_, cpp_type_); + if (!attribute_array.has_value()) { return; } - Vector<float3> new_positions; - Vector<float3> new_velocities; - Vector<float> new_birth_times; - - TimeInterval time_interval = context.simulation_time_interval(); - float start_time = time_interval.start(); - RandomNumberGenerator rng{(*(uint32_t *)&start_time) ^ seed_}; + ParticleFunctionEvaluator evaluator{inputs_fn_, context.solve_context, context.particles}; + evaluator.compute(); + GVSpan values = evaluator.get(0); - const float time_between_particles = 1.0f / rate; - while (state->last_birth_time + time_between_particles < time_interval.end()) { - new_positions.append(rng.get_unit_float3() * 0.3 + float3(object->loc)); - new_velocities.append(rng.get_unit_float3()); - const float birth_time = state->last_birth_time + time_between_particles; - new_birth_times.append(birth_time); - state->last_birth_time = birth_time; + if (values.is_single_element()) { + cpp_type_.fill_initialized_indices( + values.as_single_element(), attribute_array->data(), context.particles.index_mask); + } + else { + GSpan value_array = values.as_full_array(); + cpp_type_.copy_to_initialized_indices( + value_array.data(), attribute_array->data(), context.particles.index_mask); } - for (StringRef name : names_) { - ParticleAllocator *allocator = context.try_get_particle_allocator(name); - if (allocator == nullptr) { - return; - } - - int amount = new_positions.size(); - fn::MutableAttributesRef attributes = allocator->allocate(amount); - - initialized_copy_n(new_positions.data(), amount, attributes.get<float3>("Position").data()); - initialized_copy_n(new_velocities.data(), amount, attributes.get<float3>("Velocity").data()); - initialized_copy_n( - new_birth_times.data(), amount, attributes.get<float>("Birth Time").data()); + if (attribute_name_ == "Velocity") { + context.particles.update_diffs_after_velocity_change(); } } }; -static Vector<const nodes::DNode *> find_linked_particle_simulations( - const nodes::DOutputSocket &output_socket) +static const ParticleAction *concatenate_actions(CollectContext &context, + Span<const ParticleAction *> actions) { - Vector<const nodes::DNode *> simulation_nodes; - for (const nodes::DInputSocket *target_socket : output_socket.linked_sockets()) { - if (target_socket->node().idname() == "SimulationNodeParticleSimulation") { - simulation_nodes.append(&target_socket->node()); + Vector<const ParticleAction *> non_null_actions; + for (const ParticleAction *action : actions) { + if (action != nullptr) { + non_null_actions.append(action); } } - return simulation_nodes; + if (non_null_actions.size() == 0) { + return nullptr; + } + if (non_null_actions.size() == 1) { + return non_null_actions[0]; + } + return &context.resources.construct<SequenceParticleAction>(AT, std::move(non_null_actions)); } -static ParticleEmitter *create_particle_emitter(const nodes::DNode &dnode, - ResourceCollector &resources, - nodes::MFNetworkTreeMap &network_map, - RequiredStates &r_required_states) +static const ParticleAction *create_set_particle_attribute_action( + CollectContext &context, const DOutputSocket &dsocket, Span<StringRefNull> particle_names) { - Vector<const nodes::DNode *> simulation_dnodes = find_linked_particle_simulations( - dnode.output(0)); - if (simulation_dnodes.size() == 0) { - return nullptr; + const DNode &dnode = dsocket.node(); + + const ParticleAction *previous_action = create_particle_action( + context, dnode.input(0), particle_names); + + MFInputSocket &name_socket = context.network_map.lookup_dummy(dnode.input(1)); + MFInputSocket &value_socket = name_socket.node().input(1); + std::optional<Array<std::string>> names = compute_global_string_inputs(context.network_map, + {&name_socket}); + if (!names.has_value()) { + return previous_action; } - Array<std::string> names{simulation_dnodes.size()}; - for (int i : simulation_dnodes.index_range()) { - names[i] = dnode_to_path(*simulation_dnodes[i]); + std::string attribute_name = (*names)[0]; + if (attribute_name.empty()) { + return previous_action; } + const CPPType &attribute_type = value_socket.data_type().single_type(); - Array<const fn::MFInputSocket *> input_sockets{dnode.inputs().size()}; - for (int i : input_sockets.index_range()) { - input_sockets[i] = &network_map.lookup_dummy(dnode.input(i)); + const ParticleFunction *inputs_fn = create_particle_function_for_inputs(context, + {&value_socket}); + if (inputs_fn == nullptr) { + return previous_action; } - if (network_map.network().have_dummy_or_unlinked_dependencies(input_sockets)) { - return nullptr; + for (StringRef particle_name : particle_names) { + context.influences.particle_attributes_builder.lookup_as(particle_name) + ->add(attribute_name, attribute_type); } - fn::MultiFunction &inputs_fn = resources.construct<fn::MFNetworkEvaluator>( - AT, Span<const fn::MFOutputSocket *>(), input_sockets.as_span()); + ParticleAction &this_action = context.resources.construct<SetParticleAttributeAction>( + AT, attribute_name, attribute_type, *inputs_fn); - std::string my_state_name = dnode_to_path(dnode); - r_required_states.add(my_state_name, SIM_TYPE_NAME_PARTICLE_MESH_EMITTER); - uint32_t seed = DefaultHash<std::string>{}(my_state_name); - ParticleEmitter &emitter = resources.construct<MyBasicEmitter>( - AT, std::move(names), std::move(my_state_name), inputs_fn, seed); - return &emitter; + return concatenate_actions(context, {previous_action, &this_action}); } -static void collect_emitters(nodes::MFNetworkTreeMap &network_map, - ResourceCollector &resources, - SimulationInfluences &r_influences, - RequiredStates &r_required_states) +class ParticleConditionAction : public ParticleAction { + private: + const ParticleFunction &inputs_fn_; + const ParticleAction *action_true_; + const ParticleAction *action_false_; + + public: + ParticleConditionAction(const ParticleFunction &inputs_fn, + const ParticleAction *action_true, + const ParticleAction *action_false) + : inputs_fn_(inputs_fn), action_true_(action_true), action_false_(action_false) + { + } + + void execute(ParticleActionContext &context) const override + { + ParticleFunctionEvaluator evaluator{inputs_fn_, context.solve_context, context.particles}; + evaluator.compute(); + VSpan<bool> conditions = evaluator.get<bool>(0, "Condition"); + + if (conditions.is_single_element()) { + const bool condition = conditions.as_single_element(); + if (condition) { + if (action_true_ != nullptr) { + action_true_->execute(context); + } + } + else { + if (action_false_ != nullptr) { + action_false_->execute(context); + } + } + } + else { + Span<bool> conditions_array = conditions.as_full_array(); + + Vector<int64_t> true_indices; + Vector<int64_t> false_indices; + for (int i : context.particles.index_mask) { + if (conditions_array[i]) { + true_indices.append(i); + } + else { + false_indices.append(i); + } + } + + if (action_true_ != nullptr) { + ParticleChunkContext chunk_context{context.particles.state, + true_indices.as_span(), + context.particles.attributes, + context.particles.integration}; + ParticleActionContext action_context{context.solve_context, chunk_context}; + action_true_->execute(action_context); + } + if (action_false_ != nullptr) { + ParticleChunkContext chunk_context{context.particles.state, + false_indices.as_span(), + context.particles.attributes, + context.particles.integration}; + ParticleActionContext action_context{context.solve_context, chunk_context}; + action_false_->execute(action_context); + } + } + } +}; + +static const ParticleAction *create_particle_condition_action(CollectContext &context, + const DOutputSocket &dsocket, + Span<StringRefNull> particle_names) { - for (const nodes::DNode *dnode : - network_map.tree().nodes_by_type("SimulationNodeParticleMeshEmitter")) { - ParticleEmitter *emitter = create_particle_emitter( - *dnode, resources, network_map, r_required_states); - if (emitter != nullptr) { - r_influences.particle_emitters.append(emitter); + const DNode &dnode = dsocket.node(); + + const ParticleFunction *inputs_fn = create_particle_function_for_inputs( + context, {&dnode.input(0, "Condition")}); + if (inputs_fn == nullptr) { + return nullptr; + } + + const ParticleAction *true_action = create_particle_action( + context, dnode.input(1), particle_names); + const ParticleAction *false_action = create_particle_action( + context, dnode.input(2), particle_names); + + if (true_action == nullptr && false_action == nullptr) { + return nullptr; + } + return &context.resources.construct<ParticleConditionAction>( + AT, *inputs_fn, true_action, false_action); +} + +class KillParticleAction : public ParticleAction { + public: + void execute(ParticleActionContext &context) const override + { + MutableSpan<int> dead_states = context.particles.attributes.get<int>("Dead"); + for (int i : context.particles.index_mask) { + dead_states[i] = true; } } +}; + +static const ParticleAction *create_particle_action(CollectContext &context, + const DOutputSocket &dsocket, + Span<StringRefNull> particle_names) +{ + const DNode &dnode = dsocket.node(); + StringRef idname = dnode.idname(); + if (idname == "SimulationNodeSetParticleAttribute") { + return create_set_particle_attribute_action(context, dsocket, particle_names); + } + if (idname == "SimulationNodeExecuteCondition") { + return create_particle_condition_action(context, dsocket, particle_names); + } + if (idname == "SimulationNodeKillParticle") { + return &context.resources.construct<KillParticleAction>(AT); + } + return nullptr; } -static void prepare_particle_attribute_builders(nodes::MFNetworkTreeMap &network_map, - ResourceCollector &resources, - SimulationInfluences &r_influences) +static void initialize_particle_attribute_builders(CollectContext &context) { - for (const nodes::DNode *dnode : get_particle_simulation_nodes(network_map.tree())) { - std::string name = dnode_to_path(*dnode); - fn::AttributesInfoBuilder &builder = resources.construct<fn::AttributesInfoBuilder>(AT); - builder.add<float3>("Position", {0, 0, 0}); - builder.add<float3>("Velocity", {0, 0, 0}); - builder.add<int>("ID", 0); + for (const DNode *dnode : context.particle_simulation_nodes) { + StringRef name = get_identifier(context, *dnode); + AttributesInfoBuilder &attributes_builder = context.resources.construct<AttributesInfoBuilder>( + AT); + attributes_builder.add<float3>("Position", {0, 0, 0}); + attributes_builder.add<float3>("Velocity", {0, 0, 0}); + attributes_builder.add<int>("ID", 0); /* TODO: Use bool property, but need to add CD_PROP_BOOL first. */ - builder.add<int>("Dead", 0); - builder.add<float>("Birth Time", 0.0f); - r_influences.particle_attributes_builder.add_new(std::move(name), &builder); + attributes_builder.add<int>("Dead", 0); + /* TODO: Use uint32_t, but we don't have a corresponding custom property type. */ + attributes_builder.add<int>("Hash", 0); + attributes_builder.add<float>("Birth Time", 0.0f); + attributes_builder.add<float>("Radius", 0.02f); + context.influences.particle_attributes_builder.add_new(name, &attributes_builder); } } -static void find_used_data_blocks(const nodes::DerivedNodeTree &tree, - SimulationInfluences &r_influences) +static void optimize_function_network(CollectContext &context) +{ + fn::mf_network_optimization::constant_folding(context.network, context.resources); + fn::mf_network_optimization::common_subnetwork_elimination(context.network); + fn::mf_network_optimization::dead_node_removal(context.network); + // WM_clipboard_text_set(network.to_dot().c_str(), false); +} + +class AgeReachedEvent : public ParticleEvent { + private: + std::string attribute_name_; + const ParticleFunction &inputs_fn_; + const ParticleAction &action_; + + public: + AgeReachedEvent(std::string attribute_name, + const ParticleFunction &inputs_fn, + const ParticleAction &action) + : attribute_name_(std::move(attribute_name)), inputs_fn_(inputs_fn), action_(action) + { + } + + void filter(ParticleEventFilterContext &context) const override + { + Span<float> birth_times = context.particles.attributes.get<float>("Birth Time"); + std::optional<Span<int>> has_been_triggered = context.particles.attributes.try_get<int>( + attribute_name_); + if (!has_been_triggered.has_value()) { + return; + } + + ParticleFunctionEvaluator evaluator{inputs_fn_, context.solve_context, context.particles}; + evaluator.compute(); + VSpan<float> trigger_ages = evaluator.get<float>(0, "Age"); + + const float end_time = context.particles.integration->end_time; + for (int i : context.particles.index_mask) { + if ((*has_been_triggered)[i]) { + continue; + } + const float trigger_age = trigger_ages[i]; + const float birth_time = birth_times[i]; + const float trigger_time = birth_time + trigger_age; + if (trigger_time > end_time) { + continue; + } + + const float duration = context.particles.integration->durations[i]; + TimeInterval interval(end_time - duration, duration); + const float time_factor = interval.safe_factor_at_time(trigger_time); + + context.factor_dst[i] = std::max<float>(0.0f, time_factor); + } + } + + void execute(ParticleActionContext &context) const override + { + MutableSpan<int> has_been_triggered = context.particles.attributes.get<int>(attribute_name_); + for (int i : context.particles.index_mask) { + has_been_triggered[i] = 1; + } + action_.execute(context); + } +}; + +static void collect_age_reached_events(CollectContext &context) { - const bNodeSocketType *socktype = nodeSocketTypeFind("NodeSocketObject"); - BLI_assert(socktype != nullptr); - - for (const nodes::DInputSocket *dsocket : tree.input_sockets()) { - const bNodeSocket *bsocket = dsocket->bsocket(); - if (bsocket->typeinfo == socktype) { - Object *value = ((const bNodeSocketValueObject *)bsocket->default_value)->value; - if (value != nullptr) { - r_influences.used_data_blocks.add(&value->id); + for (const DNode *dnode : nodes_by_type(context, "SimulationNodeAgeReachedEvent")) { + const DInputSocket &age_input = dnode->input(0, "Age"); + const DInputSocket &execute_input = dnode->input(1, "Execute"); + Array<StringRefNull> particle_names = find_linked_particle_simulations(context, + dnode->output(0)); + const ParticleAction *action = create_particle_action(context, execute_input, particle_names); + if (action == nullptr) { + continue; + } + const ParticleFunction *inputs_fn = create_particle_function_for_inputs(context, {&age_input}); + if (inputs_fn == nullptr) { + continue; + } + + std::string attribute_name = get_identifier(context, *dnode); + const ParticleEvent &event = context.resources.construct<AgeReachedEvent>( + AT, attribute_name, *inputs_fn, *action); + for (StringRefNull particle_name : particle_names) { + const bool added_attribute = context.influences.particle_attributes_builder + .lookup_as(particle_name) + ->add<int>(attribute_name, 0); + if (added_attribute) { + context.influences.particle_events.add_as(particle_name, &event); } } } @@ -456,30 +879,29 @@ void collect_simulation_influences(Simulation &simulation, SimulationInfluences &r_influences, RequiredStates &r_required_states) { - nodes::NodeTreeRefMap tree_refs; - const nodes::DerivedNodeTree tree{simulation.nodetree, tree_refs}; + NodeTreeRefMap tree_refs; + const DerivedNodeTree tree{simulation.nodetree, tree_refs}; - fn::MFNetwork &network = resources.construct<fn::MFNetwork>(AT); - nodes::MFNetworkTreeMap network_map = insert_node_tree_into_mf_network(network, tree, resources); + MFNetwork &network = resources.construct<MFNetwork>(AT); + MFNetworkTreeMap network_map = insert_node_tree_into_mf_network(network, tree, resources); - prepare_particle_attribute_builders(network_map, resources, r_influences); + CollectContext context{r_influences, r_required_states, resources, network_map}; + initialize_particle_attribute_builders(context); - DummyDataSources data_sources; - find_and_deduplicate_particle_attribute_nodes(network_map, data_sources); + prepare_particle_attribute_nodes(context); + prepare_time_input_nodes(context); - fn::mf_network_optimization::constant_folding(network, resources); - fn::mf_network_optimization::common_subnetwork_elimination(network); - fn::mf_network_optimization::dead_node_removal(network); - // WM_clipboard_text_set(network.to_dot().c_str(), false); + collect_forces(context); + collect_emitters(context); + collect_birth_events(context); + collect_time_step_events(context); + collect_age_reached_events(context); - collect_forces(network_map, resources, data_sources, r_influences); - collect_emitters(network_map, resources, r_influences, r_required_states); + optimize_function_network(context); - for (const nodes::DNode *dnode : get_particle_simulation_nodes(tree)) { - r_required_states.add(dnode_to_path(*dnode), SIM_TYPE_NAME_PARTICLE_SIMULATION); + for (const DNode *dnode : context.particle_simulation_nodes) { + r_required_states.add(get_identifier(context, *dnode), SIM_TYPE_NAME_PARTICLE_SIMULATION); } - - find_used_data_blocks(tree, r_influences); } } // namespace blender::sim diff --git a/source/blender/simulation/intern/simulation_collect_influences.hh b/source/blender/simulation/intern/simulation_collect_influences.hh index 5035461191e..8673a308b04 100644 --- a/source/blender/simulation/intern/simulation_collect_influences.hh +++ b/source/blender/simulation/intern/simulation_collect_influences.hh @@ -20,7 +20,7 @@ #include "BLI_resource_collector.hh" -#include "simulation_solver.hh" +#include "simulation_solver_influences.hh" namespace blender::sim { diff --git a/source/blender/simulation/intern/simulation_solver.cc b/source/blender/simulation/intern/simulation_solver.cc index ee7a8d40035..d53ccd2bd49 100644 --- a/source/blender/simulation/intern/simulation_solver.cc +++ b/source/blender/simulation/intern/simulation_solver.cc @@ -17,23 +17,16 @@ #include "simulation_solver.hh" #include "BKE_customdata.h" -#include "BKE_lib_id.h" #include "BKE_persistent_data_handle.hh" #include "BLI_rand.hh" #include "BLI_set.hh" -namespace blender::sim { - -ParticleForce::~ParticleForce() -{ -} +#include "DEG_depsgraph_query.h" -ParticleEmitter::~ParticleEmitter() -{ -} +namespace blender::sim { -static CustomDataType cpp_to_custom_data_type(const fn::CPPType &type) +static CustomDataType cpp_to_custom_data_type(const CPPType &type) { if (type.is<float3>()) { return CD_PROP_FLOAT3; @@ -48,18 +41,18 @@ static CustomDataType cpp_to_custom_data_type(const fn::CPPType &type) return CD_PROP_FLOAT; } -static const fn::CPPType &custom_to_cpp_data_type(CustomDataType type) +static const CPPType &custom_to_cpp_data_type(CustomDataType type) { switch (type) { case CD_PROP_FLOAT3: - return fn::CPPType::get<float3>(); + return CPPType::get<float3>(); case CD_PROP_FLOAT: - return fn::CPPType::get<float>(); + return CPPType::get<float>(); case CD_PROP_INT32: - return fn::CPPType::get<int32_t>(); + return CPPType::get<int32_t>(); default: BLI_assert(false); - return fn::CPPType::get<float>(); + return CPPType::get<float>(); } } @@ -67,33 +60,33 @@ class CustomDataAttributesRef { private: Array<void *> buffers_; int64_t size_; - const fn::AttributesInfo &info_; + const AttributesInfo &info_; public: - CustomDataAttributesRef(CustomData &custom_data, int64_t size, const fn::AttributesInfo &info) + CustomDataAttributesRef(CustomData &custom_data, int64_t size, const AttributesInfo &info) : buffers_(info.size(), nullptr), size_(size), info_(info) { for (int attribute_index : info.index_range()) { StringRefNull name = info.name_of(attribute_index); - const fn::CPPType &cpp_type = info.type_of(attribute_index); + const CPPType &cpp_type = info.type_of(attribute_index); CustomDataType custom_type = cpp_to_custom_data_type(cpp_type); void *data = CustomData_get_layer_named(&custom_data, custom_type, name.c_str()); buffers_[attribute_index] = data; } } - operator fn::MutableAttributesRef() + operator MutableAttributesRef() { - return fn::MutableAttributesRef(info_, buffers_, size_); + return MutableAttributesRef(info_, buffers_, size_); } - operator fn::AttributesRef() const + operator AttributesRef() const { - return fn::AttributesRef(info_, buffers_, size_); + return AttributesRef(info_, buffers_, size_); } }; -static void ensure_attributes_exist(ParticleSimulationState *state, const fn::AttributesInfo &info) +static void ensure_attributes_exist(ParticleSimulationState *state, const AttributesInfo &info) { bool found_layer_to_remove; do { @@ -101,7 +94,7 @@ static void ensure_attributes_exist(ParticleSimulationState *state, const fn::At for (int layer_index = 0; layer_index < state->attributes.totlayer; layer_index++) { CustomDataLayer *layer = &state->attributes.layers[layer_index]; BLI_assert(layer->name != nullptr); - const fn::CPPType &cpp_type = custom_to_cpp_data_type((CustomDataType)layer->type); + const CPPType &cpp_type = custom_to_cpp_data_type((CustomDataType)layer->type); StringRefNull name = layer->name; if (!info.has_attribute(name, cpp_type)) { found_layer_to_remove = true; @@ -113,7 +106,7 @@ static void ensure_attributes_exist(ParticleSimulationState *state, const fn::At for (int attribute_index : info.index_range()) { StringRefNull attribute_name = info.name_of(attribute_index); - const fn::CPPType &cpp_type = info.type_of(attribute_index); + const CPPType &cpp_type = info.type_of(attribute_index); CustomDataType custom_type = cpp_to_custom_data_type(cpp_type); if (CustomData_get_layer_named(&state->attributes, custom_type, attribute_name.c_str()) == nullptr) { @@ -128,50 +121,241 @@ static void ensure_attributes_exist(ParticleSimulationState *state, const fn::At } } -BLI_NOINLINE static void simulate_existing_particles(SimulationSolveContext &solve_context, - ParticleSimulationState &state, - const fn::AttributesInfo &attributes_info) +BLI_NOINLINE static void apply_remaining_diffs(ParticleChunkContext &context) { - CustomDataAttributesRef custom_data_attributes{ - state.attributes, state.tot_particles, attributes_info}; - fn::MutableAttributesRef attributes = custom_data_attributes; + BLI_assert(context.integration != nullptr); + MutableSpan<float3> positions = context.attributes.get<float3>("Position"); + MutableSpan<float3> velocities = context.attributes.get<float3>("Velocity"); + + for (int i : context.index_mask) { + positions[i] += context.integration->position_diffs[i]; + velocities[i] += context.integration->velocity_diffs[i]; + } +} - Array<float3> force_vectors{state.tot_particles, {0, 0, 0}}; - const Vector<const ParticleForce *> *forces = - solve_context.influences().particle_forces.lookup_ptr(state.head.name); +BLI_NOINLINE static void find_next_event_per_particle( + SimulationSolveContext &solve_context, + ParticleChunkContext &particles, + Span<const ParticleEvent *> events, + MutableSpan<int> r_next_event_indices, + MutableSpan<float> r_time_factors_to_next_event) +{ + r_next_event_indices.fill_indices(particles.index_mask, -1); + r_time_factors_to_next_event.fill_indices(particles.index_mask, 1.0f); + + Array<float> time_factors(particles.index_mask.min_array_size()); + for (int event_index : events.index_range()) { + time_factors.fill(-1.0f); + ParticleEventFilterContext event_context{solve_context, particles, time_factors}; + const ParticleEvent &event = *events[event_index]; + event.filter(event_context); + + for (int i : particles.index_mask) { + const float time_factor = time_factors[i]; + const float previously_smallest_time_factor = r_time_factors_to_next_event[i]; + if (time_factor >= 0.0f && time_factor <= previously_smallest_time_factor) { + r_time_factors_to_next_event[i] = time_factor; + r_next_event_indices[i] = event_index; + } + } + } +} - if (forces != nullptr) { - ParticleChunkContext particle_chunk_context{IndexMask(state.tot_particles), attributes}; - ParticleForceContext particle_force_context{ - solve_context, particle_chunk_context, force_vectors}; +BLI_NOINLINE static void forward_particles_to_next_event_or_end( + ParticleChunkContext &particles, Span<float> time_factors_to_next_event) +{ + MutableSpan<float3> positions = particles.attributes.get<float3>("Position"); + MutableSpan<float3> velocities = particles.attributes.get<float3>("Velocity"); + + MutableSpan<float3> position_diffs = particles.integration->position_diffs; + MutableSpan<float3> velocity_diffs = particles.integration->velocity_diffs; + MutableSpan<float> durations = particles.integration->durations; + + for (int i : particles.index_mask) { + const float time_factor = time_factors_to_next_event[i]; + positions[i] += position_diffs[i] * time_factor; + velocities[i] += velocity_diffs[i] * time_factor; + + const float remaining_time_factor = 1.0f - time_factor; + position_diffs[i] *= remaining_time_factor; + velocity_diffs[i] *= remaining_time_factor; + durations[i] *= remaining_time_factor; + } +} - for (const ParticleForce *force : *forces) { - force->add_force(particle_force_context); +BLI_NOINLINE static void group_particles_by_event( + IndexMask mask, + Span<int> next_event_indices, + MutableSpan<Vector<int64_t>> r_particles_per_event) +{ + for (int i : mask) { + int event_index = next_event_indices[i]; + if (event_index >= 0) { + r_particles_per_event[event_index].append(i); } } +} - MutableSpan<float3> positions = attributes.get<float3>("Position"); - MutableSpan<float3> velocities = attributes.get<float3>("Velocity"); - MutableSpan<float> birth_times = attributes.get<float>("Birth Time"); - MutableSpan<int> dead_states = attributes.get<int>("Dead"); - float end_time = solve_context.solve_interval().end(); - float time_step = solve_context.solve_interval().duration(); - for (int i : positions.index_range()) { - velocities[i] += force_vectors[i] * time_step; - positions[i] += velocities[i] * time_step; - - if (end_time - birth_times[i] > 2) { - dead_states[i] = true; +BLI_NOINLINE static void execute_events(SimulationSolveContext &solve_context, + ParticleChunkContext &all_particles, + Span<const ParticleEvent *> events, + Span<Vector<int64_t>> particles_per_event) +{ + for (int event_index : events.index_range()) { + Span<int64_t> pindices = particles_per_event[event_index]; + if (pindices.is_empty()) { + continue; + } + + const ParticleEvent &event = *events[event_index]; + ParticleChunkContext particles{ + all_particles.state, pindices, all_particles.attributes, all_particles.integration}; + ParticleActionContext action_context{solve_context, particles}; + event.execute(action_context); + } +} + +BLI_NOINLINE static void find_unfinished_particles(IndexMask index_mask, + Span<float> time_factors_to_next_event, + Vector<int64_t> &r_unfinished_pindices) +{ + for (int i : index_mask) { + float time_factor = time_factors_to_next_event[i]; + if (time_factor < 1.0f) { + r_unfinished_pindices.append(i); + } + } +} + +BLI_NOINLINE static void simulate_to_next_event(SimulationSolveContext &solve_context, + ParticleChunkContext &particles, + Span<const ParticleEvent *> events, + Vector<int64_t> &r_unfinished_pindices) +{ + int array_size = particles.index_mask.min_array_size(); + Array<int> next_event_indices(array_size); + Array<float> time_factors_to_next_event(array_size); + + find_next_event_per_particle( + solve_context, particles, events, next_event_indices, time_factors_to_next_event); + + forward_particles_to_next_event_or_end(particles, time_factors_to_next_event); + + Array<Vector<int64_t>> particles_per_event(events.size()); + group_particles_by_event(particles.index_mask, next_event_indices, particles_per_event); + + execute_events(solve_context, particles, events, particles_per_event); + find_unfinished_particles( + particles.index_mask, time_factors_to_next_event, r_unfinished_pindices); +} + +BLI_NOINLINE static void simulate_with_max_n_events(SimulationSolveContext &solve_context, + ParticleSimulationState &state, + ParticleChunkContext &particles, + int max_events) +{ + Span<const ParticleEvent *> events = solve_context.influences.particle_events.lookup_as( + state.head.name); + if (events.size() == 0) { + apply_remaining_diffs(particles); + return; + } + + Vector<int64_t> unfininished_pindices = particles.index_mask.indices(); + for (int iteration : IndexRange(max_events)) { + UNUSED_VARS(iteration); + if (unfininished_pindices.is_empty()) { + break; } + + Vector<int64_t> new_unfinished_pindices; + ParticleChunkContext remaining_particles{particles.state, + unfininished_pindices.as_span(), + particles.attributes, + particles.integration}; + simulate_to_next_event(solve_context, remaining_particles, events, new_unfinished_pindices); + unfininished_pindices = std::move(new_unfinished_pindices); + } + + if (!unfininished_pindices.is_empty()) { + ParticleChunkContext remaining_particles{particles.state, + unfininished_pindices.as_span(), + particles.attributes, + particles.integration}; + apply_remaining_diffs(remaining_particles); } } +BLI_NOINLINE static void simulate_particle_chunk(SimulationSolveContext &solve_context, + ParticleSimulationState &state, + MutableAttributesRef attributes, + MutableSpan<float> remaining_durations, + float end_time) +{ + int particle_amount = attributes.size(); + + Span<const ParticleAction *> begin_actions = + solve_context.influences.particle_time_step_begin_actions.lookup_as(state.head.name); + for (const ParticleAction *action : begin_actions) { + ParticleChunkContext particles{state, IndexMask(particle_amount), attributes}; + ParticleActionContext action_context{solve_context, particles}; + action->execute(action_context); + } + + Array<float3> force_vectors{particle_amount, {0, 0, 0}}; + Span<const ParticleForce *> forces = solve_context.influences.particle_forces.lookup_as( + state.head.name); + for (const ParticleForce *force : forces) { + ParticleChunkContext particles{state, IndexMask(particle_amount), attributes}; + ParticleForceContext particle_force_context{solve_context, particles, force_vectors}; + force->add_force(particle_force_context); + } + + MutableSpan<float3> velocities = attributes.get<float3>("Velocity"); + + Array<float3> position_diffs(particle_amount); + Array<float3> velocity_diffs(particle_amount); + for (int i : IndexRange(particle_amount)) { + const float time_step = remaining_durations[i]; + velocity_diffs[i] = force_vectors[i] * time_step; + position_diffs[i] = (velocities[i] + velocity_diffs[i] / 2.0f) * time_step; + } + + ParticleChunkIntegrationContext integration_context = { + position_diffs, velocity_diffs, remaining_durations, end_time}; + ParticleChunkContext particle_chunk_context{ + state, IndexMask(particle_amount), attributes, &integration_context}; + + simulate_with_max_n_events(solve_context, state, particle_chunk_context, 10); + + Span<const ParticleAction *> end_actions = + solve_context.influences.particle_time_step_end_actions.lookup_as(state.head.name); + for (const ParticleAction *action : end_actions) { + ParticleChunkContext particles{state, IndexMask(particle_amount), attributes}; + ParticleActionContext action_context{solve_context, particles}; + action->execute(action_context); + } +} + +BLI_NOINLINE static void simulate_existing_particles(SimulationSolveContext &solve_context, + ParticleSimulationState &state, + const AttributesInfo &attributes_info) +{ + CustomDataAttributesRef custom_data_attributes{ + state.attributes, state.tot_particles, attributes_info}; + MutableAttributesRef attributes = custom_data_attributes; + + Array<float> remaining_durations(state.tot_particles, solve_context.solve_interval.duration()); + simulate_particle_chunk( + solve_context, state, attributes, remaining_durations, solve_context.solve_interval.stop()); +} + BLI_NOINLINE static void run_emitters(SimulationSolveContext &solve_context, ParticleAllocators &particle_allocators) { - for (const ParticleEmitter *emitter : solve_context.influences().particle_emitters) { + for (const ParticleEmitter *emitter : solve_context.influences.particle_emitters) { ParticleEmitterContext emitter_context{ - solve_context, particle_allocators, solve_context.solve_interval()}; + solve_context, particle_allocators, solve_context.solve_interval}; emitter->emit(emitter_context); } } @@ -181,10 +365,10 @@ BLI_NOINLINE static int count_particles_after_time_step(ParticleSimulationState { CustomDataAttributesRef custom_data_attributes{ state.attributes, state.tot_particles, allocator.attributes_info()}; - fn::MutableAttributesRef attributes = custom_data_attributes; + MutableAttributesRef attributes = custom_data_attributes; int new_particle_amount = attributes.get<int>("Dead").count(0); - for (fn::MutableAttributesRef emitted_attributes : allocator.get_allocations()) { + for (MutableAttributesRef emitted_attributes : allocator.get_allocations()) { new_particle_amount += emitted_attributes.get<int>("Dead").count(0); } @@ -199,7 +383,7 @@ BLI_NOINLINE static void remove_dead_and_add_new_particles(ParticleSimulationSta CustomDataAttributesRef custom_data_attributes{ state.attributes, state.tot_particles, allocator.attributes_info()}; - Vector<fn::MutableAttributesRef> particle_sources; + Vector<MutableAttributesRef> particle_sources; particle_sources.append(custom_data_attributes); particle_sources.extend(allocator.get_allocations()); @@ -211,16 +395,16 @@ BLI_NOINLINE static void remove_dead_and_add_new_particles(ParticleSimulationSta dead_layer = &layer; continue; } - const fn::CPPType &cpp_type = custom_to_cpp_data_type((CustomDataType)layer.type); - fn::GMutableSpan new_buffer{ + const CPPType &cpp_type = custom_to_cpp_data_type((CustomDataType)layer.type); + GMutableSpan new_buffer{ cpp_type, MEM_mallocN_aligned(new_particle_amount * cpp_type.size(), cpp_type.alignment(), AT), new_particle_amount}; int current = 0; - for (fn::MutableAttributesRef attributes : particle_sources) { + for (MutableAttributesRef attributes : particle_sources) { Span<int> dead_states = attributes.get<int>("Dead"); - fn::GSpan source_buffer = attributes.get(name); + GSpan source_buffer = attributes.get(name); BLI_assert(source_buffer.type() == cpp_type); for (int i : attributes.index_range()) { if (dead_states[i] == 0) { @@ -233,7 +417,7 @@ BLI_NOINLINE static void remove_dead_and_add_new_particles(ParticleSimulationSta if (layer.data != nullptr) { MEM_freeN(layer.data); } - layer.data = new_buffer.buffer(); + layer.data = new_buffer.data(); } BLI_assert(dead_layer != nullptr); @@ -246,56 +430,10 @@ BLI_NOINLINE static void remove_dead_and_add_new_particles(ParticleSimulationSta state.next_particle_id += allocator.total_allocated(); } -static void update_persistent_data_handles(Simulation &simulation, - const VectorSet<ID *> &used_data_blocks) -{ - Set<ID *> contained_ids; - Set<int> used_handles; - - /* Remove handles that have been invalidated. */ - LISTBASE_FOREACH_MUTABLE ( - PersistentDataHandleItem *, handle_item, &simulation.persistent_data_handles) { - if (handle_item->id == nullptr) { - BLI_remlink(&simulation.persistent_data_handles, handle_item); - continue; - } - if (!used_data_blocks.contains(handle_item->id)) { - id_us_min(handle_item->id); - BLI_remlink(&simulation.persistent_data_handles, handle_item); - MEM_freeN(handle_item); - continue; - } - contained_ids.add_new(handle_item->id); - used_handles.add_new(handle_item->handle); - } - - /* Add new handles that are not in the list yet. */ - int next_handle = 0; - for (ID *id : used_data_blocks) { - if (contained_ids.contains(id)) { - continue; - } - - /* Find the next available handle. */ - while (used_handles.contains(next_handle)) { - next_handle++; - } - used_handles.add_new(next_handle); - - PersistentDataHandleItem *handle_item = (PersistentDataHandleItem *)MEM_callocN( - sizeof(*handle_item), AT); - /* Cannot store const pointers in DNA. */ - id_us_plus(id); - handle_item->id = id; - handle_item->handle = next_handle; - - BLI_addtail(&simulation.persistent_data_handles, handle_item); - } -} - void initialize_simulation_states(Simulation &simulation, Depsgraph &UNUSED(depsgraph), - const SimulationInfluences &UNUSED(influences)) + const SimulationInfluences &UNUSED(influences), + const bke::PersistentDataHandleMap &UNUSED(handle_map)) { simulation.current_simulation_time = 0.0f; } @@ -303,15 +441,10 @@ void initialize_simulation_states(Simulation &simulation, void solve_simulation_time_step(Simulation &simulation, Depsgraph &depsgraph, const SimulationInfluences &influences, + const bke::PersistentDataHandleMap &handle_map, + const DependencyAnimations &dependency_animations, float time_step) { - update_persistent_data_handles(simulation, influences.used_data_blocks); - - bke::PersistentDataHandleMap handle_map; - LISTBASE_FOREACH (PersistentDataHandleItem *, handle, &simulation.persistent_data_handles) { - handle_map.add(handle->handle, *handle->id); - } - SimulationStateMap state_map; LISTBASE_FOREACH (SimulationState *, state, &simulation.states) { state_map.add(state); @@ -322,30 +455,32 @@ void solve_simulation_time_step(Simulation &simulation, influences, TimeInterval(simulation.current_simulation_time, time_step), state_map, - handle_map}; - TimeInterval simulation_time_interval{simulation.current_simulation_time, time_step}; + handle_map, + dependency_animations}; Span<ParticleSimulationState *> particle_simulation_states = state_map.lookup<ParticleSimulationState>(); - Map<std::string, std::unique_ptr<fn::AttributesInfo>> attribute_infos; + Map<std::string, std::unique_ptr<AttributesInfo>> attribute_infos; Map<std::string, std::unique_ptr<ParticleAllocator>> particle_allocators_map; for (ParticleSimulationState *state : particle_simulation_states) { - const fn::AttributesInfoBuilder &builder = *influences.particle_attributes_builder.lookup_as( + const AttributesInfoBuilder &builder = *influences.particle_attributes_builder.lookup_as( state->head.name); - auto info = std::make_unique<fn::AttributesInfo>(builder); + auto info = std::make_unique<AttributesInfo>(builder); ensure_attributes_exist(state, *info); + uint32_t hash_seed = DefaultHash<StringRef>{}(state->head.name); particle_allocators_map.add_new( - state->head.name, std::make_unique<ParticleAllocator>(*info, state->next_particle_id)); + state->head.name, + std::make_unique<ParticleAllocator>(*info, state->next_particle_id, hash_seed)); attribute_infos.add_new(state->head.name, std::move(info)); } ParticleAllocators particle_allocators{particle_allocators_map}; for (ParticleSimulationState *state : particle_simulation_states) { - const fn::AttributesInfo &attributes_info = *attribute_infos.lookup_as(state->head.name); + const AttributesInfo &attributes_info = *attribute_infos.lookup_as(state->head.name); simulate_existing_particles(solve_context, *state, attributes_info); } @@ -353,10 +488,35 @@ void solve_simulation_time_step(Simulation &simulation, for (ParticleSimulationState *state : particle_simulation_states) { ParticleAllocator &allocator = *particle_allocators.try_get_allocator(state->head.name); + + for (MutableAttributesRef attributes : allocator.get_allocations()) { + Span<const ParticleAction *> actions = influences.particle_birth_actions.lookup_as( + state->head.name); + for (const ParticleAction *action : actions) { + ParticleChunkContext chunk_context{*state, IndexRange(attributes.size()), attributes}; + ParticleActionContext action_context{solve_context, chunk_context}; + action->execute(action_context); + } + } + } + + for (ParticleSimulationState *state : particle_simulation_states) { + ParticleAllocator &allocator = *particle_allocators.try_get_allocator(state->head.name); + + for (MutableAttributesRef attributes : allocator.get_allocations()) { + Array<float> remaining_durations(attributes.size()); + Span<float> birth_times = attributes.get<float>("Birth Time"); + const float end_time = solve_context.solve_interval.stop(); + for (int i : attributes.index_range()) { + remaining_durations[i] = end_time - birth_times[i]; + } + simulate_particle_chunk(solve_context, *state, attributes, remaining_durations, end_time); + } + remove_dead_and_add_new_particles(*state, allocator); } - simulation.current_simulation_time = simulation_time_interval.end(); + simulation.current_simulation_time = solve_context.solve_interval.stop(); } } // namespace blender::sim diff --git a/source/blender/simulation/intern/simulation_solver.hh b/source/blender/simulation/intern/simulation_solver.hh index 3fc61f579e3..2cf8eb2aa27 100644 --- a/source/blender/simulation/intern/simulation_solver.hh +++ b/source/blender/simulation/intern/simulation_solver.hh @@ -16,259 +16,22 @@ #pragma once -#include "BLI_float3.hh" -#include "BLI_span.hh" - -#include "DNA_simulation_types.h" - -#include "FN_attributes_ref.hh" - -#include "BKE_persistent_data_handle.hh" -#include "BKE_simulation.h" - -#include "particle_allocator.hh" -#include "time_interval.hh" +#include "simulation_collect_influences.hh" struct Depsgraph; namespace blender::sim { -class ParticleEmitterContext; -class ParticleForceContext; - -class ParticleEmitter { - public: - virtual ~ParticleEmitter(); - virtual void emit(ParticleEmitterContext &context) const = 0; -}; - -class ParticleForce { - public: - virtual ~ParticleForce(); - virtual void add_force(ParticleForceContext &context) const = 0; -}; - -struct SimulationInfluences { - Map<std::string, Vector<const ParticleForce *>> particle_forces; - Map<std::string, fn::AttributesInfoBuilder *> particle_attributes_builder; - Vector<const ParticleEmitter *> particle_emitters; - VectorSet<ID *> used_data_blocks; -}; - -class SimulationStateMap { - private: - Map<StringRefNull, SimulationState *> states_by_name_; - Map<StringRefNull, Vector<SimulationState *>> states_by_type_; - - public: - void add(SimulationState *state) - { - states_by_name_.add_new(state->name, state); - states_by_type_.lookup_or_add_default(state->type).append(state); - } - - template<typename StateType> StateType *lookup(StringRef name) const - { - const char *type = BKE_simulation_get_state_type_name<StateType>(); - return (StateType *)this->lookup_name_type(name, type); - } - - template<typename StateType> Span<StateType *> lookup() const - { - const char *type = BKE_simulation_get_state_type_name<StateType>(); - return this->lookup_type(type).cast<StateType *>(); - } - - SimulationState *lookup_name_type(StringRef name, StringRef type) const - { - SimulationState *state = states_by_name_.lookup_default_as(name, nullptr); - if (state == nullptr) { - return nullptr; - } - if (state->type == type) { - return state; - } - return nullptr; - } - - Span<SimulationState *> lookup_type(StringRef type) const - { - const Vector<SimulationState *> *states = states_by_type_.lookup_ptr_as(type); - if (states == nullptr) { - return {}; - } - else { - return states->as_span(); - } - } -}; - -class SimulationSolveContext { - private: - Simulation &simulation_; - Depsgraph &depsgraph_; - const SimulationInfluences &influences_; - TimeInterval solve_interval_; - const SimulationStateMap &state_map_; - const bke::PersistentDataHandleMap &id_handle_map_; - - public: - SimulationSolveContext(Simulation &simulation, - Depsgraph &depsgraph, - const SimulationInfluences &influences, - TimeInterval solve_interval, - const SimulationStateMap &state_map, - const bke::PersistentDataHandleMap &handle_map) - : simulation_(simulation), - depsgraph_(depsgraph), - influences_(influences), - solve_interval_(solve_interval), - state_map_(state_map), - id_handle_map_(handle_map) - { - } - - TimeInterval solve_interval() const - { - return solve_interval_; - } - - const SimulationInfluences &influences() const - { - return influences_; - } - - const bke::PersistentDataHandleMap &handle_map() const - { - return id_handle_map_; - } - - const SimulationStateMap &state_map() const - { - return state_map_; - } -}; - -class ParticleAllocators { - private: - Map<std::string, std::unique_ptr<ParticleAllocator>> &allocators_; - - public: - ParticleAllocators(Map<std::string, std::unique_ptr<ParticleAllocator>> &allocators) - : allocators_(allocators) - { - } - - ParticleAllocator *try_get_allocator(StringRef particle_simulation_name) - { - auto *ptr = allocators_.lookup_ptr_as(particle_simulation_name); - if (ptr != nullptr) { - return ptr->get(); - } - else { - return nullptr; - } - } -}; - -class ParticleChunkContext { - private: - IndexMask index_mask_; - fn::MutableAttributesRef attributes_; - - public: - ParticleChunkContext(IndexMask index_mask, fn::MutableAttributesRef attributes) - : index_mask_(index_mask), attributes_(attributes) - { - } - - IndexMask index_mask() const - { - return index_mask_; - } - - fn::MutableAttributesRef attributes() - { - return attributes_; - } - - fn::AttributesRef attributes() const - { - return attributes_; - } -}; - -class ParticleEmitterContext { - private: - SimulationSolveContext &solve_context_; - ParticleAllocators &particle_allocators_; - TimeInterval simulation_time_interval_; - - public: - ParticleEmitterContext(SimulationSolveContext &solve_context, - ParticleAllocators &particle_allocators, - TimeInterval simulation_time_interval) - : solve_context_(solve_context), - particle_allocators_(particle_allocators), - simulation_time_interval_(simulation_time_interval) - { - } - - SimulationSolveContext &solve_context() - { - return solve_context_; - } - - ParticleAllocator *try_get_particle_allocator(StringRef particle_simulation_name) - { - return particle_allocators_.try_get_allocator(particle_simulation_name); - } - - TimeInterval simulation_time_interval() const - { - return simulation_time_interval_; - } -}; - -class ParticleForceContext { - private: - SimulationSolveContext &solve_context_; - const ParticleChunkContext &particle_chunk_context_; - MutableSpan<float3> force_dst_; - - public: - ParticleForceContext(SimulationSolveContext &solve_context, - const ParticleChunkContext &particle_chunk_context, - MutableSpan<float3> force_dst) - : solve_context_(solve_context), - particle_chunk_context_(particle_chunk_context), - force_dst_(force_dst) - { - } - - SimulationSolveContext &solve_context() - { - return solve_context_; - } - - const ParticleChunkContext &particle_chunk() const - { - return particle_chunk_context_; - } - - MutableSpan<float3> force_dst() - { - return force_dst_; - } -}; - void initialize_simulation_states(Simulation &simulation, Depsgraph &depsgraph, - const SimulationInfluences &influences); + const SimulationInfluences &influences, + const bke::PersistentDataHandleMap &handle_map); void solve_simulation_time_step(Simulation &simulation, Depsgraph &depsgraph, const SimulationInfluences &influences, + const bke::PersistentDataHandleMap &handle_map, + const DependencyAnimations &dependency_animations, float time_step); } // namespace blender::sim diff --git a/source/blender/simulation/intern/simulation_solver_influences.cc b/source/blender/simulation/intern/simulation_solver_influences.cc new file mode 100644 index 00000000000..3485d7c7bfb --- /dev/null +++ b/source/blender/simulation/intern/simulation_solver_influences.cc @@ -0,0 +1,57 @@ +/* + * 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. + */ + +#include "simulation_solver_influences.hh" + +#include "DNA_object_types.h" + +namespace blender::sim { + +ParticleForce::~ParticleForce() +{ +} + +ParticleEmitter::~ParticleEmitter() +{ +} + +ParticleAction::~ParticleAction() +{ +} + +ParticleEvent::~ParticleEvent() +{ +} + +DependencyAnimations::~DependencyAnimations() +{ +} + +bool DependencyAnimations::is_object_transform_changing(Object &UNUSED(object)) const +{ + return false; +} + +void DependencyAnimations::get_object_transforms(Object &object, + Span<float> simulation_times, + MutableSpan<float4x4> r_transforms) const +{ + assert_same_size(simulation_times, r_transforms); + float4x4 world_matrix = object.obmat; + r_transforms.fill(world_matrix); +} + +} // namespace blender::sim diff --git a/source/blender/simulation/intern/simulation_solver_influences.hh b/source/blender/simulation/intern/simulation_solver_influences.hh new file mode 100644 index 00000000000..d7914819d36 --- /dev/null +++ b/source/blender/simulation/intern/simulation_solver_influences.hh @@ -0,0 +1,234 @@ +/* + * 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. + */ + +#pragma once + +#include "BLI_float3.hh" +#include "BLI_float4x4.hh" +#include "BLI_multi_value_map.hh" +#include "BLI_span.hh" + +#include "DNA_simulation_types.h" + +#include "FN_attributes_ref.hh" + +#include "BKE_persistent_data_handle.hh" +#include "BKE_simulation.h" + +#include "particle_allocator.hh" +#include "time_interval.hh" + +namespace blender::sim { + +using fn::AttributesInfo; +using fn::AttributesInfoBuilder; +using fn::AttributesRef; +using fn::CPPType; +using fn::GMutableSpan; +using fn::GSpan; +using fn::MutableAttributesRef; + +struct ParticleEmitterContext; +struct ParticleForceContext; +struct ParticleActionContext; +struct ParticleEventFilterContext; + +class ParticleEmitter { + public: + virtual ~ParticleEmitter(); + virtual void emit(ParticleEmitterContext &context) const = 0; +}; + +class ParticleForce { + public: + virtual ~ParticleForce(); + virtual void add_force(ParticleForceContext &context) const = 0; +}; + +class ParticleAction { + public: + virtual ~ParticleAction(); + virtual void execute(ParticleActionContext &context) const = 0; +}; + +class ParticleEvent { + public: + virtual ~ParticleEvent(); + virtual void filter(ParticleEventFilterContext &context) const = 0; + virtual void execute(ParticleActionContext &context) const = 0; +}; + +struct SimulationInfluences { + MultiValueMap<std::string, const ParticleForce *> particle_forces; + MultiValueMap<std::string, const ParticleAction *> particle_birth_actions; + MultiValueMap<std::string, const ParticleAction *> particle_time_step_begin_actions; + MultiValueMap<std::string, const ParticleAction *> particle_time_step_end_actions; + MultiValueMap<std::string, const ParticleEvent *> particle_events; + Map<std::string, AttributesInfoBuilder *> particle_attributes_builder; + Vector<const ParticleEmitter *> particle_emitters; +}; + +class SimulationStateMap { + private: + Map<StringRefNull, SimulationState *> states_by_name_; + MultiValueMap<StringRefNull, SimulationState *> states_by_type_; + + public: + void add(SimulationState *state) + { + states_by_name_.add_new(state->name, state); + states_by_type_.add(state->type, state); + } + + template<typename StateType> StateType *lookup(StringRef name) const + { + const char *type = BKE_simulation_get_state_type_name<StateType>(); + return (StateType *)this->lookup_name_type(name, type); + } + + template<typename StateType> Span<StateType *> lookup() const + { + const char *type = BKE_simulation_get_state_type_name<StateType>(); + return this->lookup_type(type).cast<StateType *>(); + } + + SimulationState *lookup_name_type(StringRef name, StringRef type) const + { + SimulationState *state = states_by_name_.lookup_default_as(name, nullptr); + if (state == nullptr) { + return nullptr; + } + if (state->type == type) { + return state; + } + return nullptr; + } + + Span<SimulationState *> lookup_type(StringRef type) const + { + return states_by_type_.lookup_as(type); + } +}; + +class DependencyAnimations { + public: + ~DependencyAnimations(); + + virtual bool is_object_transform_changing(Object &object) const; + virtual void get_object_transforms(Object &object, + Span<float> simulation_times, + MutableSpan<float4x4> r_transforms) const; +}; + +struct SimulationSolveContext { + Simulation &simulation; + Depsgraph &depsgraph; + const SimulationInfluences &influences; + TimeInterval solve_interval; + const SimulationStateMap &state_map; + const bke::PersistentDataHandleMap &handle_map; + const DependencyAnimations &dependency_animations; +}; + +class ParticleAllocators { + private: + Map<std::string, std::unique_ptr<ParticleAllocator>> &allocators_; + + public: + ParticleAllocators(Map<std::string, std::unique_ptr<ParticleAllocator>> &allocators) + : allocators_(allocators) + { + } + + ParticleAllocator *try_get_allocator(StringRef particle_simulation_name) + { + auto *ptr = allocators_.lookup_ptr_as(particle_simulation_name); + if (ptr != nullptr) { + return ptr->get(); + } + else { + return nullptr; + } + } +}; + +struct ParticleChunkIntegrationContext { + MutableSpan<float3> position_diffs; + MutableSpan<float3> velocity_diffs; + MutableSpan<float> durations; + float end_time; +}; + +struct ParticleChunkContext { + ParticleSimulationState &state; + IndexMask index_mask; + MutableAttributesRef attributes; + ParticleChunkIntegrationContext *integration = nullptr; + + void update_diffs_after_velocity_change() + { + if (integration == nullptr) { + return; + } + + Span<float> remaining_durations = integration->durations; + MutableSpan<float3> position_diffs = integration->position_diffs; + Span<float3> velocities = attributes.get<float3>("Velocity"); + + for (int i : index_mask) { + const float duration = remaining_durations[i]; + /* This is certainly not a perfect way to "re-integrate" the velocity, but it should be good + * enough for most use cases. Changing the velocity in an instant is not physically correct + * anyway. */ + position_diffs[i] = velocities[i] * duration; + } + } +}; + +struct ParticleEmitterContext { + SimulationSolveContext &solve_context; + ParticleAllocators &particle_allocators; + TimeInterval emit_interval; + + template<typename StateType> StateType *lookup_state(StringRef name) + { + return solve_context.state_map.lookup<StateType>(name); + } + + ParticleAllocator *try_get_particle_allocator(StringRef particle_simulation_name) + { + return particle_allocators.try_get_allocator(particle_simulation_name); + } +}; + +struct ParticleForceContext { + SimulationSolveContext &solve_context; + ParticleChunkContext &particles; + MutableSpan<float3> force_dst; +}; + +struct ParticleActionContext { + SimulationSolveContext &solve_context; + ParticleChunkContext &particles; +}; + +struct ParticleEventFilterContext { + SimulationSolveContext &solve_context; + ParticleChunkContext &particles; + MutableSpan<float> factor_dst; +}; + +} // namespace blender::sim diff --git a/source/blender/simulation/intern/simulation_update.cc b/source/blender/simulation/intern/simulation_update.cc index 09219e0238f..32b582977d0 100644 --- a/source/blender/simulation/intern/simulation_update.cc +++ b/source/blender/simulation/intern/simulation_update.cc @@ -17,8 +17,11 @@ #include "SIM_simulation_update.hh" #include "BKE_customdata.h" +#include "BKE_lib_id.h" +#include "BKE_object.h" #include "BKE_simulation.h" +#include "DNA_modifier_types.h" #include "DNA_scene_types.h" #include "DNA_simulation_types.h" @@ -29,8 +32,11 @@ #include "BLI_listbase.h" #include "BLI_map.hh" #include "BLI_rand.h" +#include "BLI_set.hh" #include "BLI_vector.hh" +#include "NOD_node_tree_dependencies.hh" + #include "particle_function.hh" #include "simulation_collect_influences.hh" #include "simulation_solver.hh" @@ -88,6 +94,131 @@ static void update_simulation_state_list(Simulation *simulation, add_missing_states(simulation, required_states); } +class SampledDependencyAnimations : public DependencyAnimations { + private: + TimeInterval simulation_time_interval_; + MultiValueMap<Object *, float4x4> object_transforms_cache_; + + public: + SampledDependencyAnimations(TimeInterval simulation_time_interval) + : simulation_time_interval_(simulation_time_interval) + { + } + + void add_object_transforms(Object &object, Span<float4x4> transforms) + { + object_transforms_cache_.add_multiple(&object, transforms); + } + + bool is_object_transform_changing(Object &object) const + { + return object_transforms_cache_.lookup(&object).size() >= 2; + } + + void get_object_transforms(Object &object, + Span<float> simulation_times, + MutableSpan<float4x4> r_transforms) const + { + assert_same_size(simulation_times, r_transforms); + Span<float4x4> cached_transforms = object_transforms_cache_.lookup(&object); + if (cached_transforms.size() == 0) { + r_transforms.fill(object.obmat); + return; + } + if (cached_transforms.size() == 1) { + r_transforms.fill(cached_transforms[0]); + return; + } + + for (int i : simulation_times.index_range()) { + const float simulation_time = simulation_times[i]; + if (simulation_time <= simulation_time_interval_.start()) { + r_transforms[i] = cached_transforms.first(); + continue; + } + if (simulation_time >= simulation_time_interval_.stop()) { + r_transforms[i] = cached_transforms.last(); + continue; + } + const float factor = simulation_time_interval_.factor_at_time(simulation_time); + BLI_assert(factor > 0.0f && factor < 1.0f); + const float scaled_factor = factor * (cached_transforms.size() - 1); + const int lower_sample = (int)scaled_factor; + const int upper_sample = lower_sample + 1; + const float mix_factor = scaled_factor - lower_sample; + r_transforms[i] = float4x4::interpolate( + cached_transforms[lower_sample], cached_transforms[upper_sample], mix_factor); + } + } +}; + +static void sample_object_transforms(Object &object, + Depsgraph &depsgraph, + Scene &scene, + TimeInterval scene_frame_interval, + MutableSpan<float4x4> r_transforms) +{ + if (r_transforms.size() == 0) { + return; + } + if (r_transforms.size() == 1) { + r_transforms[0] = object.obmat; + return; + } + + Array<float> frames(r_transforms.size()); + scene_frame_interval.compute_uniform_samples(frames); + + for (int i : frames.index_range()) { + float frame = frames[i]; + const int recursion_depth = 5; + BKE_object_modifier_update_subframe( + &depsgraph, &scene, &object, false, recursion_depth, frame, eModifierType_None); + r_transforms[i] = object.obmat; + } +} + +template<typename T> static bool all_values_equal(Span<T> values) +{ + if (values.size() == 0) { + return true; + } + for (const T &value : values.drop_front(1)) { + if (value != values[0]) { + return false; + } + } + return true; +} + +static void prepare_dependency_animations(Depsgraph &depsgraph, + Scene &scene, + Simulation &simulation, + TimeInterval scene_frame_interval, + SampledDependencyAnimations &r_dependency_animations) +{ + LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation.dependencies) { + ID *id_cow = DEG_get_evaluated_id(&depsgraph, dependency->id); + if (id_cow == nullptr) { + continue; + } + if (GS(id_cow->name) != ID_OB) { + continue; + } + Object &object_cow = *(Object *)id_cow; + constexpr int sample_count = 10; + Array<float4x4, sample_count> transforms(sample_count); + sample_object_transforms(object_cow, depsgraph, scene, scene_frame_interval, transforms); + + /* If all samples are the same, only store one. */ + Span<float4x4> transforms_to_use = (all_values_equal(transforms.as_span())) ? + transforms.as_span().take_front(1) : + transforms.as_span(); + + r_dependency_animations.add_object_transforms(object_cow, transforms_to_use); + } +} + void update_simulation_in_depsgraph(Depsgraph *depsgraph, Scene *scene_cow, Simulation *simulation_cow) @@ -108,13 +239,20 @@ void update_simulation_in_depsgraph(Depsgraph *depsgraph, SimulationInfluences influences; RequiredStates required_states; - /* TODO: Use simulation_cow, but need to add depsgraph relations before that. */ - collect_simulation_influences(*simulation_orig, resources, influences, required_states); + collect_simulation_influences(*simulation_cow, resources, influences, required_states); + + bke::PersistentDataHandleMap handle_map; + LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation_orig->dependencies) { + ID *id_cow = DEG_get_evaluated_id(depsgraph, dependency->id); + if (id_cow != nullptr) { + handle_map.add(dependency->handle, *id_cow); + } + } if (current_frame == 1) { reinitialize_empty_simulation_states(simulation_orig, required_states); - initialize_simulation_states(*simulation_orig, *depsgraph, influences); + initialize_simulation_states(*simulation_orig, *depsgraph, influences, handle_map); simulation_orig->current_frame = 1; copy_states_to_cow(simulation_orig, simulation_cow); @@ -122,12 +260,97 @@ void update_simulation_in_depsgraph(Depsgraph *depsgraph, else if (current_frame == simulation_orig->current_frame + 1) { update_simulation_state_list(simulation_orig, required_states); - float time_step = 1.0f / 24.0f; - solve_simulation_time_step(*simulation_orig, *depsgraph, influences, time_step); + const float fps = scene_cow->r.frs_sec / scene_cow->r.frs_sec_base; + const float time_step = 1.0f / fps; + TimeInterval scene_frame_interval(current_frame - 1, 1); + TimeInterval simulation_time_interval(simulation_orig->current_simulation_time, time_step); + SampledDependencyAnimations dependency_animations{simulation_time_interval}; + prepare_dependency_animations( + *depsgraph, *scene_cow, *simulation_orig, scene_frame_interval, dependency_animations); + + solve_simulation_time_step( + *simulation_orig, *depsgraph, influences, handle_map, dependency_animations, time_step); simulation_orig->current_frame = current_frame; copy_states_to_cow(simulation_orig, simulation_cow); } } +/* Returns true when dependencies have changed. */ +bool update_simulation_dependencies(Simulation *simulation) +{ + nodes::NodeTreeDependencies dependencies = nodes::find_node_tree_dependencies( + *simulation->nodetree); + + ListBase *dependency_list = &simulation->dependencies; + + bool dependencies_changed = false; + + Map<ID *, SimulationDependency *> dependency_by_id; + Map<SimulationDependency *, int> old_flag_by_dependency; + Set<int> used_handles; + + /* Remove unused handle items and clear flags that are reinitialized later. */ + LISTBASE_FOREACH_MUTABLE (SimulationDependency *, dependency, dependency_list) { + if (dependencies.depends_on(dependency->id)) { + dependency_by_id.add_new(dependency->id, dependency); + used_handles.add_new(dependency->handle); + old_flag_by_dependency.add_new(dependency, dependency->flag); + dependency->flag &= ~(SIM_DEPENDS_ON_TRANSFORM | SIM_DEPENDS_ON_GEOMETRY); + } + else { + if (dependency->id != nullptr) { + id_us_min(dependency->id); + } + BLI_remlink(dependency_list, dependency); + MEM_freeN(dependency); + dependencies_changed = true; + } + } + + /* Add handle items for new id dependencies. */ + int next_handle = 0; + for (ID *id : dependencies.id_dependencies()) { + dependency_by_id.lookup_or_add_cb(id, [&]() { + while (used_handles.contains(next_handle)) { + next_handle++; + } + used_handles.add_new(next_handle); + + SimulationDependency *dependency = (SimulationDependency *)MEM_callocN(sizeof(*dependency), + AT); + id_us_plus(id); + dependency->id = id; + dependency->handle = next_handle; + BLI_addtail(dependency_list, dependency); + + return dependency; + }); + } + + /* Set appropriate dependency flags. */ + for (Object *object : dependencies.transform_dependencies()) { + SimulationDependency *dependency = dependency_by_id.lookup(&object->id); + dependency->flag |= SIM_DEPENDS_ON_TRANSFORM; + } + for (Object *object : dependencies.geometry_dependencies()) { + SimulationDependency *dependency = dependency_by_id.lookup(&object->id); + dependency->flag |= SIM_DEPENDS_ON_GEOMETRY; + } + + if (!dependencies_changed) { + /* Check if any flags have changed. */ + LISTBASE_FOREACH (SimulationDependency *, dependency, dependency_list) { + uint32_t old_flag = old_flag_by_dependency.lookup_default(dependency, 0); + uint32_t new_flag = dependency->flag; + if (old_flag != new_flag) { + dependencies_changed = true; + break; + } + } + } + + return dependencies_changed; +} + } // namespace blender::sim diff --git a/source/blender/simulation/intern/time_interval.hh b/source/blender/simulation/intern/time_interval.hh index 6f13634ed06..034628fa9be 100644 --- a/source/blender/simulation/intern/time_interval.hh +++ b/source/blender/simulation/intern/time_interval.hh @@ -21,7 +21,7 @@ namespace blender::sim { /** - * The start time is inclusive and the end time is exclusive. The duration is zero, the interval + * The start time is exclusive and the end time is inclusive. If the duration is zero, the interval * describes a single point in time. */ class TimeInterval { @@ -40,7 +40,7 @@ class TimeInterval { return start_; } - float end() const + float stop() const { return start_ + duration_; } @@ -49,6 +49,42 @@ class TimeInterval { { return duration_; } + + float time_at_factor(float factor) const + { + return start_ + factor * duration_; + } + + float factor_at_time(float time) const + { + BLI_assert(duration_ > 0.0f); + return (time - start_) / duration_; + } + + float safe_factor_at_time(float time) const + { + if (duration_ > 0.0f) { + return this->factor_at_time(time); + } + return 0.0f; + } + + void compute_uniform_samples(MutableSpan<float> r_samples) const + { + int64_t amount = r_samples.size(); + if (amount == 0) { + return; + } + if (amount == 1) { + r_samples[0] = this->time_at_factor(0.5f); + return; + } + + const float step = duration_ / (float)(amount - 1); + for (int64_t i : r_samples.index_range()) { + r_samples[i] = start_ + i * step; + } + } }; } // namespace blender::sim diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 332f53c9ee7..07746af4b60 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -98,7 +98,7 @@ void WM_main(struct bContext *C) ATTR_NORETURN; void WM_init_splash(struct bContext *C); -void WM_init_opengl(struct Main *bmain); +void WM_init_opengl(void); void WM_check(struct bContext *C); void WM_reinit_gizmomap_all(struct Main *bmain); diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo.c index e687af15982..87cb4d5f584 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo.c @@ -29,7 +29,6 @@ #include "BKE_context.h" #include "GPU_batch.h" -#include "GPU_glew.h" #include "RNA_access.h" #include "RNA_define.h" @@ -453,9 +452,7 @@ bool wm_gizmo_select_and_highlight(bContext *C, wmGizmoMap *gzmap, wmGizmo *gz) wm_gizmomap_highlight_set(gzmap, C, gz, gz->highlight_part); return true; } - else { - return false; - } + return false; } /** diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c index 67f30f0d7ee..b64d544962d 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c @@ -166,12 +166,10 @@ int WM_gizmo_cmp_temp_fl(const void *gz_a_ptr, const void *gz_b_ptr) if (gz_a->temp.f < gz_b->temp.f) { return -1; } - else if (gz_a->temp.f > gz_b->temp.f) { + if (gz_a->temp.f > gz_b->temp.f) { return 1; } - else { - return 0; - } + return 0; } int WM_gizmo_cmp_temp_fl_reverse(const void *gz_a_ptr, const void *gz_b_ptr) @@ -181,12 +179,10 @@ int WM_gizmo_cmp_temp_fl_reverse(const void *gz_a_ptr, const void *gz_b_ptr) if (gz_a->temp.f < gz_b->temp.f) { return 1; } - else if (gz_a->temp.f > gz_b->temp.f) { + if (gz_a->temp.f > gz_b->temp.f) { return -1; } - else { - return 0; - } + return 0; } static bool wm_gizmo_keymap_uses_event_modifier(wmWindowManager *wm, @@ -396,10 +392,9 @@ static int gizmo_select_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE return OPERATOR_FINISHED; } - else { - BLI_assert(0); - return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH); - } + + BLI_assert(0); + return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH); } void GIZMOGROUP_OT_gizmo_select(wmOperatorType *ot) @@ -476,9 +471,7 @@ static bool gizmo_tweak_start_and_finish( } return true; } - else { - return false; - } + return false; } static void gizmo_tweak_finish(bContext *C, wmOperator *op, const bool cancel, bool clear_modal) diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c index 396b59ba6e2..cecd324ff28 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c @@ -38,7 +38,6 @@ #include "ED_select_utils.h" #include "ED_view3d.h" -#include "GPU_glew.h" #include "GPU_matrix.h" #include "GPU_select.h" #include "GPU_state.h" @@ -264,11 +263,10 @@ bool WM_gizmomap_minmax(const wmGizmoMap *gzmap, } return i != 0; } - else { - bool ok = false; - BLI_assert(!"TODO"); - return ok; - } + + bool ok = false; + BLI_assert(!"TODO"); + return ok; } /** @@ -582,7 +580,7 @@ static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos, Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); rcti rect; /* Almost certainly overkill, but allow for many custom gizmos. */ - GLuint buffer[MAXPICKBUF]; + uint buffer[MAXPICKBUF]; short hits; BLI_rcti_init_pt_radius(&rect, co, hotspot); @@ -625,7 +623,7 @@ static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos, GPU_matrix_unproject_with_precalc(&unproj_precalc, co_screen, co_3d_origin); - GLuint *buf_iter = buffer; + uint *buf_iter = buffer; int hit_found = -1; float dot_best = FLT_MAX; @@ -648,10 +646,9 @@ static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos, } return hit_found; } - else { - const GLuint *hit_near = GPU_select_buffer_near(buffer, hits); - return hit_near ? hit_near[3] : -1; - } + + const uint *hit_near = GPU_select_buffer_near(buffer, hits); + return hit_near ? hit_near[3] : -1; } /** diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c index 2dc03d1419c..b056ed40943 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c @@ -70,9 +70,7 @@ wmGizmoProperty *WM_gizmo_target_property_find(wmGizmo *gz, const char *idname) if (index != -1) { return WM_gizmo_target_property_at_index(gz, index); } - else { - return NULL; - } + return NULL; } void WM_gizmo_target_property_def_rna_ptr(wmGizmo *gz, @@ -195,9 +193,7 @@ float WM_gizmo_target_property_float_get(const wmGizmo *gz, wmGizmoProperty *gz_ if (gz_prop->index == -1) { return RNA_property_float_get(&gz_prop->ptr, gz_prop->prop); } - else { - return RNA_property_float_get_index(&gz_prop->ptr, gz_prop->prop, gz_prop->index); - } + return RNA_property_float_get_index(&gz_prop->ptr, gz_prop->prop, gz_prop->index); } void WM_gizmo_target_property_float_set(bContext *C, @@ -255,9 +251,7 @@ bool WM_gizmo_target_property_float_range_get(const wmGizmo *gz, gz_prop->custom_func.range_get_fn(gz, gz_prop, range); return true; } - else { - return false; - } + return false; } float step, precision; diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index 2112477e62a..43c08a2b980 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -293,7 +293,7 @@ void WM_keyconfig_init(bContext *C) /* initialize only after python init is done, for keymaps that * use python operators */ - if (CTX_py_init_get(C) && (wm->initialized & WM_KEYCONFIG_IS_INITIALIZED) == 0) { + if (CTX_py_init_get(C) && (wm->initialized & WM_KEYCONFIG_IS_INIT) == 0) { /* create default key config, only initialize once, * it's persistent across sessions */ if (!(wm->defaultconf->flag & KEYCONF_INIT_DEFAULT)) { @@ -308,7 +308,7 @@ void WM_keyconfig_init(bContext *C) WM_keyconfig_update_tag(NULL, NULL); WM_keyconfig_update(wm); - wm->initialized |= WM_KEYCONFIG_IS_INITIALIZED; + wm->initialized |= WM_KEYCONFIG_IS_INIT; } } @@ -334,7 +334,7 @@ void WM_check(bContext *C) if (!G.background) { /* case: fileread */ - if ((wm->initialized & WM_WINDOW_IS_INITIALIZED) == 0) { + if ((wm->initialized & WM_WINDOW_IS_INIT) == 0) { WM_keyconfig_init(C); WM_autosave_init(wm); } @@ -345,9 +345,9 @@ void WM_check(bContext *C) /* case: fileread */ /* note: this runs in bg mode to set the screen context cb */ - if ((wm->initialized & WM_WINDOW_IS_INITIALIZED) == 0) { - ED_screens_initialize(bmain, wm); - wm->initialized |= WM_WINDOW_IS_INITIALIZED; + if ((wm->initialized & WM_WINDOW_IS_INIT) == 0) { + ED_screens_init(bmain, wm); + wm->initialized |= WM_WINDOW_IS_INIT; } } diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c index 2af68956923..8e89c08a831 100644 --- a/source/blender/windowmanager/intern/wm_cursors.c +++ b/source/blender/windowmanager/intern/wm_cursors.c @@ -121,7 +121,7 @@ static GHOST_TStandardCursor convert_to_ghost_standard_cursor(WMCursorType curs) } static void window_set_custom_cursor( - wmWindow *win, const uchar mask[16][2], uchar bitmap[16][2], int hotx, int hoty) + wmWindow *win, const uchar mask[16][2], const uchar bitmap[16][2], int hotx, int hoty) { GHOST_SetCustomCursorShape( win->ghostwin, (GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, 16, 16, hotx, hoty, true); @@ -319,15 +319,15 @@ bool wm_cursor_arrow_move(wmWindow *win, const wmEvent *event) wm_cursor_warp_relative(win, 0, fac); return 1; } - else if (event->type == EVT_DOWNARROWKEY) { + if (event->type == EVT_DOWNARROWKEY) { wm_cursor_warp_relative(win, 0, -fac); return 1; } - else if (event->type == EVT_LEFTARROWKEY) { + if (event->type == EVT_LEFTARROWKEY) { wm_cursor_warp_relative(win, -fac, 0); return 1; } - else if (event->type == EVT_RIGHTARROWKEY) { + if (event->type == EVT_RIGHTARROWKEY) { wm_cursor_warp_relative(win, fac, 0); return 1; } diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c index ad3fc7a1302..ec18a401fa4 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.c +++ b/source/blender/windowmanager/intern/wm_dragdrop.c @@ -39,7 +39,6 @@ #include "BKE_context.h" #include "BKE_idtype.h" -#include "GPU_glew.h" #include "GPU_shader.h" #include "GPU_state.h" #include "GPU_viewport.h" @@ -297,7 +296,7 @@ void WM_drag_add_ID(wmDrag *drag, ID *id, ID *from_parent) } return; } - else if (GS(drag_id->id->name) != GS(id->name)) { + if (GS(drag_id->id->name) != GS(id->name)) { BLI_assert(!"All dragged IDs must have the same type"); return; } @@ -356,7 +355,7 @@ static const char *wm_drag_name(wmDrag *drag) if (single) { return id->name + 2; } - else if (id) { + if (id) { return BKE_idtype_idcode_to_name_plural(GS(id->name)); } break; @@ -424,9 +423,8 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect) y, drag->imb->x, drag->imb->y, - GL_RGBA, - GL_UNSIGNED_BYTE, - GL_NEAREST, + GPU_RGBA8, + false, drag->imb->rect, drag->scale, drag->scale, diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index fdbc7a7d136..b8cb5432a49 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -52,7 +52,6 @@ #include "ED_view3d.h" #include "GPU_context.h" -#include "GPU_draw.h" #include "GPU_framebuffer.h" #include "GPU_immediate.h" #include "GPU_state.h" @@ -208,7 +207,7 @@ static bool wm_draw_region_stereo_set(Main *bmain, if (region->regiontype == RGN_TYPE_PREVIEW) { return true; } - else if (region->regiontype == RGN_TYPE_WINDOW) { + if (region->regiontype == RGN_TYPE_WINDOW) { return (sseq->draw_flag & SEQ_DRAW_BACKDROP) != 0; } } @@ -521,9 +520,7 @@ GPUTexture *wm_draw_region_texture(ARegion *region, int view) if (viewport) { return GPU_viewport_color_texture(viewport, view); } - else { - return GPU_offscreen_color_texture(region->draw_buffer->offscreen); - } + return GPU_offscreen_color_texture(region->draw_buffer->offscreen); } void wm_draw_region_blend(ARegion *region, int view, bool blend) @@ -573,8 +570,8 @@ void wm_draw_region_blend(ARegion *region, int view, bool blend) } /* Not the same layout as rectf/recti. */ - float rectt[4] = {rect_tex.xmin, rect_tex.ymin, rect_tex.xmax, rect_tex.ymax}; - float rectg[4] = {rect_geo.xmin, rect_geo.ymin, rect_geo.xmax, rect_geo.ymax}; + const float rectt[4] = {rect_tex.xmin, rect_tex.ymin, rect_tex.xmax, rect_tex.ymax}; + const float rectg[4] = {rect_geo.xmin, rect_geo.ymin, rect_geo.xmax, rect_geo.ymax}; if (blend) { /* GL_ONE because regions drawn offscreen have premultiplied alpha. */ @@ -1001,7 +998,7 @@ void wm_draw_update(bContext *C) wmWindow *win; GPU_context_main_lock(); - GPU_free_unused_buffers(); + BKE_image_free_unused_gpu_textures(); for (win = wm->windows.first; win; win = win->next) { #ifdef WIN32 diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 05ef4bfac30..0941dd49d23 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -597,7 +597,7 @@ static int wm_handler_ui_call(bContext *C, if (is_wheel) { return WM_HANDLER_CONTINUE; } - else if (wm_event_always_pass(event) == 0) { + if (wm_event_always_pass(event) == 0) { do_wheel_ui = true; } } @@ -783,7 +783,7 @@ bool WM_operator_poll(bContext *C, wmOperatorType *ot) if (ot->pyop_poll) { return ot->pyop_poll(C, ot); } - else if (ot->poll) { + if (ot->poll) { return ot->poll(C); } @@ -1095,7 +1095,7 @@ bool WM_operator_repeat_check(const bContext *UNUSED(C), wmOperator *op) if (op->type->exec != NULL) { return true; } - else if (op->opm) { + if (op->opm) { /* for macros, check all have exec() we can call */ wmOperatorTypeMacro *otmacro; for (otmacro = op->opm->type->macro.first; otmacro; otmacro = otmacro->next) { @@ -1816,10 +1816,10 @@ static bool wm_eventmatch(const wmEvent *winevent, const wmKeyMapItem *kmi) /* tablet events can occur on hover + keypress */ return false; } - else if ((kmitype == TABLET_STYLUS) && (wmtab->active != EVT_TABLET_STYLUS)) { + if ((kmitype == TABLET_STYLUS) && (wmtab->active != EVT_TABLET_STYLUS)) { return false; } - else if ((kmitype == TABLET_ERASER) && (wmtab->active != EVT_TABLET_ERASER)) { + if ((kmitype == TABLET_ERASER) && (wmtab->active != EVT_TABLET_ERASER)) { return false; } } @@ -2434,13 +2434,11 @@ static int wm_handlers_do_keymap_with_keymap_handler( } break; } + if (action & WM_HANDLER_HANDLED) { + CLOG_INFO(WM_LOG_HANDLERS, 2, "handled - and pass on! '%s'", kmi->idname); + } else { - if (action & WM_HANDLER_HANDLED) { - CLOG_INFO(WM_LOG_HANDLERS, 2, "handled - and pass on! '%s'", kmi->idname); - } - else { - CLOG_INFO(WM_LOG_HANDLERS, 2, "un-handled '%s'", kmi->idname); - } + CLOG_INFO(WM_LOG_HANDLERS, 2, "un-handled '%s'", kmi->idname); } } } @@ -2492,16 +2490,14 @@ static int wm_handlers_do_keymap_with_gizmo_handler( } break; } - else { - if (action & WM_HANDLER_HANDLED) { - if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS)) { - printf("%s: handled - and pass on! '%s'\n", __func__, kmi->idname); - } - } - else { - PRINT("%s: un-handled '%s'\n", __func__, kmi->idname); + if (action & WM_HANDLER_HANDLED) { + if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS)) { + printf("%s: handled - and pass on! '%s'\n", __func__, kmi->idname); } } + else { + PRINT("%s: un-handled '%s'\n", __func__, kmi->idname); + } } } } @@ -3126,13 +3122,9 @@ static bool wm_event_pie_filter(wmWindow *win, const wmEvent *event) win->lock_pie_event = EVENT_NONE; return false; } - else { - return true; - } - } - else { - return false; + return true; } + return false; } /** @@ -3692,10 +3684,8 @@ wmKeyMap *WM_event_get_keymap_from_toolsystem_fallback(wmWindowManager *wm, handler->keymap_tool = area->runtime.tool; return km; } - else { - printf( - "Keymap: '%s' not found for tool '%s'\n", tref_rt->keymap, area->runtime.tool->idname); - } + printf( + "Keymap: '%s' not found for tool '%s'\n", tref_rt->keymap, area->runtime.tool->idname); } } return NULL; @@ -3716,10 +3706,8 @@ wmKeyMap *WM_event_get_keymap_from_toolsystem(wmWindowManager *wm, wmEventHandle handler->keymap_tool = area->runtime.tool; return km; } - else { - printf( - "Keymap: '%s' not found for tool '%s'\n", tref_rt->keymap, area->runtime.tool->idname); - } + printf( + "Keymap: '%s' not found for tool '%s'\n", tref_rt->keymap, area->runtime.tool->idname); } } return NULL; @@ -3775,12 +3763,10 @@ static bool event_or_prev_in_rect(const wmEvent *event, const rcti *rect) if (BLI_rcti_isect_pt(rect, event->x, event->y)) { return true; } - else if (event->type == MOUSEMOVE && BLI_rcti_isect_pt(rect, event->prevx, event->prevy)) { + if (event->type == MOUSEMOVE && BLI_rcti_isect_pt(rect, event->prevx, event->prevy)) { return true; } - else { - return false; - } + return false; } static bool handler_region_v2d_mask_test(const ARegion *region, const wmEvent *event) @@ -3966,138 +3952,137 @@ static int convert_key(GHOST_TKey key) if (key >= GHOST_kKeyA && key <= GHOST_kKeyZ) { return (EVT_AKEY + ((int)key - GHOST_kKeyA)); } - else if (key >= GHOST_kKey0 && key <= GHOST_kKey9) { + if (key >= GHOST_kKey0 && key <= GHOST_kKey9) { return (EVT_ZEROKEY + ((int)key - GHOST_kKey0)); } - else if (key >= GHOST_kKeyNumpad0 && key <= GHOST_kKeyNumpad9) { + if (key >= GHOST_kKeyNumpad0 && key <= GHOST_kKeyNumpad9) { return (EVT_PAD0 + ((int)key - GHOST_kKeyNumpad0)); } - else if (key >= GHOST_kKeyF1 && key <= GHOST_kKeyF24) { + if (key >= GHOST_kKeyF1 && key <= GHOST_kKeyF24) { return (EVT_F1KEY + ((int)key - GHOST_kKeyF1)); } - else { - switch (key) { - case GHOST_kKeyBackSpace: - return EVT_BACKSPACEKEY; - case GHOST_kKeyTab: - return EVT_TABKEY; - case GHOST_kKeyLinefeed: - return EVT_LINEFEEDKEY; - case GHOST_kKeyClear: - return 0; - case GHOST_kKeyEnter: - return EVT_RETKEY; - - case GHOST_kKeyEsc: - return EVT_ESCKEY; - case GHOST_kKeySpace: - return EVT_SPACEKEY; - case GHOST_kKeyQuote: - return EVT_QUOTEKEY; - case GHOST_kKeyComma: - return EVT_COMMAKEY; - case GHOST_kKeyMinus: - return EVT_MINUSKEY; - case GHOST_kKeyPlus: - return EVT_PLUSKEY; - case GHOST_kKeyPeriod: - return EVT_PERIODKEY; - case GHOST_kKeySlash: - return EVT_SLASHKEY; - - case GHOST_kKeySemicolon: - return EVT_SEMICOLONKEY; - case GHOST_kKeyEqual: - return EVT_EQUALKEY; - - case GHOST_kKeyLeftBracket: - return EVT_LEFTBRACKETKEY; - case GHOST_kKeyRightBracket: - return EVT_RIGHTBRACKETKEY; - case GHOST_kKeyBackslash: - return EVT_BACKSLASHKEY; - case GHOST_kKeyAccentGrave: - return EVT_ACCENTGRAVEKEY; - - case GHOST_kKeyLeftShift: - return EVT_LEFTSHIFTKEY; - case GHOST_kKeyRightShift: - return EVT_RIGHTSHIFTKEY; - case GHOST_kKeyLeftControl: - return EVT_LEFTCTRLKEY; - case GHOST_kKeyRightControl: - return EVT_RIGHTCTRLKEY; - case GHOST_kKeyOS: - return EVT_OSKEY; - case GHOST_kKeyLeftAlt: - return EVT_LEFTALTKEY; - case GHOST_kKeyRightAlt: - return EVT_RIGHTALTKEY; - case GHOST_kKeyApp: - return EVT_APPKEY; - - case GHOST_kKeyCapsLock: - return EVT_CAPSLOCKKEY; - case GHOST_kKeyNumLock: - return 0; - case GHOST_kKeyScrollLock: - return 0; - - case GHOST_kKeyLeftArrow: - return EVT_LEFTARROWKEY; - case GHOST_kKeyRightArrow: - return EVT_RIGHTARROWKEY; - case GHOST_kKeyUpArrow: - return EVT_UPARROWKEY; - case GHOST_kKeyDownArrow: - return EVT_DOWNARROWKEY; - - case GHOST_kKeyPrintScreen: - return 0; - case GHOST_kKeyPause: - return EVT_PAUSEKEY; - - case GHOST_kKeyInsert: - return EVT_INSERTKEY; - case GHOST_kKeyDelete: - return EVT_DELKEY; - case GHOST_kKeyHome: - return EVT_HOMEKEY; - case GHOST_kKeyEnd: - return EVT_ENDKEY; - case GHOST_kKeyUpPage: - return EVT_PAGEUPKEY; - case GHOST_kKeyDownPage: - return EVT_PAGEDOWNKEY; - - case GHOST_kKeyNumpadPeriod: - return EVT_PADPERIOD; - case GHOST_kKeyNumpadEnter: - return EVT_PADENTER; - case GHOST_kKeyNumpadPlus: - return EVT_PADPLUSKEY; - case GHOST_kKeyNumpadMinus: - return EVT_PADMINUS; - case GHOST_kKeyNumpadAsterisk: - return EVT_PADASTERKEY; - case GHOST_kKeyNumpadSlash: - return EVT_PADSLASHKEY; - - case GHOST_kKeyGrLess: - return EVT_GRLESSKEY; - - case GHOST_kKeyMediaPlay: - return EVT_MEDIAPLAY; - case GHOST_kKeyMediaStop: - return EVT_MEDIASTOP; - case GHOST_kKeyMediaFirst: - return EVT_MEDIAFIRST; - case GHOST_kKeyMediaLast: - return EVT_MEDIALAST; - - default: - return EVT_UNKNOWNKEY; /* GHOST_kKeyUnknown */ - } + + switch (key) { + case GHOST_kKeyBackSpace: + return EVT_BACKSPACEKEY; + case GHOST_kKeyTab: + return EVT_TABKEY; + case GHOST_kKeyLinefeed: + return EVT_LINEFEEDKEY; + case GHOST_kKeyClear: + return 0; + case GHOST_kKeyEnter: + return EVT_RETKEY; + + case GHOST_kKeyEsc: + return EVT_ESCKEY; + case GHOST_kKeySpace: + return EVT_SPACEKEY; + case GHOST_kKeyQuote: + return EVT_QUOTEKEY; + case GHOST_kKeyComma: + return EVT_COMMAKEY; + case GHOST_kKeyMinus: + return EVT_MINUSKEY; + case GHOST_kKeyPlus: + return EVT_PLUSKEY; + case GHOST_kKeyPeriod: + return EVT_PERIODKEY; + case GHOST_kKeySlash: + return EVT_SLASHKEY; + + case GHOST_kKeySemicolon: + return EVT_SEMICOLONKEY; + case GHOST_kKeyEqual: + return EVT_EQUALKEY; + + case GHOST_kKeyLeftBracket: + return EVT_LEFTBRACKETKEY; + case GHOST_kKeyRightBracket: + return EVT_RIGHTBRACKETKEY; + case GHOST_kKeyBackslash: + return EVT_BACKSLASHKEY; + case GHOST_kKeyAccentGrave: + return EVT_ACCENTGRAVEKEY; + + case GHOST_kKeyLeftShift: + return EVT_LEFTSHIFTKEY; + case GHOST_kKeyRightShift: + return EVT_RIGHTSHIFTKEY; + case GHOST_kKeyLeftControl: + return EVT_LEFTCTRLKEY; + case GHOST_kKeyRightControl: + return EVT_RIGHTCTRLKEY; + case GHOST_kKeyOS: + return EVT_OSKEY; + case GHOST_kKeyLeftAlt: + return EVT_LEFTALTKEY; + case GHOST_kKeyRightAlt: + return EVT_RIGHTALTKEY; + case GHOST_kKeyApp: + return EVT_APPKEY; + + case GHOST_kKeyCapsLock: + return EVT_CAPSLOCKKEY; + case GHOST_kKeyNumLock: + return 0; + case GHOST_kKeyScrollLock: + return 0; + + case GHOST_kKeyLeftArrow: + return EVT_LEFTARROWKEY; + case GHOST_kKeyRightArrow: + return EVT_RIGHTARROWKEY; + case GHOST_kKeyUpArrow: + return EVT_UPARROWKEY; + case GHOST_kKeyDownArrow: + return EVT_DOWNARROWKEY; + + case GHOST_kKeyPrintScreen: + return 0; + case GHOST_kKeyPause: + return EVT_PAUSEKEY; + + case GHOST_kKeyInsert: + return EVT_INSERTKEY; + case GHOST_kKeyDelete: + return EVT_DELKEY; + case GHOST_kKeyHome: + return EVT_HOMEKEY; + case GHOST_kKeyEnd: + return EVT_ENDKEY; + case GHOST_kKeyUpPage: + return EVT_PAGEUPKEY; + case GHOST_kKeyDownPage: + return EVT_PAGEDOWNKEY; + + case GHOST_kKeyNumpadPeriod: + return EVT_PADPERIOD; + case GHOST_kKeyNumpadEnter: + return EVT_PADENTER; + case GHOST_kKeyNumpadPlus: + return EVT_PADPLUSKEY; + case GHOST_kKeyNumpadMinus: + return EVT_PADMINUS; + case GHOST_kKeyNumpadAsterisk: + return EVT_PADASTERKEY; + case GHOST_kKeyNumpadSlash: + return EVT_PADSLASHKEY; + + case GHOST_kKeyGrLess: + return EVT_GRLESSKEY; + + case GHOST_kKeyMediaPlay: + return EVT_MEDIAPLAY; + case GHOST_kKeyMediaStop: + return EVT_MEDIASTOP; + case GHOST_kKeyMediaFirst: + return EVT_MEDIAFIRST; + case GHOST_kKeyMediaLast: + return EVT_MEDIALAST; + + default: + return EVT_UNKNOWNKEY; /* GHOST_kKeyUnknown */ } } diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index f431a6f431b..ef4f2b4a62a 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -258,7 +258,7 @@ static void wm_window_match_keep_current_wm(const bContext *C, bScreen *screen = NULL; /* match oldwm to new dbase, only old files */ - wm->initialized &= ~WM_WINDOW_IS_INITIALIZED; + wm->initialized &= ~WM_WINDOW_IS_INIT; /* when loading without UI, no matching needed */ if (load_ui && (screen = CTX_wm_screen(C))) { @@ -1404,10 +1404,8 @@ bool write_crash_blend(void) printf("written: %s\n", path); return 1; } - else { - printf("failed: %s\n", path); - return 0; - } + printf("failed: %s\n", path); + return 0; } /** @@ -2091,9 +2089,7 @@ static int wm_homefile_read_invoke(bContext *C, wmOperator *op, const wmEvent *U wm_close_file_dialog(C, callback); return OPERATOR_INTERFACE; } - else { - return wm_homefile_read_exec(C, op); - } + return wm_homefile_read_exec(C, op); } static void read_homefile_props(wmOperatorType *ot) @@ -2255,9 +2251,7 @@ static int wm_open_mainfile__discard_changes(bContext *C, wmOperator *op) wm_close_file_dialog(C, callback); return OPERATOR_INTERFACE; } - else { - return wm_open_mainfile_dispatch(C, op); - } + return wm_open_mainfile_dispatch(C, op); } static int wm_open_mainfile__select_file_path(bContext *C, wmOperator *op) @@ -2328,9 +2322,7 @@ static int wm_open_mainfile__open(bContext *C, wmOperator *op) ED_view3d_local_collections_reset(C, (G.fileflags & G_FILE_NO_UI) != 0); return OPERATOR_FINISHED; } - else { - return OPERATOR_CANCELLED; - } + return OPERATOR_CANCELLED; } static OperatorDispatchTarget wm_open_mainfile_dispatch_targets[] = { @@ -2475,9 +2467,7 @@ static int wm_revert_mainfile_exec(bContext *C, wmOperator *op) if (success) { return OPERATOR_FINISHED; } - else { - return OPERATOR_CANCELLED; - } + return OPERATOR_CANCELLED; } static bool wm_revert_mainfile_poll(bContext *UNUSED(C)) @@ -2572,9 +2562,7 @@ static int wm_recover_auto_save_exec(bContext *C, wmOperator *op) if (success) { return OPERATOR_FINISHED; } - else { - return OPERATOR_CANCELLED; - } + return OPERATOR_CANCELLED; } static int wm_recover_auto_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c index 31d36603505..6ccc5d79962 100644 --- a/source/blender/windowmanager/intern/wm_files_link.c +++ b/source/blender/windowmanager/intern/wm_files_link.c @@ -357,11 +357,11 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) BKE_reportf(op->reports, RPT_ERROR, "'%s': not a library", path); return OPERATOR_CANCELLED; } - else if (!group) { + if (!group) { BKE_reportf(op->reports, RPT_ERROR, "'%s': nothing indicated", path); return OPERATOR_CANCELLED; } - else if (BLI_path_cmp(BKE_main_blendfile_path(bmain), libname) == 0) { + if (BLI_path_cmp(BKE_main_blendfile_path(bmain), libname) == 0) { BKE_reportf(op->reports, RPT_ERROR, "'%s': cannot use current file as library", path); return OPERATOR_CANCELLED; } @@ -755,7 +755,7 @@ static void lib_relocate_do_remap(Main *bmain, if (c == '.') { break; } - else if (c < '0' || c > '9') { + if (c < '0' || c > '9') { has_num = false; break; } diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index eee93fc9459..55233168ab2 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -324,7 +324,7 @@ static void draw_filled_lasso(wmGesture *gt) int(*mcoords)[2] = MEM_mallocN(sizeof(*mcoords) * (mcoords_len + 1), __func__); int i; rcti rect; - float red[4] = {1.0f, 0.0f, 0.0f, 0.0f}; + const float red[4] = {1.0f, 0.0f, 0.0f, 0.0f}; for (i = 0; i < mcoords_len; i++, lasso += 2) { mcoords[i][0] = lasso[0]; @@ -362,18 +362,8 @@ static void draw_filled_lasso(wmGesture *gt) GPU_shader_uniform_vector( state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red); - immDrawPixelsTex(&state, - rect.xmin, - rect.ymin, - w, - h, - GL_RED, - GL_UNSIGNED_BYTE, - GL_NEAREST, - pixel_buf, - 1.0f, - 1.0f, - NULL); + immDrawPixelsTex( + &state, rect.xmin, rect.ymin, w, h, GL_R8, false, pixel_buf, 1.0f, 1.0f, NULL); GPU_shader_unbind(); diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 945d5fd42e4..85694dec9c8 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -59,6 +59,7 @@ #include "BKE_font.h" #include "BKE_global.h" #include "BKE_icons.h" +#include "BKE_image.h" #include "BKE_keyconfig.h" #include "BKE_lib_remap.h" #include "BKE_main.h" @@ -120,7 +121,6 @@ #include "UI_interface.h" #include "UI_resources.h" -#include "GPU_draw.h" #include "GPU_init_exit.h" #include "GPU_material.h" @@ -171,7 +171,7 @@ void WM_init_state_start_with_console_set(bool value) */ static bool opengl_is_init = false; -void WM_init_opengl(Main *bmain) +void WM_init_opengl(void) { /* must be called only once */ BLI_assert(opengl_is_init == false); @@ -185,9 +185,6 @@ void WM_init_opengl(Main *bmain) DRW_opengl_context_create(); GPU_init(); - GPU_set_mipmap(bmain, true); - GPU_set_linear_mipmap(true); - GPU_set_anisotropic(U.anisotropic_filter); GPU_pass_cache_init(); @@ -315,7 +312,7 @@ void WM_init(bContext *C, int argc, const char **argv) /* sets 3D mouse deadzone */ WM_ndof_deadzone_set(U.ndof_deadzone); #endif - WM_init_opengl(G_MAIN); + WM_init_opengl(); if (!WM_platform_support_perform_checks()) { exit(-1); @@ -578,7 +575,7 @@ void WM_exit_ex(bContext *C, const bool do_python) BKE_subdiv_exit(); if (opengl_is_init) { - GPU_free_unused_buffers(); + BKE_image_free_unused_gpu_textures(); } BKE_blender_free(); /* blender.c, does entire library and spacetypes */ diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c index 87a19d832c9..c9b125901e7 100644 --- a/source/blender/windowmanager/intern/wm_jobs.c +++ b/source/blender/windowmanager/intern/wm_jobs.c @@ -344,9 +344,7 @@ void *WM_jobs_customdata_get(wmJob *wm_job) if (!wm_job->customdata) { return wm_job->run_customdata; } - else { - return wm_job->customdata; - } + return wm_job->customdata; } void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void (*free)(void *)) diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index d7102a1e8af..d7ff2689a86 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -321,9 +321,7 @@ bool WM_keyconfig_remove(wmWindowManager *wm, wmKeyConfig *keyconf) return true; } - else { - return false; - } + return false; } void WM_keyconfig_clear(wmKeyConfig *keyconf) @@ -363,7 +361,7 @@ void WM_keyconfig_set_active(wmWindowManager *wm, const char *idname) WM_keyconfig_update(wm); BLI_strncpy(U.keyconfigstr, idname, sizeof(U.keyconfigstr)); - if (wm->initialized & WM_KEYCONFIG_IS_INITIALIZED) { + if (wm->initialized & WM_KEYCONFIG_IS_INIT) { U.runtime.is_dirty = true; } @@ -448,9 +446,7 @@ bool WM_keymap_remove(wmKeyConfig *keyconf, wmKeyMap *keymap) return true; } - else { - return false; - } + return false; } bool WM_keymap_poll(bContext *C, wmKeyMap *keymap) @@ -551,9 +547,7 @@ bool WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi) WM_keyconfig_update_tag(keymap, NULL); return true; } - else { - return false; - } + return false; } /** \} */ @@ -1122,7 +1116,7 @@ const char *WM_key_event_string(const short type, const bool compact) if (platform == MACOS) { return key_event_glyph_or_text(font_id, IFACE_("Cmd"), "\xe2\x8c\x98"); } - else if (platform == MSWIN) { + if (platform == MSWIN) { return key_event_glyph_or_text(font_id, IFACE_("Win"), "\xe2\x9d\x96"); } return IFACE_("OS"); diff --git a/source/blender/windowmanager/intern/wm_keymap_utils.c b/source/blender/windowmanager/intern/wm_keymap_utils.c index 5ab36b15666..83558bc9192 100644 --- a/source/blender/windowmanager/intern/wm_keymap_utils.c +++ b/source/blender/windowmanager/intern/wm_keymap_utils.c @@ -379,7 +379,25 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname) } /* Animation Generic - after channels */ else if (STRPREFIX(opname, "ANIM_OT")) { - km = WM_keymap_find_all(wm, "Animation", 0, 0); + if (sl->spacetype == SPACE_VIEW3D) { + switch (CTX_data_mode_enum(C)) { + case CTX_MODE_OBJECT: + km = WM_keymap_find_all(wm, "Object Mode", 0, 0); + break; + case CTX_MODE_POSE: + km = WM_keymap_find_all(wm, "Pose", 0, 0); + break; + default: + break; + } + if (km && !WM_keymap_poll((bContext *)C, km)) { + km = NULL; + } + } + + if (!km) { + km = WM_keymap_find_all(wm, "Animation", 0, 0); + } } /* Graph Editor */ else if (STRPREFIX(opname, "GRAPH_OT")) { diff --git a/source/blender/windowmanager/intern/wm_operator_type.c b/source/blender/windowmanager/intern/wm_operator_type.c index 650d5bbe015..457cd0f16be 100644 --- a/source/blender/windowmanager/intern/wm_operator_type.c +++ b/source/blender/windowmanager/intern/wm_operator_type.c @@ -606,9 +606,7 @@ char *WM_operatortype_description(struct bContext *C, if (description[0]) { return description; } - else { - MEM_freeN(description); - } + MEM_freeN(description); } } @@ -621,9 +619,7 @@ char *WM_operatortype_description(struct bContext *C, if (info && info[0]) { return BLI_strdup(info); } - else { - return NULL; - } + return NULL; } /** \} */ diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index d1f65b6271b..8dea1a1031a 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -864,19 +864,17 @@ int WM_generic_select_modal(bContext *C, wmOperator *op, const wmEvent *event) } return ret_value | OPERATOR_PASS_THROUGH; } - else { - /* If we are in init phase, and cannot validate init of modal operations, - * just fall back to basic exec. - */ - RNA_property_boolean_set(op->ptr, wait_to_deselect_prop, false); + /* If we are in init phase, and cannot validate init of modal operations, + * just fall back to basic exec. + */ + RNA_property_boolean_set(op->ptr, wait_to_deselect_prop, false); - ret_value = op->type->exec(C, op); - OPERATOR_RETVAL_CHECK(ret_value); + ret_value = op->type->exec(C, op); + OPERATOR_RETVAL_CHECK(ret_value); - return ret_value | OPERATOR_PASS_THROUGH; - } + return ret_value | OPERATOR_PASS_THROUGH; } - else if (event->type == init_event_type && event->val == KM_RELEASE) { + if (event->type == init_event_type && event->val == KM_RELEASE) { RNA_property_boolean_set(op->ptr, wait_to_deselect_prop, false); ret_value = op->type->exec(C, op); @@ -884,7 +882,7 @@ int WM_generic_select_modal(bContext *C, wmOperator *op, const wmEvent *event) return ret_value | OPERATOR_PASS_THROUGH; } - else if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { + if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { const int drag_delta[2] = { mval[0] - event->mval[0], mval[1] - event->mval[1], @@ -895,11 +893,9 @@ int WM_generic_select_modal(bContext *C, wmOperator *op, const wmEvent *event) if (WM_event_drag_test_with_delta(event, drag_delta)) { return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH; } - else { - /* Important not to return anything other than PASS_THROUGH here, - * otherwise it prevents underlying tweak detection code to work properly. */ - return OPERATOR_PASS_THROUGH; - } + /* Important not to return anything other than PASS_THROUGH here, + * otherwise it prevents underlying tweak detection code to work properly. */ + return OPERATOR_PASS_THROUGH; } return OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH; @@ -1151,9 +1147,7 @@ int WM_operator_confirm_or_exec(bContext *C, wmOperator *op, const wmEvent *UNUS if (confirm) { return WM_operator_confirm_message(C, op, NULL); } - else { - return op->type->exec(C, op); - } + return op->type->exec(C, op); } /* op->invoke, opens fileselect if path property not set, otherwise executes */ @@ -1162,10 +1156,8 @@ int WM_operator_filesel(bContext *C, wmOperator *op, const wmEvent *UNUSED(event if (RNA_struct_property_is_set(op->ptr, "filepath")) { return WM_operator_call_notest(C, op); /* call exec direct */ } - else { - WM_event_add_fileselect(C, op); - return OPERATOR_RUNNING_MODAL; - } + WM_event_add_fileselect(C, op); + return OPERATOR_RUNNING_MODAL; } bool WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFormatData *im_format) @@ -2322,7 +2314,7 @@ static void radial_control_paint_curve(uint pos, Brush *br, float radius, int li GPU_line_width(2.0f); immUniformColor4f(0.8f, 0.8f, 0.8f, 0.85f); float step = (radius * 2.0f) / (float)line_segments; - BKE_curvemapping_initialize(br->curve); + BKE_curvemapping_init(br->curve); immBegin(GPU_PRIM_LINES, line_segments * 2); for (int i = 0; i < line_segments; i++) { float h1 = BKE_brush_curve_strength_clamped(br, fabsf((i * step) - radius), radius); @@ -2453,7 +2445,7 @@ static void radial_control_paint_cursor(bContext *UNUSED(C), int x, int y, void imm_draw_circle_wire_2d(pos, 0.0f, 0.0f, r2, 80); if (rmin > 0.0f) { /* Inner fill circle to increase the contrast of the value */ - float black[3] = {0.0f}; + const float black[3] = {0.0f}; immUniformColor3fvAlpha(black, 0.2f); imm_draw_circle_fill_2d(pos, 0.0, 0.0f, rmin, 80); @@ -2536,10 +2528,8 @@ static int radial_control_get_path(PointerRNA *ctx_ptr, if (flags & RC_PROP_ALLOW_MISSING) { return 1; } - else { - BKE_reportf(op->reports, RPT_ERROR, "Could not resolve path '%s'", name); - return 0; - } + BKE_reportf(op->reports, RPT_ERROR, "Could not resolve path '%s'", name); + return 0; } /* check property type */ @@ -2591,13 +2581,12 @@ static int radial_control_get_properties(bContext *C, wmOperator *op) (RC_PROP_ALLOW_MISSING | RC_PROP_REQUIRE_BOOL))) { return 0; } + + if (use_secondary_prop && RNA_property_boolean_get(&use_secondary_ptr, use_secondary_prop)) { + data_path = "data_path_secondary"; + } else { - if (use_secondary_prop && RNA_property_boolean_get(&use_secondary_ptr, use_secondary_prop)) { - data_path = "data_path_secondary"; - } - else { - data_path = "data_path_primary"; - } + data_path = "data_path_primary"; } if (!radial_control_get_path(&ctx_ptr, op, data_path, &rc->ptr, &rc->prop, 0, 0)) { @@ -2664,7 +2653,7 @@ static int radial_control_get_properties(bContext *C, wmOperator *op) if (!radial_control_get_path(&ctx_ptr, op, "image_id", &rc->image_id_ptr, NULL, 0, 0)) { return 0; } - else if (rc->image_id_ptr.data) { + if (rc->image_id_ptr.data) { /* extra check, pointer must be to an ID */ if (!RNA_struct_is_ID(rc->image_id_ptr.type)) { BKE_report(op->reports, RPT_ERROR, "Pointer from path image_id is not an ID"); @@ -2841,171 +2830,169 @@ static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *even radial_control_update_header(op, C); return OPERATOR_RUNNING_MODAL; } - else { - handled = false; - switch (event->type) { - case EVT_ESCKEY: - case RIGHTMOUSE: - /* canceled; restore original value */ - radial_control_set_value(rc, rc->initial_value); - ret = OPERATOR_CANCELLED; - break; - - case LEFTMOUSE: - case EVT_PADENTER: - case EVT_RETKEY: - /* done; value already set */ - RNA_property_update(C, &rc->ptr, rc->prop); - ret = OPERATOR_FINISHED; - break; - - case MOUSEMOVE: - if (!has_numInput) { - if (rc->slow_mode) { - if (rc->subtype == PROP_ANGLE) { - float position[2] = {event->x, event->y}; - - /* calculate the initial angle here first */ - delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0]; - delta[1] = rc->initial_mouse[1] - rc->slow_mouse[1]; - - /* precision angle gets calculated from dial and gets added later */ - angle_precision = -0.1f * BLI_dial_angle(rc->dial, position); - } - else { - delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0]; - delta[1] = 0.0f; - if (rc->zoom_prop) { - RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom); - delta[0] /= zoom[0]; - } + handled = false; + switch (event->type) { + case EVT_ESCKEY: + case RIGHTMOUSE: + /* canceled; restore original value */ + radial_control_set_value(rc, rc->initial_value); + ret = OPERATOR_CANCELLED; + break; - dist = len_v2(delta); + case LEFTMOUSE: + case EVT_PADENTER: + case EVT_RETKEY: + /* done; value already set */ + RNA_property_update(C, &rc->ptr, rc->prop); + ret = OPERATOR_FINISHED; + break; - delta[0] = event->x - rc->slow_mouse[0]; + case MOUSEMOVE: + if (!has_numInput) { + if (rc->slow_mode) { + if (rc->subtype == PROP_ANGLE) { + const float position[2] = {event->x, event->y}; - if (rc->zoom_prop) { - delta[0] /= zoom[0]; - } + /* calculate the initial angle here first */ + delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0]; + delta[1] = rc->initial_mouse[1] - rc->slow_mouse[1]; - dist = dist + 0.1f * (delta[0]); - } + /* precision angle gets calculated from dial and gets added later */ + angle_precision = -0.1f * BLI_dial_angle(rc->dial, position); } else { - delta[0] = rc->initial_mouse[0] - event->x; - delta[1] = rc->initial_mouse[1] - event->y; + delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0]; + delta[1] = 0.0f; + if (rc->zoom_prop) { RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom); delta[0] /= zoom[0]; - delta[1] /= zoom[1]; } - if (rc->subtype == PROP_ANGLE) { - dist = len_v2(delta); - } - else { - dist = clamp_f(-delta[0], 0.0f, FLT_MAX); + + dist = len_v2(delta); + + delta[0] = event->x - rc->slow_mouse[0]; + + if (rc->zoom_prop) { + delta[0] /= zoom[0]; } - } - /* calculate new value and apply snapping */ - switch (rc->subtype) { - case PROP_NONE: - case PROP_DISTANCE: - case PROP_PIXEL: - new_value = dist; - if (snap) { - new_value = ((int)new_value + 5) / 10 * 10; - } - break; - case PROP_PERCENTAGE: - new_value = ((dist - WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE) / - WM_RADIAL_CONTROL_DISPLAY_WIDTH) * - 100.0f; - if (snap) { - new_value = ((int)(new_value + 2.5f)) / 5 * 5; - } - break; - case PROP_FACTOR: - new_value = (WM_RADIAL_CONTROL_DISPLAY_SIZE - dist) / - WM_RADIAL_CONTROL_DISPLAY_WIDTH; - if (snap) { - new_value = ((int)ceil(new_value * 10.f) * 10.0f) / 100.f; - } - /* Invert new value to increase the factor moving the mouse to the right */ - new_value = 1 - new_value; - break; - case PROP_ANGLE: - new_value = atan2f(delta[1], delta[0]) + (float)M_PI + angle_precision; - new_value = fmod(new_value, 2.0f * (float)M_PI); - if (new_value < 0.0f) { - new_value += 2.0f * (float)M_PI; - } - if (snap) { - new_value = DEG2RADF(((int)RAD2DEGF(new_value) + 5) / 10 * 10); - } - break; - default: - new_value = dist; /* dummy value, should this ever happen? - campbell */ - break; + dist = dist + 0.1f * (delta[0]); } - - /* clamp and update */ - CLAMP(new_value, rc->min_value, rc->max_value); - radial_control_set_value(rc, new_value); - rc->current_value = new_value; - handled = true; - break; } - break; - - case EVT_LEFTSHIFTKEY: - case EVT_RIGHTSHIFTKEY: { - if (event->val == KM_PRESS) { - rc->slow_mouse[0] = event->x; - rc->slow_mouse[1] = event->y; - rc->slow_mode = true; + else { + delta[0] = rc->initial_mouse[0] - event->x; + delta[1] = rc->initial_mouse[1] - event->y; + if (rc->zoom_prop) { + RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom); + delta[0] /= zoom[0]; + delta[1] /= zoom[1]; + } if (rc->subtype == PROP_ANGLE) { - float initial_position[2] = {UNPACK2(rc->initial_mouse)}; - float current_position[2] = {UNPACK2(rc->slow_mouse)}; - rc->dial = BLI_dial_initialize(initial_position, 0.0f); - /* immediately set the position to get a an initial direction */ - BLI_dial_angle(rc->dial, current_position); + dist = len_v2(delta); } - handled = true; - } - if (event->val == KM_RELEASE) { - rc->slow_mode = false; - handled = true; - if (rc->dial) { - MEM_freeN(rc->dial); - rc->dial = NULL; + else { + dist = clamp_f(-delta[0], 0.0f, FLT_MAX); } } + + /* calculate new value and apply snapping */ + switch (rc->subtype) { + case PROP_NONE: + case PROP_DISTANCE: + case PROP_PIXEL: + new_value = dist; + if (snap) { + new_value = ((int)new_value + 5) / 10 * 10; + } + break; + case PROP_PERCENTAGE: + new_value = ((dist - WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE) / + WM_RADIAL_CONTROL_DISPLAY_WIDTH) * + 100.0f; + if (snap) { + new_value = ((int)(new_value + 2.5f)) / 5 * 5; + } + break; + case PROP_FACTOR: + new_value = (WM_RADIAL_CONTROL_DISPLAY_SIZE - dist) / WM_RADIAL_CONTROL_DISPLAY_WIDTH; + if (snap) { + new_value = ((int)ceil(new_value * 10.f) * 10.0f) / 100.f; + } + /* Invert new value to increase the factor moving the mouse to the right */ + new_value = 1 - new_value; + break; + case PROP_ANGLE: + new_value = atan2f(delta[1], delta[0]) + (float)M_PI + angle_precision; + new_value = fmod(new_value, 2.0f * (float)M_PI); + if (new_value < 0.0f) { + new_value += 2.0f * (float)M_PI; + } + if (snap) { + new_value = DEG2RADF(((int)RAD2DEGF(new_value) + 5) / 10 * 10); + } + break; + default: + new_value = dist; /* dummy value, should this ever happen? - campbell */ + break; + } + + /* clamp and update */ + CLAMP(new_value, rc->min_value, rc->max_value); + radial_control_set_value(rc, new_value); + rc->current_value = new_value; + handled = true; break; } + break; + + case EVT_LEFTSHIFTKEY: + case EVT_RIGHTSHIFTKEY: { + if (event->val == KM_PRESS) { + rc->slow_mouse[0] = event->x; + rc->slow_mouse[1] = event->y; + rc->slow_mode = true; + if (rc->subtype == PROP_ANGLE) { + const float initial_position[2] = {UNPACK2(rc->initial_mouse)}; + const float current_position[2] = {UNPACK2(rc->slow_mouse)}; + rc->dial = BLI_dial_init(initial_position, 0.0f); + /* immediately set the position to get a an initial direction */ + BLI_dial_angle(rc->dial, current_position); + } + handled = true; + } + if (event->val == KM_RELEASE) { + rc->slow_mode = false; + handled = true; + if (rc->dial) { + MEM_freeN(rc->dial); + rc->dial = NULL; + } + } + break; } + } - /* Modal numinput inactive, try to handle numeric inputs last... */ - if (!handled && event->val == KM_PRESS && handleNumInput(C, &rc->num_input, event)) { - applyNumInput(&rc->num_input, &numValue); + /* Modal numinput inactive, try to handle numeric inputs last... */ + if (!handled && event->val == KM_PRESS && handleNumInput(C, &rc->num_input, event)) { + applyNumInput(&rc->num_input, &numValue); - if (rc->subtype == PROP_ANGLE) { - numValue = fmod(numValue, 2.0f * (float)M_PI); - if (numValue < 0.0f) { - numValue += 2.0f * (float)M_PI; - } + if (rc->subtype == PROP_ANGLE) { + numValue = fmod(numValue, 2.0f * (float)M_PI); + if (numValue < 0.0f) { + numValue += 2.0f * (float)M_PI; } + } - CLAMP(numValue, rc->min_value, rc->max_value); - new_value = numValue; + CLAMP(numValue, rc->min_value, rc->max_value); + new_value = numValue; - radial_control_set_value(rc, new_value); + radial_control_set_value(rc, new_value); - rc->current_value = new_value; - radial_control_update_header(op, C); - return OPERATOR_RUNNING_MODAL; - } + rc->current_value = new_value; + radial_control_update_header(op, C); + return OPERATOR_RUNNING_MODAL; } ED_region_tag_redraw(CTX_wm_region(C)); @@ -3917,6 +3904,7 @@ static void gesture_box_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "CLIP_OT_select_box"); WM_modalkeymap_assign(keymap, "CLIP_OT_graph_select_box"); WM_modalkeymap_assign(keymap, "MASK_OT_select_box"); + WM_modalkeymap_assign(keymap, "PAINT_OT_mask_box_gesture"); WM_modalkeymap_assign(keymap, "VIEW2D_OT_zoom_border"); WM_modalkeymap_assign(keymap, "VIEW3D_OT_clip_border"); WM_modalkeymap_assign(keymap, "VIEW3D_OT_render_border"); diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index 74e1c495a00..d0a70596957 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -335,9 +335,8 @@ static void playanim_toscreen( offs_y + (ps->draw_flip[1] ? span_y : 0.0f), ibuf->x, ibuf->y, - GL_RGBA, - GL_UNSIGNED_BYTE, - GL_NEAREST, + GPU_RGBA8, + false, ibuf->rect, ((ps->draw_flip[0] ? -1.0f : 1.0f)) * (ps->zoom / (float)ps->win_x), ((ps->draw_flip[1] ? -1.0f : 1.0f)) * (ps->zoom / (float)ps->win_y), diff --git a/source/blender/windowmanager/intern/wm_stereo.c b/source/blender/windowmanager/intern/wm_stereo.c index 245560d3795..9667ed5b631 100644 --- a/source/blender/windowmanager/intern/wm_stereo.c +++ b/source/blender/windowmanager/intern/wm_stereo.c @@ -353,12 +353,11 @@ int wm_stereo3d_set_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_WINDOW, NULL); return OPERATOR_FINISHED; } - else { - /* without this, the popup won't be freed freed properly T44688 */ - CTX_wm_window_set(C, win_src); - win_src->stereo3d_format->display_mode = prev_display_mode; - return OPERATOR_CANCELLED; - } + + /* without this, the popup won't be freed freed properly T44688 */ + CTX_wm_window_set(C, win_src); + win_src->stereo3d_format->display_mode = prev_display_mode; + return OPERATOR_CANCELLED; } int wm_stereo3d_set_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) @@ -368,9 +367,7 @@ int wm_stereo3d_set_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(ev if (wm_stereo3d_set_properties(C, op)) { return wm_stereo3d_set_exec(C, op); } - else { - return WM_operator_props_dialog_popup(C, op, 250); - } + return WM_operator_props_dialog_popup(C, op, 250); } void wm_stereo3d_set_draw(bContext *UNUSED(C), wmOperator *op) diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index 477579ed620..0cb76404258 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -29,7 +29,6 @@ #include "DNA_screen_types.h" #include "DNA_windowmanager_types.h" -#include "GPU_glew.h" #include "GPU_matrix.h" #include "GPU_viewport.h" diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index e444c5b2109..e0dcd746aea 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -355,10 +355,8 @@ wmWindow *wm_window_copy_test(bContext *C, WM_event_add_notifier_ex(wm, CTX_wm_window(C), NC_WINDOW | NA_ADDED, NULL); return win_dst; } - else { - wm_window_close(C, wm, win_dst); - return NULL; - } + wm_window_close(C, wm, win_dst); + return NULL; } /** \} */ @@ -813,9 +811,7 @@ static bool wm_window_update_size_position(wmWindow *win) win->posy = posy; return true; } - else { - return false; - } + return false; } /** @@ -840,11 +836,10 @@ wmWindow *WM_window_open(bContext *C, const rcti *rect) if (win->ghostwin) { return win; } - else { - wm_window_close(C, wm, win); - CTX_wm_window_set(C, win_prev); - return NULL; - } + + wm_window_close(C, wm, win); + CTX_wm_window_set(C, win_prev); + return NULL; } /** @@ -969,13 +964,12 @@ wmWindow *WM_window_open_temp(bContext *C, GHOST_SetTitle(win->ghostwin, title); return win; } - else { - /* very unlikely! but opening a new window can fail */ - wm_window_close(C, wm, win); - CTX_wm_window_set(C, win_prev); - return NULL; - } + /* very unlikely! but opening a new window can fail */ + wm_window_close(C, wm, win); + CTX_wm_window_set(C, win_prev); + + return NULL; } /* ****************** Operators ****************** */ @@ -1206,7 +1200,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr /* Ghost now can call this function for life resizes, * but it should return if WM didn't initialize yet. * Can happen on file read (especially full size window). */ - if ((wm->initialized & WM_WINDOW_IS_INITIALIZED) == 0) { + if ((wm->initialized & WM_WINDOW_IS_INIT) == 0) { return 1; } if (!ghostwin) { @@ -1215,15 +1209,13 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr puts("<!> event has no window"); return 1; } - else if (!GHOST_ValidWindow(g_system, ghostwin)) { + if (!GHOST_ValidWindow(g_system, ghostwin)) { /* XXX - should be checked, why are we getting an event here, and */ /* what is it? */ puts("<!> event has invalid window"); return 1; } - else { - win = GHOST_GetWindowUserData(ghostwin); - } + win = GHOST_GetWindowUserData(ghostwin); switch (type) { case GHOST_kEventWindowDeactivate: diff --git a/source/blender/windowmanager/wm_draw.h b/source/blender/windowmanager/wm_draw.h index a26c02317d0..4997361b485 100644 --- a/source/blender/windowmanager/wm_draw.h +++ b/source/blender/windowmanager/wm_draw.h @@ -23,8 +23,6 @@ #pragma once -#include "GPU_glew.h" - struct GPUOffScreen; struct GPUTexture; struct GPUViewport; diff --git a/source/blender/windowmanager/xr/intern/wm_xr_session.c b/source/blender/windowmanager/xr/intern/wm_xr_session.c index c564f74b771..b44f006cde8 100644 --- a/source/blender/windowmanager/xr/intern/wm_xr_session.c +++ b/source/blender/windowmanager/xr/intern/wm_xr_session.c @@ -183,16 +183,15 @@ static wmXrSessionStateEvent wm_xr_session_state_to_event(const wmXrSessionState if (!state->is_view_data_set) { return SESSION_STATE_EVENT_START; } - else if (wm_xr_session_draw_data_needs_reset_to_base_pose(state, settings)) { + if (wm_xr_session_draw_data_needs_reset_to_base_pose(state, settings)) { return SESSION_STATE_EVENT_RESET_TO_BASE_POSE; } - else { - const bool position_tracking_toggled = ((state->prev_settings_flag & - XR_SESSION_USE_POSITION_TRACKING) != - (settings->flag & XR_SESSION_USE_POSITION_TRACKING)); - if (position_tracking_toggled) { - return SESSION_STATE_EVENT_POSITON_TRACKING_TOGGLE; - } + + const bool position_tracking_toggled = ((state->prev_settings_flag & + XR_SESSION_USE_POSITION_TRACKING) != + (settings->flag & XR_SESSION_USE_POSITION_TRACKING)); + if (position_tracking_toggled) { + return SESSION_STATE_EVENT_POSITON_TRACKING_TOGGLE; } return SESSION_STATE_EVENT_NONE; |