diff options
Diffstat (limited to 'source')
301 files changed, 5501 insertions, 3862 deletions
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index 76829db755c..5724d844089 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -221,9 +221,7 @@ void blf_batch_draw(void) return; } - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); #ifndef BLF_STANDALONE /* We need to flush widget base first to ensure correct ordering. */ @@ -239,7 +237,7 @@ void blf_batch_draw(void) GPU_batch_uniform_1i(g_batch.batch, "glyph", 0); GPU_batch_draw(g_batch.batch); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* restart to 1st vertex data pointers */ GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.pos_loc, &g_batch.pos_step); diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 6ea113d8828..231cd0e53c5 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -50,6 +50,9 @@ extern "C" { /** User readable version string. */ const char *BKE_blender_version_string(void); +/* Returns true when version cycle is alpha, otherwise (beta, rc) returns false. */ +bool BKE_blender_version_is_alpha(void); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_mesh_runtime.h b/source/blender/blenkernel/BKE_mesh_runtime.h index adb7c357049..267be4f44fd 100644 --- a/source/blender/blenkernel/BKE_mesh_runtime.h +++ b/source/blender/blenkernel/BKE_mesh_runtime.h @@ -71,7 +71,7 @@ struct Mesh *mesh_get_eval_deform(struct Depsgraph *depsgraph, struct Object *ob, const struct CustomData_MeshMasks *dataMask); -struct Mesh *mesh_create_eval_final_render(struct Depsgraph *depsgraph, +struct Mesh *mesh_create_eval_final(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, const struct CustomData_MeshMasks *dataMask); @@ -82,11 +82,6 @@ struct Mesh *mesh_create_eval_final_index_render(struct Depsgraph *depsgraph, const struct CustomData_MeshMasks *dataMask, int index); -struct Mesh *mesh_create_eval_final_view(struct Depsgraph *depsgraph, - struct Scene *scene, - struct Object *ob, - const struct CustomData_MeshMasks *dataMask); - struct Mesh *mesh_create_eval_no_deform(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 7b63a4154fa..b2794e9d9d6 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -338,7 +338,7 @@ typedef struct SculptBoundary { int num_vertices; /* Distance from a vertex in the boundary to initial vertex indexed by vertex index, taking into - * account the lengh of all edges between them. Any vertex that is not in the boundary will have + * account the length of all edges between them. Any vertex that is not in the boundary will have * a distance of 0. */ float *distance; diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 8cd86593873..3ab923f05f6 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -110,6 +110,8 @@ void BKE_toolsettings_free(struct ToolSettings *toolsettings); struct Scene *BKE_scene_duplicate(struct Main *bmain, struct Scene *sce, eSceneCopyMethod type); void BKE_scene_groups_relink(struct Scene *sce); +struct Scene *BKE_scene_find_from_view_layer(const struct Main *bmain, + const struct ViewLayer *layer); struct Scene *BKE_scene_find_from_collection(const struct Main *bmain, const struct Collection *collection); @@ -145,7 +147,7 @@ void BKE_scene_update_tag_audio_volume(struct Depsgraph *, struct Scene *scene); void BKE_scene_graph_update_tagged(struct Depsgraph *depsgraph, struct Main *bmain); void BKE_scene_graph_evaluated_ensure(struct Depsgraph *depsgraph, struct Main *bmain); -void BKE_scene_graph_update_for_newframe(struct Depsgraph *depsgraph, struct Main *bmain); +void BKE_scene_graph_update_for_newframe(struct Depsgraph *depsgraph); void BKE_scene_view_layer_graph_evaluated_ensure(struct Main *bmain, struct Scene *scene, diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 0c09d491ca1..6cf72eb09d9 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -36,8 +36,8 @@ set(INC ../makesrna ../modifiers ../nodes - ../simulation ../shader_fx + ../simulation ../render/extern/include ../../../intern/ghost ../../../intern/glew-mx @@ -366,8 +366,8 @@ set(SRC BKE_packedFile.h BKE_paint.h BKE_particle.h - BKE_persistent_data_handle.hh BKE_pbvh.h + BKE_persistent_data_handle.hh BKE_pointcache.h BKE_pointcloud.h BKE_report.h @@ -442,9 +442,9 @@ set(LIB bf_intern_opensubdiv # Uses stub when disabled. bf_modifiers bf_nodes - bf_simulation bf_rna bf_shader_fx + bf_simulation ) if(WITH_BINRELOC) diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 0dc85dfaa18..4f587abd9f0 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -909,8 +909,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph, const int required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime; /* Sculpt can skip certain modifiers. */ - MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); - const bool has_multires = (mmd && mmd->sculptlvl != 0); + const bool has_multires = BKE_sculpt_multires_active(scene, ob) != NULL; bool multires_applied = false; const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt && !use_render; const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm) && !use_render; @@ -1991,7 +1990,7 @@ Mesh *mesh_get_eval_deform(struct Depsgraph *depsgraph, return ob->runtime.mesh_deform_eval; } -Mesh *mesh_create_eval_final_render(Depsgraph *depsgraph, +Mesh *mesh_create_eval_final(Depsgraph *depsgraph, Scene *scene, Object *ob, const CustomData_MeshMasks *dataMask) @@ -2016,26 +2015,6 @@ Mesh *mesh_create_eval_final_index_render(Depsgraph *depsgraph, return final; } -Mesh *mesh_create_eval_final_view(Depsgraph *depsgraph, - Scene *scene, - Object *ob, - const CustomData_MeshMasks *dataMask) -{ - Mesh *final; - - /* XXX hack - * psys modifier updates particle state when called during dupli-list generation, - * which can lead to wrong transforms. This disables particle system modifier execution. - */ - ob->transflag |= OB_NO_PSYS_UPDATE; - - mesh_calc_modifiers(depsgraph, scene, ob, 1, false, dataMask, -1, false, false, NULL, &final); - - ob->transflag &= ~OB_NO_PSYS_UPDATE; - - return final; -} - Mesh *mesh_create_eval_no_deform(Depsgraph *depsgraph, Scene *scene, Object *ob, diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index e8aa13a8beb..1d5c8f76cc5 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -135,6 +135,12 @@ const char *BKE_blender_version_string(void) return blender_version_string; } +bool BKE_blender_version_is_alpha(void) +{ + bool is_alpha = STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "alpha"); + return is_alpha; +} + void BKE_blender_globals_init(void) { blender_version_init(); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 027761335b0..24b4b85d0d4 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -1611,7 +1611,6 @@ static int cloth_build_springs(ClothModifierData *clmd, Mesh *mesh) if (use_internal_springs && numpolys > 0) { BVHTreeFromMesh treedata = {NULL}; unsigned int tar_v_idx; - BLI_bitmap *verts_used = NULL; Mesh *tmp_mesh = NULL; RNG *rng; @@ -1622,7 +1621,7 @@ static int cloth_build_springs(ClothModifierData *clmd, Mesh *mesh) BKE_mesh_calc_normals(tmp_mesh); } - verts_used = BLI_BITMAP_NEW(mvert_num * mvert_num, __func__); + EdgeSet *existing_vert_pairs = BLI_edgeset_new("cloth_sewing_edges_graph"); BKE_bvhtree_from_mesh_get(&treedata, tmp_mesh ? tmp_mesh : mesh, BVHTREE_FROM_LOOPTRI, 2); rng = BLI_rng_new_srandom(0); @@ -1635,12 +1634,12 @@ static int cloth_build_springs(ClothModifierData *clmd, Mesh *mesh) clmd->sim_parms->internal_spring_max_diversion, (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_INTERNAL_SPRINGS_NORMAL), &tar_v_idx)) { - if (BLI_BITMAP_TEST_BOOL(verts_used, i * mvert_num + tar_v_idx)) { + if (BLI_edgeset_haskey(existing_vert_pairs, i, tar_v_idx)) { + /* We have already created a spring between these verts! */ continue; } - BLI_BITMAP_ENABLE(verts_used, i * mvert_num + tar_v_idx); - BLI_BITMAP_ENABLE(verts_used, tar_v_idx * mvert_num + i); + BLI_edgeset_insert(existing_vert_pairs, i, tar_v_idx); spring = (ClothSpring *)MEM_callocN(sizeof(ClothSpring), "cloth spring"); @@ -1666,7 +1665,7 @@ static int cloth_build_springs(ClothModifierData *clmd, Mesh *mesh) } else { cloth_free_errorsprings(cloth, edgelist, spring_ref); - MEM_freeN(verts_used); + BLI_edgeset_free(existing_vert_pairs); free_bvhtree_from_mesh(&treedata); if (tmp_mesh) { BKE_mesh_free(tmp_mesh); @@ -1675,7 +1674,7 @@ static int cloth_build_springs(ClothModifierData *clmd, Mesh *mesh) } } } - MEM_freeN(verts_used); + BLI_edgeset_free(existing_vert_pairs); free_bvhtree_from_mesh(&treedata); if (tmp_mesh) { BKE_mesh_free(tmp_mesh); diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 047f927ae88..e5a9ee53054 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -6032,7 +6032,7 @@ void BKE_constraints_solve(struct Depsgraph *depsgraph, */ enf = con->enforce; - /* make copy of worldspace matrix pre-constraint for use with blending later */ + /* make copy of world-space matrix pre-constraint for use with blending later */ copy_m4_m4(oldmat, cob->matrix); /* move owner matrix into right space */ @@ -6053,16 +6053,16 @@ void BKE_constraints_solve(struct Depsgraph *depsgraph, cti->flush_constraint_targets(con, &targets, 1); } - /* move owner back into worldspace for next constraint/other business */ + /* move owner back into world-space for next constraint/other business */ if ((con->flag & CONSTRAINT_SPACEONCE) == 0) { BKE_constraint_mat_convertspace( cob->ob, cob->pchan, cob->matrix, con->ownspace, CONSTRAINT_SPACE_WORLD, false); } /* Interpolate the enforcement, to blend result of constraint into final owner transform - * - all this happens in worldspace to prevent any weirdness creeping in + * - all this happens in world-space to prevent any weirdness creeping in * (T26014 and T25725), since some constraints may not convert the solution back to the input - * space before blending but all are guaranteed to end up in good "worldspace" result. + * space before blending but all are guaranteed to end up in good "world-space" result. */ /* Note: all kind of stuff here before (caused trouble), much easier to just interpolate, * or did I miss something? -jahka (r.32105) */ diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 09305434289..4f65f8a57ab 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -532,6 +532,7 @@ bGPdata *BKE_gpencil_data_addnew(Main *bmain, const char name[]) gpd->grid.lines = GP_DEFAULT_GRID_LINES; /* Number of lines */ /* Onion-skinning settings (data-block level) */ + gpd->onion_keytype = -1; /* All by default. */ gpd->onion_flag |= (GP_ONION_GHOST_PREVCOL | GP_ONION_GHOST_NEXTCOL); gpd->onion_flag |= GP_ONION_FADE; gpd->onion_mode = GP_ONION_MODE_RELATIVE; diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index de07c96e3f0..d2f7ee68430 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -196,11 +196,11 @@ MetaElem *BKE_mball_element_add(MetaBall *mb, const int type) return ml; } /** - * Compute bounding box of all MetaElems/MetaBalls. + * Compute bounding box of all #MetaElem / #MetaBall * - * Bounding box is computed from polygonized surface. Object *ob is - * basic MetaBall (usually with name Meta). All other MetaBalls (with - * names Meta.001, Meta.002, etc) are included in this Bounding Box. + * Bounding box is computed from polygonized surface. \a ob is + * basic meta-balls (with name `Meta` for example). All other meta-ball objects + * (with names `Meta.001`, `Meta.002`, etc) are included in this bounding-box. */ void BKE_mball_texspace_calc(Object *ob) { @@ -298,25 +298,30 @@ float *BKE_mball_make_orco(Object *ob, ListBase *dispbase) return orcodata; } -/* Note on mball basis stuff 2.5x (this is a can of worms) +/** + * \brief Test, if \a ob is a basis meta-ball. + * + * It test last character of Object ID name. If last character + * is digit it return 0, else it return 1. + * + * + * Meta-Ball Basis Notes from Blender-2.5x + * ======================================= + * + * This is a can of worms. + * * This really needs a rewrite/refactor its totally broken in anything other then basic cases - * Multiple Scenes + Set Scenes & mixing mball basis SHOULD work but fails to update the depsgraph - * on rename and linking into scenes or removal of basis mball. + * Multiple Scenes + Set Scenes & mixing meta-ball basis _should_ work but fails to update the + * depsgraph on rename and linking into scenes or removal of basis meta-ball. * So take care when changing this code. * - * Main idiot thing here is that the system returns find_basis_mball() - * objects which fail a is_basis_mball() test. + * Main idiot thing here is that the system returns #BKE_mball_basis_find() + * objects which fail a #BKE_mball_is_basis() test. * - * Not only that but the depsgraph and their areas depend on this behavior!, + * Not only that but the depsgraph and their areas depend on this behavior, * so making small fixes here isn't worth it. * - Campbell */ - -/** \brief Test, if Object *ob is basic MetaBall. - * - * It test last character of Object ID name. If last character - * is digit it return 0, else it return 1. - */ bool BKE_mball_is_basis(Object *ob) { /* just a quick test */ @@ -378,12 +383,12 @@ bool BKE_mball_is_any_unselected(const MetaBall *mb) } /** - * \brief copy some properties from object to other metaball object with same base name + * \brief copy some properties from object to other meta-ball object with same base name * - * When some properties (wiresize, threshold, update flags) of metaball are changed, then this - * properties are copied to all metaballs in same "group" (metaballs with same base name: MBall, - * MBall.001, MBall.002, etc). The most important is to copy properties to the base metaball, - * because this metaball influence polygonization of metaballs. */ + * When some properties (wire-size, threshold, update flags) of meta-ball are changed, then this + * properties are copied to all meta-balls in same "group" (meta-balls with same base name: + * `MBall`, `MBall.001`, `MBall.002`, etc). The most important is to copy properties to the base + * meta-ball, because this meta-ball influence polygonization of meta-balls. */ void BKE_mball_properties_copy(Scene *scene, Object *active_object) { Scene *sce_iter = scene; @@ -397,7 +402,7 @@ void BKE_mball_properties_copy(Scene *scene, Object *active_object) BLI_split_name_num(basisname, &basisnr, active_object->id.name + 2, '.'); /* Pass depsgraph as NULL, which means we will not expand into - * duplis unlike when we generate the mball. Expanding duplis + * duplis unlike when we generate the meta-ball. Expanding duplis * would not be compatible when editing multiple view layers. */ BKE_scene_base_iter_next(NULL, &iter, &sce_iter, 0, NULL, NULL); while (BKE_scene_base_iter_next(NULL, &iter, &sce_iter, 1, &base, &ob)) { @@ -424,12 +429,11 @@ void BKE_mball_properties_copy(Scene *scene, Object *active_object) /** \brief This function finds basic MetaBall. * - * Basic MetaBall doesn't include any number at the end of - * its name. All MetaBalls with same base of name can be - * blended. MetaBalls with different basic name can't be - * blended. + * Basic meta-ball doesn't include any number at the end of + * its name. All meta-balls with same base of name can be + * blended. meta-balls with different basic name can't be blended. * - * warning!, is_basis_mball() can fail on returned object, see long note above. + * \warning #BKE_mball_is_basis() can fail on returned object, see function docs for details. */ Object *BKE_mball_basis_find(Scene *scene, Object *basis) { diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c index 76a6d23bc8f..9426d09885e 100644 --- a/source/blender/blenkernel/intern/mesh_convert.c +++ b/source/blender/blenkernel/intern/mesh_convert.c @@ -1111,15 +1111,7 @@ static Mesh *mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph, Object Scene *scene = DEG_get_evaluated_scene(depsgraph); CustomData_MeshMasks mask = CD_MASK_MESH; - Mesh *result; - - if (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER) { - result = mesh_create_eval_final_render(depsgraph, scene, &object_for_eval, &mask); - } - else { - result = mesh_create_eval_final_view(depsgraph, scene, &object_for_eval, &mask); - } - + Mesh *result = mesh_create_eval_final(depsgraph, scene, &object_for_eval, &mask); return result; } diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 19d5c34ad73..e3c209b60e6 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -1421,7 +1421,7 @@ MultiresModifierData *BKE_sculpt_multires_active(Scene *scene, Object *ob) continue; } - if (mmd->sculptlvl > 0) { + if (mmd->sculptlvl > 0 && !(mmd->flags & eMultiresModifierFlag_UseSculptBaseMesh)) { return mmd; } @@ -1437,10 +1437,9 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob) { ModifierData *md; Mesh *me = (Mesh *)ob->data; - MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob); VirtualModifierData virtualModifierData; - if (mmd || ob->sculpt->bm) { + if (ob->sculpt->bm || BKE_sculpt_multires_active(scene, ob)) { return false; } @@ -1458,7 +1457,10 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob) continue; } if (md->type == eModifierType_Multires && (ob->mode & OB_MODE_SCULPT)) { - continue; + MultiresModifierData *mmd = (MultiresModifierData *)md; + if (!(mmd->flags & eMultiresModifierFlag_UseSculptBaseMesh)) { + continue; + } } if (md->type == eModifierType_ShapeKey) { continue; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 64e642462af..8c5915d3768 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -4025,7 +4025,6 @@ static void ptcache_dt_to_str(char *str, double dtime) /* if bake is not given run simulations to current frame */ void BKE_ptcache_bake(PTCacheBaker *baker) { - Main *bmain = baker->bmain; Scene *scene = baker->scene; ViewLayer *view_layer = baker->view_layer; struct Depsgraph *depsgraph = baker->depsgraph; @@ -4156,7 +4155,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker) stime = ptime = PIL_check_seconds_timer(); for (int fr = CFRA; fr <= endframe; fr += baker->quick_step, CFRA = fr) { - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); if (baker->update_progress) { float progress = ((float)(CFRA - startframe) / (float)(endframe - startframe)); @@ -4255,7 +4254,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker) CFRA = cfrao; if (bake) { /* already on cfra unless baking */ - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); } /* TODO: call redraw all windows somehow */ diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 7e25e8c96ae..1dc51c9ddae 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1129,6 +1129,17 @@ int BKE_scene_base_iter_next( return iter->phase; } +Scene *BKE_scene_find_from_view_layer(const Main *bmain, const ViewLayer *layer) +{ + for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) { + if (BLI_findindex(&scene->view_layers, layer) != -1) { + return scene; + } + } + + return NULL; +} + Scene *BKE_scene_find_from_collection(const Main *bmain, const Collection *collection) { for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) { @@ -1485,7 +1496,7 @@ static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool on for (int pass = 0; pass < 2; pass++) { /* (Re-)build dependency graph if needed. */ - DEG_graph_relations_update(depsgraph, bmain, scene, view_layer); + DEG_graph_relations_update(depsgraph); /* Uncomment this to check if graph was properly tagged for update. */ // DEG_debug_graph_relations_validate(depsgraph, bmain, scene); /* Flush editing data if needed. */ @@ -1493,7 +1504,7 @@ static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool on /* Update all objects: drivers, matrices, displists, etc. flags set * by depgraph or manual, no layer check here, gets correct flushed. */ - DEG_evaluate_on_refresh(bmain, depsgraph); + DEG_evaluate_on_refresh(depsgraph); /* Update sound system. */ BKE_scene_update_sound(depsgraph, bmain); /* Notify python about depsgraph update. */ @@ -1512,7 +1523,7 @@ static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool on * be tagged for an update anyway. * * If there are no relations changed by the callback this call will do nothing. */ - DEG_graph_relations_update(depsgraph, bmain, scene, view_layer); + DEG_graph_relations_update(depsgraph); } /* Inform editors about possible changes. */ DEG_ids_check_recalc(bmain, depsgraph, scene, view_layer, false); @@ -1541,10 +1552,11 @@ void BKE_scene_graph_evaluated_ensure(Depsgraph *depsgraph, Main *bmain) } /* applies changes right away, does all sets too */ -void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph, Main *bmain) +void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph) { Scene *scene = DEG_get_input_scene(depsgraph); ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph); + Main *bmain = DEG_get_bmain(depsgraph); /* Keep this first. */ BKE_callback_exec_id(bmain, &scene->id, BKE_CB_EVT_FRAME_CHANGE_PRE); @@ -1555,7 +1567,7 @@ void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph, Main *bmain) */ BKE_image_editors_update_frame(bmain, scene->r.cfra); BKE_sound_set_cfra(scene->r.cfra); - DEG_graph_relations_update(depsgraph, bmain, scene, view_layer); + DEG_graph_relations_update(depsgraph); /* Update all objects: drivers, matrices, displists, etc. flags set * by depgraph or manual, no layer check here, gets correct flushed. * @@ -1564,10 +1576,10 @@ void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph, Main *bmain) * loose any possible unkeyed changes made by the handler. */ if (pass == 0) { const float ctime = BKE_scene_frame_get(scene); - DEG_evaluate_on_framechange(bmain, depsgraph, ctime); + DEG_evaluate_on_framechange(depsgraph, ctime); } else { - DEG_evaluate_on_refresh(bmain, depsgraph); + DEG_evaluate_on_refresh(depsgraph); } /* Update sound system animation. */ BKE_scene_update_sound(depsgraph, bmain); @@ -1578,7 +1590,7 @@ void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph, Main *bmain) /* NOTE: Similar to this case in scene_graph_update_tagged(). Need to ensure that * DEG_ids_clear_recalc() doesn't access freed memory of possibly removed ID. */ - DEG_graph_relations_update(depsgraph, bmain, scene, view_layer); + DEG_graph_relations_update(depsgraph); } /* Inform editors about possible changes. */ @@ -2245,6 +2257,7 @@ static Depsgraph **scene_get_depsgraph_p(Main *bmain, { BLI_assert(scene != NULL); BLI_assert(view_layer != NULL); + BLI_assert(BKE_scene_find_from_view_layer(bmain, view_layer) == scene); /* Make sure hash itself exists. */ if (allocate_ghash_entry) { BKE_scene_ensure_depsgraph_hash(scene); diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c index 3d1f33190dc..7d2858050be 100644 --- a/source/blender/blenkernel/intern/seqcache.c +++ b/source/blender/blenkernel/intern/seqcache.c @@ -1326,6 +1326,7 @@ void BKE_sequencer_cache_put(const SeqRenderData *context, context = BKE_sequencer_prefetch_get_original_context(context); scene = context->scene; seq = BKE_sequencer_prefetch_get_original_sequence(seq, scene); + BLI_assert(seq != NULL); } /* Prevent reinserting, it breaks cache key linking. */ diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index afec9b835a5..c6daecbcee6 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -2387,6 +2387,8 @@ static void copy_transform_effect(Sequence *dst, Sequence *src, const int UNUSED static void transform_image(int x, int y, + int start_line, + int total_lines, ImBuf *ibuf1, ImBuf *out, float scale_x, @@ -2396,34 +2398,27 @@ static void transform_image(int x, float rotate, int interpolation) { - int xo, yo, xi, yi; - float xt, yt, xr, yr; - float s, c; - - xo = x; - yo = y; - /* Rotate */ - s = sinf(rotate); - c = cosf(rotate); + float s = sinf(rotate); + float c = cosf(rotate); - for (yi = 0; yi < yo; yi++) { - for (xi = 0; xi < xo; xi++) { + for (int yi = start_line; yi < start_line + total_lines; yi++) { + for (int xi = 0; xi < x; xi++) { /* translate point */ - xt = xi - translate_x; - yt = yi - translate_y; + float xt = xi - translate_x; + float yt = yi - translate_y; /* rotate point with center ref */ - xr = c * xt + s * yt; - yr = -s * xt + c * yt; + float xr = c * xt + s * yt; + float yr = -s * xt + c * yt; /* scale point with center ref */ xt = xr / scale_x; yt = yr / scale_y; /* undo reference center point */ - xt += (xo / 2.0f); - yt += (yo / 2.0f); + xt += (x / 2.0f); + yt += (y / 2.0f); /* interpolate */ switch (interpolation) { @@ -2441,9 +2436,19 @@ static void transform_image(int x, } } -static void do_transform( - Scene *scene, Sequence *seq, float UNUSED(facf0), int x, int y, ImBuf *ibuf1, ImBuf *out) +static void do_transform_effect(const SeqRenderData *context, + Sequence *seq, + float UNUSED(cfra), + float UNUSED(facf0), + float UNUSED(facf1), + ImBuf *ibuf1, + ImBuf *UNUSED(ibuf2), + ImBuf *UNUSED(ibuf3), + int start_line, + int total_lines, + ImBuf *out) { + Scene *scene = context->scene; TransformVars *transform = (TransformVars *)seq->effectdata; float scale_x, scale_y, translate_x, translate_y, rotate_radians; @@ -2456,6 +2461,9 @@ static void do_transform( scale_y = transform->ScaleyIni; } + int x = context->rectx; + int y = context->recty; + /* Translate */ if (!transform->percent) { float rd_s = (scene->r.size / 100.0f); @@ -2473,6 +2481,8 @@ static void do_transform( transform_image(x, y, + start_line, + total_lines, ibuf1, out, scale_x, @@ -2483,22 +2493,6 @@ static void do_transform( transform->interpolation); } -static ImBuf *do_transform_effect(const SeqRenderData *context, - Sequence *seq, - float UNUSED(cfra), - float facf0, - float UNUSED(facf1), - ImBuf *ibuf1, - ImBuf *ibuf2, - ImBuf *ibuf3) -{ - ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); - - do_transform(context->scene, seq, facf0, context->rectx, context->recty, ibuf1, out); - - return out; -} - /*********************** Glow *************************/ static void RVBlurBitmap2_float(float *map, int width, int height, float blur, int quality) @@ -4183,11 +4177,12 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type) rval.execute = do_glow_effect; break; case SEQ_TYPE_TRANSFORM: + rval.multithreaded = true; rval.init = init_transform_effect; rval.num_inputs = num_inputs_transform; rval.free = free_transform_effect; rval.copy = copy_transform_effect; - rval.execute = do_transform_effect; + rval.execute_slice = do_transform_effect; break; case SEQ_TYPE_SPEED: rval.init = init_speed_effect; diff --git a/source/blender/blenkernel/intern/seqprefetch.c b/source/blender/blenkernel/intern/seqprefetch.c index 795086fffa4..3a7e4af490a 100644 --- a/source/blender/blenkernel/intern/seqprefetch.c +++ b/source/blender/blenkernel/intern/seqprefetch.c @@ -207,7 +207,7 @@ static void seq_prefetch_free_depsgraph(PrefetchJob *pfjob) static void seq_prefetch_update_depsgraph(PrefetchJob *pfjob) { - DEG_evaluate_on_framechange(pfjob->bmain_eval, pfjob->depsgraph, seq_prefetch_cfra(pfjob)); + DEG_evaluate_on_framechange(pfjob->depsgraph, seq_prefetch_cfra(pfjob)); } static void seq_prefetch_init_depsgraph(PrefetchJob *pfjob) @@ -220,7 +220,7 @@ static void seq_prefetch_init_depsgraph(PrefetchJob *pfjob) DEG_debug_name_set(pfjob->depsgraph, "SEQUENCER PREFETCH"); /* Make sure there is a correct evaluated scene pointer. */ - DEG_graph_build_for_render_pipeline(pfjob->depsgraph, bmain, scene, view_layer); + DEG_graph_build_for_render_pipeline(pfjob->depsgraph); /* Update immediately so we have proper evaluated scene. */ seq_prefetch_update_depsgraph(pfjob); diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index a2a45ae56b3..b4da0c5bd33 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -3593,7 +3593,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, /* opengl offscreen render */ depsgraph = BKE_scene_get_depsgraph(context->bmain, scene, view_layer, true); - BKE_scene_graph_update_for_newframe(depsgraph, context->bmain); + BKE_scene_graph_update_for_newframe(depsgraph); ibuf = sequencer_view3d_fn( /* set for OpenGL render (NULL when scrubbing) */ depsgraph, @@ -3695,7 +3695,7 @@ finally: scene->r.subframe = orig_data.subframe; if (is_frame_update && (depsgraph != NULL)) { - BKE_scene_graph_update_for_newframe(depsgraph, context->bmain); + BKE_scene_graph_update_for_newframe(depsgraph); } #ifdef DURIAN_CAMERA_SWITCH diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index 8414f93ddaa..9b78c9e5fc3 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -757,7 +757,6 @@ static char *find_next_op(const char *str, char *remaining_str, int len_max) if (ch_is_op(remaining_str[i])) { if (scientific_notation) { scientific_notation = false; - continue; } /* Make sure we don't look backwards before the start of the string. */ diff --git a/source/blender/blenlib/BLI_compiler_compat.h b/source/blender/blenlib/BLI_compiler_compat.h index 0870d01872a..bd8f84cedd6 100644 --- a/source/blender/blenlib/BLI_compiler_compat.h +++ b/source/blender/blenlib/BLI_compiler_compat.h @@ -55,4 +55,3 @@ template<typename T> static inline T decltype_helper(T x) #else # define BLI_NOINLINE #endif - diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index fa7cf7a1847..aff80a2bd86 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -171,6 +171,15 @@ struct LinkData *BLI_genericNodeN(void *data); #define LISTBASE_FOREACH(type, var, list) \ for (type var = (type)((list)->first); var != NULL; var = (type)(((Link *)(var))->next)) +/** + * A version of #LISTBASE_FOREACH that supports incrementing an index variable at every step. + * Including this in the macro helps prevent mistakes where "continue" mistakenly skips the + * incrementation. + */ +#define LISTBASE_FOREACH_INDEX(type, var, list, index_var) \ + for (type var = (((void)(index_var = 0)), (type)((list)->first)); var != NULL; \ + var = (type)(((Link *)(var))->next), index_var++) + #define LISTBASE_FOREACH_BACKWARD(type, var, list) \ for (type var = (type)((list)->last); var != NULL; var = (type)(((Link *)(var))->prev)) diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index f63a523ca60..f030a733752 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -201,6 +201,23 @@ const float bvhtree_kdop_axes[13][3] = { {0, 1.0, -1.0}, }; +/* Used to correct the epsilon and thus match the overlap distance. */ +const float bvhtree_kdop_axes_length[13] = { + 1.0f, + 1.0f, + 1.0f, + 1.7320508075688772f, + 1.7320508075688772f, + 1.7320508075688772f, + 1.7320508075688772f, + 1.4142135623730951f, + 1.4142135623730951f, + 1.4142135623730951f, + 1.4142135623730951f, + 1.4142135623730951f, + 1.4142135623730951f, +}; + /* -------------------------------------------------------------------- */ /** \name Utility Functions * \{ */ @@ -970,9 +987,18 @@ void BLI_bvhtree_balance(BVHTree *tree) #endif } -void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints) +static void bvhtree_node_inflate(const BVHTree *tree, BVHNode *node, const float dist) { axis_t axis_iter; + for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) { + float dist_corrected = dist * bvhtree_kdop_axes_length[axis_iter]; + node->bv[(2 * axis_iter)] -= dist_corrected; /* minimum */ + node->bv[(2 * axis_iter) + 1] += dist_corrected; /* maximum */ + } +} + +void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints) +{ BVHNode *node = NULL; /* insert should only possible as long as tree->totbranch is 0 */ @@ -986,10 +1012,7 @@ void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoin node->index = index; /* inflate the bv with some epsilon */ - for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) { - node->bv[(2 * axis_iter)] -= tree->epsilon; /* minimum */ - node->bv[(2 * axis_iter) + 1] += tree->epsilon; /* maximum */ - } + bvhtree_node_inflate(tree, node, tree->epsilon); } /* call before BLI_bvhtree_update_tree() */ @@ -997,7 +1020,6 @@ bool BLI_bvhtree_update_node( BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints) { BVHNode *node = NULL; - axis_t axis_iter; /* check if index exists */ if (index > tree->totleaf) { @@ -1013,10 +1035,7 @@ bool BLI_bvhtree_update_node( } /* inflate the bv with some epsilon */ - for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) { - node->bv[(2 * axis_iter)] -= tree->epsilon; /* minimum */ - node->bv[(2 * axis_iter) + 1] += tree->epsilon; /* maximum */ - } + bvhtree_node_inflate(tree, node, tree->epsilon); return true; } diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index 34886054cb0..301d9dc2296 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -15,7 +15,8 @@ * * The Original Code is written by Rob Haarsma (phase) * All rights reserved. - * This code parses the Freetype font outline data to chains of Blender's beziertriples. + * + * This code parses the Freetype font outline data to chains of Blender's bezier-triples. * Additional information can be found at the bottom of this file. * * Code that uses exotic character maps is present but commented out. diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index 97c77ed2e19..580c833d8dc 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -186,6 +186,9 @@ void BLO_update_defaults_workspace(struct WorkSpace *workspace, const char *app_ /* Version patch user preferences. */ void BLO_version_defaults_userpref_blend(struct Main *mainvar, struct UserDef *userdef); +/* Disable unwanted experimental feature settings on startup. */ +void BLO_sanitize_experimental_features_userpref_blend(struct UserDef *userdef); + struct BlendThumbnail *BLO_thumbnail_from_file(const char *filepath); /* datafiles (generated theme) */ diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt index c56e0b5ad2e..f5c7223a37c 100644 --- a/source/blender/blenloader/CMakeLists.txt +++ b/source/blender/blenloader/CMakeLists.txt @@ -101,8 +101,8 @@ add_dependencies(bf_blenloader bf_dna) if(WITH_GTESTS) set(TEST_SRC - tests/blendfile_loading_base_test.cc tests/blendfile_load_test.cc + tests/blendfile_loading_base_test.cc ) set(TEST_INC ) diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c index 12b5a297df5..bc13e3b3a39 100644 --- a/source/blender/blenloader/intern/versioning_290.c +++ b/source/blender/blenloader/intern/versioning_290.c @@ -190,17 +190,19 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) /* Patch first frame for old files. */ Scene *scene = bmain->scenes.first; - LISTBASE_FOREACH (Object *, ob, &bmain->objects) { - if (ob->type != OB_GPENCIL) { - continue; - } - bGPdata *gpd = ob->data; - LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { - bGPDframe *gpf = gpl->frames.first; - if (gpf && gpf->framenum > scene->r.sfra) { - bGPDframe *gpf_dup = BKE_gpencil_frame_duplicate(gpf); - gpf_dup->framenum = scene->r.sfra; - BLI_addhead(&gpl->frames, gpf_dup); + if (scene != NULL) { + LISTBASE_FOREACH (Object *, ob, &bmain->objects) { + if (ob->type != OB_GPENCIL) { + continue; + } + bGPdata *gpd = ob->data; + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { + bGPDframe *gpf = gpl->frames.first; + if (gpf && gpf->framenum > scene->r.sfra) { + bGPDframe *gpf_dup = BKE_gpencil_frame_duplicate(gpf); + gpf_dup->framenum = scene->r.sfra; + BLI_addhead(&gpl->frames, gpf_dup); + } } } } diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c index e2dc27d7e88..0b116804481 100644 --- a/source/blender/blenloader/intern/versioning_userdef.c +++ b/source/blender/blenloader/intern/versioning_userdef.c @@ -38,6 +38,7 @@ #include "DNA_windowmanager_types.h" #include "BKE_addon.h" +#include "BKE_blender_version.h" #include "BKE_colorband.h" #include "BKE_idprop.h" #include "BKE_keyconfig.h" @@ -784,4 +785,23 @@ void BLO_version_defaults_userpref_blend(Main *bmain, UserDef *userdef) #undef USER_VERSION_ATLEAST } +void BLO_sanitize_experimental_features_userpref_blend(UserDef *userdef) +{ + /* User preference experimental settings are only supported in alpha builds. + * This prevents users corrupting data and relying on API that may change. + * + * If user preferences are saved this will be stored in disk as expected. + * This only starts to take effect when there is a release branch (on beta). + * + * At that time master already has its version bumped so its user preferences + * are not touched by these settings. */ + + if (BKE_blender_version_is_alpha()) { + return; + } + userdef->experimental.use_new_particle_system = false; + userdef->experimental.use_new_hair_type = false; + userdef->experimental.use_sculpt_vertex_colors = false; +} + #undef USER_LMOUSESELECT diff --git a/source/blender/blenloader/tests/blendfile_loading_base_test.cc b/source/blender/blenloader/tests/blendfile_loading_base_test.cc index d74bab4b31c..c743e6bcd3f 100644 --- a/source/blender/blenloader/tests/blendfile_loading_base_test.cc +++ b/source/blender/blenloader/tests/blendfile_loading_base_test.cc @@ -148,7 +148,7 @@ void BlendfileLoadingBaseTest::depsgraph_create(eEvaluationMode depsgraph_evalua { depsgraph = DEG_graph_new( bfile->main, bfile->curscene, bfile->cur_view_layer, depsgraph_evaluation_mode); - DEG_graph_build_from_view_layer(depsgraph, bfile->main, bfile->curscene, bfile->cur_view_layer); + DEG_graph_build_from_view_layer(depsgraph); BKE_scene_graph_update_tagged(depsgraph, bfile->main); } diff --git a/source/blender/blenloader/tests/blendfile_loading_base_test.h b/source/blender/blenloader/tests/blendfile_loading_base_test.h index a5e75ef6df8..f90e07218fb 100644 --- a/source/blender/blenloader/tests/blendfile_loading_base_test.h +++ b/source/blender/blenloader/tests/blendfile_loading_base_test.h @@ -56,9 +56,9 @@ class BlendfileLoadingBaseTest : public testing::Test { void blendfile_free(); /* Create a depsgraph. Assumes a blend file has been loaded to this->bfile. */ - void depsgraph_create(eEvaluationMode depsgraph_evaluation_mode); + virtual void depsgraph_create(eEvaluationMode depsgraph_evaluation_mode); /* Free the depsgraph if it's not nullptr. */ - void depsgraph_free(); + virtual void depsgraph_free(); }; #endif /* __BLENDFILE_LOADING_BASE_TEST_H__ */ diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index 0eeb0d21b5b..7368e3d044d 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -154,10 +154,10 @@ set(SRC tools/bmesh_path.h tools/bmesh_path_region.c tools/bmesh_path_region.h - tools/bmesh_path_uv.c - tools/bmesh_path_uv.h tools/bmesh_path_region_uv.c tools/bmesh_path_region_uv.h + tools/bmesh_path_uv.c + tools/bmesh_path_uv.h tools/bmesh_region_match.c tools/bmesh_region_match.h tools/bmesh_separate.c diff --git a/source/blender/compositor/COM_compositor.h b/source/blender/compositor/COM_compositor.h index b200fa8d266..79c1ebcfe9f 100644 --- a/source/blender/compositor/COM_compositor.h +++ b/source/blender/compositor/COM_compositor.h @@ -362,4 +362,3 @@ void COM_deinitialize(void); #ifdef __cplusplus } #endif - diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt index 417aaa2c4c0..e0916491edb 100644 --- a/source/blender/depsgraph/CMakeLists.txt +++ b/source/blender/depsgraph/CMakeLists.txt @@ -55,6 +55,7 @@ set(SRC intern/builder/deg_builder_rna.cc intern/builder/deg_builder_transitive.cc intern/builder/pipeline.cc + intern/builder/pipeline_all_objects.cc intern/builder/pipeline_compositor.cc intern/builder/pipeline_from_ids.cc intern/builder/pipeline_render.cc @@ -106,16 +107,17 @@ set(SRC intern/builder/deg_builder.h intern/builder/deg_builder_cache.h intern/builder/deg_builder_cycle.h - intern/builder/deg_builder_relations_drivers.h intern/builder/deg_builder_map.h intern/builder/deg_builder_nodes.h intern/builder/deg_builder_pchanmap.h intern/builder/deg_builder_relations.h + intern/builder/deg_builder_relations_drivers.h intern/builder/deg_builder_relations_impl.h 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_all_objects.h intern/builder/pipeline_compositor.h intern/builder/pipeline_from_ids.h intern/builder/pipeline_render.h diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h index b3636743101..8f33e9f480d 100644 --- a/source/blender/depsgraph/DEG_depsgraph.h +++ b/source/blender/depsgraph/DEG_depsgraph.h @@ -149,16 +149,11 @@ void DEG_ids_check_recalc(struct Main *bmain, /* Graph Evaluation ----------------------------- */ -/* Frame changed recalculation entry point - * < context_type: context to perform evaluation for - * < ctime: (frame) new frame to evaluate values on - */ -void DEG_evaluate_on_framechange(struct Main *bmain, Depsgraph *graph, float ctime); +/* Frame changed recalculation entry point. */ +void DEG_evaluate_on_framechange(Depsgraph *graph, float ctime); -/* Data changed recalculation entry point. - * < context_type: context to perform evaluation for - */ -void DEG_evaluate_on_refresh(struct Main *bmain, Depsgraph *graph); +/* Data changed recalculation entry point. */ +void DEG_evaluate_on_refresh(Depsgraph *graph); bool DEG_needs_eval(Depsgraph *graph); diff --git a/source/blender/depsgraph/DEG_depsgraph_build.h b/source/blender/depsgraph/DEG_depsgraph_build.h index 50f22b00028..2147a584765 100644 --- a/source/blender/depsgraph/DEG_depsgraph_build.h +++ b/source/blender/depsgraph/DEG_depsgraph_build.h @@ -51,44 +51,29 @@ extern "C" { /* Graph Building -------------------------------- */ /* Build depsgraph for the given scene, and dump results in given graph container. */ -void DEG_graph_build_from_view_layer(struct Depsgraph *graph, - struct Main *bmain, - struct Scene *scene, - struct ViewLayer *view_layer); +void DEG_graph_build_from_view_layer(struct Depsgraph *graph); + +/* Build depsgraph for all objects (so also invisible ones) in the given view layer. */ +void DEG_graph_build_for_all_objects(struct Depsgraph *graph); /* Special version of builder which produces dependency graph suitable for the render pipeline. * It will contain sequencer and compositor (if needed) and all their dependencies. */ -void DEG_graph_build_for_render_pipeline(struct Depsgraph *graph, - struct Main *bmain, - struct Scene *scene, - struct ViewLayer *view_layer); +void DEG_graph_build_for_render_pipeline(struct Depsgraph *graph); /* Builds minimal dependency graph for compositor preview. * * Note that compositor editor might have pinned node tree, which is different from scene's node * tree. */ -void DEG_graph_build_for_compositor_preview(struct Depsgraph *graph, - struct Main *bmain, - struct Scene *scene, - struct ViewLayer *view_layer, - struct bNodeTree *nodetree); - -void DEG_graph_build_from_ids(struct Depsgraph *graph, - struct Main *bmain, - struct Scene *scene, - struct ViewLayer *view_layer, - struct ID **ids, - const int num_ids); +void DEG_graph_build_for_compositor_preview(struct Depsgraph *graph, struct bNodeTree *nodetree); + +void DEG_graph_build_from_ids(struct Depsgraph *graph, struct ID **ids, const int num_ids); /* Tag relations from the given graph for update. */ void DEG_graph_tag_relations_update(struct Depsgraph *graph); /* Create or update relations in the specified graph. */ -void DEG_graph_relations_update(struct Depsgraph *graph, - struct Main *bmain, - struct Scene *scene, - struct ViewLayer *view_layer); +void DEG_graph_relations_update(struct Depsgraph *graph); /* Tag all relations in the database for update.*/ void DEG_relations_tag_update(struct Main *bmain); diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h index e0166a13d69..7eb5f1ccec1 100644 --- a/source/blender/depsgraph/DEG_depsgraph_query.h +++ b/source/blender/depsgraph/DEG_depsgraph_query.h @@ -55,6 +55,9 @@ struct Scene *DEG_get_input_scene(const Depsgraph *graph); /* Get view layer that depsgraph was built for. */ struct ViewLayer *DEG_get_input_view_layer(const Depsgraph *graph); +/* Get bmain that depsgraph was built for. */ +struct Main *DEG_get_bmain(const Depsgraph *graph); + /* Get evaluation mode that depsgraph was built for. */ eEvaluationMode DEG_get_mode(const Depsgraph *graph); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 37b23833e00..c0b692f28c1 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -978,13 +978,13 @@ void DepsgraphRelationBuilder::build_object_parent(Object *object) break; } } - /* Metaballs are the odd balls here (no pun intended): they will request + /* Meta-balls are the odd balls here (no pun intended): they will request * instance-list (formerly known as dupli-list) during evaluation. This is * their way of interacting with all instanced surfaces, making a nice * effect when is used form particle system. */ if (object->type == OB_MBALL && parent->transflag & OB_DUPLI) { ComponentKey parent_geometry_key(parent_id, NodeType::GEOMETRY); - /* NOTE: Metaballs are evaluating geometry only after their transform, + /* NOTE: Meta-balls are evaluating geometry only after their transform, * so we only hook up to transform channel here. */ add_relation(parent_geometry_key, object_transform_key, "Parent"); } diff --git a/source/blender/depsgraph/intern/builder/pipeline.cc b/source/blender/depsgraph/intern/builder/pipeline.cc index d6893ba11d8..b13077e4792 100644 --- a/source/blender/depsgraph/intern/builder/pipeline.cc +++ b/source/blender/depsgraph/intern/builder/pipeline.cc @@ -33,14 +33,11 @@ namespace blender { namespace deg { -AbstractBuilderPipeline::AbstractBuilderPipeline(::Depsgraph *graph, - Main *bmain, - Scene *scene, - ViewLayer *view_layer) +AbstractBuilderPipeline::AbstractBuilderPipeline(::Depsgraph *graph) : deg_graph_(reinterpret_cast<Depsgraph *>(graph)), - bmain_(bmain), - scene_(scene), - view_layer_(view_layer), + bmain_(deg_graph_->bmain), + scene_(deg_graph_->scene), + view_layer_(deg_graph_->view_layer), builder_cache_() { } diff --git a/source/blender/depsgraph/intern/builder/pipeline.h b/source/blender/depsgraph/intern/builder/pipeline.h index 2c9c78bb2cb..d98d834932c 100644 --- a/source/blender/depsgraph/intern/builder/pipeline.h +++ b/source/blender/depsgraph/intern/builder/pipeline.h @@ -49,7 +49,7 @@ class DepsgraphRelationBuilder; */ class AbstractBuilderPipeline { public: - AbstractBuilderPipeline(::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer); + AbstractBuilderPipeline(::Depsgraph *graph); virtual ~AbstractBuilderPipeline(); void build(); diff --git a/source/blender/depsgraph/intern/builder/pipeline_all_objects.cc b/source/blender/depsgraph/intern/builder/pipeline_all_objects.cc new file mode 100644 index 00000000000..81d239239be --- /dev/null +++ b/source/blender/depsgraph/intern/builder/pipeline_all_objects.cc @@ -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. + */ + +#include "pipeline_all_objects.h" + +#include "intern/builder/deg_builder_nodes.h" +#include "intern/builder/deg_builder_relations.h" +#include "intern/depsgraph.h" + +#include "DNA_layer_types.h" + +namespace blender { +namespace deg { + +namespace { + +class AllObjectsNodeBuilder : public DepsgraphNodeBuilder { + public: + AllObjectsNodeBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache) + : DepsgraphNodeBuilder(bmain, graph, cache) + { + } + + virtual bool need_pull_base_into_graph(Base * /*base*/) override + { + return true; + } +}; + +class AllObjectsRelationBuilder : public DepsgraphRelationBuilder { + public: + AllObjectsRelationBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache) + : DepsgraphRelationBuilder(bmain, graph, cache) + { + } + + virtual bool need_pull_base_into_graph(Base * /*base*/) override + { + return true; + } +}; + +} // namespace + +AllObjectsBuilderPipeline::AllObjectsBuilderPipeline(::Depsgraph *graph) + : ViewLayerBuilderPipeline(graph) +{ +} + +unique_ptr<DepsgraphNodeBuilder> AllObjectsBuilderPipeline::construct_node_builder() +{ + return std::make_unique<AllObjectsNodeBuilder>(bmain_, deg_graph_, &builder_cache_); +} + +unique_ptr<DepsgraphRelationBuilder> AllObjectsBuilderPipeline::construct_relation_builder() +{ + return std::make_unique<AllObjectsRelationBuilder>(bmain_, deg_graph_, &builder_cache_); +} + +} // namespace deg +} // namespace blender diff --git a/source/blender/depsgraph/intern/builder/pipeline_all_objects.h b/source/blender/depsgraph/intern/builder/pipeline_all_objects.h new file mode 100644 index 00000000000..11ca2314331 --- /dev/null +++ b/source/blender/depsgraph/intern/builder/pipeline_all_objects.h @@ -0,0 +1,44 @@ +/* + * 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_view_layer.h" + +namespace blender { +namespace deg { + +/* Builds a dependency graph that contains all objects in the view layer. + * This is contrary to the regular ViewLayerBuilderPipeline, which is limited to visible objects + * (and their dependencies). */ +class AllObjectsBuilderPipeline : public ViewLayerBuilderPipeline { + public: + AllObjectsBuilderPipeline(::Depsgraph *graph); + + protected: + virtual unique_ptr<DepsgraphNodeBuilder> construct_node_builder() override; + virtual unique_ptr<DepsgraphRelationBuilder> construct_relation_builder() override; +}; + +} // namespace deg +} // namespace blender diff --git a/source/blender/depsgraph/intern/builder/pipeline_compositor.cc b/source/blender/depsgraph/intern/builder/pipeline_compositor.cc index 3e56f17fc7e..2b9922851c1 100644 --- a/source/blender/depsgraph/intern/builder/pipeline_compositor.cc +++ b/source/blender/depsgraph/intern/builder/pipeline_compositor.cc @@ -26,9 +26,8 @@ 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) +CompositorBuilderPipeline::CompositorBuilderPipeline(::Depsgraph *graph, bNodeTree *nodetree) + : AbstractBuilderPipeline(graph), nodetree_(nodetree) { deg_graph_->is_render_pipeline_depsgraph = true; } diff --git a/source/blender/depsgraph/intern/builder/pipeline_compositor.h b/source/blender/depsgraph/intern/builder/pipeline_compositor.h index 892ece7c2a4..46f1e3694d3 100644 --- a/source/blender/depsgraph/intern/builder/pipeline_compositor.h +++ b/source/blender/depsgraph/intern/builder/pipeline_compositor.h @@ -32,8 +32,7 @@ namespace deg { class CompositorBuilderPipeline : public AbstractBuilderPipeline { public: - CompositorBuilderPipeline( - ::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer, bNodeTree *nodetree); + CompositorBuilderPipeline(::Depsgraph *graph, bNodeTree *nodetree); protected: virtual void build_nodes(DepsgraphNodeBuilder &node_builder) override; diff --git a/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc b/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc index e44f554f197..87cfeb46693 100644 --- a/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc +++ b/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc @@ -32,11 +32,9 @@ namespace { class DepsgraphFromIDsFilter { public: - DepsgraphFromIDsFilter(ID **ids, const int num_ids) + DepsgraphFromIDsFilter(Span<ID *> ids) { - for (int i = 0; i < num_ids; ++i) { - ids_.add(ids[i]); - } + ids_.add_multiple(ids); } bool contains(ID *id) @@ -50,9 +48,11 @@ class DepsgraphFromIDsFilter { 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) + DepsgraphFromIDsNodeBuilder(Main *bmain, + Depsgraph *graph, + DepsgraphBuilderCache *cache, + Span<ID *> ids) + : DepsgraphNodeBuilder(bmain, graph, cache), filter_(ids) { } @@ -81,9 +81,11 @@ class DepsgraphFromIDsNodeBuilder : public DepsgraphNodeBuilder { 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) + DepsgraphFromIDsRelationBuilder(Main *bmain, + Depsgraph *graph, + DepsgraphBuilderCache *cache, + Span<ID *> ids) + : DepsgraphRelationBuilder(bmain, graph, cache), filter_(ids) { } @@ -112,41 +114,35 @@ class DepsgraphFromIDsRelationBuilder : public DepsgraphRelationBuilder { } // 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) +FromIDsBuilderPipeline::FromIDsBuilderPipeline(::Depsgraph *graph, Span<ID *> ids) + : AbstractBuilderPipeline(graph), ids_(ids) { } unique_ptr<DepsgraphNodeBuilder> FromIDsBuilderPipeline::construct_node_builder() { - return std::make_unique<DepsgraphFromIDsNodeBuilder>( - bmain_, deg_graph_, &builder_cache_, ids_, num_ids_); + return std::make_unique<DepsgraphFromIDsNodeBuilder>(bmain_, deg_graph_, &builder_cache_, ids_); } unique_ptr<DepsgraphRelationBuilder> FromIDsBuilderPipeline::construct_relation_builder() { return std::make_unique<DepsgraphFromIDsRelationBuilder>( - bmain_, deg_graph_, &builder_cache_, ids_, num_ids_); + bmain_, deg_graph_, &builder_cache_, 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]); + for (ID *id : ids_) { + node_builder.build_id(id); } } 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]); + for (ID *id : ids_) { + relation_builder.build_id(id); } } diff --git a/source/blender/depsgraph/intern/builder/pipeline_from_ids.h b/source/blender/depsgraph/intern/builder/pipeline_from_ids.h index 4a507f2c728..79fcfc52446 100644 --- a/source/blender/depsgraph/intern/builder/pipeline_from_ids.h +++ b/source/blender/depsgraph/intern/builder/pipeline_from_ids.h @@ -43,8 +43,7 @@ namespace deg { class FromIDsBuilderPipeline : public AbstractBuilderPipeline { public: - FromIDsBuilderPipeline( - ::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer, ID **ids, int num_ids); + FromIDsBuilderPipeline(::Depsgraph *graph, Span<ID *> ids); protected: virtual unique_ptr<DepsgraphNodeBuilder> construct_node_builder() override; @@ -54,8 +53,7 @@ class FromIDsBuilderPipeline : public AbstractBuilderPipeline { virtual void build_relations(DepsgraphRelationBuilder &relation_builder) override; private: - ID **ids_; - const int num_ids_; + Span<ID *> ids_; }; } // namespace deg diff --git a/source/blender/depsgraph/intern/builder/pipeline_render.cc b/source/blender/depsgraph/intern/builder/pipeline_render.cc index 50a37d0d3e4..3b065f7f1bc 100644 --- a/source/blender/depsgraph/intern/builder/pipeline_render.cc +++ b/source/blender/depsgraph/intern/builder/pipeline_render.cc @@ -26,11 +26,7 @@ namespace blender { namespace deg { -RenderBuilderPipeline::RenderBuilderPipeline(::Depsgraph *graph, - Main *bmain, - Scene *scene, - ViewLayer *view_layer) - : AbstractBuilderPipeline(graph, bmain, scene, view_layer) +RenderBuilderPipeline::RenderBuilderPipeline(::Depsgraph *graph) : AbstractBuilderPipeline(graph) { deg_graph_->is_render_pipeline_depsgraph = true; } diff --git a/source/blender/depsgraph/intern/builder/pipeline_render.h b/source/blender/depsgraph/intern/builder/pipeline_render.h index df7f9e0de68..91a4be137b6 100644 --- a/source/blender/depsgraph/intern/builder/pipeline_render.h +++ b/source/blender/depsgraph/intern/builder/pipeline_render.h @@ -30,7 +30,7 @@ namespace deg { class RenderBuilderPipeline : public AbstractBuilderPipeline { public: - RenderBuilderPipeline(::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer); + RenderBuilderPipeline(::Depsgraph *graph); protected: virtual void build_nodes(DepsgraphNodeBuilder &node_builder) override; diff --git a/source/blender/depsgraph/intern/builder/pipeline_view_layer.cc b/source/blender/depsgraph/intern/builder/pipeline_view_layer.cc index 3223f17f349..f1852a40a10 100644 --- a/source/blender/depsgraph/intern/builder/pipeline_view_layer.cc +++ b/source/blender/depsgraph/intern/builder/pipeline_view_layer.cc @@ -26,11 +26,8 @@ namespace blender { namespace deg { -ViewLayerBuilderPipeline::ViewLayerBuilderPipeline(::Depsgraph *graph, - Main *bmain, - Scene *scene, - ViewLayer *view_layer) - : AbstractBuilderPipeline(graph, bmain, scene, view_layer) +ViewLayerBuilderPipeline::ViewLayerBuilderPipeline(::Depsgraph *graph) + : AbstractBuilderPipeline(graph) { } diff --git a/source/blender/depsgraph/intern/builder/pipeline_view_layer.h b/source/blender/depsgraph/intern/builder/pipeline_view_layer.h index fbd7b98acad..aa85dd7a47b 100644 --- a/source/blender/depsgraph/intern/builder/pipeline_view_layer.h +++ b/source/blender/depsgraph/intern/builder/pipeline_view_layer.h @@ -30,7 +30,7 @@ namespace deg { class ViewLayerBuilderPipeline : public AbstractBuilderPipeline { public: - ViewLayerBuilderPipeline(::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer); + ViewLayerBuilderPipeline(::Depsgraph *graph); protected: virtual void build_nodes(DepsgraphNodeBuilder &node_builder) override; diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index fb933cb38f3..96c17ae4dc5 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -44,6 +44,7 @@ #include "DEG_depsgraph_debug.h" #include "builder/deg_builder_relations.h" +#include "builder/pipeline_all_objects.h" #include "builder/pipeline_compositor.h" #include "builder/pipeline_from_ids.h" #include "builder/pipeline_render.h" @@ -209,39 +210,33 @@ struct Depsgraph *DEG_get_graph_from_handle(struct DepsNodeHandle *node_handle) /* Graph Building API's */ /* 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) +void DEG_graph_build_from_view_layer(Depsgraph *graph) { - deg::ViewLayerBuilderPipeline builder(graph, bmain, scene, view_layer); + deg::ViewLayerBuilderPipeline builder(graph); builder.build(); } -void DEG_graph_build_for_render_pipeline(Depsgraph *graph, - Main *bmain, - Scene *scene, - ViewLayer *view_layer) +void DEG_graph_build_for_all_objects(struct Depsgraph *graph) { - deg::RenderBuilderPipeline builder(graph, bmain, scene, view_layer); + deg::AllObjectsBuilderPipeline builder(graph); builder.build(); } -void DEG_graph_build_for_compositor_preview( - Depsgraph *graph, Main *bmain, Scene *scene, struct ViewLayer *view_layer, bNodeTree *nodetree) +void DEG_graph_build_for_render_pipeline(Depsgraph *graph) { - deg::CompositorBuilderPipeline builder(graph, bmain, scene, view_layer, nodetree); + deg::RenderBuilderPipeline builder(graph); builder.build(); } -void DEG_graph_build_from_ids(Depsgraph *graph, - Main *bmain, - Scene *scene, - ViewLayer *view_layer, - ID **ids, - const int num_ids) +void DEG_graph_build_for_compositor_preview(Depsgraph *graph, bNodeTree *nodetree) { - deg::FromIDsBuilderPipeline builder(graph, bmain, scene, view_layer, ids, num_ids); + deg::CompositorBuilderPipeline builder(graph, nodetree); + builder.build(); +} + +void DEG_graph_build_from_ids(Depsgraph *graph, ID **ids, const int num_ids) +{ + deg::FromIDsBuilderPipeline builder(graph, blender::Span(ids, num_ids)); builder.build(); } @@ -264,14 +259,14 @@ void DEG_graph_tag_relations_update(Depsgraph *graph) } /* Create or update relations in the specified graph. */ -void DEG_graph_relations_update(Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer) +void DEG_graph_relations_update(Depsgraph *graph) { deg::Depsgraph *deg_graph = (deg::Depsgraph *)graph; if (!deg_graph->need_update) { /* Graph is up to date, nothing to do. */ return; } - DEG_graph_build_from_view_layer(graph, bmain, scene, view_layer); + DEG_graph_build_from_view_layer(graph); } /* Tag all relations for update. */ diff --git a/source/blender/depsgraph/intern/depsgraph_debug.cc b/source/blender/depsgraph/intern/depsgraph_debug.cc index 0763738ff59..c5e306f3148 100644 --- a/source/blender/depsgraph/intern/depsgraph_debug.cc +++ b/source/blender/depsgraph/intern/depsgraph_debug.cc @@ -93,7 +93,7 @@ bool DEG_debug_graph_relations_validate(Depsgraph *graph, { Depsgraph *temp_depsgraph = DEG_graph_new(bmain, scene, view_layer, DEG_get_mode(graph)); bool valid = true; - DEG_graph_build_from_view_layer(temp_depsgraph, bmain, scene, view_layer); + DEG_graph_build_from_view_layer(temp_depsgraph); if (!DEG_debug_compare(temp_depsgraph, graph)) { fprintf(stderr, "ERROR! Depsgraph wasn't tagged for update when it should have!\n"); BLI_assert(!"This should not happen!"); diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc index 8a641f23a42..0c116f5863c 100644 --- a/source/blender/depsgraph/intern/depsgraph_eval.cc +++ b/source/blender/depsgraph/intern/depsgraph_eval.cc @@ -48,32 +48,26 @@ namespace deg = blender::deg; /* Evaluate all nodes tagged for updating. */ -void DEG_evaluate_on_refresh(Main *bmain, Depsgraph *graph) +void DEG_evaluate_on_refresh(Depsgraph *graph) { deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph); deg_graph->ctime = BKE_scene_frame_get(deg_graph->scene); - /* Update time on primary timesource. */ - deg::TimeSourceNode *tsrc = deg_graph->find_time_source(); - tsrc->cfra = deg_graph->ctime; /* Update time in scene. */ if (deg_graph->scene_cow) { BKE_scene_frame_set(deg_graph->scene_cow, deg_graph->ctime); } - deg::deg_graph_flush_updates(bmain, deg_graph); + deg::deg_graph_flush_updates(deg_graph); deg::deg_evaluate_on_refresh(deg_graph); deg_graph->need_update_time = false; } /* Frame-change happened for root scene that graph belongs to. */ -void DEG_evaluate_on_framechange(Main *bmain, Depsgraph *graph, float ctime) +void DEG_evaluate_on_framechange(Depsgraph *graph, float ctime) { deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph); deg_graph->ctime = ctime; - /* Update time on primary timesource. */ - deg::TimeSourceNode *tsrc = deg_graph->find_time_source(); - tsrc->cfra = ctime; deg_graph->need_update_time = true; - deg::deg_graph_flush_updates(bmain, deg_graph); + deg::deg_graph_flush_updates(deg_graph); /* Update time in scene. */ if (deg_graph->scene_cow) { BKE_scene_frame_set(deg_graph->scene_cow, deg_graph->ctime); diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc index 0b6014c18f1..fc9ed9a6ab9 100644 --- a/source/blender/depsgraph/intern/depsgraph_query.cc +++ b/source/blender/depsgraph/intern/depsgraph_query.cc @@ -61,6 +61,12 @@ struct ViewLayer *DEG_get_input_view_layer(const Depsgraph *graph) return deg_graph->view_layer; } +struct Main *DEG_get_bmain(const Depsgraph *graph) +{ + const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph); + return deg_graph->bmain; +} + eEvaluationMode DEG_get_mode(const Depsgraph *graph) { const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph); diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc index 048c0125f53..7d47e1fb541 100644 --- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc +++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc @@ -106,8 +106,8 @@ bool deg_object_hide_original(eEvaluationMode eval_mode, Object *ob, DupliObject * visible otherwise. The better solution eventually would be for objects * to specify which object they instance, instead of through parenting. * - * This function should not be used for metaballs. They have custom visibility rules, as hiding - * the base metaball will also hide all the other balls in the group. */ + * This function should not be used for meta-balls. They have custom visibility rules, as hiding + * the base meta-ball will also hide all the other balls in the group. */ if (eval_mode == DAG_EVAL_RENDER || dob) { const int hide_original_types = OB_DUPLIVERTS | OB_DUPLIFACES; diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index 1ede2cf914a..2e0487bfca1 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -86,8 +86,8 @@ enum class EvaluationStage { /* Workaround for areas which can not be evaluated in threads. * - * For example, metaballs, which are iterating over all bases and are requesting dupli-lists - * to see whether there are metaballs inside. */ + * For example, meta-balls, which are iterating over all bases and are requesting dupli-lists + * to see whether there are meta-balls inside. */ SINGLE_THREADED_WORKAROUND, }; diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index a74ec485d88..dea23c9f96d 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -351,11 +351,12 @@ void invalidate_tagged_evaluated_data(Depsgraph *graph) /* Flush updates from tagged nodes outwards until all affected nodes * are tagged. */ -void deg_graph_flush_updates(Main *bmain, Depsgraph *graph) +void deg_graph_flush_updates(Depsgraph *graph) { /* Sanity checks. */ - BLI_assert(bmain != nullptr); BLI_assert(graph != nullptr); + Main *bmain = graph->bmain; + /* Nothing to update, early out. */ if (graph->need_update_time) { const Scene *scene_orig = graph->scene; diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.h b/source/blender/depsgraph/intern/eval/deg_eval_flush.h index c76dc9fe01d..1f58c54dbf4 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.h +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.h @@ -35,7 +35,7 @@ struct Depsgraph; /* Flush updates from tagged nodes outwards until all affected nodes * are tagged. */ -void deg_graph_flush_updates(struct Main *bmain, struct Depsgraph *graph); +void deg_graph_flush_updates(struct Depsgraph *graph); /* Clear tags from all operation nodes. */ void deg_graph_clear_tags(struct Depsgraph *graph); diff --git a/source/blender/depsgraph/intern/node/deg_node_time.h b/source/blender/depsgraph/intern/node/deg_node_time.h index 364c214b014..fe17684abb0 100644 --- a/source/blender/depsgraph/intern/node/deg_node_time.h +++ b/source/blender/depsgraph/intern/node/deg_node_time.h @@ -30,12 +30,6 @@ namespace deg { /* Time Source Node. */ struct TimeSourceNode : public Node { - /* New "current time". */ - float cfra; - - /* time-offset relative to the "official" time source that this one has. */ - float offset; - // TODO: evaluate() operation needed virtual void tag_update(Depsgraph *graph, eUpdateSource source) override; diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c index 6d2577d5b78..a785d27c2db 100644 --- a/source/blender/draw/engines/eevee/eevee_lightcache.c +++ b/source/blender/draw/engines/eevee/eevee_lightcache.c @@ -1302,8 +1302,8 @@ void EEVEE_lightbake_job(void *custom_data, short *stop, short *do_update, float EEVEE_LightBake *lbake = (EEVEE_LightBake *)custom_data; Depsgraph *depsgraph = lbake->depsgraph; - DEG_graph_relations_update(depsgraph, lbake->bmain, lbake->scene, lbake->view_layer_input); - DEG_evaluate_on_framechange(lbake->bmain, depsgraph, lbake->frame); + DEG_graph_relations_update(depsgraph); + DEG_evaluate_on_framechange(depsgraph, lbake->frame); lbake->view_layer = DEG_get_evaluated_view_layer(depsgraph); lbake->stop = stop; diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c index 9aae801197f..052fb485b19 100644 --- a/source/blender/draw/engines/eevee/eevee_occlusion.c +++ b/source/blender/draw/engines/eevee/eevee_occlusion.c @@ -78,7 +78,8 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) e_data.dummy_horizon_tx = DRW_texture_create_2d(1, 1, GPU_RGBA8, DRW_TEX_WRAP, pixel); } - if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) { + if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED || + stl->g_data->render_passes & EEVEE_RENDER_PASS_AO) { const float *viewport_size = DRW_viewport_size_get(); const int fs_size[2] = {(int)viewport_size[0], (int)viewport_size[1]}; @@ -101,10 +102,11 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) common_data->ao_bounce_fac = (scene_eval->eevee.flag & SCE_EEVEE_GTAO_BOUNCE) ? 1.0f : 0.0f; - effects->gtao_horizons = DRW_texture_pool_query_2d( + effects->gtao_horizons_renderpass = DRW_texture_pool_query_2d( fs_size[0], fs_size[1], GPU_RGBA8, &draw_engine_eevee_type); GPU_framebuffer_ensure_config( - &fbl->gtao_fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(effects->gtao_horizons)}); + &fbl->gtao_fb, + {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(effects->gtao_horizons_renderpass)}); if (G.debug_value == 6) { effects->gtao_horizons_debug = DRW_texture_pool_query_2d( @@ -117,10 +119,15 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) effects->gtao_horizons_debug = NULL; } + effects->gtao_horizons = (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) ? + effects->gtao_horizons_renderpass : + e_data.dummy_horizon_tx; + return EFFECT_GTAO | EFFECT_NORMAL_BUFFER; } /* Cleanup */ + effects->gtao_horizons_renderpass = e_data.dummy_horizon_tx; effects->gtao_horizons = e_data.dummy_horizon_tx; GPU_FRAMEBUFFER_FREE_SAFE(fbl->gtao_fb); common_data->ao_settings = 0.0f; @@ -136,45 +143,41 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata EEVEE_PassList *psl = vedata->psl; EEVEE_EffectsInfo *effects = stl->effects; - const DRWContextState *draw_ctx = DRW_context_state_get(); - const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); - - if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) { - const eGPUTextureFormat texture_format = (tot_samples > 128) ? GPU_R32F : GPU_R16F; + const eGPUTextureFormat texture_format = (tot_samples > 128) ? GPU_R32F : GPU_R16F; - DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - 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); + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - GPU_framebuffer_ensure_config(&fbl->ao_accum_fb, - {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->ao_accum)}); + /* Should be enough precision for many samples. */ + DRW_texture_ensure_fullscreen_2d(&txl->ao_accum, texture_format, 0); - /* Clear texture. */ - if (effects->taa_current_sample == 1) { - GPU_framebuffer_bind(fbl->ao_accum_fb); - GPU_framebuffer_clear_color(fbl->ao_accum_fb, clear); - } + GPU_framebuffer_ensure_config(&fbl->ao_accum_fb, + {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->ao_accum)}); - /* Accumulation pass */ - DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD; - DRW_PASS_CREATE(psl->ao_accum_ps, state); - DRWShadingGroup *grp = DRW_shgroup_create(e_data.gtao_debug_sh, psl->ao_accum_ps); - DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex()); - DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer); - DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth); - DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input); - DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons); - 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); + /* Clear texture. */ + if (effects->taa_current_sample == 1) { + GPU_framebuffer_bind(fbl->ao_accum_fb); + GPU_framebuffer_clear_color(fbl->ao_accum_fb, clear); } - else { - /* Cleanup to release memory */ - DRW_TEXTURE_FREE_SAFE(txl->ao_accum); - GPU_FRAMEBUFFER_FREE_SAFE(fbl->ao_accum_fb); + + /* Clear texture. */ + if (DRW_state_is_image_render() || effects->taa_current_sample == 1) { + GPU_framebuffer_bind(fbl->ao_accum_fb); + GPU_framebuffer_clear_color(fbl->ao_accum_fb, clear); } + + /* Accumulation pass */ + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD; + DRW_PASS_CREATE(psl->ao_accum_ps, state); + DRWShadingGroup *grp = DRW_shgroup_create(e_data.gtao_debug_sh, psl->ao_accum_ps); + DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex()); + DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer); + DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth); + DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input); + DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons_renderpass); + 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); } void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) @@ -225,7 +228,7 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer); DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth); DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input); - DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons); + DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons_renderpass); 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, quad, NULL); diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 1e2de521cdf..40d7676c38c 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -679,8 +679,9 @@ typedef struct EEVEE_EffectsInfo { struct DRWView *taa_view; /* Ambient Occlusion */ int ao_depth_layer; - struct GPUTexture *ao_src_depth; /* pointer copy */ - struct GPUTexture *gtao_horizons; /* Textures from pool */ + struct GPUTexture *ao_src_depth; /* pointer copy */ + struct GPUTexture *gtao_horizons; /* Textures from pool */ + struct GPUTexture *gtao_horizons_renderpass; /* Texture when rendering render pass */ struct GPUTexture *gtao_horizons_debug; /* Motion Blur */ float current_ndc_to_world[4][4]; diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c index 21a4013e309..65a856c39e1 100644 --- a/source/blender/draw/engines/eevee/eevee_render.c +++ b/source/blender/draw/engines/eevee/eevee_render.c @@ -359,11 +359,6 @@ static void eevee_render_result_occlusion(RenderLayer *rl, EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata) { - if ((vedata->stl->effects->enabled_effects & EFFECT_GTAO) == 0) { - /* AO is not enabled. */ - return; - } - if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_AO) != 0) { EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_AO); eevee_render_color_result( diff --git a/source/blender/draw/engines/eevee/eevee_renderpasses.c b/source/blender/draw/engines/eevee/eevee_renderpasses.c index 089d8b7a287..55fe5882211 100644 --- a/source/blender/draw/engines/eevee/eevee_renderpasses.c +++ b/source/blender/draw/engines/eevee/eevee_renderpasses.c @@ -90,12 +90,8 @@ void EEVEE_renderpasses_init(EEVEE_Data *vedata) if (v3d) { const Scene *scene = draw_ctx->scene; eViewLayerEEVEEPassType render_pass = v3d->shading.render_pass; - if (render_pass == EEVEE_RENDER_PASS_AO && - ((scene->eevee.flag & SCE_EEVEE_GTAO_ENABLED) == 0)) { - render_pass = EEVEE_RENDER_PASS_COMBINED; - } - else if (render_pass == EEVEE_RENDER_PASS_BLOOM && - ((scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) == 0)) { + if (render_pass == EEVEE_RENDER_PASS_BLOOM && + ((scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) == 0)) { render_pass = EEVEE_RENDER_PASS_COMBINED; } g_data->render_passes = render_pass; @@ -392,8 +388,6 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) ((stl->g_data->render_passes & EEVEE_RENDERPASSES_LIGHT_PASS) != 0) ? (stl->g_data->render_passes & EEVEE_RENDERPASSES_LIGHT_PASS) : stl->g_data->render_passes; - const DRWContextState *draw_ctx = DRW_context_state_get(); - const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); bool is_valid = (render_pass & EEVEE_RENDERPASSES_ALL) > 0; bool needs_color_transfer = (render_pass & EEVEE_RENDERPASSES_COLOR_PASS) > 0 && @@ -405,12 +399,6 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) is_valid = false; } - /* When SSS isn't available, but the pass is requested, we mark it as invalid */ - if ((render_pass & EEVEE_RENDER_PASS_AO) != 0 && - (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) == 0) { - is_valid = false; - } - const int current_sample = stl->effects->taa_current_sample; const int total_samples = stl->effects->taa_total_sample; if ((render_pass & EEVEE_RENDERPASSES_POST_PROCESS_ON_FIRST_SAMPLE) && @@ -462,10 +450,10 @@ void EEVEE_renderpasses_draw_debug(EEVEE_Data *vedata) tx = txl->color_double_buffer; break; case 6: - tx = effects->gtao_horizons; + tx = effects->gtao_horizons_renderpass; break; case 7: - tx = effects->gtao_horizons; + tx = effects->gtao_horizons_renderpass; break; case 8: tx = effects->sss_irradiance; diff --git a/source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl b/source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl index a400aadb052..9311542a79e 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl +++ b/source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl @@ -58,7 +58,7 @@ void main() if ((curveHandleDisplay != CURVE_HANDLE_ALL) && (!handle_selected)) { /* Nurbs must show the handles always. */ bool is_u_segment = (((vertFlag[1] ^ vertFlag[0]) & EVEN_U_BIT) != 0); - if (!is_u_segment) { + if ((!is_u_segment) && (color_id <= 4)) { return; } } diff --git a/source/blender/draw/engines/overlay/shaders/edit_gpencil_vert.glsl b/source/blender/draw/engines/overlay/shaders/edit_gpencil_vert.glsl index 5818d8eca52..a6161d36a07 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_gpencil_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/edit_gpencil_vert.glsl @@ -73,7 +73,7 @@ void main() } #ifdef USE_POINTS - gl_PointSize = sizeVertex * 2.0; + gl_PointSize = sizeVertexGpencil * 2.0; if (is_point_dimmed) { finalColor.rgb = clamp(colorUnselect.rgb + vec3(0.3), 0.0, 1.0); 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 71816f6ff6e..899ada852f9 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,4 +1,4 @@ - +#pragma BLENDER_REQUIRE(common_view_lib.glsl) #pragma BLENDER_REQUIRE(common_math_lib.glsl) /** diff --git a/source/blender/draw/engines/workbench/workbench_shader.c b/source/blender/draw/engines/workbench/workbench_shader.c index 9cc5087bd36..af3b5d31b2b 100644 --- a/source/blender/draw/engines/workbench/workbench_shader.c +++ b/source/blender/draw/engines/workbench/workbench_shader.c @@ -380,24 +380,26 @@ void workbench_shader_depth_of_field_get(GPUShader **prepare_sh, GPUShader **resolve_sh) { if (e_data.dof_prepare_sh == NULL) { - char *frag = BLI_string_joinN(datatoc_common_view_lib_glsl, - datatoc_workbench_effect_dof_frag_glsl); - e_data.dof_prepare_sh = DRW_shader_create_fullscreen(frag, "#define PREPARE\n"); - e_data.dof_downsample_sh = DRW_shader_create_fullscreen(frag, "#define DOWNSAMPLE\n"); + e_data.dof_prepare_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_workbench_effect_dof_frag_glsl, e_data.lib, "#define PREPARE\n"); + e_data.dof_downsample_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_workbench_effect_dof_frag_glsl, e_data.lib, "#define DOWNSAMPLE\n"); #if 0 /* TODO(fclem) finish COC min_max optimization */ - e_data.dof_flatten_v_sh = DRW_shader_create_fullscreen(frag, - "#define FLATTEN_VERTICAL\n"); - e_data.dof_flatten_h_sh = DRW_shader_create_fullscreen(frag, - "#define FLATTEN_HORIZONTAL\n"); - e_data.dof_dilate_v_sh = DRW_shader_create_fullscreen(frag, - "#define DILATE_VERTICAL\n"); - e_data.dof_dilate_h_sh = DRW_shader_create_fullscreen(frag, - "#define DILATE_HORIZONTAL\n"); + e_data.dof_flatten_v_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_workbench_effect_dof_frag_glsl, e_data.lib, "#define FLATTEN_VERTICAL\n"); + e_data.dof_flatten_h_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_workbench_effect_dof_frag_glsl, e_data.lib, "#define FLATTEN_HORIZONTAL\n"); + e_data.dof_dilate_v_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_workbench_effect_dof_frag_glsl, e_data.lib, "#define DILATE_VERTICAL\n"); + e_data.dof_dilate_h_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_workbench_effect_dof_frag_glsl, e_data.lib, "#define DILATE_HORIZONTAL\n"); #endif - e_data.dof_blur1_sh = DRW_shader_create_fullscreen(frag, "#define BLUR1\n"); - e_data.dof_blur2_sh = DRW_shader_create_fullscreen(frag, "#define BLUR2\n"); - e_data.dof_resolve_sh = DRW_shader_create_fullscreen(frag, "#define RESOLVE\n"); - MEM_freeN(frag); + e_data.dof_blur1_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_workbench_effect_dof_frag_glsl, e_data.lib, "#define BLUR1\n"); + e_data.dof_blur2_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_workbench_effect_dof_frag_glsl, e_data.lib, "#define BLUR2\n"); + e_data.dof_resolve_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_workbench_effect_dof_frag_glsl, e_data.lib, "#define RESOLVE\n"); } *prepare_sh = e_data.dof_prepare_sh; diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 956bddfb357..63625fae185 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -208,27 +208,44 @@ typedef void (*GPUMaterialEvalCallbackFn)(struct GPUMaterial *mat, const char **defines); #endif -struct GPUShader *DRW_shader_create(const char *vert, - const char *geom, - const char *frag, - const char *defines); -struct GPUShader *DRW_shader_create_with_lib( - const char *vert, const char *geom, const char *frag, const char *lib, const char *defines); -struct GPUShader *DRW_shader_create_with_shaderlib(const char *vert, - const char *geom, - const char *frag, - const DRWShaderLibrary *lib, - const char *defines); +struct GPUShader *DRW_shader_create_ex( + const char *vert, const char *geom, const char *frag, const char *defines, const char *func); +struct GPUShader *DRW_shader_create_with_lib_ex(const char *vert, + const char *geom, + const char *frag, + const char *lib, + const char *defines, + const char *func); +struct GPUShader *DRW_shader_create_with_shaderlib_ex(const char *vert, + const char *geom, + const char *frag, + const DRWShaderLibrary *lib, + const char *defines, + const char *func); struct GPUShader *DRW_shader_create_with_transform_feedback(const char *vert, const char *geom, const char *defines, const eGPUShaderTFBType prim_type, const char **varying_names, const int varying_count); -struct GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines); -struct GPUShader *DRW_shader_create_fullscreen_with_shaderlib(const char *frag, - const DRWShaderLibrary *lib, - const char *defines); +struct GPUShader *DRW_shader_create_fullscreen_ex(const char *frag, + const char *defines, + const char *func); +struct GPUShader *DRW_shader_create_fullscreen_with_shaderlib_ex(const char *frag, + const DRWShaderLibrary *lib, + const char *defines, + const char *func); +#define DRW_shader_create(vert, geom, frag, defines) \ + DRW_shader_create_ex(vert, geom, frag, defines, __func__) +#define DRW_shader_create_with_lib(vert, geom, frag, lib, defines) \ + DRW_shader_create_with_lib_ex(vert, geom, frag, lib, defines, __func__) +#define DRW_shader_create_with_shaderlib(vert, geom, frag, lib, defines) \ + DRW_shader_create_with_shaderlib_ex(vert, geom, frag, lib, defines, __func__) +#define DRW_shader_create_fullscreen(frag, defines) \ + DRW_shader_create_fullscreen_ex(frag, defines, __func__) +#define DRW_shader_create_fullscreen_with_shaderlib(frag, lib, defines) \ + DRW_shader_create_fullscreen_with_shaderlib_ex(frag, lib, defines, __func__) + struct GPUMaterial *DRW_shader_find_from_world(struct World *wo, const void *engine_type, const int options, @@ -344,6 +361,10 @@ typedef enum { #define DRW_STATE_DEFAULT \ (DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL) +#define DRW_STATE_BLEND_ENABLED \ + (DRW_STATE_BLEND_ADD | DRW_STATE_BLEND_ADD_FULL | DRW_STATE_BLEND_ALPHA | \ + DRW_STATE_BLEND_ALPHA_PREMUL | DRW_STATE_BLEND_BACKGROUND | DRW_STATE_BLEND_OIT | \ + DRW_STATE_BLEND_MUL | DRW_STATE_BLEND_SUB | DRW_STATE_BLEND_CUSTOM | DRW_STATE_LOGIC_INVERT) #define DRW_STATE_RASTERIZER_ENABLED \ (DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_STENCIL | \ DRW_STATE_WRITE_STENCIL_SHADOW_PASS | DRW_STATE_WRITE_STENCIL_SHADOW_FAIL) @@ -718,7 +739,6 @@ bool DRW_state_draw_background(void); /* Avoid too many lookups while drawing */ typedef struct DRWContextState { - struct ARegion *region; /* 'CTX_wm_region(C)' */ struct RegionView3D *rv3d; /* 'CTX_wm_region_view3d(C)' */ struct View3D *v3d; /* 'CTX_wm_view3d(C)' */ diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index f0d73d5bb84..aac9af088de 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -187,6 +187,7 @@ void DRW_globals_update(void) /* M_SQRT2 to be at least the same size of the old square */ gb->sizeVertex = U.pixelsize * (max_ff(1.0f, UI_GetThemeValuef(TH_VERTEX_SIZE) * (float)M_SQRT2 / 2.0f)); + gb->sizeVertexGpencil = U.pixelsize * UI_GetThemeValuef(TH_GP_VERTEX_SIZE); gb->sizeFaceDot = U.pixelsize * UI_GetThemeValuef(TH_FACEDOT_SIZE); gb->sizeEdge = U.pixelsize * (1.0f / 2.0f); /* TODO Theme */ gb->sizeEdgeFix = U.pixelsize * (0.5f + 2.0f * (2.0f * (gb->sizeEdge * (float)M_SQRT1_2))); diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index 6060dce47ac..d6402127e5e 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -150,8 +150,7 @@ typedef struct GlobalsUboStorage { float sizeObjectCenter, sizeLightCenter, sizeLightCircle, sizeLightCircleShadow; float sizeVertex, sizeEdge, sizeEdgeFix, sizeFaceDot; float sizeChecker; - - float pad_globalsBlock; + float sizeVertexGpencil; } GlobalsUboStorage; /* Keep in sync with globalsBlock in shaders */ BLI_STATIC_ASSERT_ALIGN(GlobalsUboStorage, 16) diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index e436424b460..d90d7d36ebc 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1595,8 +1595,7 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph, GPU_clear_color(0.0f, 0.0f, 0.0f, 1.0f); GPU_clear(GPU_COLOR_BIT); /* Premult Alpha over black background. */ - GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA_PREMULT); } GPU_matrix_identity_set(); @@ -1606,9 +1605,7 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph, if (draw_background) { /* Reset default. */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* Free temporary viewport. */ @@ -1758,8 +1755,6 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) BLI_rcti_init(&render_rect, 0, size[0], 0, size[1]); } - /* Set the default Blender draw state */ - GPU_state_init(); /* Reset state before drawing */ DRW_state_reset(); @@ -2475,7 +2470,7 @@ void DRW_draw_depth_object( GPU_SHADER_CFG_DEFAULT; GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_DEPTH_ONLY, sh_cfg); if (world_clip_planes != NULL) { - GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]); + GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes); } GPU_batch_draw(batch); @@ -2788,8 +2783,6 @@ void DRW_opengl_context_create(void) if (!G.background) { immActivate(); } - /* Set default Blender OpenGL state */ - GPU_state_init(); /* So we activate the window's one afterwards. */ wm_window_reset_drawable(); } diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index b931bdd0cbe..44e2eec04d9 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -31,8 +31,8 @@ #include "GPU_extensions.h" #include "GPU_platform.h" -#include "intern/gpu_primitive_private.h" -#include "intern/gpu_shader_private.h" +#include "GPU_shader.h" +#include "GPU_state.h" #ifdef USE_GPU_SELECT # include "GPU_select.h" @@ -82,309 +82,169 @@ void drw_state_set(DRWState state) return; } -#define CHANGED_TO(f) \ - ((DST.state_lock & (f)) ? \ - 0 : \ - (((DST.state & (f)) ? ((state & (f)) ? 0 : -1) : ((state & (f)) ? 1 : 0)))) + eGPUWriteMask write_mask = 0; + eGPUBlend blend = 0; + eGPUFaceCullTest culling_test = 0; + eGPUDepthTest depth_test = 0; + eGPUStencilTest stencil_test = 0; + eGPUStencilOp stencil_op = 0; + eGPUProvokingVertex provoking_vert = 0; -#define CHANGED_ANY(f) (((DST.state & (f)) != (state & (f))) && ((DST.state_lock & (f)) == 0)) - -#define CHANGED_ANY_STORE_VAR(f, enabled) \ - (((DST.state & (f)) != (enabled = (state & (f)))) && (((DST.state_lock & (f)) == 0))) - - /* Depth Write */ - { - int test; - if ((test = CHANGED_TO(DRW_STATE_WRITE_DEPTH))) { - GPU_depth_mask(test == 1); - } + if (state & DRW_STATE_WRITE_DEPTH) { + write_mask |= GPU_WRITE_DEPTH; } - - /* Stencil Write */ - { - DRWState test; - if (CHANGED_ANY_STORE_VAR(DRW_STATE_WRITE_STENCIL_ENABLED, test)) { - /* Stencil Write */ - if (test) { - glStencilMask(0xFF); - switch (test) { - case DRW_STATE_WRITE_STENCIL: - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - break; - case DRW_STATE_WRITE_STENCIL_SHADOW_PASS: - glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR_WRAP); - glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR_WRAP); - break; - case DRW_STATE_WRITE_STENCIL_SHADOW_FAIL: - glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_KEEP); - glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_KEEP); - break; - default: - BLI_assert(0); - } - } - else { - glStencilMask(0x00); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - } - } + if (state & DRW_STATE_WRITE_COLOR) { + write_mask |= GPU_WRITE_COLOR; } - /* Color Write */ - { - int test; - if ((test = CHANGED_TO(DRW_STATE_WRITE_COLOR))) { - if (test == 1) { - GPU_color_mask(true, true, true, true); - } - else { - GPU_color_mask(false, false, false, false); - } - } + switch (state & (DRW_STATE_CULL_BACK | DRW_STATE_CULL_FRONT)) { + case DRW_STATE_CULL_BACK: + culling_test = GPU_CULL_BACK; + break; + case DRW_STATE_CULL_FRONT: + culling_test = GPU_CULL_FRONT; + break; + default: + culling_test = GPU_CULL_NONE; + break; } - /* Raster Discard */ - { - if (CHANGED_ANY(DRW_STATE_RASTERIZER_ENABLED)) { - if ((state & DRW_STATE_RASTERIZER_ENABLED) != 0) { - glDisable(GL_RASTERIZER_DISCARD); - } - else { - glEnable(GL_RASTERIZER_DISCARD); - } - } + switch (state & DRW_STATE_DEPTH_TEST_ENABLED) { + case DRW_STATE_DEPTH_LESS: + depth_test = GPU_DEPTH_LESS; + break; + case DRW_STATE_DEPTH_LESS_EQUAL: + depth_test = GPU_DEPTH_LESS_EQUAL; + break; + case DRW_STATE_DEPTH_EQUAL: + depth_test = GPU_DEPTH_EQUAL; + break; + case DRW_STATE_DEPTH_GREATER: + depth_test = GPU_DEPTH_GREATER; + break; + case DRW_STATE_DEPTH_GREATER_EQUAL: + depth_test = GPU_DEPTH_GREATER_EQUAL; + break; + case DRW_STATE_DEPTH_ALWAYS: + depth_test = GPU_DEPTH_ALWAYS; + break; + default: + depth_test = GPU_DEPTH_NONE; + break; } - /* Cull */ - { - DRWState test; - if (CHANGED_ANY_STORE_VAR(DRW_STATE_CULL_BACK | DRW_STATE_CULL_FRONT, test)) { - if (test) { - glEnable(GL_CULL_FACE); - - if ((state & DRW_STATE_CULL_BACK) != 0) { - glCullFace(GL_BACK); - } - else if ((state & DRW_STATE_CULL_FRONT) != 0) { - glCullFace(GL_FRONT); - } - else { - BLI_assert(0); - } - } - else { - glDisable(GL_CULL_FACE); - } - } + switch (state & DRW_STATE_WRITE_STENCIL_ENABLED) { + case DRW_STATE_WRITE_STENCIL: + stencil_op = GPU_STENCIL_OP_REPLACE; + GPU_stencil_write_mask_set(0xFF); + break; + case DRW_STATE_WRITE_STENCIL_SHADOW_PASS: + stencil_op = GPU_STENCIL_OP_COUNT_DEPTH_PASS; + GPU_stencil_write_mask_set(0xFF); + break; + case DRW_STATE_WRITE_STENCIL_SHADOW_FAIL: + stencil_op = GPU_STENCIL_OP_COUNT_DEPTH_FAIL; + GPU_stencil_write_mask_set(0xFF); + break; + default: + stencil_op = GPU_STENCIL_OP_NONE; + GPU_stencil_write_mask_set(0x00); + break; } - /* Depth Test */ - { - DRWState test; - if (CHANGED_ANY_STORE_VAR(DRW_STATE_DEPTH_TEST_ENABLED, test)) { - if (test) { - glEnable(GL_DEPTH_TEST); - - switch (test) { - case DRW_STATE_DEPTH_LESS: - glDepthFunc(GL_LESS); - break; - case DRW_STATE_DEPTH_LESS_EQUAL: - glDepthFunc(GL_LEQUAL); - break; - case DRW_STATE_DEPTH_EQUAL: - glDepthFunc(GL_EQUAL); - break; - case DRW_STATE_DEPTH_GREATER: - glDepthFunc(GL_GREATER); - break; - case DRW_STATE_DEPTH_GREATER_EQUAL: - glDepthFunc(GL_GEQUAL); - break; - case DRW_STATE_DEPTH_ALWAYS: - glDepthFunc(GL_ALWAYS); - break; - default: - BLI_assert(0); - } - } - else { - glDisable(GL_DEPTH_TEST); - } - } + switch (state & DRW_STATE_STENCIL_TEST_ENABLED) { + case DRW_STATE_STENCIL_ALWAYS: + stencil_test = GPU_STENCIL_ALWAYS; + break; + case DRW_STATE_STENCIL_EQUAL: + stencil_test = GPU_STENCIL_EQUAL; + break; + case DRW_STATE_STENCIL_NEQUAL: + stencil_test = GPU_STENCIL_NEQUAL; + break; + default: + stencil_test = GPU_STENCIL_NONE; + break; } - /* Stencil Test */ - { - int test; - if (CHANGED_ANY_STORE_VAR(DRW_STATE_STENCIL_TEST_ENABLED, test)) { - if (test) { - glEnable(GL_STENCIL_TEST); - } - else { - glDisable(GL_STENCIL_TEST); - } - } + switch (state & DRW_STATE_BLEND_ENABLED) { + case DRW_STATE_BLEND_ADD: + blend = GPU_BLEND_ADDITIVE; + break; + case DRW_STATE_BLEND_ADD_FULL: + blend = GPU_BLEND_ADDITIVE_PREMULT; + break; + case DRW_STATE_BLEND_ALPHA: + blend = GPU_BLEND_ALPHA; + break; + case DRW_STATE_BLEND_ALPHA_PREMUL: + blend = GPU_BLEND_ALPHA_PREMULT; + break; + case DRW_STATE_BLEND_BACKGROUND: + blend = GPU_BLEND_BACKGROUND; + break; + case DRW_STATE_BLEND_OIT: + blend = GPU_BLEND_OIT; + break; + case DRW_STATE_BLEND_MUL: + blend = GPU_BLEND_MULTIPLY; + break; + case DRW_STATE_BLEND_SUB: + blend = GPU_BLEND_SUBTRACT; + break; + case DRW_STATE_BLEND_CUSTOM: + blend = GPU_BLEND_CUSTOM; + break; + case DRW_STATE_LOGIC_INVERT: + blend = GPU_BLEND_INVERT; + break; + default: + blend = GPU_BLEND_NONE; + break; } - /* Blending (all buffer) */ - { - int test; - if (CHANGED_ANY_STORE_VAR(DRW_STATE_BLEND_ALPHA | DRW_STATE_BLEND_ALPHA_PREMUL | - DRW_STATE_BLEND_ADD | DRW_STATE_BLEND_MUL | - DRW_STATE_BLEND_ADD_FULL | DRW_STATE_BLEND_OIT | - DRW_STATE_BLEND_BACKGROUND | DRW_STATE_BLEND_CUSTOM | - DRW_STATE_LOGIC_INVERT | DRW_STATE_BLEND_SUB, - test)) { - if (test) { - glEnable(GL_BLEND); - - switch (test) { - case DRW_STATE_BLEND_ALPHA: - glBlendFuncSeparate(GL_SRC_ALPHA, - GL_ONE_MINUS_SRC_ALPHA, /* RGB */ - GL_ONE, - GL_ONE_MINUS_SRC_ALPHA); /* Alpha */ - break; - case DRW_STATE_BLEND_BACKGROUND: - /* Special blend to add color under and multiply dst by alpha. */ - glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA, - GL_SRC_ALPHA, /* RGB */ - GL_ZERO, - GL_SRC_ALPHA); /* Alpha */ - break; - case DRW_STATE_BLEND_ALPHA_PREMUL: - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - break; - case DRW_STATE_BLEND_MUL: - glBlendFunc(GL_DST_COLOR, GL_ZERO); - break; - case DRW_STATE_BLEND_OIT: - glBlendFuncSeparate(GL_ONE, - GL_ONE, /* RGB */ - GL_ZERO, - GL_ONE_MINUS_SRC_ALPHA); /* Alpha */ - break; - case DRW_STATE_BLEND_ADD: - /* Do not let alpha accumulate but premult the source RGB by it. */ - glBlendFuncSeparate(GL_SRC_ALPHA, - GL_ONE, /* RGB */ - GL_ZERO, - GL_ONE); /* Alpha */ - break; - case DRW_STATE_BLEND_ADD_FULL: - /* Let alpha accumulate. */ - glBlendFunc(GL_ONE, GL_ONE); - break; - case DRW_STATE_BLEND_SUB: - glBlendFunc(GL_ONE, GL_ONE); - break; - case DRW_STATE_BLEND_CUSTOM: - /* Custom blend parameters using dual source blending. - * Can only be used with one Draw Buffer. */ - glBlendFunc(GL_ONE, GL_SRC1_COLOR); - break; - case DRW_STATE_LOGIC_INVERT: - /* Replace logic op by blend func to support floating point framebuffer. */ - glBlendFuncSeparate(GL_ONE_MINUS_DST_COLOR, - GL_ZERO, /* RGB */ - GL_ZERO, - GL_ONE); /* Alpha */ - break; - default: - BLI_assert(0); - } + GPU_state_set( + write_mask, blend, culling_test, depth_test, stencil_test, stencil_op, provoking_vert); - if (test == DRW_STATE_BLEND_SUB) { - glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); - } - else { - glBlendEquation(GL_FUNC_ADD); - } - } - else { - glDisable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE); /* Don't multiply incoming color by alpha. */ - } - } + if (state & DRW_STATE_SHADOW_OFFSET) { + GPU_shadow_offset(true); } - - /* Shadow Bias */ - { - int test; - if ((test = CHANGED_TO(DRW_STATE_SHADOW_OFFSET))) { - if (test == 1) { - glEnable(GL_POLYGON_OFFSET_FILL); - glEnable(GL_POLYGON_OFFSET_LINE); - /* 2.0 Seems to be the lowest possible slope bias that works in every case. */ - glPolygonOffset(2.0f, 1.0f); - } - else { - glDisable(GL_POLYGON_OFFSET_FILL); - glDisable(GL_POLYGON_OFFSET_LINE); - } - } + else { + GPU_shadow_offset(false); } - /* In Front objects selection */ - { - int test; - if ((test = CHANGED_TO(DRW_STATE_IN_FRONT_SELECT))) { - if (test == 1) { - /* XXX `GPU_depth_range` is not a perfect solution - * since very distant geometries can still be occluded. - * Also the depth test precision of these geometries is impaired. - * However, it solves the selection for the vast majority of cases. */ - GPU_depth_range(0.0f, 0.01f); - } - else { - GPU_depth_range(0.0f, 1.0f); - } - } + /* TODO this should be part of shader state. */ + if (state & DRW_STATE_CLIP_PLANES) { + GPU_clip_distances(DST.view_active->clip_planes_len); } - - /* Clip Planes */ - { - int test; - if ((test = CHANGED_TO(DRW_STATE_CLIP_PLANES))) { - if (test == 1) { - GPU_clip_distances(DST.view_active->clip_planes_len); - } - else { - GPU_clip_distances(0); - } - } + else { + GPU_clip_distances(0); } - /* Program Points Size */ - { - int test; - if ((test = CHANGED_TO(DRW_STATE_PROGRAM_POINT_SIZE))) { - if (test == 1) { - GPU_program_point_size(true); - } - else { - GPU_program_point_size(false); - } - } + if (state & DRW_STATE_IN_FRONT_SELECT) { + /* XXX `GPU_depth_range` is not a perfect solution + * since very distant geometries can still be occluded. + * Also the depth test precision of these geometries is impaired. + * However, it solves the selection for the vast majority of cases. */ + GPU_depth_range(0.0f, 0.01f); + } + else { + GPU_depth_range(0.0f, 1.0f); } - /* Provoking Vertex */ - { - int test; - if ((test = CHANGED_TO(DRW_STATE_FIRST_VERTEX_CONVENTION))) { - if (test == 1) { - glProvokingVertex(GL_FIRST_VERTEX_CONVENTION); - } - else { - glProvokingVertex(GL_LAST_VERTEX_CONVENTION); - } - } + if (state & DRW_STATE_PROGRAM_POINT_SIZE) { + GPU_program_point_size(true); + } + else { + GPU_program_point_size(false); } -#undef CHANGED_TO -#undef CHANGED_ANY -#undef CHANGED_ANY_STORE_VAR + if (state & DRW_STATE_FIRST_VERTEX_CONVENTION) { + GPU_provoking_vertex(GPU_VERTEX_FIRST); + } + else { + GPU_provoking_vertex(GPU_VERTEX_LAST); + } DST.state = state; } @@ -396,17 +256,9 @@ static void drw_stencil_state_set(uint write_mask, uint reference, uint compare_ * stencil_value being the value stored in the stencil buffer. * - (write-mask & reference) is what gets written if the test condition is fulfilled. **/ - glStencilMask(write_mask); - DRWState stencil_test = DST.state & DRW_STATE_STENCIL_TEST_ENABLED; - if (stencil_test == DRW_STATE_STENCIL_ALWAYS) { - glStencilFunc(GL_ALWAYS, reference, compare_mask); - } - else if (stencil_test == DRW_STATE_STENCIL_EQUAL) { - glStencilFunc(GL_EQUAL, reference, compare_mask); - } - else if (stencil_test == DRW_STATE_STENCIL_NEQUAL) { - glStencilFunc(GL_NOTEQUAL, reference, compare_mask); - } + GPU_stencil_write_mask_set(write_mask); + GPU_stencil_reference_set(reference); + GPU_stencil_compare_mask_set(compare_mask); } /* Reset state to not interfer with other UI drawcall */ @@ -821,8 +673,8 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup, break; case DRW_UNIFORM_TFEEDBACK_TARGET: BLI_assert(uni->pvalue && (*use_tfeedback == false)); - *use_tfeedback = GPU_shader_transform_feedback_enable( - shgroup->shader, ((GPUVertBuf *)uni->pvalue)->vbo_id); + *use_tfeedback = GPU_shader_transform_feedback_enable(shgroup->shader, + ((GPUVertBuf *)uni->pvalue)); break; /* Legacy/Fallback support. */ case DRW_UNIFORM_BASE_INSTANCE: @@ -922,7 +774,7 @@ static void draw_call_resource_bind(DRWCommandsState *state, const DRWResourceHa int chunk = DRW_handle_chunk_get(handle); if (state->resource_chunk != chunk) { if (state->chunkid_loc != -1) { - GPU_shader_uniform_int(NULL, state->chunkid_loc, chunk); + GPU_shader_uniform_int(DST.shader, state->chunkid_loc, chunk); } if (state->obmats_loc != -1) { GPU_uniformbuffer_unbind(DST.vmempool->matrices_ubo[state->resource_chunk]); @@ -938,7 +790,7 @@ static void draw_call_resource_bind(DRWCommandsState *state, const DRWResourceHa if (state->resourceid_loc != -1) { int id = DRW_handle_id_get(handle); if (state->resource_id != id) { - GPU_shader_uniform_int(NULL, state->resourceid_loc, id); + GPU_shader_uniform_int(DST.shader, state->resourceid_loc, id); state->resource_id = id; } } diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c index 1c260721efb..7602bbb39ac 100644 --- a/source/blender/draw/intern/draw_manager_shader.c +++ b/source/blender/draw/intern/draw_manager_shader.c @@ -312,16 +312,18 @@ void DRW_deferred_shader_remove(GPUMaterial *mat) /** \{ */ -GPUShader *DRW_shader_create(const char *vert, - const char *geom, - const char *frag, - const char *defines) +GPUShader *DRW_shader_create_ex( + const char *vert, const char *geom, const char *frag, const char *defines, const char *name) { - return GPU_shader_create(vert, frag, geom, NULL, defines, __func__); + return GPU_shader_create(vert, frag, geom, NULL, defines, name); } -GPUShader *DRW_shader_create_with_lib( - const char *vert, const char *geom, const char *frag, const char *lib, const char *defines) +GPUShader *DRW_shader_create_with_lib_ex(const char *vert, + const char *geom, + const char *frag, + const char *lib, + const char *defines, + const char *name) { GPUShader *sh; char *vert_with_lib = NULL; @@ -334,7 +336,7 @@ GPUShader *DRW_shader_create_with_lib( geom_with_lib = BLI_string_joinN(lib, geom); } - sh = GPU_shader_create(vert_with_lib, frag_with_lib, geom_with_lib, NULL, defines, __func__); + sh = GPU_shader_create(vert_with_lib, frag_with_lib, geom_with_lib, NULL, defines, name); MEM_freeN(vert_with_lib); MEM_freeN(frag_with_lib); @@ -345,18 +347,19 @@ GPUShader *DRW_shader_create_with_lib( return sh; } -GPUShader *DRW_shader_create_with_shaderlib(const char *vert, - const char *geom, - const char *frag, - const DRWShaderLibrary *lib, - const char *defines) +GPUShader *DRW_shader_create_with_shaderlib_ex(const char *vert, + const char *geom, + const char *frag, + const DRWShaderLibrary *lib, + const char *defines, + const char *name) { GPUShader *sh; char *vert_with_lib = DRW_shader_library_create_shader_string(lib, vert); char *frag_with_lib = DRW_shader_library_create_shader_string(lib, frag); char *geom_with_lib = (geom) ? DRW_shader_library_create_shader_string(lib, geom) : NULL; - sh = GPU_shader_create(vert_with_lib, frag_with_lib, geom_with_lib, NULL, defines, __func__); + sh = GPU_shader_create(vert_with_lib, frag_with_lib, geom_with_lib, NULL, defines, name); MEM_SAFE_FREE(vert_with_lib); MEM_SAFE_FREE(frag_with_lib); @@ -383,22 +386,22 @@ GPUShader *DRW_shader_create_with_transform_feedback(const char *vert, __func__); } -GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines) +GPUShader *DRW_shader_create_fullscreen_ex(const char *frag, const char *defines, const char *name) { - return GPU_shader_create( - datatoc_common_fullscreen_vert_glsl, frag, NULL, NULL, defines, __func__); + return GPU_shader_create(datatoc_common_fullscreen_vert_glsl, frag, NULL, NULL, defines, name); } -GPUShader *DRW_shader_create_fullscreen_with_shaderlib(const char *frag, - const DRWShaderLibrary *lib, - const char *defines) +GPUShader *DRW_shader_create_fullscreen_with_shaderlib_ex(const char *frag, + const DRWShaderLibrary *lib, + const char *defines, + const char *name) { GPUShader *sh; char *vert = datatoc_common_fullscreen_vert_glsl; char *frag_with_lib = DRW_shader_library_create_shader_string(lib, frag); - sh = GPU_shader_create(vert, frag_with_lib, NULL, NULL, defines, __func__); + sh = GPU_shader_create(vert, frag_with_lib, NULL, NULL, defines, name); MEM_SAFE_FREE(frag_with_lib); diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c index 1458ff5341c..0dc35d44788 100644 --- a/source/blender/draw/intern/draw_view.c +++ b/source/blender/draw/intern/draw_view.c @@ -123,7 +123,7 @@ void DRW_draw_cursor(void) /* Draw nice Anti Aliased cursor. */ GPU_line_width(1.0f); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); float eps = 1e-5f; @@ -188,7 +188,7 @@ void DRW_draw_cursor(void) GPU_batch_draw(cursor_batch); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); GPU_matrix_pop(); GPU_matrix_projection_set(original_proj); diff --git a/source/blender/draw/intern/shaders/common_globals_lib.glsl b/source/blender/draw/intern/shaders/common_globals_lib.glsl index 40a527a6ba4..bd1b1fb6f3a 100644 --- a/source/blender/draw/intern/shaders/common_globals_lib.glsl +++ b/source/blender/draw/intern/shaders/common_globals_lib.glsl @@ -117,8 +117,7 @@ layout(std140) uniform globalsBlock float sizeEdgeFix; float sizeFaceDot; float sizeChecker; - - float pad_globalsBlock; + float sizeVertexGpencil; }; #define sizeViewportInv (sizeViewport.zw) diff --git a/source/blender/draw/intern/smaa_textures.h b/source/blender/draw/intern/smaa_textures.h index 7556f3a1952..fcf0ced1eed 100644 --- a/source/blender/draw/intern/smaa_textures.h +++ b/source/blender/draw/intern/smaa_textures.h @@ -15081,4 +15081,3 @@ static const unsigned char searchTexBytes[] = { }; /* clang-format off */ - diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 53401e0c05a..0a464e6709a 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -4386,9 +4386,7 @@ void ANIM_channel_draw( } /* set blending again, as may not be set in previous step */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* step 1) draw backdrop ........................................... */ if (acf->draw_backdrop) { @@ -4437,7 +4435,7 @@ void ANIM_channel_draw( } /* turn off blending, since not needed anymore... */ - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* icon is drawn as widget now... */ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) { diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index b2f687b49af..73df0518f06 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -98,9 +98,7 @@ void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width) /* only draw this if preview range is set */ if (PRVRANGEON) { - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -121,7 +119,7 @@ void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } @@ -133,9 +131,7 @@ void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width) void ANIM_draw_framerange(Scene *scene, View2D *v2d) { /* draw darkened area outside of active timeline frame range */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -151,7 +147,7 @@ void ANIM_draw_framerange(Scene *scene, View2D *v2d) immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* thin lines where the actual frames are */ immUniformThemeColorShade(TH_BACK, -60); diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index bcdbf4c74f0..3bfa3b9d5be 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -499,16 +499,14 @@ static void draw_marker( marker_color_get(marker, text_color, line_color); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); draw_marker_line(line_color, xpos, UI_DPI_FAC * 20, region_height); int icon_id = marker_get_icon_id(marker, flag); UI_icon_draw(xpos - 0.55f * UI_DPI_ICON_SIZE, UI_DPI_FAC * 18, icon_id); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); float name_y = UI_DPI_FAC * 18; /* Give an offset to the marker name when selected, @@ -529,13 +527,11 @@ static void draw_markers_background(rctf *rect) immUniformColor4ubv(shade); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); } diff --git a/source/blender/editors/animation/anim_motion_paths.c b/source/blender/editors/animation/anim_motion_paths.c index 4c10c66dfa6..2a37302872a 100644 --- a/source/blender/editors/animation/anim_motion_paths.c +++ b/source/blender/editors/animation/anim_motion_paths.c @@ -69,9 +69,9 @@ typedef struct MPathTarget { /* ........ */ /* update scene for current frame */ -static void motionpaths_calc_update_scene(Main *bmain, struct Depsgraph *depsgraph) +static void motionpaths_calc_update_scene(struct Depsgraph *depsgraph) { - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); } Depsgraph *animviz_depsgraph_build(Main *bmain, @@ -91,11 +91,11 @@ Depsgraph *animviz_depsgraph_build(Main *bmain, } /* Build graph from all requested IDs. */ - DEG_graph_build_from_ids(depsgraph, bmain, scene, view_layer, ids, num_ids); + DEG_graph_build_from_ids(depsgraph, ids, num_ids); MEM_freeN(ids); /* Update once so we can access pointers of evaluated animation data. */ - motionpaths_calc_update_scene(bmain, depsgraph); + motionpaths_calc_update_scene(depsgraph); return depsgraph; } @@ -471,7 +471,7 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph, } else { /* Update relevant data for new frame. */ - motionpaths_calc_update_scene(bmain, depsgraph); + motionpaths_calc_update_scene(depsgraph); } /* perform baking for targets */ @@ -484,7 +484,7 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph, * We always have to restore the current frame though. */ CFRA = cfra; if (range != ANIMVIZ_CALC_RANGE_CURRENT_FRAME && restore) { - motionpaths_calc_update_scene(bmain, depsgraph); + motionpaths_calc_update_scene(depsgraph); } if (is_active_depsgraph) { diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index c69f3ce3e3a..4d6d7fa3ad5 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -692,7 +692,7 @@ static void draw_keylist(View2D *v2d, const float smaller_sz = 0.35f * icon_sz; const float ipo_sz = 0.1f * icon_sz; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */ /* TODO: allow this opacity factor to be themed? */ @@ -848,7 +848,7 @@ static void draw_keylist(View2D *v2d, } } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* *************************** Channel Drawing Funcs *************************** */ diff --git a/source/blender/editors/animation/time_scrub_ui.c b/source/blender/editors/animation/time_scrub_ui.c index edc36326c57..0615e21c4a5 100644 --- a/source/blender/editors/animation/time_scrub_ui.c +++ b/source/blender/editors/animation/time_scrub_ui.c @@ -66,13 +66,11 @@ static void draw_background(const rcti *rect) immUniformThemeColor(TH_TIME_SCRUB_BACKGROUND); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); } diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c index 748bf040fbb..2dac273501d 100644 --- a/source/blender/editors/curve/editcurve_paint.c +++ b/source/blender/editors/curve/editcurve_paint.c @@ -420,7 +420,7 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); GPU_depth_test(false); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); GPU_line_width(3.0f); @@ -442,7 +442,7 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), /* Reset defaults */ GPU_depth_test(true); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); immUnbindProgram(); @@ -666,7 +666,7 @@ static void curve_draw_exec_precalc(wmOperator *op) selem_prev = selem; } scale_px = ((len_3d > 0.0f) && (len_2d > 0.0f)) ? (len_3d / len_2d) : 0.0f; - float error_threshold = (cps->error_threshold * U.pixelsize) * scale_px; + float error_threshold = (cps->error_threshold * U.dpi_fac) * scale_px; RNA_property_float_set(op->ptr, prop, error_threshold); } @@ -685,7 +685,7 @@ static void curve_draw_exec_precalc(wmOperator *op) } if (len_squared_v2v2(selem_first->mval, selem_last->mval) <= - square_f(STROKE_CYCLIC_DIST_PX * U.pixelsize)) { + square_f(STROKE_CYCLIC_DIST_PX * U.dpi_fac)) { use_cyclic = true; } } 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 341f43d0662..d4d9f9bf424 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c @@ -195,9 +195,9 @@ static void arrow_draw_intern(ArrowGizmo3D *arrow, const bool select, const bool GPU_matrix_push(); GPU_matrix_mul(matrix_final); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); arrow_draw_geom(arrow, select, color); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_matrix_pop(); @@ -207,9 +207,9 @@ static void arrow_draw_intern(ArrowGizmo3D *arrow, const bool select, const bool GPU_matrix_push(); GPU_matrix_mul(inter->init_matrix_final); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); arrow_draw_geom(arrow, select, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f}); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_matrix_pop(); } 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 c5231b3cd96..13f3903f0b2 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c @@ -195,7 +195,7 @@ static void button2d_draw_intern(const bContext *C, } else { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); if (draw_options & ED_GIZMO_BUTTON_SHOW_BACKDROP) { const float fill_alpha = RNA_float_get(gz->ptr, "backdrop_fill_alpha"); @@ -226,10 +226,10 @@ static void button2d_draw_intern(const bContext *C, float color_contrast[4]; copy_v3_fl(color_contrast, rgb_to_grayscale(color) < 0.2f ? 1 : 0); color_contrast[3] = color[3]; - GPU_batch_uniform_4f(button->shape_batch[i], "color", UNPACK4(color_contrast)); + GPU_shader_uniform_4f(button->shape_batch[i]->shader, "color", UNPACK4(color_contrast)); } else { - GPU_batch_uniform_4f(button->shape_batch[i], "color", UNPACK4(color)); + GPU_shader_uniform_4f(button->shape_batch[i]->shader, "color", UNPACK4(color)); } GPU_batch_draw(button->shape_batch[i]); @@ -265,7 +265,7 @@ static void button2d_draw_intern(const bContext *C, UI_icon_draw_alpha(pos[0], pos[1], button->icon, alpha); GPU_polygon_smooth(true); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } if (need_to_pop) { @@ -283,9 +283,9 @@ static void gizmo_button2d_draw(const bContext *C, wmGizmo *gz) { const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); button2d_draw_intern(C, gz, false, is_highlight); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static int gizmo_button2d_test_select(bContext *C, wmGizmo *gz, const int mval[2]) 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 406d66dfd8f..be5f488d759 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c @@ -626,14 +626,14 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz, /* Handy for quick testing draw (if it's outside bounds). */ if (false) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv((const float[4]){1, 1, 1, 0.5f}); float s = 0.5f; immRectf(pos, -s, -s, s, s); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } if (select) { @@ -722,7 +722,7 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz, float color[4], black[3] = {0, 0, 0}; gizmo_color_get(gz, highlight, color); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); float outline_line_width = gz->line_width + 3.0f; cage2d_draw_circle_wire(&r, margin, black, transform_flag, draw_options, outline_line_width); @@ -732,7 +732,7 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz, cage2d_draw_circle_handles(&r, margin, color, transform_flag, true); cage2d_draw_circle_handles(&r, margin, (const float[3]){0, 0, 0}, transform_flag, false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } else { BLI_assert(0); 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 0bc65fe10a5..644a4247d84 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c @@ -303,14 +303,14 @@ static void gizmo_cage3d_draw_intern( /* Handy for quick testing draw (if it's outside bounds). */ if (false) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformColor4fv((const float[4]){1, 1, 1, 0.5f}); float s = 0.5f; immRectf(pos, -s, -s, s, s); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } if (select) { @@ -382,7 +382,7 @@ static void gizmo_cage3d_draw_intern( float color[4], black[3] = {0, 0, 0}; gizmo_color_get(gz, highlight, color); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); cage3d_draw_circle_wire( size_real, margin, black, transform_flag, draw_options, gz->line_width + 3.0f); @@ -395,7 +395,7 @@ static void gizmo_cage3d_draw_intern( cage3d_draw_circle_handles(rv3d, matrix_final, size_real, margin, color, true, 40); GPU_polygon_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } else { BLI_assert(0); diff --git a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c index 5d7c3a9e717..e1860d5d0fd 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c @@ -482,9 +482,9 @@ static void gizmo_dial_draw(const bContext *C, wmGizmo *gz) clip_plane[3] += DIAL_CLIP_BIAS; } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); dial_draw_intern(C, gz, false, is_highlight, clip_plane); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static int gizmo_dial_modal(bContext *C, diff --git a/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c index db57a33f543..ad7036f4460 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c @@ -207,9 +207,9 @@ static void move3d_draw_intern(const bContext *C, GPU_matrix_mul(matrix_align); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); move_geom_draw(gz, color, select, draw_options); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_matrix_pop(); if (gz->interaction_data) { @@ -220,9 +220,9 @@ static void move3d_draw_intern(const bContext *C, GPU_matrix_mul(matrix_align); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); move_geom_draw(gz, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f}, select, draw_options); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_matrix_pop(); } } @@ -240,9 +240,9 @@ static void gizmo_move_draw(const bContext *C, wmGizmo *gz) (void)is_modal; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); move3d_draw_intern(C, gz, false, is_highlight); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static int gizmo_move_modal(bContext *C, diff --git a/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c index 48b2e3348c9..177687b6afd 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c @@ -96,9 +96,9 @@ static void gizmo_primitive_draw_intern(wmGizmo *gz, GPU_matrix_push(); GPU_matrix_mul(matrix_final); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); gizmo_primitive_draw_geom(color_inner, color_outer, draw_style); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_matrix_pop(); @@ -112,9 +112,9 @@ static void gizmo_primitive_draw_intern(wmGizmo *gz, GPU_matrix_push(); GPU_matrix_mul(inter->init_matrix_final); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); gizmo_primitive_draw_geom(color_inner, color_outer, draw_style); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_matrix_pop(); } diff --git a/source/blender/editors/gpencil/annotate_draw.c b/source/blender/editors/gpencil/annotate_draw.c index df479325027..654d1b87918 100644 --- a/source/blender/editors/gpencil/annotate_draw.c +++ b/source/blender/editors/gpencil/annotate_draw.c @@ -734,9 +734,7 @@ static void annotation_draw_data( GPU_line_smooth(true); /* turn on alpha-blending */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* Do not write to depth (avoid self-occlusion). */ bool prev_depth_mask = GPU_depth_mask_get(); @@ -746,8 +744,8 @@ static void annotation_draw_data( annotation_draw_data_layers(gpd, offsx, offsy, winx, winy, cfra, dflag); /* turn off alpha blending, then smooth lines */ - GPU_blend(false); // alpha blending - GPU_line_smooth(false); // smooth lines + GPU_blend(GPU_BLEND_NONE); // alpha blending + GPU_line_smooth(false); // smooth lines GPU_depth_mask(prev_depth_mask); } diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c index 30e4fe0b531..8237e6cfd62 100644 --- a/source/blender/editors/gpencil/annotate_paint.c +++ b/source/blender/editors/gpencil/annotate_paint.c @@ -1700,9 +1700,7 @@ static void annotation_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_pt immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); GPU_line_smooth(true); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor4ub(255, 100, 100, 20); imm_draw_circle_fill_2d(shdr_pos, x, y, p->radius, 40); @@ -1730,7 +1728,7 @@ static void annotation_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_pt immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); } } @@ -1768,7 +1766,7 @@ static void annotation_draw_stabilizer(bContext *C, int x, int y, void *p_ptr) uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_width(1.25f); const float color[3] = {1.0f, 0.39f, 0.39f}; @@ -1793,7 +1791,7 @@ static void annotation_draw_stabilizer(bContext *C, int x, int y, void *p_ptr) immEnd(); /* Returns back all GPU settings */ - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); immUnbindProgram(); diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 99e98df3397..1bbba6c4b8a 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -3645,7 +3645,6 @@ static int gpencil_strokes_reproject_exec(bContext *C, wmOperator *op) { bGPdata *gpd = ED_gpencil_data_get_active(C); Scene *scene = CTX_data_scene(C); - Main *bmain = CTX_data_main(C); Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); ARegion *region = CTX_wm_region(C); int oldframe = (int)DEG_get_ctime(depsgraph); @@ -3669,7 +3668,7 @@ static int gpencil_strokes_reproject_exec(bContext *C, wmOperator *op) if ((mode == GP_REPROJECT_SURFACE) && (cfra_prv != gpf_->framenum)) { cfra_prv = gpf_->framenum; CFRA = gpf_->framenum; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); } ED_gpencil_stroke_reproject(depsgraph, &gsc, sctx, gpl, gpf_, gps, mode, keep_original); @@ -3679,7 +3678,7 @@ static int gpencil_strokes_reproject_exec(bContext *C, wmOperator *op) /* return frame state and DB to original state */ CFRA = oldframe; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); if (sctx != NULL) { ED_transform_snap_object_context_destroy(sctx); diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index 9d99773348b..ae9146b3a6a 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -252,7 +252,7 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4]) tgpw.disable_fill = 1; tgpw.dflag |= (GP_DRAWFILLS_ONLY3D | GP_DRAWFILLS_NOSTATUS); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); bGPDlayer *gpl_active = BKE_gpencil_layer_active_get(gpd); BLI_assert(gpl_active != NULL); @@ -371,7 +371,7 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4]) } } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* draw strokes in offscreen buffer */ diff --git a/source/blender/editors/gpencil/gpencil_mesh.c b/source/blender/editors/gpencil/gpencil_mesh.c index a6088e31ff8..f4e40c2670f 100644 --- a/source/blender/editors/gpencil/gpencil_mesh.c +++ b/source/blender/editors/gpencil/gpencil_mesh.c @@ -246,7 +246,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) /* Move scene to new frame. */ CFRA = i; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); /* Loop all objects in the list. */ LISTBASE_FOREACH (GpBakeOb *, elem, &list) { @@ -287,7 +287,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) /* Return scene frame state and DB to original state. */ CFRA = oldframe; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); /* Remove unused materials. */ int actcol = ob_gpencil->actcol; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 680e7b37d31..3f62c3ec8c0 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -2268,9 +2268,7 @@ static void gpencil_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr) immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); GPU_line_smooth(true); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor4ub(255, 100, 100, 20); imm_draw_circle_fill_2d(shdr_pos, x, y, p->radius, 40); @@ -2298,7 +2296,7 @@ static void gpencil_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); } } diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 5aae10a5db5..8b77709bacb 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -1760,9 +1760,7 @@ void ED_gpencil_brush_draw_eraser(Brush *brush, int x, int y) immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); GPU_line_smooth(true); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor4ub(255, 100, 100, 20); imm_draw_circle_fill_2d(shdr_pos, x, y, radius, 40); @@ -1790,7 +1788,7 @@ void ED_gpencil_brush_draw_eraser(Brush *brush, int x, int y) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); } @@ -1944,7 +1942,7 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* Inner Ring: Color from UI panel */ immUniformColor4f(color[0], color[1], color[2], 0.8f); @@ -1963,13 +1961,13 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat immUniformColor4f(darkcolor[0], darkcolor[1], darkcolor[2], 0.8f); imm_draw_circle_wire_2d(pos, x, y, radius + 1, 40); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); /* Draw line for lazy mouse */ if ((last_mouse_position) && (brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP)) { GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); copy_v3_v3(color, brush->add_col); immUniformColor4f(color[0], color[1], color[2], 0.8f); @@ -1981,7 +1979,7 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat last_mouse_position[1] + region->winrct.ymin); immEnd(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); } diff --git a/source/blender/editors/include/ED_info.h b/source/blender/editors/include/ED_info.h index df6b6a20ddc..e3ce494e09a 100644 --- a/source/blender/editors/include/ED_info.h +++ b/source/blender/editors/include/ED_info.h @@ -31,8 +31,13 @@ struct Main; /* info_stats.c */ void ED_info_stats_clear(struct ViewLayer *view_layer); const char *ED_info_statusbar_string(struct Main *bmain, - struct bScreen *screen, - struct bContext *C); + struct Scene *scene, + struct ViewLayer *view_layer); + +const char *ED_info_statistics_string(struct Main *bmain, + struct Scene *scene, + struct ViewLayer *view_layer); + void ED_info_draw_stats( struct Main *bmain, Scene *scene, ViewLayer *view_layer, int x, int *y, int height); diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 29fe766b2d0..ad46dada0c9 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -187,11 +187,7 @@ void ED_area_newspace(struct bContext *C, ScrArea *area, int type, const bool sk void ED_area_prevspace(struct bContext *C, ScrArea *area); void ED_area_swapspace(struct bContext *C, ScrArea *sa1, ScrArea *sa2); int ED_area_headersize(void); -int ED_area_header_alignment_or_fallback(const ScrArea *area, int fallback); -int ED_area_header_alignment(const ScrArea *area); int ED_area_footersize(void); -int ED_area_footer_alignment_or_fallback(const ScrArea *area, int fallback); -int ED_area_footer_alignment(const ScrArea *area); int ED_area_global_size_y(const ScrArea *area); int ED_area_global_min_size_y(const ScrArea *area); int ED_area_global_max_size_y(const ScrArea *area); diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h index c3abde479f1..bfc46534b99 100644 --- a/source/blender/editors/include/ED_sculpt.h +++ b/source/blender/editors/include/ED_sculpt.h @@ -53,6 +53,10 @@ void ED_sculpt_undosys_type(struct UndoType *ut); void ED_sculpt_undo_geometry_begin(struct Object *ob, const char *name); void ED_sculpt_undo_geometry_end(struct Object *ob); +/* Face sets. */ +int ED_sculpt_face_sets_find_next_available_id(struct Mesh *mesh); +void ED_sculpt_face_sets_initialize_none_to_id(struct Mesh *mesh, const int new_id); + /* Undo for changes happening on a base mesh for multires sculpting. * if there is no multires sculpt active regular undo is used. */ void ED_sculpt_undo_push_multires_mesh_begin(struct bContext *C, const char *str); diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h index 1bd9b3063bd..d14731b81b7 100644 --- a/source/blender/editors/include/UI_view2d.h +++ b/source/blender/editors/include/UI_view2d.h @@ -121,9 +121,9 @@ void UI_view2d_curRect_reset(struct View2D *v2d); void UI_view2d_sync(struct bScreen *screen, struct ScrArea *area, struct View2D *v2dcur, int flag); /* Perform all required updates after `v2d->cur` as been modified. - * This includes like validation view validation (UI_view2d_curRect_validate). + * This includes like validation view validation (#UI_view2d_curRect_validate). * - * Current lintent is to use it from user code, such as view navigation and zoom operations. */ + * Current intent is to use it from user code, such as view navigation and zoom operations. */ void UI_view2d_curRect_changed(const struct bContext *C, struct View2D *v2d); void UI_view2d_totRect_set(struct View2D *v2d, int width, int height); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 2ee1ecccd56..e04531bb1dd 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -44,6 +44,8 @@ #include "BLI_utildefines.h" +#include "BLO_readfile.h" + #include "BKE_animsys.h" #include "BKE_context.h" #include "BKE_idprop.h" @@ -69,7 +71,9 @@ #include "RNA_access.h" -#include "BPY_extern.h" +#ifdef WITH_PYTHON +# include "BPY_extern_run.h" +#endif #include "ED_numinput.h" #include "ED_screen.h" @@ -354,9 +358,7 @@ void ui_region_winrct_get_no_margin(const struct ARegion *region, struct rcti *r void UI_block_translate(uiBlock *block, int x, int y) { - uiBut *but; - - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { BLI_rctf_translate(&but->rect, x, y); } @@ -366,12 +368,13 @@ void UI_block_translate(uiBlock *block, int x, int y) static void ui_block_bounds_calc_text(uiBlock *block, float offset) { const uiStyle *style = UI_style_get(); - uiBut *bt, *init_col_bt, *col_bt; + uiBut *col_bt; int i = 0, j, x1addval = offset; UI_fontstyle_set(&style->widget); - for (init_col_bt = bt = block->buttons.first; bt; bt = bt->next) { + uiBut *init_col_bt = block->buttons.first; + LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { if (!ELEM(bt->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_SEPR_SPACER)) { j = BLF_width(style->widget.uifont_id, bt->drawstr, sizeof(bt->drawstr)); @@ -407,7 +410,6 @@ static void ui_block_bounds_calc_text(uiBlock *block, float offset) void ui_block_bounds_calc(uiBlock *block) { - uiBut *bt; int xof; if (BLI_listbase_is_empty(&block->buttons)) { @@ -422,7 +424,7 @@ void ui_block_bounds_calc(uiBlock *block) BLI_rctf_init_minmax(&block->rect); - for (bt = block->buttons.first; bt; bt = bt->next) { + LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { BLI_rctf_union(&block->rect, &bt->rect); } @@ -435,7 +437,7 @@ void ui_block_bounds_calc(uiBlock *block) block->rect.xmax = block->rect.xmin + max_ff(BLI_rctf_size_x(&block->rect), block->minbounds); /* hardcoded exception... but that one is annoying with larger safety */ - bt = block->buttons.first; + uiBut *bt = block->buttons.first; if (bt && STREQLEN(bt->str, "ERROR", 5)) { xof = 10; } @@ -697,9 +699,10 @@ static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut) uiBut *ui_but_find_old(uiBlock *block_old, const uiBut *but_new) { - uiBut *but_old; - for (but_old = block_old->buttons.first; but_old; but_old = but_old->next) { - if (ui_but_equals_old(but_new, but_old)) { + uiBut *but_old = NULL; + LISTBASE_FOREACH (uiBut *, but, &block_old->buttons) { + if (ui_but_equals_old(but_new, but)) { + but_old = but; break; } } @@ -707,9 +710,10 @@ uiBut *ui_but_find_old(uiBlock *block_old, const uiBut *but_new) } uiBut *ui_but_find_new(uiBlock *block_new, const uiBut *but_old) { - uiBut *but_new; - for (but_new = block_new->buttons.first; but_new; but_new = but_new->next) { - if (ui_but_equals_old(but_new, but_old)) { + uiBut *but_new = NULL; + LISTBASE_FOREACH (uiBut *, but, &block_new->buttons) { + if (ui_but_equals_old(but, but_old)) { + but_new = but; break; } } @@ -1461,7 +1465,6 @@ static void ui_but_pie_direction_string(uiBut *but, char *buf, int size) static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) { - uiBut *but; char buf[128]; BLI_assert(block->flag & (UI_BLOCK_LOOP | UI_BLOCK_SHOW_SHORTCUT_ALWAYS)); @@ -1475,7 +1478,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) } if (block->flag & UI_BLOCK_RADIAL) { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->pie_dir != UI_RADIAL_NONE) { ui_but_pie_direction_string(but, buf, sizeof(buf)); ui_but_add_shortcut(but, buf, false); @@ -1483,7 +1486,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) } } else { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (block->flag & UI_BLOCK_SHOW_SHORTCUT_ALWAYS) { /* Skip icon-only buttons (as used in the toolbar). */ if (but->drawstr[0] == '\0') { @@ -1571,10 +1574,7 @@ static void ui_but_extra_operator_icon_free(uiButExtraOpIcon *extra_icon) void ui_but_extra_operator_icons_free(uiBut *but) { - - for (uiButExtraOpIcon *op_icon = but->extra_op_icons.first, *op_icon_next; op_icon; - op_icon = op_icon_next) { - op_icon_next = op_icon->next; + LISTBASE_FOREACH_MUTABLE (uiButExtraOpIcon *, op_icon, &but->extra_op_icons) { ui_but_extra_operator_icon_free(op_icon); } BLI_listbase_clear(&but->extra_op_icons); @@ -1706,7 +1706,6 @@ static void ui_but_predefined_extra_operator_icons_add(uiBut *but) void UI_block_update_from_old(const bContext *C, uiBlock *block) { uiBut *but_old; - uiBut *but; if (!block->oldblock) { return; @@ -1718,7 +1717,7 @@ void UI_block_update_from_old(const bContext *C, uiBlock *block) UI_butstore_update(block); } - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (ui_but_update_from_old_block(C, block, &but, &but_old)) { ui_but_update(but); @@ -1743,7 +1742,6 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x Scene *scene = CTX_data_scene(C); ARegion *region = CTX_wm_region(C); Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); - uiBut *but; BLI_assert(block->active); @@ -1753,7 +1751,7 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x * on matching buttons, we need this to make button event handling non * blocking, while still allowing buttons to be remade each redraw as it * is expected by blender code */ - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { /* temp? Proper check for graying out */ if (but->optype) { wmOperatorType *ot = but->optype; @@ -1873,7 +1871,6 @@ void UI_block_draw(const bContext *C, uiBlock *block) { uiStyle style = *UI_style_get_dpi(); /* XXX pass on as arg */ ARegion *region; - uiBut *but; rcti rect; /* get menu region or area region */ @@ -1887,8 +1884,7 @@ void UI_block_draw(const bContext *C, uiBlock *block) } /* we set this only once */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); /* scale fonts */ ui_fontscale(&style.paneltitle.points, block->aspect); @@ -1939,7 +1935,7 @@ void UI_block_draw(const bContext *C, uiBlock *block) UI_widgetbase_draw_cache_begin(); /* widgets */ - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (!(but->flag & (UI_HIDDEN | UI_SCROLLED))) { ui_but_to_pixelrect(&rect, region, block, but); @@ -2505,17 +2501,18 @@ int ui_but_string_get_max_length(uiBut *but) uiBut *ui_but_drag_multi_edit_get(uiBut *but) { - uiBut *but_iter; + uiBut *return_but = NULL; BLI_assert(but->flag & UI_BUT_DRAG_MULTI); - for (but_iter = but->block->buttons.first; but_iter; but_iter = but_iter->next) { + LISTBASE_FOREACH (uiBut *, but_iter, &but->block->buttons) { if (but_iter->editstr) { + return_but = but_iter; break; } } - return but_iter; + return return_but; } static double ui_get_but_scale_unit(uiBut *but, double value) @@ -2812,7 +2809,7 @@ char *ui_but_string_get_dynamic(uiBut *but, int *r_str_size) } /** - * Report a generic error prefix when evaluating a string with #BPY_execute_string_as_number + * Report a generic error prefix when evaluating a string with #BPY_run_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") @@ -2837,7 +2834,7 @@ static bool ui_number_from_string(bContext *C, const char *str, double *r_value) { bool ok; #ifdef WITH_PYTHON - ok = BPY_execute_string_as_number(C, NULL, str, UI_NUMBER_EVAL_ERROR_PREFIX, r_value); + ok = BPY_run_string_as_number(C, NULL, str, UI_NUMBER_EVAL_ERROR_PREFIX, r_value); #else UNUSED_VARS(C); *r_value = atof(str); @@ -3375,11 +3372,7 @@ void UI_blocklist_free(const bContext *C, ListBase *lb) void UI_blocklist_free_inactive(const bContext *C, ListBase *lb) { - uiBlock *block, *nextblock; - - for (block = lb->first; block; block = nextblock) { - nextblock = block->next; - + LISTBASE_FOREACH_MUTABLE (uiBlock *, block, lb) { if (!block->handle) { if (!block->active) { BLI_remlink(lb, block); @@ -5953,10 +5946,9 @@ uiBut *uiDefIconTextButO(uiBlock *block, int UI_blocklist_min_y_get(ListBase *lb) { - uiBlock *block; int min = 0; - for (block = lb->first; block; block = block->next) { + LISTBASE_FOREACH (uiBlock *, block, lb) { if (block == lb->first || block->rect.ymin < min) { min = block->rect.ymin; } @@ -5973,7 +5965,6 @@ void UI_block_direction_set(uiBlock *block, char direction) /* this call escapes if there's alignment flags */ void UI_block_order_flip(uiBlock *block) { - uiBut *but; float centy, miny = 10000, maxy = -10000; if (U.uiflag & USER_MENUFIXEDORDER) { @@ -5983,7 +5974,7 @@ void UI_block_order_flip(uiBlock *block) return; } - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->drawflag & UI_BUT_ALIGN) { return; } @@ -5996,7 +5987,7 @@ void UI_block_order_flip(uiBlock *block) } /* mirror trick */ centy = (miny + maxy) / 2.0f; - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { but->rect.ymin = centy - (but->rect.ymin - centy); but->rect.ymax = centy - (but->rect.ymax - centy); SWAP(float, but->rect.ymin, but->rect.ymax); @@ -6971,6 +6962,8 @@ void UI_init_userdef(Main *bmain) /* fix saved themes */ init_userdef_do_versions(bmain); uiStyleInit(); + + BLO_sanitize_experimental_features_userpref_blend(&U); } void UI_reinit_font(void) diff --git a/source/blender/editors/interface/interface_align.c b/source/blender/editors/interface/interface_align.c index 4981ef111e0..e92adc8a2ec 100644 --- a/source/blender/editors/interface/interface_align.c +++ b/source/blender/editors/interface/interface_align.c @@ -24,6 +24,7 @@ #include "DNA_screen_types.h" #include "DNA_userdef_types.h" +#include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_rect.h" @@ -385,7 +386,6 @@ static void ui_block_align_but_to_region(uiBut *but, const ARegion *region) */ void ui_block_align_calc(uiBlock *block, const ARegion *region) { - uiBut *but; int num_buttons = 0; const int sides_to_ui_but_align_flags[4] = SIDE_TO_UI_BUT_ALIGN; @@ -398,7 +398,7 @@ void ui_block_align_calc(uiBlock *block, const ARegion *region) /* First loop: we count number of buttons belonging to an align group, * and clear their align flag. * Tabs get some special treatment here, they get aligned to region border. */ - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { /* special case: tabs need to be aligned to a region border, drawflag tells which one */ if (but->type == UI_BTYPE_TAB) { ui_block_align_but_to_region(but, region); @@ -431,7 +431,8 @@ void ui_block_align_calc(uiBlock *block, const ARegion *region) memset(butal_array, 0, sizeof(*butal_array) * (size_t)num_buttons); /* Second loop: we initialize our ButAlign data for each button. */ - for (but = block->buttons.first, butal = butal_array; but; but = but->next) { + butal = butal_array; + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->alignnr != 0) { butal->but = but; butal->borders[LEFT] = &but->rect.xmin; @@ -726,11 +727,10 @@ static void ui_block_align_calc_but(uiBut *first, short nr) void ui_block_align_calc(uiBlock *block, const struct ARegion *UNUSED(region)) { - uiBut *but; short nr; /* align buttons with same align nr */ - for (but = block->buttons.first; but;) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->alignnr) { nr = but->alignnr; ui_block_align_calc_but(but, nr); diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c index 46876fca9a5..59178e209db 100644 --- a/source/blender/editors/interface/interface_context_menu.c +++ b/source/blender/editors/interface/interface_context_menu.c @@ -47,7 +47,10 @@ #include "RNA_access.h" -#include "BPY_extern.h" +#ifdef WITH_PYTHON +# include "BPY_extern.h" +# include "BPY_extern_run.h" +#endif #include "WM_api.h" #include "WM_types.h" @@ -407,7 +410,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, __func__, &expr_result)) { + if (BPY_run_string_as_string(C, expr_imports, expr, __func__, &expr_result)) { STRNCPY(drawstr, expr_result); MEM_freeN(expr_result); } diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 6cd274c8b15..ba878be3dc7 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -161,13 +161,13 @@ void UI_draw_roundbox_aa( GPUBatch *batch = ui_batch_roundbox_widget_get(); GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); - GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params); + GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float(*)[4]) & widget_params); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_batch_draw(batch); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } void UI_draw_roundbox_4fv( @@ -290,13 +290,13 @@ void UI_draw_roundbox_4fv( GPUBatch *batch = ui_batch_roundbox_widget_get(); GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); - GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params); + GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float(*)[4]) & widget_params); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_batch_draw(batch); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } #if 0 @@ -479,14 +479,14 @@ void UI_draw_roundbox_shade_x(bool filled, .alpha_discard = 1.0f, }; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUBatch *batch = ui_batch_roundbox_widget_get(); GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); - GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params); + GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float(*)[4]) & widget_params); GPU_batch_draw(batch); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } #if 0 /* unused */ @@ -748,13 +748,12 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region), # if 0 /* prevent drawing outside widget area */ int scissor[4]; - GPU_scissor_get_i(scissor); + GPU_scissor_get(scissor); GPU_scissor(rect->xmin, rect->ymin, w, h); # endif - GPU_blend(true); /* Combine with premultiplied alpha. */ - GPU_blend_set_func_separate(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA_PREMULT); if (w != ibuf->x || h != ibuf->y) { /* We scale the bitmap, rather than have OGL do a worse job. */ @@ -780,10 +779,7 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region), 1.0f, col); - GPU_blend(false); - /* Reset default. */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_NONE); # if 0 // restore scissortest @@ -830,13 +826,9 @@ void UI_draw_safe_areas(uint pos, } } -static void draw_scope_end(const rctf *rect, GLint *scissor) +static void draw_scope_end(const rctf *rect) { - /* Restore scissor test. */ - GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]); - - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); /* outline */ UI_draw_roundbox_corner_set(UI_CNR_ALL); @@ -866,7 +858,7 @@ static void histogram_draw_one(float r, } GPU_line_smooth(true); - GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE, GPU_ONE, GPU_ONE); + GPU_blend(GPU_BLEND_ADDITIVE); immUniformColor4fv(color); @@ -896,8 +888,7 @@ static void histogram_draw_one(float r, /* curve outline */ immUniformColor4f(0.0f, 0.0f, 0.0f, 0.25f); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); immBegin(GPU_PRIM_LINE_STRIP, res); for (int i = 0; i < res; i++) { float x2 = x + i * (w / (float)res); @@ -930,9 +921,7 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(region), float w = BLI_rctf_size_x(&rect); float h = BLI_rctf_size_y(&rect) * hist->ymax; - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); float color[4]; UI_GetThemeColor4fv(TH_PREVIEW_BACK, color); @@ -942,7 +931,7 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(region), /* need scissor test, histogram can draw outside of boundary */ int scissor[4]; - GPU_scissor_get_i(scissor); + GPU_scissor_get(scissor); GPU_scissor((rect.xmin - 1), (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), @@ -999,8 +988,11 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(region), immUnbindProgram(); + /* Restore scissor test. */ + GPU_scissor(UNPACK4(scissor)); + /* outline */ - draw_scope_end(&rect, scissor); + draw_scope_end(&rect); } #undef HISTOGRAM_TOT_GRID_LINES @@ -1071,9 +1063,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region), /* Flush text cache before changing scissors. */ BLF_batch_draw_flush(); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); float color[4]; UI_GetThemeColor4fv(TH_PREVIEW_BACK, color); @@ -1082,7 +1072,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region), true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color); /* need scissor test, waveform can draw outside of boundary */ - GPU_scissor_get_i(scissor); + GPU_scissor_get(scissor); GPU_scissor((rect.xmin - 1), (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), @@ -1100,9 +1090,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region), /* Flush text cache before drawing things on top. */ BLF_batch_draw_flush(); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -1167,7 +1155,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region), } if (scopes->ok && scopes->waveform_1 != NULL) { - GPU_blend_set_func(GPU_ONE, GPU_ONE); + GPU_blend(GPU_BLEND_ADDITIVE); GPU_point_size(1.0); /* LUMA (1 channel) */ @@ -1257,10 +1245,13 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region), immUnbindProgram(); + /* Restore scissor test. */ + GPU_scissor(UNPACK4(scissor)); + /* outline */ - draw_scope_end(&rect, scissor); + draw_scope_end(&rect); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static float polar_to_x(float center, float diam, float ampli, float angle) @@ -1401,9 +1392,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(region), float alpha = scopes->vecscope_alpha * scopes->vecscope_alpha * scopes->vecscope_alpha; - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); float color[4]; UI_GetThemeColor4fv(TH_PREVIEW_BACK, color); @@ -1413,7 +1402,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(region), /* need scissor test, hvectorscope can draw outside of boundary */ int scissor[4]; - GPU_scissor_get_i(scissor); + GPU_scissor_get(scissor); GPU_scissor((rect.xmin - 1), (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), @@ -1467,7 +1456,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(region), /* pixel point cloud */ const float col[3] = {alpha, alpha, alpha}; - GPU_blend_set_func(GPU_ONE, GPU_ONE); + GPU_blend(GPU_BLEND_ADDITIVE); GPU_point_size(1.0); GPU_matrix_push(); @@ -1481,10 +1470,12 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(region), immUnbindProgram(); + /* Restore scissor test. */ + GPU_scissor(UNPACK4(scissor)); /* outline */ - draw_scope_end(&rect, scissor); + draw_scope_end(&rect); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void ui_draw_colorband_handle_tri_hlight( @@ -1595,7 +1586,7 @@ static void ui_draw_colorband_handle(uint shdr_pos, shdr_pos, x - half_width, y1 - 1, x + half_width, y1 + height, false); /* draw all triangles blended */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); ui_draw_colorband_handle_tri(shdr_pos, x, y1 + height, half_width, half_width, true); @@ -1619,7 +1610,7 @@ static void ui_draw_colorband_handle(uint shdr_pos, immUniformColor3ub(0, 0, 0); ui_draw_colorband_handle_tri_hlight(shdr_pos, x, y1 + height, half_width, half_width); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUniformColor3ub(128, 128, 128); ui_draw_colorband_handle_box( @@ -1677,7 +1668,7 @@ void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); /* layer: color ramp */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); CBData *cbd = coba->data; @@ -1725,7 +1716,7 @@ void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* New format */ format = immVertexFormat(); @@ -1737,7 +1728,7 @@ void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const imm_draw_box_wire_2d(pos_id, x1, y1, x1 + sizex, rect->ymax); /* layer: box outline */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f); immBegin(GPU_PRIM_LINES, 2); @@ -1752,7 +1743,7 @@ void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const immVertex2f(pos_id, x1 + sizex, y1 - 1); immEnd(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* layer: draw handles */ for (int a = 0; a < coba->tot; a++, cbd++) { @@ -1817,10 +1808,10 @@ void ui_draw_but_UNITVEC(uiBut *but, const uiWidgetColors *wcol, const rcti *rec immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3ubv(wcol->inner); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); imm_draw_circle_wire_2d(pos, 0.0f, 0.0f, 1.0f, 32); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); if (use_project_matrix) { @@ -1917,7 +1908,7 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol, /* need scissor test, curve can draw outside of boundary */ int scissor[4]; - GPU_scissor_get_i(scissor); + GPU_scissor_get(scissor); rcti scissor_new = { .xmin = rect->xmin, .ymin = rect->ymin, @@ -1957,13 +1948,11 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol, if (but->a1 == UI_GRAD_H) { /* grid, hsv uses different grid */ - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); ARRAY_SET_ITEMS(color_backdrop, 0, 0, 0, 48.0 / 255.0); immUniformColor4fv(color_backdrop); ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.1666666f); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } else { if (cumap->flag & CUMA_DO_CLIP) { @@ -2076,7 +2065,7 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol, } immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* Curve filled. */ immUniformColor3ubvAlpha(wcol->item, 128); @@ -2109,7 +2098,7 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol, /* Reset state for fill & line. */ GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); /* The points, use aspect to make them visible on edges. */ @@ -2194,7 +2183,7 @@ void ui_draw_but_CURVEPROFILE(ARegion *region, /* Test needed because path can draw outside of boundary. */ int scissor[4]; - GPU_scissor_get_i(scissor); + GPU_scissor_get(scissor); rcti scissor_new = { .xmin = rect->xmin, .ymin = rect->ymin, @@ -2293,7 +2282,7 @@ void ui_draw_but_CURVEPROFILE(ARegion *region, /* Draw the triangles for the profile fill. */ immUniformColor3ubvAlpha((const uchar *)wcol->item, 128); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_polygon_smooth(false); immBegin(GPU_PRIM_TRIS, 3 * tot_triangles); for (i = 0; i < tot_triangles; i++) { @@ -2381,7 +2370,7 @@ void ui_draw_but_CURVEPROFILE(ARegion *region, /* Draw the control points. */ GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_point_size(max_ff(3.0f, min_ff(UI_DPI_FAC / but->block->aspect * 5.0f, 5.0f))); immBegin(GPU_PRIM_POINTS, tot_points); for (i = 0; i < tot_points; i++) { @@ -2395,7 +2384,7 @@ void ui_draw_but_CURVEPROFILE(ARegion *region, /* Draw the handle points. */ if (selected_free_points > 0) { GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_point_size(max_ff(2.0f, min_ff(UI_DPI_FAC / but->block->aspect * 4.0f, 4.0f))); immBegin(GPU_PRIM_POINTS, selected_free_points * 2); for (i = 0; i < tot_points; i++) { @@ -2462,13 +2451,11 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region), int width = BLI_rctf_size_x(&rect) + 1; int height = BLI_rctf_size_y(&rect); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); /* need scissor test, preview image can draw outside of boundary */ int scissor[4]; - GPU_scissor_get_i(scissor); + GPU_scissor_get(scissor); GPU_scissor((rect.xmin - 1), (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), @@ -2593,10 +2580,12 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region), true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color); } + /* Restore scissor test. */ + GPU_scissor(UNPACK4(scissor)); /* outline */ - draw_scope_end(&rect, scissor); + draw_scope_end(&rect); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* ****************************************************** */ @@ -2677,7 +2666,7 @@ static void ui_shadowbox(uint pos, void UI_draw_box_shadow(uchar alpha, float minx, float miny, float maxx, float maxy) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -2697,7 +2686,7 @@ void UI_draw_box_shadow(uchar alpha, float minx, float miny, float maxx, float m immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } void ui_draw_dropshadow( @@ -2723,7 +2712,7 @@ void ui_draw_dropshadow( a = i * aspect; } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); const float dalpha = alpha * 2.0f / 255.0f; float calpha = dalpha; float visibility = 1.0f; @@ -2760,7 +2749,7 @@ void ui_draw_dropshadow( GPUBatch *batch = ui_batch_roundbox_shadow_get(); GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_SHADOW); - GPU_batch_uniform_4fv_array(batch, "parameters", 4, (float *)&widget_params); + GPU_batch_uniform_4fv_array(batch, "parameters", 4, (float(*)[4]) & widget_params); GPU_batch_uniform_1f(batch, "alpha", 1.0f - visibility); GPU_batch_draw(batch); @@ -2774,5 +2763,5 @@ void ui_draw_dropshadow( radius + 0.5f, color); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 455c4fd5073..77cd3e00f3c 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -874,7 +874,7 @@ static void ui_apply_but_autokey(bContext *C, uiBut *but) static void ui_apply_but_funcs_after(bContext *C) { - uiAfterFunc *afterf, after; + uiAfterFunc after; PointerRNA opptr; ListBase funcs; @@ -882,7 +882,7 @@ static void ui_apply_but_funcs_after(bContext *C) funcs = UIAfterFuncs; BLI_listbase_clear(&UIAfterFuncs); - for (afterf = funcs.first; afterf; afterf = after.next) { + LISTBASE_FOREACH_MUTABLE (uiAfterFunc *, afterf, &funcs) { after = *afterf; /* copy to avoid memleak on exit() */ BLI_freelinkN(&funcs, afterf); @@ -1009,14 +1009,12 @@ static void ui_apply_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data) static void ui_apply_but_ROW(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data) { - uiBut *bt; - ui_but_value_set(but, but->hardmax); ui_apply_but_func(C, but); /* states of other row buttons */ - for (bt = block->buttons.first; bt; bt = bt->next) { + LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { if (bt != but && bt->poin == but->poin && ELEM(bt->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) { ui_but_update_edited(bt); } @@ -1180,9 +1178,7 @@ static uiButMultiState *ui_multibut_lookup(uiHandleButtonData *data, const uiBut static void ui_multibut_restore(bContext *C, uiHandleButtonData *data, uiBlock *block) { - uiBut *but; - - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->flag & UI_BUT_DRAG_MULTI) { uiButMultiState *mbut_state = ui_multibut_lookup(data, but); if (mbut_state) { @@ -1235,7 +1231,6 @@ static bool ui_multibut_states_tag(uiBut *but_active, uiHandleButtonData *data, const wmEvent *event) { - uiBut *but; float seg[2][2]; bool changed = false; @@ -1253,7 +1248,7 @@ static bool ui_multibut_states_tag(uiBut *but_active, data->multi_data.has_mbuts = false; /* follow ui_but_find_mouse_over_ex logic */ - for (but = but_active->block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &but_active->block->buttons) { bool drag_prev = false; bool drag_curr = false; @@ -1318,12 +1313,11 @@ static void ui_multibut_states_apply(bContext *C, uiHandleButtonData *data, uiBl const double value_delta = data->value - data->origvalue; const double value_scale = data->multi_data.is_proportional ? (data->value / data->origvalue) : 0.0; - uiBut *but; BLI_assert(data->multi_data.init == BUTTON_MULTI_INIT_ENABLE); BLI_assert(data->multi_data.skip == false); - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->flag & UI_BUT_DRAG_MULTI) { /* mbut_states for delta */ uiButMultiState *mbut_state = ui_multibut_lookup(data, but); @@ -1447,18 +1441,15 @@ static bool ui_drag_toggle_set_xy_xy( /* popups such as layers won't re-evaluate on redraw */ const bool do_check = (region->regiontype == RGN_TYPE_TEMPORARY); bool changed = false; - uiBlock *block; - - for (block = region->uiblocks.first; block; block = block->next) { - uiBut *but; + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { float xy_a_block[2] = {UNPACK2(xy_src)}; float xy_b_block[2] = {UNPACK2(xy_dst)}; ui_window_to_block_fl(region, block, &xy_a_block[0], &xy_a_block[1]); ui_window_to_block_fl(region, block, &xy_b_block[0], &xy_b_block[1]); - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { /* Note: ctrl is always true here because (at least for now) * we always want to consider text control in this case, even when not embossed. */ if (ui_but_is_interactive(but, true)) { @@ -2246,10 +2237,9 @@ static void ui_apply_but( /* only call if event type is EVT_DROP */ static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleButtonData *data) { - wmDrag *wmd; ListBase *drags = event->customdata; /* drop event type has listbase customdata by default */ - for (wmd = drags->first; wmd; wmd = wmd->next) { + LISTBASE_FOREACH (wmDrag *, wmd, drags) { if (wmd->type == WM_DRAG_ID) { /* align these types with UI_but_active_drop_name */ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) { @@ -4178,7 +4168,7 @@ static uiButExtraOpIcon *ui_but_extra_operator_icon_mouse_over_get(uiBut *but, } /* Inverse order, from right to left. */ - for (uiButExtraOpIcon *op_icon = but->extra_op_icons.last; op_icon; op_icon = op_icon->prev) { + LISTBASE_FOREACH_BACKWARD (uiButExtraOpIcon *, op_icon, &but->extra_op_icons) { if ((x > (xmax - icon_size)) && x < xmax) { return op_icon; } @@ -4845,7 +4835,7 @@ static bool ui_numedit_but_NUM(uiBut *but, if (is_float == false) { /* at minimum, moving cursor 2 pixels should change an int button. */ - CLAMP_MIN(non_linear_scale, 0.5f * U.pixelsize); + CLAMP_MIN(non_linear_scale, 0.5f * UI_DPI_FAC); } data->dragf += (((float)(mx - data->draglastx)) / deler) * non_linear_scale; @@ -7777,15 +7767,13 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * static void ui_blocks_set_tooltips(ARegion *region, const bool enable) { - uiBlock *block; - if (!region) { return; } /* we disabled buttons when when they were already shown, and * re-enable them on mouse move */ - for (block = region->uiblocks.first; block; block = block->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { block->tooltipdisabled = !enable; } } @@ -8164,7 +8152,6 @@ static void button_activate_exit( { wmWindow *win = data->window; uiBlock *block = but->block; - uiBut *bt; if (but->type == UI_BTYPE_GRIP) { WM_cursor_modal_restore(win); @@ -8182,7 +8169,7 @@ static void button_activate_exit( #ifdef USE_DRAG_MULTINUM if (data->multi_data.has_mbuts) { - for (bt = block->buttons.first; bt; bt = bt->next) { + LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { if (bt->flag & UI_BUT_DRAG_MULTI) { bt->flag &= ~UI_BUT_DRAG_MULTI; @@ -8238,12 +8225,12 @@ static void button_activate_exit( } /* disable tooltips until mousemove + last active flag */ - for (block = data->region->uiblocks.first; block; block = block->next) { - for (bt = block->buttons.first; bt; bt = bt->next) { + LISTBASE_FOREACH (uiBlock *, block_iter, &data->region->uiblocks) { + LISTBASE_FOREACH (uiBut *, bt, &block_iter->buttons) { bt->flag &= ~UI_BUT_LAST_ACTIVE; } - block->tooltipdisabled = 1; + block_iter->tooltipdisabled = 1; } ui_blocks_set_tooltips(data->region, false); @@ -8308,12 +8295,11 @@ static uiBut *ui_context_button_active(ARegion *region, bool (*but_check_cb)(uiB uiBut *but_found = NULL; while (region) { - uiBlock *block; - uiBut *but, *activebut = NULL; + uiBut *activebut = NULL; /* find active button */ - for (block = region->uiblocks.first; block; block = block->next) { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->active) { activebut = but; } @@ -8436,7 +8422,6 @@ void UI_context_active_but_clear(bContext *C, wmWindow *win, ARegion *region) wmOperator *UI_context_active_operator_get(const struct bContext *C) { ARegion *region_ctx = CTX_wm_region(C); - uiBlock *block; /* background mode */ if (region_ctx == NULL) { @@ -8444,7 +8429,7 @@ wmOperator *UI_context_active_operator_get(const struct bContext *C) } /* scan active regions ui */ - for (block = region_ctx->uiblocks.first; block; block = block->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion_ctx->uiblocks) { if (block->ui_operator) { return block->ui_operator; } @@ -8453,13 +8438,12 @@ wmOperator *UI_context_active_operator_get(const struct bContext *C) /* scan popups */ { bScreen *screen = CTX_wm_screen(C); - ARegion *region; - for (region = screen->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &screen->regionbase) { if (region == region_ctx) { continue; } - for (block = region->uiblocks.first; block; block = block->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { if (block->ui_operator) { return block->ui_operator; } @@ -8478,15 +8462,14 @@ void UI_context_update_anim_flag(const bContext *C) struct Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct( depsgraph, (scene) ? scene->r.cfra : 0.0f); - uiBlock *block; - uiBut *but, *activebut; + uiBut *activebut; while (region) { /* find active button */ activebut = NULL; - for (block = region->uiblocks.first; block; block = block->next) { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { ui_but_anim_flag(but, &anim_eval_context); ui_but_override_flag(CTX_data_main(C), but); if (UI_but_is_decorator(but)) { @@ -8529,11 +8512,8 @@ void UI_context_update_anim_flag(const bContext *C) static uiBut *ui_but_find_open_event(ARegion *region, const wmEvent *event) { - uiBlock *block; - uiBut *but; - - for (block = region->uiblocks.first; block; block = block->next) { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but == event->customdata) { return but; } @@ -10289,10 +10269,8 @@ static int ui_but_pie_menu_apply(bContext *C, static uiBut *ui_block_pie_dir_activate(uiBlock *block, const wmEvent *event, RadialDirection dir) { - uiBut *but; - if ((block->flag & UI_BLOCK_NUMSELECT) && event->val == KM_PRESS) { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->pie_dir == dir && !ELEM(but->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) { return but; } @@ -10324,7 +10302,6 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle { ARegion *region; uiBlock *block; - uiBut *but; float event_xy[2]; double duration; bool is_click_style; @@ -10346,7 +10323,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle is_click_style = (block->pie_data.flags & UI_PIE_CLICK_STYLE); /* if there's an active modal button, don't check events or outside, except for search menu */ - but = ui_region_find_active_but(region); + uiBut *but_active = ui_region_find_active_but(region); if (menu->scrolltimer == NULL) { menu->scrolltimer = WM_event_add_timer( @@ -10364,7 +10341,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle /* Distance from initial point. */ dist = ui_block_calc_pie_segment(block, event_xy); - if (but && button_modal_state(but->active->state)) { + if (but_active && button_modal_state(but_active->active->state)) { retval = ui_handle_menu_button(C, event, menu); } else { @@ -10386,7 +10363,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle block->pie_data.flags |= UI_PIE_ANIMATION_FINISHED; } - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->pie_dir != UI_RADIAL_NONE) { float vec[2]; float center[2]; @@ -10425,7 +10402,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle } if (len_sq < 1.0f) { - but = ui_region_find_active_but(menu->region); + uiBut *but = ui_region_find_active_but(menu->region); if (but) { return ui_but_pie_menu_apply(C, menu, but, true); @@ -10451,7 +10428,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle block->pie_data.flags |= UI_PIE_CLICK_STYLE; } else { - but = ui_region_find_active_but(menu->region); + uiBut *but = ui_region_find_active_but(menu->region); if (but && (U.pie_menu_confirm > 0) && (dist >= U.dpi_fac * (U.pie_menu_threshold + U.pie_menu_confirm))) { @@ -10536,7 +10513,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle case EVT_ZKEY: { if ((event->val == KM_PRESS || event->val == KM_DBL_CLICK) && !IS_EVENT_MOD(event, shift, ctrl, oskey)) { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->menu_key == event->type) { ui_but_pie_button_activate(C, but, menu); } @@ -10569,7 +10546,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle ATTR_FALLTHROUGH; CASE_NUM_TO_DIR(9, UI_RADIAL_NE); { - but = ui_block_pie_dir_activate(block, event, num_dir); + uiBut *but = ui_block_pie_dir_activate(block, event, num_dir); retval = ui_but_pie_button_activate(C, but, menu); break; } @@ -11033,26 +11010,28 @@ bool UI_textbutton_activate_rna(const bContext *C, const void *rna_poin_data, const char *rna_prop_id) { - uiBlock *block; - uiBut *but = NULL; + uiBlock *block_text = NULL; + uiBut *but_text = NULL; - for (block = region->uiblocks.first; block; block = block->next) { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->type == UI_BTYPE_TEXT) { if (but->rnaprop && but->rnapoin.data == rna_poin_data) { if (STREQ(RNA_property_identifier(but->rnaprop), rna_prop_id)) { + block_text = block; + but_text = but; break; } } } } - if (but) { + if (but_text) { break; } } - if (but) { - UI_but_active_only(C, region, block, but); + if (but_text) { + UI_but_active_only(C, region, block_text, but_text); return true; } return false; @@ -11061,23 +11040,25 @@ bool UI_textbutton_activate_rna(const bContext *C, bool UI_textbutton_activate_but(const bContext *C, uiBut *actbut) { ARegion *region = CTX_wm_region(C); - uiBlock *block; - uiBut *but = NULL; + uiBlock *block_text = NULL; + uiBut *but_text = NULL; - for (block = region->uiblocks.first; block; block = block->next) { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but == actbut && but->type == UI_BTYPE_TEXT) { + block_text = block; + but_text = but; break; } } - if (but) { + if (but_text) { break; } } - if (but) { - UI_but_active_only(C, region, block, but); + if (but_text) { + UI_but_active_only(C, region, block_text, but_text); return true; } return false; diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index a7b7bad2fe6..edf66d82cbc 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -1595,7 +1595,7 @@ static void icon_draw_cache_flush_ex(bool only_full_caches) /* We need to flush widget base first to ensure correct ordering. */ UI_widgetbase_draw_cache_flush(); - GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA_PREMULT); if (!only_full_caches || g_icon_draw_cache.normal.calls == ICON_DRAW_CACHE_SIZE) { icon_draw_cache_texture_flush_ex(icongltex.tex[0], &g_icon_draw_cache.normal); @@ -1605,8 +1605,7 @@ static void icon_draw_cache_flush_ex(bool only_full_caches) icon_draw_cache_texture_flush_ex(icongltex.tex[1], &g_icon_draw_cache.border); } - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); } } @@ -1620,9 +1619,9 @@ void UI_icon_draw_cache_end(void) return; } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); icon_draw_cache_flush_ex(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void icon_draw_texture_cached(float x, @@ -1690,7 +1689,7 @@ static void icon_draw_texture(float x, /* We need to flush widget base first to ensure correct ordering. */ UI_widgetbase_draw_cache_flush(); - GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA_PREMULT); float x1, x2, y1, y2; @@ -1726,8 +1725,7 @@ static void icon_draw_texture(float x, GPU_texture_unbind(texture); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); } /* Drawing size for preview images */ @@ -1815,11 +1813,9 @@ static void icon_draw_size(float x, di->data.geom.inverted = invert; } - GPU_blend_set_func_separate( - GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA_PREMULT); icon_draw_rect(x, y, w, h, aspect, w, h, ibuf->rect, alpha, desaturate); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); } else if (di->type == ICON_TYPE_EVENT) { const short event_type = di->data.input.event_type; @@ -1900,12 +1896,10 @@ static void icon_draw_size(float x, } /* Preview images use premultiplied alpha. */ - GPU_blend_set_func_separate( - GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA_PREMULT); icon_draw_rect( x, y, w, h, aspect, pi->w[size], pi->h[size], pi->rect[size], alpha, desaturate); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); } } else if (di->type == ICON_TYPE_GPLAYER) { diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 888cacb64eb..ad76466b67c 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -453,7 +453,7 @@ static uiLayout *ui_item_local_sublayout(uiLayout *test, uiLayout *layout, bool static void ui_layer_but_cb(bContext *C, void *arg_but, void *arg_index) { wmWindow *win = CTX_wm_window(C); - uiBut *but = arg_but, *cbut; + uiBut *but = arg_but; PointerRNA *ptr = &but->rnapoin; PropertyRNA *prop = but->rnaprop; int i, index = POINTER_AS_INT(arg_index); @@ -471,7 +471,7 @@ static void ui_layer_but_cb(bContext *C, void *arg_but, void *arg_index) RNA_property_update(C, ptr, prop); - for (cbut = but->block->buttons.first; cbut; cbut = cbut->next) { + LISTBASE_FOREACH (uiBut *, cbut, &but->block->buttons) { ui_but_update(cbut); } } @@ -1072,8 +1072,7 @@ void UI_context_active_but_prop_get_filebrowser(const bContext *C, bool *r_is_userdef) { ARegion *region = CTX_wm_menu(C) ? CTX_wm_menu(C) : CTX_wm_region(C); - uiBlock *block; - uiBut *but, *prevbut = NULL; + uiBut *prevbut = NULL; memset(r_ptr, 0, sizeof(*r_ptr)); *r_prop = NULL; @@ -1084,8 +1083,8 @@ void UI_context_active_but_prop_get_filebrowser(const bContext *C, return; } - for (block = region->uiblocks.first; block; block = block->next) { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but && but->rnapoin.data) { if (RNA_property_type(but->rnaprop) == PROP_STRING) { prevbut = but; @@ -3515,14 +3514,13 @@ void uiItemTabsEnumR_prop( /* single-row layout */ static void ui_litem_estimate_row(uiLayout *litem) { - uiItem *item; int itemw, itemh; bool min_size_flag = true; litem->w = 0; litem->h = 0; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); min_size_flag = min_size_flag && (item->flag & UI_ITEM_FIXED_SIZE); @@ -3547,7 +3545,7 @@ static int ui_litem_min_width(int itemw) static void ui_litem_layout_row(uiLayout *litem) { - uiItem *item, *last_free_item = NULL; + uiItem *last_free_item = NULL; int x, y, w, tot, totw, neww, newtotw, itemw, minw, itemh, offset; int fixedw, freew, fixedx, freex, flag = 0, lastw = 0; float extra_pixel; @@ -3558,7 +3556,7 @@ static void ui_litem_layout_row(uiLayout *litem) totw = 0; tot = 0; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); totw += itemw; tot++; @@ -3581,7 +3579,7 @@ static void ui_litem_layout_row(uiLayout *litem) newtotw = totw; extra_pixel = 0.0f; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { if (item->flag & UI_ITEM_AUTO_FIXED_SIZE) { continue; } @@ -3633,7 +3631,7 @@ static void ui_litem_layout_row(uiLayout *litem) extra_pixel = 0.0f; x = litem->x; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); minw = ui_litem_min_width(itemw); @@ -3682,7 +3680,7 @@ static void ui_litem_layout_row(uiLayout *litem) if (extra_pixel > 0 && litem->alignment == UI_LAYOUT_ALIGN_EXPAND && last_free_item && last_item && last_item->flag & UI_ITEM_AUTO_FIXED_SIZE) { ui_item_move(last_free_item, 0, extra_pixel); - for (item = last_free_item->next; item; item = item->next) { + for (uiItem *item = last_free_item->next; item; item = item->next) { ui_item_move(item, extra_pixel, extra_pixel); } } @@ -3696,14 +3694,13 @@ static void ui_litem_layout_row(uiLayout *litem) /* single-column layout */ static void ui_litem_estimate_column(uiLayout *litem, bool is_box) { - uiItem *item; int itemw, itemh; bool min_size_flag = true; litem->w = 0; litem->h = 0; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); min_size_flag = min_size_flag && (item->flag & UI_ITEM_FIXED_SIZE); @@ -3723,13 +3720,12 @@ static void ui_litem_estimate_column(uiLayout *litem, bool is_box) static void ui_litem_layout_column(uiLayout *litem, bool is_box) { - uiItem *item; int itemh, x, y; x = litem->x; y = litem->y; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, NULL, &itemh); y -= itemh; @@ -3789,7 +3785,6 @@ static bool ui_item_is_radial_drawable(uiButtonItem *bitem) static void ui_litem_layout_radial(uiLayout *litem) { - uiItem *item; int itemh, itemw, x, y; int itemnum = 0; int totitems = 0; @@ -3807,7 +3802,7 @@ static void ui_litem_layout_radial(uiLayout *litem) int minx = x, miny = y, maxx = x, maxy = y; /* first count total items */ - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { totitems++; } @@ -3815,7 +3810,7 @@ static void ui_litem_layout_radial(uiLayout *litem) litem->root->block->pie_data.flags |= UI_PIE_DEGREES_RANGE_LARGE; } - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { /* not all button types are drawn in a radial menu, do filtering here */ if (ui_item_is_radial_displayable(item)) { RadialDirection dir; @@ -3965,14 +3960,13 @@ static void ui_litem_estimate_column_flow(uiLayout *litem) { const uiStyle *style = litem->root->style; uiLayoutItemFlow *flow = (uiLayoutItemFlow *)litem; - uiItem *item; int col, x, y, emh, emy, miny, itemw, itemh, maxw = 0; int toth, totitem; /* compute max needed width and total height */ toth = 0; totitem = 0; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); maxw = MAX2(maxw, itemw); toth += itemh; @@ -4004,7 +3998,7 @@ static void ui_litem_estimate_column_flow(uiLayout *litem) /* create column per column */ col = 0; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); y -= itemh + style->buttonspacey; @@ -4030,14 +4024,13 @@ static void ui_litem_layout_column_flow(uiLayout *litem) { const uiStyle *style = litem->root->style; uiLayoutItemFlow *flow = (uiLayoutItemFlow *)litem; - uiItem *item; int col, x, y, w, emh, emy, miny, itemw, itemh; int toth, totitem; /* compute max needed width and total height */ toth = 0; totitem = 0; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); toth += itemh; totitem++; @@ -4055,7 +4048,7 @@ static void ui_litem_layout_column_flow(uiLayout *litem) /* create column per column */ col = 0; w = (litem->w - (flow->totcol - 1) * style->columnspace) / flow->totcol; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); itemw = (litem->alignment == UI_LAYOUT_ALIGN_EXPAND) ? w : min_ii(w, itemw); @@ -4121,9 +4114,6 @@ static void ui_litem_grid_flow_compute(ListBase *items, UILayoutGridFlowInput *parameters, UILayoutGridFlowOutput *results) { - uiItem *item; - int i; - float tot_w = 0.0f, tot_h = 0.0f; float global_avg_w = 0.0f, global_totweight_w = 0.0f; int global_max_h = 0; @@ -4163,7 +4153,8 @@ static void ui_litem_grid_flow_compute(ListBase *items, memset(max_h, 0, sizeof(*max_h) * parameters->tot_rows); } - for (i = 0, item = items->first; item; item = item->next, i++) { + int i = 0; + LISTBASE_FOREACH (uiItem *, item, items) { int item_w, item_h; ui_item_size(item, &item_w, &item_h); @@ -4186,6 +4177,7 @@ static void ui_litem_grid_flow_compute(ListBase *items, if (results->tot_items) { (*results->tot_items)++; } + i++; } /* Finalize computing of column average sizes */ @@ -4394,10 +4386,8 @@ static void ui_litem_estimate_grid_flow(uiLayout *litem) static void ui_litem_layout_grid_flow(uiLayout *litem) { - int i; const uiStyle *style = litem->root->style; uiLayoutItemGridFlow *gflow = (uiLayoutItemGridFlow *)litem; - uiItem *item; if (gflow->tot_items == 0) { litem->w = litem->h = 0; @@ -4436,7 +4426,8 @@ static void ui_litem_layout_grid_flow(uiLayout *litem) .heights_array = heights, })); - for (item = litem->items.first, i = 0; item; item = item->next, i++) { + int i; + LISTBASE_FOREACH_INDEX (uiItem *, item, &litem->items, i) { const int col = gflow->row_major ? i % gflow->tot_columns : i / gflow->tot_rows; const int row = gflow->row_major ? i / gflow->tot_columns : i % gflow->tot_rows; int item_w, item_h; @@ -4459,7 +4450,6 @@ static void ui_litem_layout_grid_flow(uiLayout *litem) /* free layout */ static void ui_litem_estimate_absolute(uiLayout *litem) { - uiItem *item; int itemx, itemy, itemw, itemh, minx, miny; minx = 1e6; @@ -4467,7 +4457,7 @@ static void ui_litem_estimate_absolute(uiLayout *litem) litem->w = 0; litem->h = 0; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_offset(item, &itemx, &itemy); ui_item_size(item, &itemw, &itemh); @@ -4484,7 +4474,6 @@ static void ui_litem_estimate_absolute(uiLayout *litem) static void ui_litem_layout_absolute(uiLayout *litem) { - uiItem *item; float scalex = 1.0f, scaley = 1.0f; int x, y, newx, newy, itemx, itemy, itemh, itemw, minx, miny, totw, toth; @@ -4493,7 +4482,7 @@ static void ui_litem_layout_absolute(uiLayout *litem) totw = 0; toth = 0; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_offset(item, &itemx, &itemy); ui_item_size(item, &itemw, &itemh); @@ -4517,7 +4506,7 @@ static void ui_litem_layout_absolute(uiLayout *litem) x = litem->x; y = litem->y - scaley * toth; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_offset(item, &itemx, &itemy); ui_item_size(item, &itemw, &itemh); @@ -4552,7 +4541,6 @@ static void ui_litem_estimate_split(uiLayout *litem) static void ui_litem_layout_split(uiLayout *litem) { uiLayoutItemSplit *split = (uiLayoutItemSplit *)litem; - uiItem *item; float percentage, extra_pixel = 0.0f; const int tot = BLI_listbase_count(&litem->items); int itemh, x, y, w, colw = 0; @@ -4570,7 +4558,7 @@ static void ui_litem_layout_split(uiLayout *litem) colw = w * percentage; colw = MAX2(colw, 0); - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, NULL, &itemh); ui_item_position(item, x, y - itemh, colw, itemh); @@ -4595,13 +4583,12 @@ static void ui_litem_layout_split(uiLayout *litem) /* overlap layout */ static void ui_litem_estimate_overlap(uiLayout *litem) { - uiItem *item; int itemw, itemh; litem->w = 0; litem->h = 0; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); litem->w = MAX2(itemw, litem->w); @@ -4611,13 +4598,12 @@ static void ui_litem_estimate_overlap(uiLayout *litem) static void ui_litem_layout_overlap(uiLayout *litem) { - uiItem *item; int itemw, itemh, x, y; x = litem->x; y = litem->y; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); ui_item_position(item, x, y - itemh, litem->w, itemh); @@ -4775,7 +4761,6 @@ static uiLayoutItemBx *ui_layout_box(uiLayout *layout, int type) uiLayout *uiLayoutRadial(uiLayout *layout) { uiLayout *litem; - uiItem *item; /* radial layouts are only valid for radial menus */ if (layout->root->type != UI_LAYOUT_PIEMENU) { @@ -4783,7 +4768,7 @@ uiLayout *uiLayoutRadial(uiLayout *layout) } /* only one radial wheel per root layout is allowed, so check and return that, if it exists */ - for (item = layout->root->layout->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &layout->root->layout->items) { litem = (uiLayout *)item; if (litem->item.type == ITEM_LAYOUT_RADIAL) { UI_block_layout_set_current(layout->root->block, litem); @@ -4813,8 +4798,7 @@ uiLayout *uiLayoutBox(uiLayout *layout) */ void ui_layout_list_set_labels_active(uiLayout *layout) { - uiButtonItem *bitem; - for (bitem = layout->items.first; bitem; bitem = bitem->item.next) { + LISTBASE_FOREACH (uiButtonItem *, bitem, &layout->items) { if (bitem->item.type != ITEM_BUTTON) { ui_layout_list_set_labels_active((uiLayout *)(&bitem->item)); } @@ -5055,10 +5039,9 @@ int uiLayoutGetEmboss(uiLayout *layout) static void ui_item_scale(uiLayout *litem, const float scale[2]) { - uiItem *item; int x, y, w, h; - for (item = litem->items.last; item; item = item->prev) { + LISTBASE_FOREACH_BACKWARD (uiItem *, item, &litem->items) { if (item->type != ITEM_BUTTON) { uiLayout *subitem = (uiLayout *)item; ui_item_scale(subitem, scale); @@ -5083,12 +5066,10 @@ static void ui_item_scale(uiLayout *litem, const float scale[2]) static void ui_item_estimate(uiItem *item) { - uiItem *subitem; - if (item->type != ITEM_BUTTON) { uiLayout *litem = (uiLayout *)item; - for (subitem = litem->items.first; subitem; subitem = subitem->next) { + LISTBASE_FOREACH (uiItem *, subitem, &litem->items) { ui_item_estimate(subitem); } @@ -5146,11 +5127,10 @@ static void ui_item_estimate(uiItem *item) static void ui_item_align(uiLayout *litem, short nr) { - uiItem *item; uiButtonItem *bitem; uiLayoutItemBx *box; - for (item = litem->items.last; item; item = item->prev) { + LISTBASE_FOREACH_BACKWARD (uiItem *, item, &litem->items) { if (item->type == ITEM_BUTTON) { bitem = (uiButtonItem *)item; #ifndef USE_UIBUT_SPATIAL_ALIGN @@ -5182,10 +5162,9 @@ static void ui_item_align(uiLayout *litem, short nr) static void ui_item_flag(uiLayout *litem, int flag) { - uiItem *item; uiButtonItem *bitem; - for (item = litem->items.last; item; item = item->prev) { + LISTBASE_FOREACH_BACKWARD (uiItem *, item, &litem->items) { if (item->type == ITEM_BUTTON) { bitem = (uiButtonItem *)item; bitem->but->flag |= flag; @@ -5198,8 +5177,6 @@ static void ui_item_flag(uiLayout *litem, int flag) static void ui_item_layout(uiItem *item) { - uiItem *subitem; - if (item->type != ITEM_BUTTON) { uiLayout *litem = (uiLayout *)item; @@ -5252,7 +5229,7 @@ static void ui_item_layout(uiItem *item) break; } - for (subitem = litem->items.first; subitem; subitem = subitem->next) { + LISTBASE_FOREACH (uiItem *, subitem, &litem->items) { if (item->flag & UI_ITEM_BOX_ITEM) { subitem->flag |= UI_ITEM_BOX_ITEM; } @@ -5286,11 +5263,7 @@ static void ui_layout_end(uiBlock *block, uiLayout *layout, int *r_x, int *r_y) static void ui_layout_free(uiLayout *layout) { - uiItem *item, *next; - - for (item = layout->items.first; item; item = next) { - next = item->next; - + LISTBASE_FOREACH_MUTABLE (uiItem *, item, &layout->items) { if (item->type == ITEM_BUTTON) { MEM_freeN(item); } @@ -5474,8 +5447,6 @@ void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv) void UI_block_layout_resolve(uiBlock *block, int *r_x, int *r_y) { - uiLayoutRoot *root; - BLI_assert(block->active); if (r_x) { @@ -5487,7 +5458,7 @@ void UI_block_layout_resolve(uiBlock *block, int *r_x, int *r_y) block->curlayout = NULL; - for (root = block->layouts.first; root; root = root->next) { + LISTBASE_FOREACH (uiLayoutRoot *, root, &block->layouts) { ui_layout_add_padding_button(root); /* NULL in advance so we don't interfere when adding button */ diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 5a49f3e70d0..e47761236ca 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -715,8 +715,7 @@ static void ui_context_selected_bones_via_pose(bContext *C, ListBase *r_lb) lb = CTX_data_collection_get(C, "selected_pose_bones"); if (!BLI_listbase_is_empty(&lb)) { - CollectionPointerLink *link; - for (link = lb.first; link; link = link->next) { + LISTBASE_FOREACH (CollectionPointerLink *, link, &lb) { bPoseChannel *pchan = link->ptr.data; RNA_pointer_create(link->ptr.owner_id, &RNA_Bone, pchan->bone, &link->ptr); } @@ -843,12 +842,10 @@ bool UI_context_copy_to_selected_list(bContext *C, /* Now filter by type */ if (node) { - CollectionPointerLink *link, *link_next; lb = CTX_data_collection_get(C, "selected_nodes"); - for (link = lb.first; link; link = link_next) { + LISTBASE_FOREACH_MUTABLE (CollectionPointerLink *, link, &lb) { bNode *node_data = link->ptr.data; - link_next = link->next; if (node_data->type != node->type) { BLI_remlink(&lb, link); @@ -876,9 +873,7 @@ bool UI_context_copy_to_selected_list(bContext *C, /* de-duplicate obdata */ if (!BLI_listbase_is_empty(&lb)) { - CollectionPointerLink *link, *link_next; - - for (link = lb.first; link; link = link->next) { + LISTBASE_FOREACH (CollectionPointerLink *, link, &lb) { Object *ob = (Object *)link->ptr.owner_id; if (ob->data) { ID *id_data = ob->data; @@ -886,10 +881,9 @@ bool UI_context_copy_to_selected_list(bContext *C, } } - for (link = lb.first; link; link = link_next) { + LISTBASE_FOREACH_MUTABLE (CollectionPointerLink *, link, &lb) { Object *ob = (Object *)link->ptr.owner_id; ID *id_data = ob->data; - link_next = link->next; if ((id_data == NULL) || (id_data->tag & LIB_TAG_DOIT) == 0 || ID_IS_LINKED(id_data) || (GS(id_data->name) != id_code)) { @@ -970,12 +964,11 @@ static bool copy_to_selected_button(bContext *C, bool all, bool poll) if (ptr.data && prop) { char *path = NULL; bool use_path_from_id; - CollectionPointerLink *link; ListBase lb = {NULL}; if (UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path) && !BLI_listbase_is_empty(&lb)) { - for (link = lb.first; link; link = link->next) { + LISTBASE_FOREACH (CollectionPointerLink *, link, &lb) { if (link->ptr.data != ptr.data) { if (use_path_from_id) { /* Path relative to ID. */ @@ -1299,13 +1292,14 @@ static int editsource_text_edit(bContext *C, const int line) { struct Main *bmain = CTX_data_main(C); - Text *text; + Text *text = NULL; /* Developers may wish to copy-paste to an external editor. */ printf("%s:%d\n", filepath, line); - for (text = bmain->texts.first; text; text = text->id.next) { - if (text->filepath && BLI_path_cmp(text->filepath, filepath) == 0) { + LISTBASE_FOREACH (Text *, text_iter, &bmain->texts) { + if (text_iter->filepath && BLI_path_cmp(text_iter->filepath, filepath) == 0) { + text = text_iter; break; } } diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index d334007a097..a70bcd208ab 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -1000,7 +1000,7 @@ void ui_draw_aligned_panel(uiStyle *style, /* Mimick the border between aligned box widgets for the bottom of the header. */ if (!(is_closed_x || is_closed_y)) { immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor4ubv(box_wcol->outline); immRectf(pos, rect->xmin, headrect.ymin - U.pixelsize, rect->xmax, headrect.ymin); @@ -1013,7 +1013,7 @@ void ui_draw_aligned_panel(uiStyle *style, rect->xmax, headrect.ymin - U.pixelsize - 1); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); } } @@ -1025,7 +1025,7 @@ void ui_draw_aligned_panel(uiStyle *style, float y = headrect.ymax; immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* draw with background color */ immUniformThemeColor(TH_PANEL_HEADER); @@ -1041,7 +1041,7 @@ void ui_draw_aligned_panel(uiStyle *style, immEnd(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); } @@ -1055,7 +1055,7 @@ void ui_draw_aligned_panel(uiStyle *style, uchar col_title[4]; panel_title_color_get(show_background, col_title); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_icon_draw_ex(headrect.xmax - ((PNL_ICON * 2.2f) / block->aspect), headrect.ymin + (5.0f / block->aspect), (panel->flag & PNL_PIN) ? ICON_PINNED : ICON_UNPINNED, @@ -1064,7 +1064,7 @@ void ui_draw_aligned_panel(uiStyle *style, 0.0f, col_title, false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* horizontal title */ @@ -1134,7 +1134,7 @@ void ui_draw_aligned_panel(uiStyle *style, } immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* Draw panel backdrop if it wasn't already been drawn by the single opaque round box earlier. * Note: Sub-panels blend with panels, so they can't be opaque. */ @@ -2366,7 +2366,7 @@ void UI_panel_category_draw_all(ARegion *region, const char *category_id_active) /* draw the background */ if (is_alpha) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor4ubv(theme_col_tab_bg); } else { @@ -2383,7 +2383,7 @@ void UI_panel_category_draw_all(ARegion *region, const char *category_id_active) } if (is_alpha) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } immUnbindProgram(); @@ -2403,7 +2403,7 @@ void UI_panel_category_draw_all(ARegion *region, const char *category_id_active) const bool is_active = STREQ(category_id, category_id_active); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); #ifdef USE_FLAT_INACTIVE if (is_active) @@ -2479,7 +2479,7 @@ void UI_panel_category_draw_all(ARegion *region, const char *category_id_active) /* main tab title */ BLF_draw(fontid, category_id_draw, category_draw_len); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* tab blackline remaining (last tab) */ pos = GPU_vertformat_attr_add( diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c index edb5d51a392..8648a54f7d5 100644 --- a/source/blender/editors/interface/interface_query.c +++ b/source/blender/editors/interface/interface_query.c @@ -276,7 +276,7 @@ uiBut *ui_but_find_mouse_over_ex(ARegion *region, const int x, const int y, cons float mx = x, my = y; ui_window_to_block_fl(region, block, &mx, &my); - for (uiBut *but = block->buttons.last; but; but = but->prev) { + LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) { if (ui_but_is_interactive(but, labeledit)) { if (but->pie_dir != UI_RADIAL_NONE) { if (ui_but_isect_pie_seg(block, but)) { @@ -324,7 +324,7 @@ uiBut *ui_but_find_rect_over(const struct ARegion *region, const rcti *rect_px) rctf rect_block; ui_window_to_block_rctf(region, block, &rect_block, &rect_px_fl); - for (uiBut *but = block->buttons.last; but; but = but->prev) { + LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) { if (ui_but_is_interactive(but, labeledit)) { /* No pie menu support. */ BLI_assert(but->pie_dir == UI_RADIAL_NONE); @@ -354,7 +354,7 @@ uiBut *ui_list_find_mouse_over_ex(ARegion *region, int x, int y) LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { float mx = x, my = y; ui_window_to_block_fl(region, block, &mx, &my); - for (uiBut *but = block->buttons.last; but; but = but->prev) { + LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) { if (but->type == UI_BTYPE_LISTBOX && ui_but_contains_pt(but, mx, my)) { return but; } @@ -399,14 +399,10 @@ uiBut *ui_but_next(uiBut *but) uiBut *ui_but_first(uiBlock *block) { - uiBut *but; - - but = block->buttons.first; - while (but) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (ui_but_is_editable(but)) { return but; } - but = but->next; } return NULL; } diff --git a/source/blender/editors/interface/interface_region_color_picker.c b/source/blender/editors/interface/interface_region_color_picker.c index 0d1b483716e..8bc0f18886b 100644 --- a/source/blender/editors/interface/interface_region_color_picker.c +++ b/source/blender/editors/interface/interface_region_color_picker.c @@ -183,7 +183,6 @@ static void ui_update_color_picker_buts_rgb(uiBut *from_but, ColorPicker *cpicker, const float rgb[3]) { - uiBut *bt; float *hsv = cpicker->color_data; /* Convert from RGB to HSV in perceptually linear space. */ @@ -196,7 +195,7 @@ static void ui_update_color_picker_buts_rgb(uiBut *from_but, /* this updates button strings, * is hackish... but button pointers are on stack of caller function */ - for (bt = block->buttons.first; bt; bt = bt->next) { + LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { if (bt->custom_data != cpicker) { continue; } @@ -849,9 +848,7 @@ static int ui_colorpicker_small_wheel_cb(const bContext *UNUSED(C), } if (add != 0.0f) { - uiBut *but; - - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->type == UI_BTYPE_HSVCUBE && but->active == NULL) { uiPopupBlockHandle *popup = block->handle; float rgb[3]; diff --git a/source/blender/editors/interface/interface_region_menu_popup.c b/source/blender/editors/interface/interface_region_menu_popup.c index 077e8888d53..881ba58174b 100644 --- a/source/blender/editors/interface/interface_region_menu_popup.c +++ b/source/blender/editors/interface/interface_region_menu_popup.c @@ -130,9 +130,10 @@ static uiBut *ui_popup_menu_memory__internal(uiBlock *block, uiBut *but) } /* get */ - for (but = block->buttons.first; but; but = but->next) { - if (mem[hash_mod] == ui_popup_string_hash(but->str, but->flag & UI_BUT_HAS_SEP_CHAR)) { - return but; + LISTBASE_FOREACH (uiBut *, but_iter, &block->buttons) { + if (mem[hash_mod] == + ui_popup_string_hash(but_iter->str, but_iter->flag & UI_BUT_HAS_SEP_CHAR)) { + return but_iter; } } @@ -232,7 +233,6 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT); if (pup->popup) { - uiBut *bt; int offset[2]; uiBut *but_activate = NULL; @@ -241,6 +241,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi UI_block_direction_set(block, direction); /* offset the mouse position, possibly based on earlier selection */ + uiBut *bt; if ((block->flag & UI_BLOCK_POPUP_MEMORY) && (bt = ui_popup_menu_memory_get(block))) { /* position mouse on last clicked item, at 0.8*width of the * button, so it doesn't overlap the text too much, also note @@ -257,15 +258,16 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi /* position mouse at 0.8*width of the button and below the tile * on the first item */ offset[0] = 0; - for (bt = block->buttons.first; bt; bt = bt->next) { - offset[0] = min_ii(offset[0], -(bt->rect.xmin + 0.8f * BLI_rctf_size_x(&bt->rect))); + LISTBASE_FOREACH (uiBut *, but_iter, &block->buttons) { + offset[0] = min_ii(offset[0], + -(but_iter->rect.xmin + 0.8f * BLI_rctf_size_x(&but_iter->rect))); } offset[1] = 2.1 * UI_UNIT_Y; - for (bt = block->buttons.first; bt; bt = bt->next) { - if (ui_but_is_editable(bt)) { - but_activate = bt; + LISTBASE_FOREACH (uiBut *, but_iter, &block->buttons) { + if (ui_but_is_editable(but_iter)) { + but_activate = but_iter; break; } } @@ -284,17 +286,10 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi else { /* for a header menu we set the direction automatic */ if (!pup->slideout && flip) { - ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); - if (area && region) { - if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) { - if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_header_alignment(area)) == RGN_ALIGN_BOTTOM) { - UI_block_direction_set(block, UI_DIR_UP); - UI_block_order_flip(block); - } - } - if (region->regiontype == RGN_TYPE_FOOTER) { - if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_footer_alignment(area)) == RGN_ALIGN_BOTTOM) { + if (region) { + if (RGN_TYPE_IS_HEADER_ANY(region->regiontype)) { + if (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_BOTTOM) { UI_block_direction_set(block, UI_DIR_UP); UI_block_order_flip(block); } @@ -506,8 +501,6 @@ uiLayout *UI_popup_menu_layout(uiPopupMenu *pup) void UI_popup_menu_reports(bContext *C, ReportList *reports) { - Report *report; - uiPopupMenu *pup = NULL; uiLayout *layout; @@ -515,7 +508,7 @@ void UI_popup_menu_reports(bContext *C, ReportList *reports) return; } - for (report = reports->list.first; report; report = report->next) { + LISTBASE_FOREACH (Report *, report, &reports->list) { int icon; const char *msg, *msg_next; diff --git a/source/blender/editors/interface/interface_region_popover.c b/source/blender/editors/interface/interface_region_popover.c index 0ad7e570e80..43233205877 100644 --- a/source/blender/editors/interface/interface_region_popover.c +++ b/source/blender/editors/interface/interface_region_popover.c @@ -171,7 +171,6 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v } if (!slideout) { - ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); if (region && region->panels.first) { @@ -180,14 +179,9 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X); } /* Prefer popover from header to be positioned into the editor. */ - else if (area && region) { - if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) { - if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_header_alignment(area)) == RGN_ALIGN_BOTTOM) { - UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X); - } - } - if (region->regiontype == RGN_TYPE_FOOTER) { - if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_footer_alignment(area)) == RGN_ALIGN_BOTTOM) { + else if (region) { + if (RGN_TYPE_IS_HEADER_ANY(region->regiontype)) { + if (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_BOTTOM) { UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X); } } @@ -209,11 +203,12 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v if (!handle->refresh) { uiBut *but = NULL; uiBut *but_first = NULL; - for (but = block->buttons.first; but; but = but->next) { - if ((but_first == NULL) && ui_but_is_editable(but)) { - but_first = but; + LISTBASE_FOREACH (uiBut *, but_iter, &block->buttons) { + if ((but_first == NULL) && ui_but_is_editable(but_iter)) { + but_first = but_iter; } - if (but->flag & (UI_SELECT | UI_SELECT_DRAW)) { + if (but_iter->flag & (UI_SELECT | UI_SELECT_DRAW)) { + but = but_iter; break; } } diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c index 13c85952f52..947bdca4f9e 100644 --- a/source/blender/editors/interface/interface_region_popup.c +++ b/source/blender/editors/interface/interface_region_popup.c @@ -59,8 +59,6 @@ */ void ui_popup_translate(ARegion *region, const int mdiff[2]) { - uiBlock *block; - BLI_rcti_translate(®ion->winrct, UNPACK2(mdiff)); ED_region_update_rect(region); @@ -68,13 +66,12 @@ void ui_popup_translate(ARegion *region, const int mdiff[2]) ED_region_tag_redraw(region); /* update blocks */ - for (block = region->uiblocks.first; block; block = block->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { uiPopupBlockHandle *handle = block->handle; /* Make empty, will be initialized on next use, see T60608. */ BLI_rctf_init(&handle->prev_block_rect, 0, 0, 0, 0); - uiSafetyRct *saferct; - for (saferct = block->saferct.first; saferct; saferct = saferct->next) { + LISTBASE_FOREACH (uiSafetyRct *, saferct, &block->saferct) { BLI_rctf_translate(&saferct->parent, UNPACK2(mdiff)); BLI_rctf_translate(&saferct->safety, UNPACK2(mdiff)); } @@ -373,16 +370,13 @@ static void ui_block_region_refresh(const bContext *C, ARegion *region) { ScrArea *ctx_area = CTX_wm_area(C); ARegion *ctx_region = CTX_wm_region(C); - uiBlock *block; if (region->do_draw & RGN_REFRESH_UI) { ScrArea *handle_ctx_area; ARegion *handle_ctx_region; - uiBlock *block_next; region->do_draw &= ~RGN_REFRESH_UI; - for (block = region->uiblocks.first; block; block = block_next) { - block_next = block->next; + LISTBASE_FOREACH_MUTABLE (uiBlock *, block, ®ion->uiblocks) { uiPopupBlockHandle *handle = block->handle; if (handle->can_refresh) { @@ -409,9 +403,7 @@ static void ui_block_region_refresh(const bContext *C, ARegion *region) static void ui_block_region_draw(const bContext *C, ARegion *region) { - uiBlock *block; - - for (block = region->uiblocks.first; block; block = block->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { UI_block_draw(C, block); } } @@ -441,7 +433,6 @@ static void ui_block_region_popup_window_listener(wmWindow *UNUSED(win), static void ui_popup_block_clip(wmWindow *window, uiBlock *block) { - uiBut *bt; const float xmin_orig = block->rect.xmin; const int margin = UI_SCREEN_MARGIN; int winx, winy; @@ -475,7 +466,7 @@ static void ui_popup_block_clip(wmWindow *window, uiBlock *block) /* ensure menu items draw inside left/right boundary */ const float xofs = block->rect.xmin - xmin_orig; - for (bt = block->buttons.first; bt; bt = bt->next) { + LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { bt->rect.xmin += xofs; bt->rect.xmax += xofs; } @@ -483,11 +474,9 @@ static void ui_popup_block_clip(wmWindow *window, uiBlock *block) void ui_popup_block_scrolltest(uiBlock *block) { - uiBut *bt; - block->flag &= ~(UI_BLOCK_CLIPBOTTOM | UI_BLOCK_CLIPTOP); - for (bt = block->buttons.first; bt; bt = bt->next) { + LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { bt->flag &= ~UI_SCROLLED; } @@ -496,7 +485,7 @@ void ui_popup_block_scrolltest(uiBlock *block) } /* mark buttons that are outside boundary */ - for (bt = block->buttons.first; bt; bt = bt->next) { + LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { if (bt->rect.ymin < block->rect.ymin) { bt->flag |= UI_SCROLLED; block->flag |= UI_BLOCK_CLIPBOTTOM; @@ -508,7 +497,7 @@ void ui_popup_block_scrolltest(uiBlock *block) } /* mark buttons overlapping arrows, if we have them */ - for (bt = block->buttons.first; bt; bt = bt->next) { + LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { if (block->flag & UI_BLOCK_CLIPBOTTOM) { if (bt->rect.ymin < block->rect.ymin + UI_MENU_SCROLL_ARROW) { bt->flag |= UI_SCROLLED; @@ -535,9 +524,10 @@ static void ui_popup_block_remove(bContext *C, uiPopupBlockHandle *handle) /* There may actually be a different window active than the one showing the popup, so lookup real * one. */ if (BLI_findindex(&screen->regionbase, handle->region) == -1) { - for (win = wm->windows.first; win; win = win->next) { - screen = WM_window_get_active_screen(win); + LISTBASE_FOREACH (wmWindow *, win_iter, &wm->windows) { + screen = WM_window_get_active_screen(win_iter); if (BLI_findindex(&screen->regionbase, handle->region) != -1) { + win = win_iter; break; } } diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c index 2010d89165e..adb2c1c802f 100644 --- a/source/blender/editors/interface/interface_region_search.c +++ b/source/blender/editors/interface/interface_region_search.c @@ -592,15 +592,15 @@ static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *region) /* indicate more */ if (data->items.more) { ui_searchbox_butrect(&rect, data, data->items.maxitem - 1); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_icon_draw(rect.xmax - 18, rect.ymin - 7, ICON_TRIA_DOWN); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } if (data->items.offset) { ui_searchbox_butrect(&rect, data, 0); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_icon_draw(rect.xmin, rect.ymax - 9, ICON_TRIA_UP); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } else { @@ -657,15 +657,15 @@ static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *region) /* indicate more */ if (data->items.more) { ui_searchbox_butrect(&rect, data, data->items.maxitem - 1); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymin - 9, ICON_TRIA_DOWN); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } if (data->items.offset) { ui_searchbox_butrect(&rect, data, 0); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymax - 7, ICON_TRIA_UP); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } } @@ -953,15 +953,15 @@ static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARe /* indicate more */ if (data->items.more) { ui_searchbox_butrect(&rect, data, data->items.maxitem - 1); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymin - 9, ICON_TRIA_DOWN); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } if (data->items.offset) { ui_searchbox_butrect(&rect, data, 0); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymax - 7, ICON_TRIA_UP); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } } diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c index 41b41cb3d75..c324e27dff9 100644 --- a/source/blender/editors/interface/interface_region_tooltip.c +++ b/source/blender/editors/interface/interface_region_tooltip.c @@ -63,7 +63,7 @@ #include "BLT_translation.h" #ifdef WITH_PYTHON -# include "BPY_extern.h" +# include "BPY_extern_run.h" #endif #include "ED_screen.h" @@ -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, __func__, &expr_result)) { + else if (BPY_run_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, __func__, &expr_result)) { + else if (BPY_run_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, __func__, &expr_result)) { + else if (BPY_run_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) { @@ -658,7 +658,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_string_and_size( + else if (BPY_run_string_as_string_and_size( 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, __func__, &expr_result)) { + else if (BPY_run_string_as_intptr(C, expr_imports, expr, __func__, &expr_result)) { if (expr_result != 0) { { uiTooltipField *field = text_field_add(data, diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index 5310ff0e3ec..28279996559 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -426,7 +426,6 @@ int UI_fontstyle_height_max(const uiFontStyle *fs) /* reading without uifont will create one */ void uiStyleInit(void) { - uiFont *font; uiStyle *style = U.uistyles.first; /* recover from uninitialized dpi */ @@ -435,7 +434,7 @@ void uiStyleInit(void) } CLAMP(U.dpi, 48, 144); - for (font = U.uifonts.first; font; font = font->next) { + LISTBASE_FOREACH (uiFont *, font, &U.uifonts) { BLF_unload_id(font->blf_id); } @@ -449,24 +448,24 @@ void uiStyleInit(void) blf_mono_font_render = -1; } - font = U.uifonts.first; + uiFont *font_first = U.uifonts.first; /* default builtin */ - if (font == NULL) { - font = MEM_callocN(sizeof(uiFont), "ui font"); - BLI_addtail(&U.uifonts, font); + if (font_first == NULL) { + font_first = MEM_callocN(sizeof(uiFont), "ui font"); + BLI_addtail(&U.uifonts, font_first); } if (U.font_path_ui[0]) { - BLI_strncpy(font->filename, U.font_path_ui, sizeof(font->filename)); - font->uifont_id = UIFONT_CUSTOM1; + BLI_strncpy(font_first->filename, U.font_path_ui, sizeof(font_first->filename)); + font_first->uifont_id = UIFONT_CUSTOM1; } else { - BLI_strncpy(font->filename, "default", sizeof(font->filename)); - font->uifont_id = UIFONT_DEFAULT; + BLI_strncpy(font_first->filename, "default", sizeof(font_first->filename)); + font_first->uifont_id = UIFONT_DEFAULT; } - for (font = U.uifonts.first; font; font = font->next) { + LISTBASE_FOREACH (uiFont *, font, &U.uifonts) { const bool unique = false; if (font->uifont_id == UIFONT_DEFAULT) { @@ -535,7 +534,7 @@ void uiStyleInit(void) flag_enable |= BLF_MONOCHROME; } - for (font = U.uifonts.first; font; font = font->next) { + LISTBASE_FOREACH (uiFont *, font, &U.uifonts) { if (font->blf_id != -1) { BLF_disable(font->blf_id, flag_disable); BLF_enable(font->blf_id, flag_enable); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index cdfe6120eee..0e801c8cee2 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -395,11 +395,10 @@ static void id_search_cb(const bContext *C, { TemplateID *template_ui = (TemplateID *)arg_template; ListBase *lb = template_ui->idlb; - ID *id; int flag = RNA_property_flag(template_ui->prop); /* ID listbase */ - for (id = lb->first; id; id = id->next) { + LISTBASE_FOREACH (ID *, id, lb) { if (!id_search_add(C, template_ui, flag, str, items, id)) { break; } @@ -416,11 +415,10 @@ static void id_search_cb_tagged(const bContext *C, { TemplateID *template_ui = (TemplateID *)arg_template; ListBase *lb = template_ui->idlb; - ID *id; int flag = RNA_property_flag(template_ui->prop); /* ID listbase */ - for (id = lb->first; id; id = id->next) { + LISTBASE_FOREACH (ID *, id, lb) { if (id->tag & LIB_TAG_DOIT) { if (!id_search_add(C, template_ui, flag, str, items, id)) { break; @@ -2420,9 +2418,8 @@ static eAutoPropButsReturn template_operator_property_buts_draw_single( /* Only do this if we're not refreshing an existing UI. */ if (block->oldblock == NULL) { const bool is_popup = (block->flag & UI_BLOCK_KEEP_OPEN) != 0; - uiBut *but; - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { /* no undo for buttons for operator redo panels */ UI_but_flag_disable(but, UI_BUT_UNDO); @@ -5415,7 +5412,6 @@ void uiTemplatePalette(uiLayout *layout, PropertyRNA *prop = RNA_struct_find_property(ptr, propname); PointerRNA cptr; Palette *palette; - PaletteColor *color; uiBlock *block; uiLayout *col; uiBut *but = NULL; @@ -5437,8 +5433,6 @@ void uiTemplatePalette(uiLayout *layout, palette = cptr.data; - color = palette->colors.first; - col = uiLayoutColumn(layout, true); uiLayoutRow(col, true); uiDefIconButO(block, @@ -5461,7 +5455,7 @@ void uiTemplatePalette(uiLayout *layout, UI_UNIT_X, UI_UNIT_Y, NULL); - if (color) { + if (palette->colors.first != NULL) { but = uiDefIconButO(block, UI_BTYPE_BUT, "PALETTE_OT_color_move", @@ -5496,7 +5490,7 @@ void uiTemplatePalette(uiLayout *layout, col = uiLayoutColumn(layout, true); uiLayoutRow(col, true); - for (; color; color = color->next) { + LISTBASE_FOREACH (PaletteColor *, color, &palette->colors) { PointerRNA color_ptr; if (row_cols >= cols_per_row) { @@ -6650,9 +6644,8 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C) UI_block_func_handle_set(block, do_running_jobs, NULL); - Scene *scene; /* another scene can be rendering too, for example via compositor */ - for (scene = bmain->scenes.first; scene; scene = scene->id.next) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { if (WM_jobs_test(wm, scene, WM_JOB_TYPE_ANY)) { handle_event = B_STOPOTHER; icon = ICON_NONE; @@ -7366,10 +7359,12 @@ void uiTemplateCacheFile(uiLayout *layout, int uiTemplateRecentFiles(uiLayout *layout, int rows) { - const RecentFile *recent; int i; + LISTBASE_FOREACH_INDEX (RecentFile *, recent, &G.recent_files, i) { + if (i >= rows) { + break; + } - for (recent = G.recent_files.first, i = 0; (i < rows) && (recent); recent = recent->next, i++) { const char *filename = BLI_path_basename(recent->filepath); PointerRNA ptr; uiItemFullO(layout, diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index 4a1c7be918e..f44987ac1d2 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -714,12 +714,8 @@ bool UI_butstore_is_valid(uiButStore *bs) bool UI_butstore_is_registered(uiBlock *block, uiBut *but) { - uiButStore *bs_handle; - - for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) { - uiButStoreElem *bs_elem; - - for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) { + LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) { + LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) { if (*bs_elem->but_p == but) { return true; } @@ -740,10 +736,7 @@ void UI_butstore_register(uiButStore *bs_handle, uiBut **but_p) void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p) { - uiButStoreElem *bs_elem, *bs_elem_next; - - for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem_next) { - bs_elem_next = bs_elem->next; + LISTBASE_FOREACH_MUTABLE (uiButStoreElem *, bs_elem, &bs_handle->items) { if (bs_elem->but_p == but_p) { BLI_remlink(&bs_handle->items, bs_elem); MEM_freeN(bs_elem); @@ -758,12 +751,10 @@ void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p) */ bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *but_src) { - uiButStore *bs_handle; bool found = false; - for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) { - uiButStoreElem *bs_elem; - for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) { + LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) { + LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) { if (*bs_elem->but_p == but_src) { *bs_elem->but_p = but_dst; found = true; @@ -779,14 +770,9 @@ bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *bu */ void UI_butstore_clear(uiBlock *block) { - uiButStore *bs_handle; - - for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) { - uiButStoreElem *bs_elem; - + LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) { bs_handle->block = NULL; - - for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) { + LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) { *bs_elem->but_p = NULL; } } @@ -797,8 +783,6 @@ void UI_butstore_clear(uiBlock *block) */ void UI_butstore_update(uiBlock *block) { - uiButStore *bs_handle; - /* move this list to the new block */ if (block->oldblock) { if (block->oldblock->butstore.first) { @@ -812,17 +796,14 @@ void UI_butstore_update(uiBlock *block) /* warning, loop-in-loop, in practice we only store <10 buttons at a time, * so this isn't going to be a problem, if that changes old-new mapping can be cached first */ - for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) { - + LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) { BLI_assert((bs_handle->block == NULL) || (bs_handle->block == block) || (block->oldblock && block->oldblock == bs_handle->block)); if (bs_handle->block == block->oldblock) { - uiButStoreElem *bs_elem; - bs_handle->block = block; - for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) { + LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) { if (*bs_elem->but_p) { uiBut *but_new = ui_but_find_new(block, *bs_elem->but_p); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 1be62e535de..c1801290152 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -29,6 +29,7 @@ #include "DNA_brush_types.h" #include "DNA_userdef_types.h" +#include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_rect.h" #include "BLI_string.h" @@ -525,7 +526,7 @@ void UI_draw_anti_tria( /* Note: This won't give back the original color. */ draw_color[3] *= 1.0f / WIDGET_AA_JITTER; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -544,7 +545,7 @@ void UI_draw_anti_tria( immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* triangle 'icon' inside rect */ @@ -569,7 +570,7 @@ void UI_draw_anti_fan(float tri_array[][2], uint length, const float color[4]) copy_v4_v4(draw_color, color); draw_color[3] *= 2.0f / WIDGET_AA_JITTER; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -593,7 +594,7 @@ void UI_draw_anti_fan(float tri_array[][2], uint length, const float color[4]) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void widget_init(uiWidgetBase *wtb) @@ -1170,7 +1171,7 @@ void UI_widgetbase_draw_cache_flush(void) /* draw single */ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); GPU_batch_uniform_4fv_array( - batch, "parameters", MAX_WIDGET_PARAMETERS, (float *)g_widget_base_batch.params); + batch, "parameters", MAX_WIDGET_PARAMETERS, (float(*)[4])g_widget_base_batch.params); GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params); GPU_batch_draw(batch); } @@ -1179,7 +1180,7 @@ void UI_widgetbase_draw_cache_flush(void) GPU_batch_uniform_4fv_array(batch, "parameters", MAX_WIDGET_PARAMETERS * MAX_WIDGET_BASE_BATCH, - (float *)g_widget_base_batch.params); + (float(*)[4])g_widget_base_batch.params); GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params); GPU_batch_draw_instanced(batch, g_widget_base_batch.count); } @@ -1197,11 +1198,11 @@ void UI_widgetbase_draw_cache_end(void) BLI_assert(g_widget_base_batch.enabled == true); g_widget_base_batch.enabled = false; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_widgetbase_draw_cache_flush(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* Disable cached/instanced drawing and enforce single widget drawing pipeline. @@ -1247,7 +1248,7 @@ static void draw_widgetbase_batch(uiWidgetBase *wtb) GPUBatch *batch = ui_batch_roundbox_widget_get(); GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); GPU_batch_uniform_4fv_array( - batch, "parameters", MAX_WIDGET_PARAMETERS, (float *)&wtb->uniform_params); + batch, "parameters", MAX_WIDGET_PARAMETERS, (float(*)[4]) & wtb->uniform_params); GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params); GPU_batch_draw(batch); } @@ -1307,9 +1308,9 @@ static void widgetbase_draw_ex(uiWidgetBase *wtb, widgetbase_set_uniform_colors_ubv( wtb, inner_col1, inner_col2, outline_col, emboss_col, tria_col, show_alpha_checkers); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); draw_widgetbase_batch(wtb); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } @@ -1363,9 +1364,9 @@ static void widget_draw_icon( float aspect, height; if (but->flag & UI_BUT_ICON_PREVIEW) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); widget_draw_preview(icon, alpha, rect); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); return; } @@ -1401,7 +1402,7 @@ static void widget_draw_icon( } } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); if (icon && icon != ICON_BLANK1) { float ofs = 1.0f / aspect; @@ -1454,7 +1455,7 @@ static void widget_draw_icon( } } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void widget_draw_submenu_tria(const uiBut *but, @@ -1475,9 +1476,9 @@ static void widget_draw_submenu_tria(const uiBut *but, BLI_rctf_init(&tria_rect, xs, xs + tria_width, ys, ys + tria_height); BLI_rctf_scale(&tria_rect, 0.4f); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_widgetbase_draw_cache_flush(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); ui_draw_anti_tria_rect(&tria_rect, 'h', col); } @@ -2022,9 +2023,9 @@ static void widget_draw_text(const uiFontStyle *fstyle, if (drawstr[0] != 0) { /* We are drawing on top of widget bases. Flush cache. */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_widgetbase_draw_cache_flush(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); if (but->selsta >= but->ofs) { selsta_draw = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->selsta - but->ofs); @@ -2069,9 +2070,9 @@ static void widget_draw_text(const uiFontStyle *fstyle, t = 0; } /* We are drawing on top of widget bases. Flush cache. */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_widgetbase_draw_cache_flush(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); uint pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); @@ -2242,7 +2243,7 @@ static void widget_draw_extra_icons(const uiWidgetColors *wcol, float alpha) { /* inverse order, from right to left. */ - for (uiButExtraOpIcon *op_icon = but->extra_op_icons.last; op_icon; op_icon = op_icon->prev) { + LISTBASE_FOREACH_BACKWARD (uiButExtraOpIcon *, op_icon, &but->extra_op_icons) { rcti temp = *rect; temp.xmin = temp.xmax - (BLI_rcti_size_y(rect) * 1.08f); @@ -2266,9 +2267,9 @@ static void widget_draw_node_link_socket(const uiWidgetColors *wcol, rgba_uchar_to_float(col, but->col); col[3] *= alpha; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_widgetbase_draw_cache_flush(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); ED_node_socket_draw(but->custom_data, rect, col, scale); } @@ -2327,9 +2328,9 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle, /* draw icon in rect above the space reserved for the label */ rect->ymin += text_size; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); widget_draw_preview(icon, alpha, rect); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* offset rect to draw label in */ rect->ymin -= text_size; @@ -2784,16 +2785,14 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir rect->ymax += 0.1f * U.widget_unit; } - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); widget_softshadow(rect, roundboxalign, wcol->roundness * U.widget_unit); round_box_edges(&wtb, roundboxalign, rect, wcol->roundness * U.widget_unit); wtb.draw_emboss = false; widgetbase_draw(&wtb, wcol); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void ui_hsv_cursor(float x, float y) @@ -2805,11 +2804,11 @@ static void ui_hsv_cursor(float x, float y) immUniformColor3f(1.0f, 1.0f, 1.0f); imm_draw_circle_fill_2d(pos, x, y, 3.0f * U.pixelsize, 8); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); immUniformColor3f(0.0f, 0.0f, 0.0f); imm_draw_circle_wire_2d(pos, x, y, 3.0f * U.pixelsize, 12); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); immUnbindProgram(); @@ -2937,7 +2936,7 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, const uiWidgetColors *wcol, const immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); immUniformColor3ubv(wcol->outline); @@ -2945,7 +2944,7 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, const uiWidgetColors *wcol, const immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); /* cursor */ @@ -3244,9 +3243,9 @@ static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect) })); /* We are drawing on top of widget bases. Flush cache. */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_widgetbase_draw_cache_flush(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* cursor */ x = rect->xmin + 0.5f * BLI_rcti_size_x(rect); @@ -3270,7 +3269,7 @@ static void ui_draw_separator(const rcti *rect, const uiWidgetColors *wcol) uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor4ubv(col); GPU_line_width(1.0f); @@ -3279,7 +3278,7 @@ static void ui_draw_separator(const rcti *rect, const uiWidgetColors *wcol) immVertex2f(pos, rect->xmax, y); immEnd(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); } @@ -3837,9 +3836,9 @@ static void widget_swatch( bw += (bw < 0.5f) ? 0.5f : -0.5f; /* We are drawing on top of widget bases. Flush cache. */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_widgetbase_draw_cache_flush(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -4201,9 +4200,9 @@ static void widget_tab(uiWidgetColors *wcol, rcti *rect, int state, int roundbox widgetbase_draw(&wtb, wcol); /* We are drawing on top of widget bases. Flush cache. */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_widgetbase_draw_cache_flush(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); #ifdef USE_TAB_SHADED_HIGHLIGHT /* draw outline (3d look) */ @@ -4818,12 +4817,12 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu } if (disabled) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); } wt->text(fstyle, &wt->wcol, but, rect); if (disabled) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } } @@ -4906,7 +4905,7 @@ static void ui_draw_popover_back_impl(const uiWidgetColors *wcol, rect->xmax - unit_size) : BLI_rcti_cent_x(rect); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* Extracted from 'widget_menu_back', keep separate to avoid menu changes breaking popovers */ { @@ -4930,7 +4929,7 @@ static void ui_draw_popover_back_impl(const uiWidgetColors *wcol, const int sign = is_down ? 1 : -1; float y = is_down ? rect->ymax : rect->ymin; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immBegin(GPU_PRIM_TRIS, 3); immUniformColor4ub(UNPACK3(wcol->outline), 166); immVertex2f(pos, cent_x - unit_half, y); @@ -4940,7 +4939,7 @@ static void ui_draw_popover_back_impl(const uiWidgetColors *wcol, y = y - sign * round(U.pixelsize * 1.41); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immBegin(GPU_PRIM_TRIS, 3); immUniformColor4ub(0, 0, 0, 0); immVertex2f(pos, cent_x - unit_half, y); @@ -4948,7 +4947,7 @@ static void ui_draw_popover_back_impl(const uiWidgetColors *wcol, immVertex2f(pos, cent_x, y + sign * unit_half); immEnd(); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immBegin(GPU_PRIM_TRIS, 3); immUniformColor4ubv(wcol->inner); immVertex2f(pos, cent_x - unit_half, y); @@ -4959,7 +4958,7 @@ static void ui_draw_popover_back_impl(const uiWidgetColors *wcol, immUnbindProgram(); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } void ui_draw_popover_back(struct ARegion *region, @@ -5060,7 +5059,7 @@ void ui_draw_pie_center(uiBlock *block) GPU_matrix_push(); GPU_matrix_translate_2f(cx, cy); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); if (btheme->tui.wcol_pie_menu.shaded) { uchar col1[4], col2[4]; shadecolors4(col1, @@ -5143,7 +5142,7 @@ void ui_draw_pie_center(uiBlock *block) false); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_matrix_pop(); } @@ -5164,11 +5163,9 @@ static void ui_draw_widget_back_color(uiWidgetTypeEnum type, uiWidgetType *wt = widget_type(type); if (use_shadow) { - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); widget_softshadow(rect, UI_CNR_ALL, 0.25f * U.widget_unit); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } rcti rect_copy = *rect; @@ -5291,10 +5288,10 @@ void ui_draw_menu_item(const uiFontStyle *fstyle, height = ICON_SIZE_FROM_BUTRECT(rect); aspect = ICON_DEFAULT_HEIGHT / height; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* XXX scale weak get from fstyle? */ UI_icon_draw_ex(xs, ys, iconid, aspect, 1.0f, 0.0f, wt->wcol.text, false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* part text right aligned */ @@ -5330,9 +5327,9 @@ void ui_draw_preview_item( /* draw icon in rect above the space reserved for the label */ rect->ymin += text_size; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); widget_draw_preview(iconid, 1.0f, rect); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); BLF_width_and_height( fstyle->uifont_id, name, BLF_DRAW_STR_DUMMY_MAX, &font_dims[0], &font_dims[1]); diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index f15a95880f8..d4f81a89bc3 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -870,8 +870,6 @@ void UI_view2d_curRect_changed(const bContext *C, View2D *v2d) * to make sure 'related' views stay in synchrony */ void UI_view2d_sync(bScreen *screen, ScrArea *area, View2D *v2dcur, int flag) { - ARegion *region; - /* don't continue if no view syncing to be done */ if ((v2dcur->flag & (V2D_VIEWSYNC_SCREEN_TIME | V2D_VIEWSYNC_AREA_VERTICAL)) == 0) { return; @@ -879,7 +877,7 @@ void UI_view2d_sync(bScreen *screen, ScrArea *area, View2D *v2dcur, int flag) /* check if doing within area syncing (i.e. channels/vertical) */ if ((v2dcur->flag & V2D_VIEWSYNC_AREA_VERTICAL) && (area)) { - for (region = area->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { /* don't operate on self */ if (v2dcur != ®ion->v2d) { /* only if view has vertical locks enabled */ @@ -905,7 +903,7 @@ void UI_view2d_sync(bScreen *screen, ScrArea *area, View2D *v2dcur, int flag) /* check if doing whole screen syncing (i.e. time/horizontal) */ if ((v2dcur->flag & V2D_VIEWSYNC_SCREEN_TIME) && (screen)) { LISTBASE_FOREACH (ScrArea *, area_iter, &screen->areabase) { - for (region = area_iter->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area_iter->regionbase) { /* don't operate on self */ if (v2dcur != ®ion->v2d) { /* only if view has horizontal locks enabled */ diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 7caa61ec91d..eb47c5c3e6d 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -1157,8 +1157,8 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) const bool zoom_to_pos = use_cursor_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS); /* get amount to move view by */ - dx = RNA_float_get(op->ptr, "deltax") / U.pixelsize; - dy = RNA_float_get(op->ptr, "deltay") / U.pixelsize; + dx = RNA_float_get(op->ptr, "deltax") / U.dpi_fac; + dy = RNA_float_get(op->ptr, "deltay") / U.dpi_fac; if (U.uiflag & USER_ZOOM_INVERT) { dx *= -1; diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c index 096dc44c758..45ea52bdebc 100644 --- a/source/blender/editors/io/io_usd.c +++ b/source/blender/editors/io/io_usd.c @@ -113,6 +113,7 @@ static int wm_usd_export_exec(bContext *C, wmOperator *op) MEM_SAFE_FREE(op->customdata); const bool selected_objects_only = RNA_boolean_get(op->ptr, "selected_objects_only"); + const bool visible_objects_only = RNA_boolean_get(op->ptr, "visible_objects_only"); const bool export_animation = RNA_boolean_get(op->ptr, "export_animation"); const bool export_hair = RNA_boolean_get(op->ptr, "export_hair"); const bool export_uvmaps = RNA_boolean_get(op->ptr, "export_uvmaps"); @@ -128,6 +129,7 @@ static int wm_usd_export_exec(bContext *C, wmOperator *op) export_normals, export_materials, selected_objects_only, + visible_objects_only, use_instancing, evaluation_mode, }; @@ -149,6 +151,7 @@ static void wm_usd_export_draw(bContext *UNUSED(C), wmOperator *op) col = uiLayoutColumn(box, true); uiItemR(col, ptr, "selected_objects_only", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "visible_objects_only", 0, NULL, ICON_NONE); col = uiLayoutColumn(box, true); uiItemR(col, ptr, "export_animation", 0, NULL, ICON_NONE); @@ -192,6 +195,13 @@ void WM_OT_usd_export(struct wmOperatorType *ot) "exported as empty transform"); RNA_def_boolean(ot->srna, + "visible_objects_only", + true, + "Visible Only", + "Only visible objects are exported. Invisible parents of exported objects are " + "exported as empty transform"); + + RNA_def_boolean(ot->srna, "export_animation", false, "Animation", diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index c617c921d70..dbaa335a9bf 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -594,9 +594,7 @@ static void draw_mask_layers(const bContext *C, const int width, const int height) { - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPU_program_point_size(true); MaskLayer *mask_layer; @@ -633,7 +631,7 @@ static void draw_mask_layers(const bContext *C, } GPU_program_point_size(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } void ED_mask_draw(const bContext *C, const char draw_flag, const char draw_type) @@ -740,8 +738,7 @@ void ED_mask_draw_region( if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) { /* More blending types could be supported in the future. */ - GPU_blend(true); - GPU_blend_set_func(GPU_DST_COLOR, GPU_ZERO); + GPU_blend(GPU_BLEND_MULTIPLY); } GPU_matrix_push(); @@ -758,7 +755,7 @@ void ED_mask_draw_region( GPU_matrix_pop(); if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } MEM_freeN(buffer); diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index b02e48a652e..94cd7650abe 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1128,9 +1128,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), v int i, snapped_verts_count, other_verts_count; float fcol[4]; - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPUVertBuf *vert = GPU_vertbuf_create_with_format(format); GPU_vertbuf_data_alloc(vert, kcd->totlinehit); @@ -1166,7 +1164,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), v GPU_batch_discard(batch); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } if (kcd->totkedge > 0) { diff --git a/source/blender/editors/mesh/editmesh_mask_extract.c b/source/blender/editors/mesh/editmesh_mask_extract.c index 8eeba5007e1..34fcee779de 100644 --- a/source/blender/editors/mesh/editmesh_mask_extract.c +++ b/source/blender/editors/mesh/editmesh_mask_extract.c @@ -354,10 +354,6 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op) if (ob->mode == OB_MODE_SCULPT) { ED_sculpt_undo_geometry_begin(ob, "mask slice"); - /* TODO: The ideal functionality would be to preserve the current face sets and add a new one - * for the new triangles, but this data-layer needs to be rebuild in order to make sculpt mode - * not crash when modifying the geometry. */ - CustomData_free_layers(&mesh->pdata, CD_SCULPT_FACE_SETS, mesh->totpoly); } BMesh *bm; @@ -429,14 +425,14 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op) BKE_mesh_calc_normals(ob->data); if (ob->mode == OB_MODE_SCULPT) { - ED_sculpt_undo_geometry_end(ob); SculptSession *ss = ob->sculpt; - /* Rebuild a new valid Face Set layer for the object. */ - ss->face_sets = CustomData_add_layer( - &mesh->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, NULL, mesh->totpoly); - for (int i = 0; i < mesh->totpoly; i++) { - ss->face_sets[i] = 1; + ss->face_sets = CustomData_get_layer(&((Mesh *)ob->data)->pdata, CD_SCULPT_FACE_SETS); + if (ss->face_sets) { + /* Assign a new Face Set ID to the new faces created by the slice operation. */ + const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(ob->data); + ED_sculpt_face_sets_initialize_none_to_id(ob->data, next_face_set_id); } + ED_sculpt_undo_geometry_end(ob); } BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL); diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index eb8b976320f..4d55aff1d1f 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -745,7 +745,7 @@ static int bake(Render *re, /* We build a depsgraph for the baking, * so we don't need to change the original data to adjust visibility and modifiers. */ Depsgraph *depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_RENDER); - DEG_graph_build_from_view_layer(depsgraph, bmain, scene, view_layer); + DEG_graph_build_from_view_layer(depsgraph); int op_result = OPERATOR_CANCELLED; bool ok = false; diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index bcb1b8afbdd..70404af6433 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -663,10 +663,13 @@ static const EnumPropertyItem constraint_owner_items[] = { {0, NULL, 0, NULL, NULL}, }; -static bool edit_constraint_poll_generic(bContext *C, StructRNA *rna_type) +static bool edit_constraint_poll_generic(bContext *C, + StructRNA *rna_type, + const bool is_liboverride_allowed) { PointerRNA ptr = CTX_data_pointer_get_type(C, "constraint", rna_type); Object *ob = (ptr.owner_id) ? (Object *)ptr.owner_id : ED_object_active_context(C); + bConstraint *con = ptr.data; if (!ob) { CTX_wm_operator_poll_msg_set(C, "Context missing active object"); @@ -678,9 +681,11 @@ static bool edit_constraint_poll_generic(bContext *C, StructRNA *rna_type) return false; } - if (ID_IS_OVERRIDE_LIBRARY(ob) && ptr.data != NULL) { - CTX_wm_operator_poll_msg_set(C, "Cannot edit constraints coming from library override"); - return (((bConstraint *)ptr.data)->flag & CONSTRAINT_OVERRIDE_LIBRARY_LOCAL) != 0; + if (ID_IS_OVERRIDE_LIBRARY(ob) && !is_liboverride_allowed) { + if ((con == NULL) || (con->flag & CONSTRAINT_OVERRIDE_LIBRARY_LOCAL) != 0) { + CTX_wm_operator_poll_msg_set(C, "Cannot edit constraints coming from library override"); + return false; + } } return true; @@ -688,7 +693,14 @@ static bool edit_constraint_poll_generic(bContext *C, StructRNA *rna_type) static bool edit_constraint_poll(bContext *C) { - return edit_constraint_poll_generic(C, &RNA_Constraint); + return edit_constraint_poll_generic(C, &RNA_Constraint, false); +} + +/* Used by operators performing actions allowed also on constraints from the overridden linked + * object (not only from added 'local' ones). */ +static bool edit_constraint_liboverride_allowed_poll(bContext *C) +{ + return edit_constraint_poll_generic(C, &RNA_Constraint, true); } static void edit_constraint_properties(wmOperatorType *ot) @@ -864,7 +876,7 @@ void CONSTRAINT_OT_stretchto_reset(wmOperatorType *ot) /* callbacks */ ot->invoke = stretchto_reset_invoke; ot->exec = stretchto_reset_exec; - ot->poll = edit_constraint_poll; + ot->poll = edit_constraint_liboverride_allowed_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -919,7 +931,7 @@ void CONSTRAINT_OT_limitdistance_reset(wmOperatorType *ot) /* callbacks */ ot->invoke = limitdistance_reset_invoke; ot->exec = limitdistance_reset_exec; - ot->poll = edit_constraint_poll; + ot->poll = edit_constraint_liboverride_allowed_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -997,7 +1009,7 @@ void CONSTRAINT_OT_childof_set_inverse(wmOperatorType *ot) /* callbacks */ ot->invoke = childof_set_inverse_invoke; ot->exec = childof_set_inverse_exec; - ot->poll = edit_constraint_poll; + ot->poll = edit_constraint_liboverride_allowed_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -1046,7 +1058,7 @@ void CONSTRAINT_OT_childof_clear_inverse(wmOperatorType *ot) /* callbacks */ ot->invoke = childof_clear_inverse_invoke; ot->exec = childof_clear_inverse_exec; - ot->poll = edit_constraint_poll; + ot->poll = edit_constraint_liboverride_allowed_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -1693,8 +1705,8 @@ void POSE_OT_constraints_clear(wmOperatorType *ot) /* callbacks */ ot->exec = pose_constraints_clear_exec; - ot->poll = - ED_operator_posemode_exclusive; // XXX - do we want to ensure there are selected bones too? + ot->poll = ED_operator_posemode_exclusive; // XXX - do we want to ensure there are selected + // bones too? } static int object_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op)) @@ -1942,7 +1954,8 @@ static bool get_new_constraint_target( /* perform some special operations on the target */ if (only_curve) { - /* Curve-Path option must be enabled for follow-path constraints to be able to work */ + /* Curve-Path option must be enabled for follow-path constraints to be able to work + */ Curve *cu = (Curve *)ob->data; cu->flag |= CU_PATH; } @@ -2214,8 +2227,8 @@ void OBJECT_OT_constraint_add_with_targets(wmOperatorType *ot) /* identifiers */ ot->name = "Add Constraint (with Targets)"; ot->description = - "Add a constraint to the active object, with target (where applicable) set to the selected " - "Objects/Bones"; + "Add a constraint to the active object, with target (where applicable) set to the " + "selected Objects/Bones"; ot->idname = "OBJECT_OT_constraint_add_with_targets"; /* api callbacks */ diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index ceb6553bdf6..14882ab8ffc 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -107,7 +107,7 @@ static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Object * Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); BKE_object_eval_reset(ob_eval); if (ob->type == OB_MESH) { - Mesh *me_eval = mesh_create_eval_final_view(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH); + Mesh *me_eval = mesh_create_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH); BKE_mesh_eval_delete(me_eval); } else if (ob->type == OB_LATTICE) { diff --git a/source/blender/editors/object/object_remesh.c b/source/blender/editors/object/object_remesh.c index d5715cf6879..9be84dc4b8c 100644 --- a/source/blender/editors/object/object_remesh.c +++ b/source/blender/editors/object/object_remesh.c @@ -294,7 +294,7 @@ static void voxel_size_edit_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), { VoxelSizeEditCustomData *cd = arg; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); uint pos3d = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); @@ -363,7 +363,7 @@ static void voxel_size_edit_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), GPU_matrix_pop(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); } diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 488bb7121a2..eb7ddfefb9c 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -3213,11 +3213,11 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata) immUniformColor4ub(255, 255, 255, 128); GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); imm_draw_circle_wire_2d(pos, (float)x, (float)y, pe_brush_size_get(scene, brush), 40); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); immUnbindProgram(); diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index f75dd428968..52a7b92217b 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -879,7 +879,6 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) { - Main *bmain = CTX_data_main(C); Scene *scene = oglrender->scene; int i; @@ -929,7 +928,7 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) if (oglrender->timer) { /* exec will not have a timer */ Depsgraph *depsgraph = oglrender->depsgraph; scene->r.cfra = oglrender->cfrao; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer); } @@ -1119,7 +1118,6 @@ static bool schedule_write_result(OGLRender *oglrender, RenderResult *rr) static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); OGLRender *oglrender = op->customdata; Scene *scene = oglrender->scene; Depsgraph *depsgraph = oglrender->depsgraph; @@ -1134,7 +1132,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op) CFRA++; } while (CFRA < oglrender->nfra) { - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); CFRA++; } @@ -1161,7 +1159,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op) WM_cursor_time(oglrender->win, scene->r.cfra); - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); if (view_context) { if (oglrender->rv3d->persp == RV3D_CAMOB && oglrender->v3d->camera && diff --git a/source/blender/editors/scene/scene_edit.c b/source/blender/editors/scene/scene_edit.c index fa63a890de7..d599c1cbcf0 100644 --- a/source/blender/editors/scene/scene_edit.c +++ b/source/blender/editors/scene/scene_edit.c @@ -119,7 +119,7 @@ void ED_scene_change_update(Main *bmain, Scene *scene, ViewLayer *layer) Depsgraph *depsgraph = BKE_scene_get_depsgraph(bmain, scene, layer, true); BKE_scene_set_background(bmain, scene); - DEG_graph_relations_update(depsgraph, bmain, scene, layer); + DEG_graph_relations_update(depsgraph); DEG_on_visible_update(bmain, false); ED_render_engine_changed(bmain, false); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 38bac3afef6..5004b0132c2 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -93,9 +93,7 @@ static void region_draw_emboss(const ARegion *region, const rcti *scirct, int si rect.ymax = scirct->ymax - region->winrct.ymin; /* set transp line */ - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); float color[4] = {0.0f, 0.0f, 0.0f, 0.25f}; UI_GetThemeColor3fv(TH_EDITOR_OUTLINE, color); @@ -134,8 +132,7 @@ static void region_draw_emboss(const ARegion *region, const rcti *scirct, int si immEnd(); immUnbindProgram(); - GPU_blend(false); - GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_NONE); } void ED_region_pixelspace(ARegion *region) @@ -248,7 +245,7 @@ static void draw_azone_arrow(float x1, float y1, float x2, float y2, AZEdge edge GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* NOTE(fclem): There is something strange going on with Mesa and GPU_SHADER_2D_UNIFORM_COLOR * that causes a crash on some GPUs (see T76113). Using 3D variant avoid the issue. */ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); @@ -266,12 +263,12 @@ static void draw_azone_arrow(float x1, float y1, float x2, float y2, AZEdge edge immEnd(); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void region_draw_azone_tab_arrow(ScrArea *area, ARegion *region, AZone *az) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* add code to draw region hidden as 'too small' */ switch (az->edge) { @@ -312,9 +309,7 @@ static void region_draw_azones(ScrArea *area, ARegion *region) } GPU_line_width(1.0f); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPU_matrix_push(); GPU_matrix_translate_2f(-region->winrct.xmin, -region->winrct.ymin); @@ -349,7 +344,7 @@ static void region_draw_azones(ScrArea *area, ARegion *region) GPU_matrix_pop(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void region_draw_status_text(ScrArea *area, ARegion *region) @@ -378,8 +373,7 @@ static void region_draw_status_text(ScrArea *area, ARegion *region) const float y1 = pad; const float y2 = region->winy - pad; - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); float color[4] = {0.0f, 0.0f, 0.0f, 0.5f}; UI_GetThemeColor3fv(TH_BACK, color); @@ -548,7 +542,7 @@ void ED_region_do_draw(bContext *C, ARegion *region) /* for debugging unneeded area redraws and partial redraw */ if (G.debug_value == 888) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -559,7 +553,7 @@ void ED_region_do_draw(bContext *C, ARegion *region) region->drawrct.xmax - region->winrct.xmin, region->drawrct.ymax - region->winrct.ymin); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } memset(®ion->drawrct, 0, sizeof(region->drawrct)); @@ -2053,6 +2047,241 @@ void ED_area_data_swap(ScrArea *area_dst, ScrArea *area_src) SWAP(ListBase, area_dst->regionbase, area_src->regionbase); } +/* -------------------------------------------------------------------- */ +/** \name Region Alignment Syncing for Space Switching + * \{ */ + +/** + * Store the alignment & other info per region type + * (use as a region-type aligned array). + * + * \note Currently this is only done for headers, + * we might want to do this with the tool-bar in the future too. + */ +struct RegionTypeAlignInfo { + struct { + /** + * Values match #ARegion.alignment without flags (see #RGN_ALIGN_ENUM_FROM_MASK). + * store all so we can sync alignment without adding extra checks. + */ + short alignment; + /** + * Needed for detecting which header displays the space-type switcher. + */ + bool hidden; + } by_type[RGN_TYPE_LEN]; +}; + +static void region_align_info_from_area(ScrArea *area, struct RegionTypeAlignInfo *r_align_info) +{ + for (int index = 0; index < RGN_TYPE_LEN; index++) { + r_align_info->by_type[index].alignment = -1; + /* Default to true, when it doesn't exist - it's effectively hidden. */ + r_align_info->by_type[index].hidden = true; + } + + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + const int index = region->regiontype; + if ((uint)index < RGN_TYPE_LEN) { + r_align_info->by_type[index].alignment = RGN_ALIGN_ENUM_FROM_MASK(region->alignment); + r_align_info->by_type[index].hidden = (region->flag & RGN_FLAG_HIDDEN) != 0; + } + } +} + +/** + * Keeping alignment between headers keep the space-type selector button in the same place. + * This is complicated by the editor-type selector being placed on the header + * closest to the screen edge which changes based on hidden state. + * + * The tool-header is used when visible, otherwise the header is used. + */ +static short region_alignment_from_header_and_tool_header_state( + const struct RegionTypeAlignInfo *region_align_info, const short fallback) +{ + const short header_alignment = region_align_info->by_type[RGN_TYPE_HEADER].alignment; + const short tool_header_alignment = region_align_info->by_type[RGN_TYPE_TOOL_HEADER].alignment; + + const bool header_hidden = region_align_info->by_type[RGN_TYPE_HEADER].hidden; + const bool tool_header_hidden = region_align_info->by_type[RGN_TYPE_TOOL_HEADER].hidden; + + if ((tool_header_alignment != -1) && + /* If tool-header is hidden, use header alignment. */ + ((tool_header_hidden == false) || + /* Don't prioritize the tool-header if both are hidden (behave as if both are visible). + * Without this, switching to a space with headers hidden will flip the alignment + * upon switching to a space with visible headers. */ + (header_hidden && tool_header_hidden))) { + return tool_header_alignment; + } + if (header_alignment != -1) { + return header_alignment; + } + return fallback; +} + +/** + * Notes on header alignment syncing. + * + * This is as involved as it is because: + * + * - There are currently 3 kinds of headers. + * - All headers can independently visible & flipped to another side + * (except for the tool-header that depends on the header visibility). + * - We don't want the space-switching button to flip when switching spaces. + * From the user perspective it feels like a bug to move the button you click on + * to the opposite side of the area. + * - The space-switcher may be on either the header or the tool-header + * depending on the tool-header visibility. + * + * How this works: + * + * - When headers match on both spaces, we copy the alignment + * from the previous regions to the next regions when syncing. + * - Otherwise detect the _primary_ header (the one that shows the space type) + * and use this to set alignment for the headers in the destination area. + * - Header & tool-header/footer may be on opposite sides, this is preserved when syncing. + */ +static void region_align_info_to_area_for_headers( + const struct RegionTypeAlignInfo *region_align_info_src, + const struct RegionTypeAlignInfo *region_align_info_dst, + ARegion *region_by_type[RGN_TYPE_LEN]) +{ + /* Abbreviate access. */ + const short header_alignment_src = region_align_info_src->by_type[RGN_TYPE_HEADER].alignment; + const short tool_header_alignment_src = + region_align_info_src->by_type[RGN_TYPE_TOOL_HEADER].alignment; + + const bool tool_header_hidden_src = region_align_info_src->by_type[RGN_TYPE_TOOL_HEADER].hidden; + + const short primary_header_alignment_src = region_alignment_from_header_and_tool_header_state( + region_align_info_src, -1); + + /* Neither alignments are usable, don't sync. */ + if (primary_header_alignment_src == -1) { + return; + } + + const short header_alignment_dst = region_align_info_dst->by_type[RGN_TYPE_HEADER].alignment; + const short tool_header_alignment_dst = + region_align_info_dst->by_type[RGN_TYPE_TOOL_HEADER].alignment; + const short footer_alignment_dst = region_align_info_dst->by_type[RGN_TYPE_FOOTER].alignment; + + const bool tool_header_hidden_dst = region_align_info_dst->by_type[RGN_TYPE_TOOL_HEADER].hidden; + + /* New synchronized alignments to set (or ignore when left as -1). */ + short header_alignment_sync = -1; + short tool_header_alignment_sync = -1; + short footer_alignment_sync = -1; + + /* Both source/destination areas have same region configurations regarding headers. + * Simply copy the values. */ + if (((header_alignment_src != -1) == (header_alignment_dst != -1)) && + ((tool_header_alignment_src != -1) == (tool_header_alignment_dst != -1)) && + (tool_header_hidden_src == tool_header_hidden_dst)) { + if (header_alignment_dst != -1) { + header_alignment_sync = header_alignment_src; + } + if (tool_header_alignment_dst != -1) { + tool_header_alignment_sync = tool_header_alignment_src; + } + } + else { + /* Not an exact match, check the space selector isn't moving. */ + const short primary_header_alignment_dst = region_alignment_from_header_and_tool_header_state( + region_align_info_dst, -1); + + if (primary_header_alignment_src != primary_header_alignment_dst) { + if ((header_alignment_dst != -1) && (tool_header_alignment_dst != -1)) { + if (header_alignment_dst == tool_header_alignment_dst) { + /* Apply to both. */ + tool_header_alignment_sync = primary_header_alignment_src; + header_alignment_sync = primary_header_alignment_src; + } + else { + /* Keep on opposite sides. */ + tool_header_alignment_sync = primary_header_alignment_src; + header_alignment_sync = (tool_header_alignment_sync == RGN_ALIGN_BOTTOM) ? + RGN_ALIGN_TOP : + RGN_ALIGN_BOTTOM; + } + } + else { + /* Apply what we can to regions that exist. */ + if (header_alignment_dst != -1) { + header_alignment_sync = primary_header_alignment_src; + } + if (tool_header_alignment_dst != -1) { + tool_header_alignment_sync = primary_header_alignment_src; + } + } + } + } + + if (footer_alignment_dst != -1) { + if ((header_alignment_dst != -1) && (header_alignment_dst == footer_alignment_dst)) { + /* Apply to both. */ + footer_alignment_sync = primary_header_alignment_src; + } + else { + /* Keep on opposite sides. */ + footer_alignment_sync = (primary_header_alignment_src == RGN_ALIGN_BOTTOM) ? + RGN_ALIGN_TOP : + RGN_ALIGN_BOTTOM; + } + } + + /* Finally apply synchronized flags. */ + if (header_alignment_sync != -1) { + ARegion *region = region_by_type[RGN_TYPE_HEADER]; + if (region != NULL) { + region->alignment = RGN_ALIGN_ENUM_FROM_MASK(header_alignment_sync) | + RGN_ALIGN_FLAG_FROM_MASK(region->alignment); + } + } + + if (tool_header_alignment_sync != -1) { + ARegion *region = region_by_type[RGN_TYPE_TOOL_HEADER]; + if (region != NULL) { + region->alignment = RGN_ALIGN_ENUM_FROM_MASK(tool_header_alignment_sync) | + RGN_ALIGN_FLAG_FROM_MASK(region->alignment); + } + } + + if (footer_alignment_sync != -1) { + ARegion *region = region_by_type[RGN_TYPE_FOOTER]; + if (region != NULL) { + region->alignment = RGN_ALIGN_ENUM_FROM_MASK(footer_alignment_sync) | + RGN_ALIGN_FLAG_FROM_MASK(region->alignment); + } + } +} + +static void region_align_info_to_area( + ScrArea *area, const struct RegionTypeAlignInfo region_align_info_src[RGN_TYPE_LEN]) +{ + ARegion *region_by_type[RGN_TYPE_LEN] = {NULL}; + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + const int index = region->regiontype; + if ((uint)index < RGN_TYPE_LEN) { + region_by_type[index] = region; + } + } + + struct RegionTypeAlignInfo region_align_info_dst; + region_align_info_from_area(area, ®ion_align_info_dst); + + if ((region_by_type[RGN_TYPE_HEADER] != NULL) || + (region_by_type[RGN_TYPE_TOOL_HEADER] != NULL)) { + region_align_info_to_area_for_headers( + region_align_info_src, ®ion_align_info_dst, region_by_type); + } + + /* Note that we could support other region types. */ +} + +/** \} */ + /* *********** Space switching code *********** */ void ED_area_swapspace(bContext *C, ScrArea *sa1, ScrArea *sa2) @@ -2104,9 +2333,13 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi * the space type defaults to in this case instead * (needed for preferences to have space-type on bottom). */ - int header_alignment = ED_area_header_alignment_or_fallback(area, -1); - const bool sync_header_alignment = ((header_alignment != -1) && - ((slold->link_flag & SPACE_FLAG_TYPE_TEMPORARY) == 0)); + + bool sync_header_alignment = false; + struct RegionTypeAlignInfo region_align_info[RGN_TYPE_LEN]; + if ((slold != NULL) && (slold->link_flag & SPACE_FLAG_TYPE_TEMPORARY) == 0) { + region_align_info_from_area(area, region_align_info); + sync_header_alignment = true; + } /* in some cases (opening temp space) we don't want to * call area exit callback, so we temporarily unset it */ @@ -2180,28 +2413,7 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi /* Sync header alignment. */ if (sync_header_alignment) { - /* Spaces with footer. */ - if (st->spaceid == SPACE_TEXT) { - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) { - region->alignment = header_alignment; - } - if (region->regiontype == RGN_TYPE_FOOTER) { - int footer_alignment = (header_alignment == RGN_ALIGN_BOTTOM) ? RGN_ALIGN_TOP : - RGN_ALIGN_BOTTOM; - region->alignment = footer_alignment; - break; - } - } - } - else { - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) { - region->alignment = header_alignment; - break; - } - } - } + region_align_info_to_area(area, region_align_info); } ED_area_init(CTX_wm_manager(C), win, area); @@ -2947,43 +3159,11 @@ int ED_area_headersize(void) return U.widget_unit + (int)(UI_DPI_FAC * HEADER_PADDING_Y); } -int ED_area_header_alignment_or_fallback(const ScrArea *area, int fallback) -{ - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - if (region->regiontype == RGN_TYPE_HEADER) { - return region->alignment; - } - } - return fallback; -} - -int ED_area_header_alignment(const ScrArea *area) -{ - return ED_area_header_alignment_or_fallback( - area, (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP); -} - int ED_area_footersize(void) { return ED_area_headersize(); } -int ED_area_footer_alignment_or_fallback(const ScrArea *area, int fallback) -{ - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - if (region->regiontype == RGN_TYPE_FOOTER) { - return region->alignment; - } - } - return fallback; -} - -int ED_area_footer_alignment(const ScrArea *area) -{ - return ED_area_footer_alignment_or_fallback( - area, (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_TOP : RGN_ALIGN_BOTTOM); -} - /** * \return the final height of a global \a area, accounting for DPI. */ @@ -3084,19 +3264,17 @@ void ED_region_info_draw_multiline(ARegion *region, rect.ymin = rect.ymax - header_height * num_lines; /* setup scissor */ - GPU_scissor_get_i(scissor); + GPU_scissor_get(scissor); GPU_scissor(rect.xmin, rect.ymin, BLI_rcti_size_x(&rect) + 1, BLI_rcti_size_y(&rect) + 1); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv(fill_color); immRecti(pos, rect.xmin, rect.ymin, rect.xmax + 1, rect.ymax + 1); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* text */ UI_FontThemeColor(fontid, TH_TEXT_HI); diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c index d8d47fb01aa..a5d3c4842e6 100644 --- a/source/blender/editors/screen/screen_draw.c +++ b/source/blender/editors/screen/screen_draw.c @@ -296,8 +296,7 @@ static GPUBatch *batch_screen_edges_get(int *corner_len) */ static void scrarea_draw_shape_dark(ScrArea *area, char dir, uint pos) { - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor4ub(0, 0, 0, 50); draw_join_shape(area, dir, pos); @@ -308,10 +307,8 @@ static void scrarea_draw_shape_dark(ScrArea *area, char dir, uint pos) */ static void scrarea_draw_shape_light(ScrArea *area, char UNUSED(dir), uint pos) { - GPU_blend_set_func(GPU_DST_COLOR, GPU_SRC_ALPHA); - /* value 181 was hardly computed: 181~105 */ - immUniformColor4ub(255, 255, 255, 50); - /* draw_join_shape(area, dir); */ + GPU_blend(GPU_BLEND_ALPHA); + immUniformColor4ub(255, 255, 255, 25); immRectf(pos, area->v1->vec.x, area->v1->vec.y, area->v3->vec.x, area->v3->vec.y); } @@ -413,9 +410,7 @@ void ED_screen_draw_edges(wmWindow *win) corner_scale = U.pixelsize * 8.0f; edge_thickness = corner_scale * 0.21f; - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPUBatch *batch = batch_screen_edges_get(&verts_per_corner); GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_AREA_EDGES); @@ -427,7 +422,7 @@ void ED_screen_draw_edges(wmWindow *win) drawscredge_area(area, winsize_x, winsize_y, edge_thickness); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); if (U.pixelsize <= 1.0f) { GPU_scissor_test(false); @@ -470,12 +465,12 @@ void ED_screen_draw_join_shape(ScrArea *sa1, ScrArea *sa2) break; } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); scrarea_draw_shape_dark(sa2, dir, pos); scrarea_draw_shape_light(sa1, dira, pos); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } immUnbindProgram(); @@ -487,9 +482,7 @@ void ED_screen_draw_split_preview(ScrArea *area, const int dir, const float fac) immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* splitpoint */ - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor4ub(255, 255, 255, 100); @@ -531,7 +524,7 @@ void ED_screen_draw_split_preview(ScrArea *area, const int dir, const float fac) immEnd(); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); } diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 06e800433b1..dbf84cad80b 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1594,7 +1594,7 @@ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph) ED_clip_update_frame(bmain, scene->r.cfra); /* this function applies the changes too */ - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); } /* diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index d4379262666..0e38340d3bc 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -634,8 +634,7 @@ static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups, uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); /* Premultiplied alpha blending. */ - GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA_PREMULT); immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR); @@ -670,8 +669,6 @@ static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups, GPU_texture_unbind(texture); - GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA); - if (ELEM(mtex->brush_map_mode, MTEX_MAP_MODE_STENCIL, MTEX_MAP_MODE_VIEW)) { GPU_matrix_pop(); } @@ -729,8 +726,7 @@ static bool paint_draw_cursor_overlay( uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA_PREMULT); immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR); @@ -757,8 +753,6 @@ static bool paint_draw_cursor_overlay( immUnbindProgram(); - GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA); - if (do_pop) { GPU_matrix_pop(); } @@ -781,7 +775,8 @@ static bool paint_draw_alpha_overlay(UnifiedPaintSettings *ups, bool alpha_overlay_active = false; ePaintOverlayControlFlags flags = BKE_paint_get_overlay_flags(); - gpuPushAttr(GPU_DEPTH_BUFFER_BIT | GPU_BLEND_BIT); + eGPUBlend blend_state = GPU_blend_get(); + bool depth_test = GPU_depth_test_enabled(); /* Translate to region. */ GPU_matrix_push(); @@ -811,7 +806,8 @@ static bool paint_draw_alpha_overlay(UnifiedPaintSettings *ups, } GPU_matrix_pop(); - gpuPopAttr(); + GPU_blend(blend_state); + GPU_depth_test(depth_test); return alpha_overlay_active; } @@ -922,7 +918,7 @@ static void paint_draw_curve_cursor(Brush *brush, ViewContext *vc) PaintCurvePoint *cp = pc->points; GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* Draw the bezier handles and the curve segment between the current and next point. */ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -983,7 +979,7 @@ static void paint_draw_curve_cursor(Brush *brush, ViewContext *vc) draw_rect_point( pos, selec_col, handle_col, &cp->bez.vec[2][0], 8.0f, cp->bez.f3 || cp->bez.f2); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); immUnbindProgram(); @@ -1762,9 +1758,6 @@ static void paint_cursor_cursor_draw_3d_view_brush_cursor_active(PaintCursorCont 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); } @@ -1842,7 +1835,7 @@ static void paint_cursor_update_anchored_location(PaintCursorContext *pcontext) static void paint_cursor_setup_2D_drawing(PaintCursorContext *pcontext) { GPU_line_width(2.0f); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); pcontext->pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -1852,7 +1845,7 @@ static void paint_cursor_setup_2D_drawing(PaintCursorContext *pcontext) static void paint_cursor_setup_3D_drawing(PaintCursorContext *pcontext) { GPU_line_width(2.0f); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); pcontext->pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); @@ -1862,7 +1855,7 @@ static void paint_cursor_setup_3D_drawing(PaintCursorContext *pcontext) static void paint_cursor_restore_drawing_state(void) { immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); } diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 431ab998f62..d2ae6912fc3 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -438,7 +438,7 @@ static void gradient_draw_line(bContext *UNUSED(C), int x, int y, void *customda if (pop) { GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); @@ -467,7 +467,7 @@ static void gradient_draw_line(bContext *UNUSED(C), int x, int y, void *customda immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); } } diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index db7de01bee5..456c1f61cb1 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -407,7 +407,6 @@ typedef struct ProjPaintState { SpinLock *tile_lock; Mesh *me_eval; - bool me_eval_free; int totlooptri_eval; int totloop_eval; int totpoly_eval; @@ -4033,27 +4032,14 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p CustomData_MeshMasks cddata_masks = scene_eval->customdata_mask; cddata_masks.fmask |= CD_MASK_MTFACE; cddata_masks.lmask |= CD_MASK_MLOOPUV; - - /* Workaround for subsurf selection, try the display mesh first */ - if (ps->source == PROJ_SRC_IMAGE_CAM) { - /* using render mesh, assume only camera was rendered from */ - ps->me_eval = mesh_create_eval_final_render(depsgraph, scene_eval, ob_eval, &cddata_masks); - ps->me_eval_free = true; - } - else { - if (ps->do_face_sel) { - cddata_masks.vmask |= CD_MASK_ORIGINDEX; - cddata_masks.emask |= CD_MASK_ORIGINDEX; - cddata_masks.pmask |= CD_MASK_ORIGINDEX; - } - ps->me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks); - ps->me_eval_free = false; + if (ps->do_face_sel) { + cddata_masks.vmask |= CD_MASK_ORIGINDEX; + cddata_masks.emask |= CD_MASK_ORIGINDEX; + cddata_masks.pmask |= CD_MASK_ORIGINDEX; } + ps->me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks); if (!CustomData_has_layer(&ps->me_eval->ldata, CD_MLOOPUV)) { - if (ps->me_eval_free) { - BKE_id_free(NULL, ps->me_eval); - } ps->me_eval = NULL; return false; } @@ -4636,9 +4622,6 @@ static void project_paint_end(ProjPaintState *ps) MEM_freeN(ps->cavities); } - if (ps->me_eval_free) { - BKE_id_free(NULL, ps->me_eval); - } ps->me_eval = NULL; } diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 90b0f017bd6..52cdebf3fd5 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -143,7 +143,7 @@ static void paint_draw_smooth_cursor(bContext *C, int x, int y, void *customdata if (stroke && brush) { GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); ARegion *region = stroke->vc.region; @@ -161,7 +161,7 @@ static void paint_draw_smooth_cursor(bContext *C, int x, int y, void *customdata immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); } } @@ -997,7 +997,19 @@ static void stroke_done(bContext *C, wmOperator *op) /* Returns zero if the stroke dots should not be spaced, non-zero otherwise */ bool paint_space_stroke_enabled(Brush *br, ePaintMode mode) { - return (br->flag & BRUSH_SPACE) && paint_supports_dynamic_size(br, mode); + if ((br->flag & BRUSH_SPACE) == 0) { + return false; + } + + if (br->sculpt_tool == SCULPT_TOOL_CLOTH) { + /* The Cloth Brush is a special case for stroke spacing. Even if it has grab modes which do + * not support dynamic size, stroke spacing needs to be enabled so it is possible to control + * whether the simulation runs constantly or only when the brush moves when using the cloth + * grab brushes. */ + return true; + } + + return paint_supports_dynamic_size(br, mode); } static bool sculpt_is_grab_tool(Brush *br) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index d68b1226b40..e1c1b8ee5fb 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -275,6 +275,19 @@ void SCULPT_active_vertex_normal_get(SculptSession *ss, float normal[3]) SCULPT_vertex_normal_get(ss, SCULPT_active_vertex_get(ss), normal); } +float *SCULPT_brush_deform_target_vertex_co_get(SculptSession *ss, + const int deform_target, + PBVHVertexIter *iter) +{ + switch (deform_target) { + case BRUSH_DEFORM_TARGET_GEOMETRY: + return iter->co; + case BRUSH_DEFORM_TARGET_CLOTH_SIM: + return ss->cache->cloth_sim->deformation_pos[iter->index]; + } + return iter->co; +} + /* Sculpt Face Sets and Visibility. */ int SCULPT_active_face_set_get(SculptSession *ss) @@ -2331,7 +2344,7 @@ static float brush_strength(const Sculpt *sd, } case SCULPT_TOOL_SMOOTH: - return alpha * pressure * feather; + return flip * alpha * pressure * feather; case SCULPT_TOOL_PINCH: if (flip > 0.0f) { @@ -5690,6 +5703,16 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe SCULPT_pose_brush_init(sd, ob, ss, brush); } + if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) { + if (!ss->cache->cloth_sim) { + ss->cache->cloth_sim = SCULPT_cloth_brush_simulation_create(ss, brush, 1.0f, 0.0f, false); + SCULPT_cloth_brush_simulation_init(ss, ss->cache->cloth_sim); + SCULPT_cloth_brush_build_nodes_constraints( + sd, ob, nodes, totnode, ss->cache->cloth_sim, ss->cache->location, FLT_MAX); + } + SCULPT_cloth_brush_store_simulation_state(ss, ss->cache->cloth_sim); + } + bool invert = ss->cache->pen_flip || ss->cache->invert || brush->flag & BRUSH_DIR_IN; /* Apply one type of brush action. */ @@ -5828,6 +5851,12 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe do_gravity(sd, ob, nodes, totnode, sd->gravity_factor); } + if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) { + if (SCULPT_stroke_is_main_symmetry_pass(ss->cache)) { + SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode); + } + } + MEM_SAFE_FREE(nodes); /* Update average stroke position. */ @@ -6365,14 +6394,15 @@ void SCULPT_cache_free(StrokeCache *cache) MEM_SAFE_FREE(cache->surface_smooth_laplacian_disp); MEM_SAFE_FREE(cache->layer_displacement_factor); MEM_SAFE_FREE(cache->prev_colors); + MEM_SAFE_FREE(cache->detail_directions); if (cache->pose_ik_chain) { SCULPT_pose_ik_chain_free(cache->pose_ik_chain); } for (int i = 0; i < PAINT_SYMM_AREAS; i++) { - if (cache->bdata[i]) { - SCULPT_boundary_data_free(cache->bdata[i]); + if (cache->boundaries[i]) { + SCULPT_boundary_data_free(cache->boundaries[i]); } } @@ -7125,6 +7155,7 @@ bool SCULPT_cursor_geometry_info_update(bContext *C, /* Update the active vertex of the SculptSession. */ ss->active_vertex_index = srd.active_vertex_index; + SCULPT_vertex_random_access_ensure(ss); copy_v3_v3(out->active_vertex_co, SCULPT_active_vertex_co_get(ss)); switch (BKE_pbvh_type(ss->pbvh)) { @@ -7306,7 +7337,8 @@ static void sculpt_brush_stroke_init(bContext *C, wmOperator *op) need_mask = true; } - if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) { + if (brush->sculpt_tool == SCULPT_TOOL_CLOTH || + brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) { need_mask = true; } diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c index f65c64d6d78..5e01e034715 100644 --- a/source/blender/editors/sculpt_paint/sculpt_boundary.c +++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c @@ -130,38 +130,39 @@ static int sculpt_boundary_get_closest_boundary_vertex(SculptSession *ss, * deformations usually need in the boundary. */ static int BOUNDARY_INDICES_BLOCK_SIZE = 300; -static void sculpt_boundary_index_add(SculptBoundary *bdata, +static void sculpt_boundary_index_add(SculptBoundary *boundary, const int new_index, const float distance, GSet *included_vertices) { - bdata->vertices[bdata->num_vertices] = new_index; - if (bdata->distance) { - bdata->distance[new_index] = distance; + boundary->vertices[boundary->num_vertices] = new_index; + if (boundary->distance) { + boundary->distance[new_index] = distance; } if (included_vertices) { BLI_gset_add(included_vertices, POINTER_FROM_INT(new_index)); } - bdata->num_vertices++; - if (bdata->num_vertices >= bdata->vertices_capacity) { - bdata->vertices_capacity += BOUNDARY_INDICES_BLOCK_SIZE; - bdata->vertices = MEM_reallocN_id( - bdata->vertices, bdata->vertices_capacity * sizeof(int), "boundary indices"); + boundary->num_vertices++; + if (boundary->num_vertices >= boundary->vertices_capacity) { + boundary->vertices_capacity += BOUNDARY_INDICES_BLOCK_SIZE; + boundary->vertices = MEM_reallocN_id( + boundary->vertices, boundary->vertices_capacity * sizeof(int), "boundary indices"); } }; -static void sculpt_boundary_preview_edge_add(SculptBoundary *bdata, const int v1, const int v2) +static void sculpt_boundary_preview_edge_add(SculptBoundary *boundary, const int v1, const int v2) { - bdata->edges[bdata->num_edges].v1 = v1; - bdata->edges[bdata->num_edges].v2 = v2; - bdata->num_edges++; + boundary->edges[boundary->num_edges].v1 = v1; + boundary->edges[boundary->num_edges].v2 = v2; + boundary->num_edges++; - if (bdata->num_edges >= bdata->edges_capacity) { - bdata->edges_capacity += BOUNDARY_INDICES_BLOCK_SIZE; - bdata->edges = MEM_reallocN_id( - bdata->edges, bdata->edges_capacity * sizeof(SculptBoundaryPreviewEdge), "boundary edges"); + if (boundary->num_edges >= boundary->edges_capacity) { + boundary->edges_capacity += BOUNDARY_INDICES_BLOCK_SIZE; + boundary->edges = MEM_reallocN_id(boundary->edges, + boundary->edges_capacity * sizeof(SculptBoundaryPreviewEdge), + "boundary edges"); } }; @@ -203,7 +204,7 @@ static bool sculpt_boundary_is_vertex_in_editable_boundary(SculptSession *ss, */ typedef struct BoundaryFloodFillData { - SculptBoundary *bdata; + SculptBoundary *boundary; GSet *included_vertices; EdgeSet *preview_edges; @@ -215,15 +216,16 @@ static bool boundary_floodfill_cb( SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata) { BoundaryFloodFillData *data = userdata; - SculptBoundary *bdata = data->bdata; + SculptBoundary *boundary = data->boundary; if (SCULPT_vertex_is_boundary(ss, to_v)) { const float edge_len = len_v3v3(SCULPT_vertex_co_get(ss, from_v), SCULPT_vertex_co_get(ss, to_v)); - const float distance_boundary_to_dst = bdata->distance ? bdata->distance[from_v] + edge_len : - 0.0f; - sculpt_boundary_index_add(bdata, to_v, distance_boundary_to_dst, data->included_vertices); + const float distance_boundary_to_dst = boundary->distance ? + boundary->distance[from_v] + edge_len : + 0.0f; + sculpt_boundary_index_add(boundary, to_v, distance_boundary_to_dst, data->included_vertices); if (!is_duplicate) { - sculpt_boundary_preview_edge_add(bdata, from_v, to_v); + sculpt_boundary_preview_edge_add(boundary, from_v, to_v); } return sculpt_boundary_is_vertex_in_editable_boundary(ss, to_v); } @@ -231,31 +233,32 @@ static bool boundary_floodfill_cb( } static void sculpt_boundary_indices_init(SculptSession *ss, - SculptBoundary *bdata, + SculptBoundary *boundary, const bool init_boundary_distances, const int initial_boundary_index) { const int totvert = SCULPT_vertex_count_get(ss); - bdata->vertices = MEM_malloc_arrayN( + boundary->vertices = MEM_malloc_arrayN( BOUNDARY_INDICES_BLOCK_SIZE, sizeof(int), "boundary indices"); if (init_boundary_distances) { - bdata->distance = MEM_calloc_arrayN(totvert, sizeof(float), "boundary distances"); + boundary->distance = MEM_calloc_arrayN(totvert, sizeof(float), "boundary distances"); } - bdata->edges = MEM_malloc_arrayN( + boundary->edges = MEM_malloc_arrayN( BOUNDARY_INDICES_BLOCK_SIZE, sizeof(SculptBoundaryPreviewEdge), "boundary edges"); GSet *included_vertices = BLI_gset_int_new_ex("included vertices", BOUNDARY_INDICES_BLOCK_SIZE); SculptFloodFill flood; SCULPT_floodfill_init(ss, &flood); - bdata->initial_vertex = initial_boundary_index; - copy_v3_v3(bdata->initial_vertex_position, SCULPT_vertex_co_get(ss, bdata->initial_vertex)); - sculpt_boundary_index_add(bdata, initial_boundary_index, 0.0f, included_vertices); + boundary->initial_vertex = initial_boundary_index; + copy_v3_v3(boundary->initial_vertex_position, + SCULPT_vertex_co_get(ss, boundary->initial_vertex)); + sculpt_boundary_index_add(boundary, initial_boundary_index, 0.0f, included_vertices); SCULPT_floodfill_add_initial(&flood, initial_boundary_index); BoundaryFloodFillData fdata = { - .bdata = bdata, + .boundary = boundary, .included_vertices = included_vertices, .last_visited_vertex = BOUNDARY_VERTEX_NONE, @@ -271,8 +274,8 @@ static void sculpt_boundary_indices_init(SculptSession *ss, SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, fdata.last_visited_vertex, ni) { if (BLI_gset_haskey(included_vertices, POINTER_FROM_INT(ni.index)) && sculpt_boundary_is_vertex_in_editable_boundary(ss, ni.index)) { - sculpt_boundary_preview_edge_add(bdata, fdata.last_visited_vertex, ni.index); - bdata->forms_loop = true; + sculpt_boundary_preview_edge_add(boundary, fdata.last_visited_vertex, ni.index); + boundary->forms_loop = true; } } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); @@ -288,7 +291,7 @@ static void sculpt_boundary_indices_init(SculptSession *ss, * the closest one. */ static void sculpt_boundary_edit_data_init(SculptSession *ss, - SculptBoundary *bdata, + SculptBoundary *boundary, const int initial_vertex, const float radius) { @@ -296,12 +299,12 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, const bool has_duplicates = BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS; - bdata->edit_info = MEM_malloc_arrayN( + boundary->edit_info = MEM_malloc_arrayN( totvert, sizeof(SculptBoundaryEditInfo), "Boundary edit info"); for (int i = 0; i < totvert; i++) { - bdata->edit_info[i].original_vertex = BOUNDARY_VERTEX_NONE; - bdata->edit_info[i].num_propagation_steps = BOUNDARY_STEPS_NONE; + boundary->edit_info[i].original_vertex = BOUNDARY_VERTEX_NONE; + boundary->edit_info[i].num_propagation_steps = BOUNDARY_STEPS_NONE; } GSQueue *current_iteration = BLI_gsqueue_new(sizeof(int)); @@ -310,23 +313,23 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, /* Initialized the first iteration with the vertices already in the boundary. This is propagation * step 0. */ BLI_bitmap *visited_vertices = BLI_BITMAP_NEW(SCULPT_vertex_count_get(ss), "visited_vertices"); - for (int i = 0; i < bdata->num_vertices; i++) { - bdata->edit_info[bdata->vertices[i]].original_vertex = bdata->vertices[i]; - bdata->edit_info[bdata->vertices[i]].num_propagation_steps = 0; + for (int i = 0; i < boundary->num_vertices; i++) { + boundary->edit_info[boundary->vertices[i]].original_vertex = boundary->vertices[i]; + boundary->edit_info[boundary->vertices[i]].num_propagation_steps = 0; /* This ensures that all duplicate vertices in the boundary have the same original_vertex * index, so the deformation for them will be the same. */ if (has_duplicates) { SculptVertexNeighborIter ni_duplis; - SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, bdata->vertices[i], ni_duplis) { + SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, boundary->vertices[i], ni_duplis) { if (ni_duplis.is_duplicate) { - bdata->edit_info[ni_duplis.index].original_vertex = bdata->vertices[i]; + boundary->edit_info[ni_duplis.index].original_vertex = boundary->vertices[i]; } } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis); } - BLI_gsqueue_push(current_iteration, &bdata->vertices[i]); + BLI_gsqueue_push(current_iteration, &boundary->vertices[i]); } int num_propagation_steps = 0; @@ -336,7 +339,7 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, /* This steps is further away from the boundary than the brush radius, so stop adding more * steps. */ if (accum_distance > radius) { - bdata->max_propagation_steps = num_propagation_steps; + boundary->max_propagation_steps = num_propagation_steps; break; } @@ -346,19 +349,20 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, SculptVertexNeighborIter ni; SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) { - if (bdata->edit_info[ni.index].num_propagation_steps == BOUNDARY_STEPS_NONE) { - bdata->edit_info[ni.index].original_vertex = bdata->edit_info[from_v].original_vertex; + if (boundary->edit_info[ni.index].num_propagation_steps == BOUNDARY_STEPS_NONE) { + boundary->edit_info[ni.index].original_vertex = + boundary->edit_info[from_v].original_vertex; BLI_BITMAP_ENABLE(visited_vertices, ni.index); if (ni.is_duplicate) { /* Grids duplicates handling. */ - bdata->edit_info[ni.index].num_propagation_steps = - bdata->edit_info[from_v].num_propagation_steps; + boundary->edit_info[ni.index].num_propagation_steps = + boundary->edit_info[from_v].num_propagation_steps; } else { - bdata->edit_info[ni.index].num_propagation_steps = - bdata->edit_info[from_v].num_propagation_steps + 1; + boundary->edit_info[ni.index].num_propagation_steps = + boundary->edit_info[from_v].num_propagation_steps + 1; BLI_gsqueue_push(next_iteration, &ni.index); @@ -370,10 +374,10 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, SculptVertexNeighborIter ni_duplis; SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, ni.index, ni_duplis) { if (ni_duplis.is_duplicate) { - bdata->edit_info[ni_duplis.index].original_vertex = - bdata->edit_info[from_v].original_vertex; - bdata->edit_info[ni_duplis.index].num_propagation_steps = - bdata->edit_info[from_v].num_propagation_steps + 1; + boundary->edit_info[ni_duplis.index].original_vertex = + boundary->edit_info[from_v].original_vertex; + boundary->edit_info[ni_duplis.index].num_propagation_steps = + boundary->edit_info[from_v].num_propagation_steps + 1; } } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis); @@ -381,9 +385,9 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, /* Check the distance using the vertex that was propagated from the initial vertex that * was used to initialize the boundary. */ - if (bdata->edit_info[from_v].original_vertex == initial_vertex) { - bdata->pivot_vertex = ni.index; - copy_v3_v3(bdata->initial_pivot_position, SCULPT_vertex_co_get(ss, ni.index)); + if (boundary->edit_info[from_v].original_vertex == initial_vertex) { + boundary->pivot_vertex = ni.index; + copy_v3_v3(boundary->initial_pivot_position, SCULPT_vertex_co_get(ss, ni.index)); accum_distance += len_v3v3(SCULPT_vertex_co_get(ss, from_v), SCULPT_vertex_co_get(ss, ni.index)); } @@ -419,7 +423,7 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, * on the brush curve and its propagation steps. The falloff goes from the boundary into the mesh. */ static void sculpt_boundary_falloff_factor_init(SculptSession *ss, - SculptBoundary *bdata, + SculptBoundary *boundary, Brush *brush, const float radius) { @@ -427,24 +431,24 @@ static void sculpt_boundary_falloff_factor_init(SculptSession *ss, BKE_curvemapping_init(brush->curve); for (int i = 0; i < totvert; i++) { - if (bdata->edit_info[i].num_propagation_steps != -1) { - bdata->edit_info[i].strength_factor = BKE_brush_curve_strength( - brush, bdata->edit_info[i].num_propagation_steps, bdata->max_propagation_steps); + if (boundary->edit_info[i].num_propagation_steps != -1) { + boundary->edit_info[i].strength_factor = BKE_brush_curve_strength( + brush, boundary->edit_info[i].num_propagation_steps, boundary->max_propagation_steps); } - if (bdata->edit_info[i].original_vertex == bdata->initial_vertex) { + if (boundary->edit_info[i].original_vertex == boundary->initial_vertex) { /* All vertices that are propagated from the original vertex won't be affected by the * boundary falloff, so there is no need to calculate anything else. */ continue; } - if (!bdata->distance) { + if (!boundary->distance) { /* There are falloff modes that do not require to modify the previously calculated falloff * based on boundary distances. */ continue; } - const float boundary_distance = bdata->distance[bdata->edit_info[i].original_vertex]; + const float boundary_distance = boundary->distance[boundary->edit_info[i].original_vertex]; float falloff_distance = 0.0f; float direction = 1.0f; @@ -471,8 +475,8 @@ static void sculpt_boundary_falloff_factor_init(SculptSession *ss, BLI_assert(false); } - bdata->edit_info[i].strength_factor *= direction * BKE_brush_curve_strength( - brush, falloff_distance, radius); + boundary->edit_info[i].strength_factor *= direction * BKE_brush_curve_strength( + brush, falloff_distance, radius); } } @@ -501,116 +505,118 @@ SculptBoundary *SCULPT_boundary_data_init(Object *object, return NULL; } - SculptBoundary *bdata = MEM_callocN(sizeof(SculptBoundary), "Boundary edit data"); + SculptBoundary *boundary = MEM_callocN(sizeof(SculptBoundary), "Boundary edit data"); const bool init_boundary_distances = brush->boundary_falloff_type != BRUSH_BOUNDARY_FALLOFF_CONSTANT; - sculpt_boundary_indices_init(ss, bdata, init_boundary_distances, boundary_initial_vertex); + sculpt_boundary_indices_init(ss, boundary, init_boundary_distances, boundary_initial_vertex); const float boundary_radius = radius * (1.0f + brush->boundary_offset); - sculpt_boundary_edit_data_init(ss, bdata, boundary_initial_vertex, boundary_radius); + sculpt_boundary_edit_data_init(ss, boundary, boundary_initial_vertex, boundary_radius); - return bdata; + return boundary; } -void SCULPT_boundary_data_free(SculptBoundary *bdata) +void SCULPT_boundary_data_free(SculptBoundary *boundary) { - MEM_SAFE_FREE(bdata->vertices); - MEM_SAFE_FREE(bdata->distance); - MEM_SAFE_FREE(bdata->edit_info); - MEM_SAFE_FREE(bdata->bend.pivot_positions); - MEM_SAFE_FREE(bdata->bend.pivot_rotation_axis); - MEM_SAFE_FREE(bdata->slide.directions); - MEM_SAFE_FREE(bdata); + MEM_SAFE_FREE(boundary->vertices); + MEM_SAFE_FREE(boundary->distance); + MEM_SAFE_FREE(boundary->edit_info); + MEM_SAFE_FREE(boundary->bend.pivot_positions); + MEM_SAFE_FREE(boundary->bend.pivot_rotation_axis); + MEM_SAFE_FREE(boundary->slide.directions); + MEM_SAFE_FREE(boundary); } /* These functions initialize the required vectors for the desired deformation using the * SculptBoundaryEditInfo. They calculate the data using the vertices that have the * max_propagation_steps value and them this data is copied to the rest of the vertices using the * original vertex index. */ -static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *bdata) +static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *boundary) { const int totvert = SCULPT_vertex_count_get(ss); - bdata->bend.pivot_rotation_axis = MEM_calloc_arrayN( + boundary->bend.pivot_rotation_axis = MEM_calloc_arrayN( totvert, 3 * sizeof(float), "pivot rotation axis"); - bdata->bend.pivot_positions = MEM_calloc_arrayN(totvert, 3 * sizeof(float), "pivot positions"); + boundary->bend.pivot_positions = MEM_calloc_arrayN( + totvert, 3 * sizeof(float), "pivot positions"); for (int i = 0; i < totvert; i++) { - if (bdata->edit_info[i].num_propagation_steps == bdata->max_propagation_steps) { + if (boundary->edit_info[i].num_propagation_steps == boundary->max_propagation_steps) { float dir[3]; float normal[3]; SCULPT_vertex_normal_get(ss, i, normal); sub_v3_v3v3(dir, - SCULPT_vertex_co_get(ss, bdata->edit_info[i].original_vertex), + SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex), SCULPT_vertex_co_get(ss, i)); cross_v3_v3v3( - bdata->bend.pivot_rotation_axis[bdata->edit_info[i].original_vertex], dir, normal); - normalize_v3(bdata->bend.pivot_rotation_axis[bdata->edit_info[i].original_vertex]); - copy_v3_v3(bdata->bend.pivot_positions[bdata->edit_info[i].original_vertex], + boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex], dir, normal); + normalize_v3(boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]); + copy_v3_v3(boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex], SCULPT_vertex_co_get(ss, i)); } } for (int i = 0; i < totvert; i++) { - if (bdata->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) { - copy_v3_v3(bdata->bend.pivot_positions[i], - bdata->bend.pivot_positions[bdata->edit_info[i].original_vertex]); - copy_v3_v3(bdata->bend.pivot_rotation_axis[i], - bdata->bend.pivot_rotation_axis[bdata->edit_info[i].original_vertex]); + if (boundary->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) { + copy_v3_v3(boundary->bend.pivot_positions[i], + boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex]); + copy_v3_v3(boundary->bend.pivot_rotation_axis[i], + boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]); } } } -static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *bdata) +static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *boundary) { const int totvert = SCULPT_vertex_count_get(ss); - bdata->slide.directions = MEM_calloc_arrayN(totvert, 3 * sizeof(float), "slide directions"); + boundary->slide.directions = MEM_calloc_arrayN(totvert, 3 * sizeof(float), "slide directions"); for (int i = 0; i < totvert; i++) { - if (bdata->edit_info[i].num_propagation_steps == bdata->max_propagation_steps) { - sub_v3_v3v3(bdata->slide.directions[bdata->edit_info[i].original_vertex], - SCULPT_vertex_co_get(ss, bdata->edit_info[i].original_vertex), + if (boundary->edit_info[i].num_propagation_steps == boundary->max_propagation_steps) { + sub_v3_v3v3(boundary->slide.directions[boundary->edit_info[i].original_vertex], + SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex), SCULPT_vertex_co_get(ss, i)); - normalize_v3(bdata->slide.directions[bdata->edit_info[i].original_vertex]); + normalize_v3(boundary->slide.directions[boundary->edit_info[i].original_vertex]); } } for (int i = 0; i < totvert; i++) { - if (bdata->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) { - copy_v3_v3(bdata->slide.directions[i], - bdata->slide.directions[bdata->edit_info[i].original_vertex]); + if (boundary->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) { + copy_v3_v3(boundary->slide.directions[i], + boundary->slide.directions[boundary->edit_info[i].original_vertex]); } } } -static void sculpt_boundary_twist_data_init(SculptSession *ss, SculptBoundary *bdata) +static void sculpt_boundary_twist_data_init(SculptSession *ss, SculptBoundary *boundary) { - zero_v3(bdata->twist.pivot_position); - float(*poly_verts)[3] = MEM_malloc_arrayN(bdata->num_vertices, sizeof(float) * 3, "poly verts"); - for (int i = 0; i < bdata->num_vertices; i++) { - add_v3_v3(bdata->twist.pivot_position, SCULPT_vertex_co_get(ss, bdata->vertices[i])); - copy_v3_v3(poly_verts[i], SCULPT_vertex_co_get(ss, bdata->vertices[i])); + zero_v3(boundary->twist.pivot_position); + float(*poly_verts)[3] = MEM_malloc_arrayN( + boundary->num_vertices, sizeof(float) * 3, "poly verts"); + for (int i = 0; i < boundary->num_vertices; i++) { + add_v3_v3(boundary->twist.pivot_position, SCULPT_vertex_co_get(ss, boundary->vertices[i])); + copy_v3_v3(poly_verts[i], SCULPT_vertex_co_get(ss, boundary->vertices[i])); } - mul_v3_fl(bdata->twist.pivot_position, 1.0f / bdata->num_vertices); - if (bdata->forms_loop) { - normal_poly_v3(bdata->twist.rotation_axis, poly_verts, bdata->num_vertices); + mul_v3_fl(boundary->twist.pivot_position, 1.0f / boundary->num_vertices); + if (boundary->forms_loop) { + normal_poly_v3(boundary->twist.rotation_axis, poly_verts, boundary->num_vertices); } else { - sub_v3_v3v3(bdata->twist.rotation_axis, - SCULPT_vertex_co_get(ss, bdata->pivot_vertex), - SCULPT_vertex_co_get(ss, bdata->initial_vertex)); - normalize_v3(bdata->twist.rotation_axis); + sub_v3_v3v3(boundary->twist.rotation_axis, + SCULPT_vertex_co_get(ss, boundary->pivot_vertex), + SCULPT_vertex_co_get(ss, boundary->initial_vertex)); + normalize_v3(boundary->twist.rotation_axis); } MEM_freeN(poly_verts); } static float sculpt_boundary_displacement_from_grab_delta_get(SculptSession *ss, - SculptBoundary *bdata) + SculptBoundary *boundary) { float plane[4]; float pos[3]; float normal[3]; - sub_v3_v3v3(normal, ss->cache->initial_location, bdata->initial_pivot_position); + sub_v3_v3v3(normal, ss->cache->initial_location, boundary->initial_pivot_position); normalize_v3(normal); plane_from_point_normal_v3(plane, ss->cache->initial_location, normal); add_v3_v3v3(pos, ss->cache->initial_location, ss->cache->grab_delta_symmetry); @@ -625,8 +631,9 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata, SculptThreadedTaskData *data = userdata; SculptSession *ss = data->ob->sculpt; const int symm_area = ss->cache->mirror_symmetry_pass; - SculptBoundary *bdata = ss->cache->bdata[symm_area]; + SculptBoundary *boundary = ss->cache->boundaries[symm_area]; const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; + const Brush *brush = data->brush; const float strength = ss->cache->bstrength; @@ -634,7 +641,7 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata, SculptOrigVertData orig_data; SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]); - const float disp = strength * sculpt_boundary_displacement_from_grab_delta_get(ss, bdata); + const float disp = strength * sculpt_boundary_displacement_from_grab_delta_get(ss, boundary); float angle_factor = disp / ss->cache->radius; /* Angle Snapping when inverting the brush. */ if (ss->cache->invert) { @@ -645,17 +652,19 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (bdata->edit_info[vd.index].num_propagation_steps != -1) { + if (boundary->edit_info[vd.index].num_propagation_steps != -1) { SCULPT_orig_vert_data_update(&orig_data, &vd); - if (SCULPT_check_vertex_pivot_symmetry(orig_data.co, bdata->initial_vertex_position, symm)) { + if (SCULPT_check_vertex_pivot_symmetry( + orig_data.co, boundary->initial_vertex_position, symm)) { const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; float t_orig_co[3]; - sub_v3_v3v3(t_orig_co, orig_data.co, bdata->bend.pivot_positions[vd.index]); - rotate_v3_v3v3fl(vd.co, + float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd); + sub_v3_v3v3(t_orig_co, orig_data.co, boundary->bend.pivot_positions[vd.index]); + rotate_v3_v3v3fl(target_co, t_orig_co, - bdata->bend.pivot_rotation_axis[vd.index], - angle * bdata->edit_info[vd.index].strength_factor * mask); - add_v3_v3(vd.co, bdata->bend.pivot_positions[vd.index]); + boundary->bend.pivot_rotation_axis[vd.index], + angle * boundary->edit_info[vd.index].strength_factor * mask); + add_v3_v3(target_co, boundary->bend.pivot_positions[vd.index]); } } @@ -673,8 +682,9 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata, SculptThreadedTaskData *data = userdata; SculptSession *ss = data->ob->sculpt; const int symm_area = ss->cache->mirror_symmetry_pass; - SculptBoundary *bdata = ss->cache->bdata[symm_area]; + SculptBoundary *boundary = ss->cache->boundaries[symm_area]; const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; + const Brush *brush = data->brush; const float strength = ss->cache->bstrength; @@ -682,19 +692,21 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata, SculptOrigVertData orig_data; SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]); - const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, bdata); + const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, boundary); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (bdata->edit_info[vd.index].num_propagation_steps != -1) { + if (boundary->edit_info[vd.index].num_propagation_steps != -1) { SCULPT_orig_vert_data_update(&orig_data, &vd); - if (SCULPT_check_vertex_pivot_symmetry(orig_data.co, bdata->initial_vertex_position, symm)) { + if (SCULPT_check_vertex_pivot_symmetry( + orig_data.co, boundary->initial_vertex_position, symm)) { const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; - madd_v3_v3v3fl(vd.co, + float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd); + madd_v3_v3v3fl(target_co, orig_data.co, - bdata->slide.directions[vd.index], - bdata->edit_info[vd.index].strength_factor * disp * mask * strength); + boundary->slide.directions[vd.index], + boundary->edit_info[vd.index].strength_factor * disp * mask * strength); } } @@ -712,8 +724,9 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata, SculptThreadedTaskData *data = userdata; SculptSession *ss = data->ob->sculpt; const int symm_area = ss->cache->mirror_symmetry_pass; - SculptBoundary *bdata = ss->cache->bdata[symm_area]; + SculptBoundary *boundary = ss->cache->boundaries[symm_area]; const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; + const Brush *brush = data->brush; const float strength = ss->cache->bstrength; @@ -721,21 +734,23 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata, SculptOrigVertData orig_data; SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]); - const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, bdata); + const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, boundary); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (bdata->edit_info[vd.index].num_propagation_steps != -1) { + if (boundary->edit_info[vd.index].num_propagation_steps != -1) { SCULPT_orig_vert_data_update(&orig_data, &vd); - if (SCULPT_check_vertex_pivot_symmetry(orig_data.co, bdata->initial_vertex_position, symm)) { + if (SCULPT_check_vertex_pivot_symmetry( + orig_data.co, boundary->initial_vertex_position, symm)) { const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; float normal[3]; normal_short_to_float_v3(normal, orig_data.no); - madd_v3_v3v3fl(vd.co, + float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd); + madd_v3_v3v3fl(target_co, orig_data.co, normal, - bdata->edit_info[vd.index].strength_factor * disp * mask * strength); + boundary->edit_info[vd.index].strength_factor * disp * mask * strength); } } @@ -753,8 +768,9 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata, SculptThreadedTaskData *data = userdata; SculptSession *ss = data->ob->sculpt; const int symm_area = ss->cache->mirror_symmetry_pass; - SculptBoundary *bdata = ss->cache->bdata[symm_area]; + SculptBoundary *boundary = ss->cache->boundaries[symm_area]; const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; + const Brush *brush = data->brush; const float strength = ss->cache->bstrength; @@ -765,14 +781,16 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (bdata->edit_info[vd.index].num_propagation_steps != -1) { + if (boundary->edit_info[vd.index].num_propagation_steps != -1) { SCULPT_orig_vert_data_update(&orig_data, &vd); - if (SCULPT_check_vertex_pivot_symmetry(orig_data.co, bdata->initial_vertex_position, symm)) { + if (SCULPT_check_vertex_pivot_symmetry( + orig_data.co, boundary->initial_vertex_position, symm)) { const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; - madd_v3_v3v3fl(vd.co, + float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd); + madd_v3_v3v3fl(target_co, orig_data.co, ss->cache->grab_delta_symmetry, - bdata->edit_info[vd.index].strength_factor * mask * strength); + boundary->edit_info[vd.index].strength_factor * mask * strength); } } @@ -790,8 +808,9 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata, SculptThreadedTaskData *data = userdata; SculptSession *ss = data->ob->sculpt; const int symm_area = ss->cache->mirror_symmetry_pass; - SculptBoundary *bdata = ss->cache->bdata[symm_area]; + SculptBoundary *boundary = ss->cache->boundaries[symm_area]; const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; + const Brush *brush = data->brush; const float strength = ss->cache->bstrength; @@ -799,7 +818,7 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata, SculptOrigVertData orig_data; SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]); - const float disp = strength * sculpt_boundary_displacement_from_grab_delta_get(ss, bdata); + const float disp = strength * sculpt_boundary_displacement_from_grab_delta_get(ss, boundary); float angle_factor = disp / ss->cache->radius; /* Angle Snapping when inverting the brush. */ if (ss->cache->invert) { @@ -810,17 +829,19 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (bdata->edit_info[vd.index].num_propagation_steps != -1) { + if (boundary->edit_info[vd.index].num_propagation_steps != -1) { SCULPT_orig_vert_data_update(&orig_data, &vd); - if (SCULPT_check_vertex_pivot_symmetry(orig_data.co, bdata->initial_vertex_position, symm)) { + if (SCULPT_check_vertex_pivot_symmetry( + orig_data.co, boundary->initial_vertex_position, symm)) { const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; float t_orig_co[3]; - sub_v3_v3v3(t_orig_co, orig_data.co, bdata->twist.pivot_position); - rotate_v3_v3v3fl(vd.co, + float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd); + sub_v3_v3v3(t_orig_co, orig_data.co, boundary->twist.pivot_position); + rotate_v3_v3v3fl(target_co, t_orig_co, - bdata->twist.rotation_axis, - angle * mask * bdata->edit_info[vd.index].strength_factor); - add_v3_v3(vd.co, bdata->twist.pivot_position); + boundary->twist.rotation_axis, + angle * mask * boundary->edit_info[vd.index].strength_factor); + add_v3_v3(target_co, boundary->twist.pivot_position); } } @@ -851,20 +872,20 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn sd, ob, location, ss->cache->radius_squared, false); } - ss->cache->bdata[symm_area] = SCULPT_boundary_data_init( + ss->cache->boundaries[symm_area] = SCULPT_boundary_data_init( ob, brush, initial_vertex, ss->cache->initial_radius); - if (ss->cache->bdata[symm_area]) { + if (ss->cache->boundaries[symm_area]) { switch (brush->boundary_deform_type) { case BRUSH_BOUNDARY_DEFORM_BEND: - sculpt_boundary_bend_data_init(ss, ss->cache->bdata[symm_area]); + sculpt_boundary_bend_data_init(ss, ss->cache->boundaries[symm_area]); break; case BRUSH_BOUNDARY_DEFORM_EXPAND: - sculpt_boundary_slide_data_init(ss, ss->cache->bdata[symm_area]); + sculpt_boundary_slide_data_init(ss, ss->cache->boundaries[symm_area]); break; case BRUSH_BOUNDARY_DEFORM_TWIST: - sculpt_boundary_twist_data_init(ss, ss->cache->bdata[symm_area]); + sculpt_boundary_twist_data_init(ss, ss->cache->boundaries[symm_area]); break; case BRUSH_BOUNDARY_DEFORM_INFLATE: case BRUSH_BOUNDARY_DEFORM_GRAB: @@ -873,12 +894,12 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn } sculpt_boundary_falloff_factor_init( - ss, ss->cache->bdata[symm_area], brush, ss->cache->initial_radius); + ss, ss->cache->boundaries[symm_area], brush, ss->cache->initial_radius); } } /* No active boundary under the cursor. */ - if (!ss->cache->bdata[symm_area]) { + if (!ss->cache->boundaries[symm_area]) { return; } diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c index 2637cb45906..9a3fbe474b8 100644 --- a/source/blender/editors/sculpt_paint/sculpt_cloth.c +++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c @@ -134,6 +134,7 @@ static float cloth_brush_simulation_falloff_get(const Brush *brush, #define CLOTH_SIMULATION_ITERATIONS 5 #define CLOTH_MAX_CONSTRAINTS_PER_VERTEX 1024 #define CLOTH_SIMULATION_TIME_STEP 0.01f +#define CLOTH_DEFORMATION_TARGET_STRENGTH 0.35f static bool cloth_brush_sim_has_length_constraint(SculptClothSimulation *cloth_sim, const int v1, @@ -297,15 +298,28 @@ static void do_cloth_brush_build_constraints_task_cb_ex( } } - 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 (brush && brush->sculpt_tool == SCULPT_TOOL_CLOTH) { + /* The cloth brush works by applying forces in most of its modes, but some of them require + * deformation coordinates to make the simulation stable. */ + if (cloth_is_deform_brush && len_squared < radius_squared) { + /* When a deform brush is used as part of the cloth brush, deformation constraints are + * created with different strengths and only inside the radius of the brush. */ + 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); + } + } + else if (data->cloth_sim->deformation_pos) { + /* Any other tool that target the cloth simulation handle the falloff in + * their own code when modifying the deformation coordinates of the simulation, so + * deformation constraints are created with a fixed strength for all vertices. */ + cloth_brush_add_deformation_constraint( + data->cloth_sim, vd.index, CLOTH_DEFORMATION_TARGET_STRENGTH); } 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. */ + /* Vertex is inside the area of the simulation without any falloff applied. */ if (sim_falloff < 1.0f) { /* Create constraints with more strength the closer the vertex is to the simulation * boundary. */ @@ -505,49 +519,6 @@ static ListBase *cloth_brush_collider_cache_create(Depsgraph *depsgraph) return cache; } -static SculptClothSimulation *cloth_brush_simulation_create(SculptSession *ss, - Brush *brush, - const float cloth_mass, - const float cloth_damping, - const bool use_collisions) -{ - const int totverts = SCULPT_vertex_count_get(ss); - SculptClothSimulation *cloth_sim; - - cloth_sim = MEM_callocN(sizeof(SculptClothSimulation), "cloth constraints"); - - cloth_sim->length_constraints = MEM_callocN(sizeof(SculptClothLengthConstraint) * - CLOTH_LENGTH_CONSTRAINTS_BLOCK, - "cloth length constraints"); - cloth_sim->capacity_length_constraints = CLOTH_LENGTH_CONSTRAINTS_BLOCK; - - cloth_sim->acceleration = MEM_calloc_arrayN( - totverts, sizeof(float[3]), "cloth sim acceleration"); - cloth_sim->pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim pos"); - cloth_sim->prev_pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "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, sizeof(float[3]), "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, sizeof(float[3]), "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; @@ -699,43 +670,6 @@ static void do_cloth_brush_solve_simulation_task_cb_ex( BKE_pbvh_vertex_iter_end; } -static void cloth_brush_build_nodes_constraints( - Sculpt *sd, - Object *ob, - PBVHNode **nodes, - int totnode, - SculptClothSimulation *cloth_sim, - /* Cannot be const, because it is assigned to a non-const variable. - * NOLINTNEXTLINE: readability-non-const-parameter. */ - float initial_location[3], - const float radius) -{ - Brush *brush = BKE_paint_brush(&sd->paint); - - /* TODO: Multi-threaded needs to be disabled for this task until implementing the optimization of - * storing the constraints per node. */ - /* Currently all constrains are added to the same global array which can't be accessed from - * different threads. */ - TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, false, totnode); - - cloth_sim->created_length_constraints = BLI_edgeset_new("created length constraints"); - - SculptThreadedTaskData build_constraints_data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .cloth_sim = cloth_sim, - .cloth_sim_initial_location = initial_location, - .cloth_sim_radius = radius, - }; - BLI_task_parallel_range( - 0, totnode, &build_constraints_data, do_cloth_brush_build_constraints_task_cb_ex, &settings); - - BLI_edgeset_free(cloth_sim->created_length_constraints); -} - static void cloth_brush_satisfy_constraints(SculptSession *ss, Brush *brush, SculptClothSimulation *cloth_sim) @@ -796,7 +730,7 @@ static void cloth_brush_satisfy_constraints(SculptSession *ss, } } -static void cloth_brush_do_simulation_step( +void SCULPT_cloth_brush_do_simulation_step( Sculpt *sd, Object *ob, SculptClothSimulation *cloth_sim, PBVHNode **nodes, int totnode) { SculptSession *ss = ob->sculpt; @@ -897,13 +831,113 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod } /* Public functions. */ +SculptClothSimulation *SCULPT_cloth_brush_simulation_create(SculptSession *ss, + Brush *brush, + const float cloth_mass, + const float cloth_damping, + const bool use_collisions) +{ + const int totverts = SCULPT_vertex_count_get(ss); + SculptClothSimulation *cloth_sim; + + cloth_sim = MEM_callocN(sizeof(SculptClothSimulation), "cloth constraints"); + + cloth_sim->length_constraints = MEM_callocN(sizeof(SculptClothLengthConstraint) * + CLOTH_LENGTH_CONSTRAINTS_BLOCK, + "cloth length constraints"); + cloth_sim->capacity_length_constraints = CLOTH_LENGTH_CONSTRAINTS_BLOCK; + + cloth_sim->acceleration = MEM_calloc_arrayN( + totverts, sizeof(float[3]), "cloth sim acceleration"); + cloth_sim->pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim pos"); + cloth_sim->prev_pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "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, sizeof(float[3]), "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, sizeof(float[3]), "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; +} + +void SCULPT_cloth_brush_build_nodes_constraints( + Sculpt *sd, + Object *ob, + PBVHNode **nodes, + int totnode, + SculptClothSimulation *cloth_sim, + /* Cannot be const, because it is assigned to a non-const variable. + * NOLINTNEXTLINE: readability-non-const-parameter. */ + float initial_location[3], + const float radius) +{ + Brush *brush = BKE_paint_brush(&sd->paint); + + /* TODO: Multi-threaded needs to be disabled for this task until implementing the optimization of + * storing the constraints per node. */ + /* Currently all constrains are added to the same global array which can't be accessed from + * different threads. */ + TaskParallelSettings settings; + BKE_pbvh_parallel_range_settings(&settings, false, totnode); + + cloth_sim->created_length_constraints = BLI_edgeset_new("created length constraints"); + + SculptThreadedTaskData build_constraints_data = { + .sd = sd, + .ob = ob, + .brush = brush, + .nodes = nodes, + .cloth_sim = cloth_sim, + .cloth_sim_initial_location = initial_location, + .cloth_sim_radius = radius, + }; + BLI_task_parallel_range( + 0, totnode, &build_constraints_data, do_cloth_brush_build_constraints_task_cb_ex, &settings); + + BLI_edgeset_free(cloth_sim->created_length_constraints); +} + +void SCULPT_cloth_brush_simulation_init(SculptSession *ss, SculptClothSimulation *cloth_sim) +{ + const int totverts = SCULPT_vertex_count_get(ss); + const bool has_deformation_pos = cloth_sim->deformation_pos != NULL; + for (int i = 0; i < totverts; i++) { + copy_v3_v3(cloth_sim->last_iteration_pos[i], SCULPT_vertex_co_get(ss, i)); + copy_v3_v3(cloth_sim->init_pos[i], SCULPT_vertex_co_get(ss, i)); + copy_v3_v3(cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, i)); + if (has_deformation_pos) { + copy_v3_v3(cloth_sim->deformation_pos[i], SCULPT_vertex_co_get(ss, i)); + } + } +} + +void SCULPT_cloth_brush_store_simulation_state(SculptSession *ss, SculptClothSimulation *cloth_sim) +{ + const int totverts = SCULPT_vertex_count_get(ss); + for (int i = 0; i < totverts; i++) { + copy_v3_v3(cloth_sim->pos[i], SCULPT_vertex_co_get(ss, i)); + } +} /* Main Brush Function. */ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); - const int totverts = SCULPT_vertex_count_get(ss); /* In the first brush step of each symmetry pass, build the constraints for the vertices in all * nodes inside the simulation's limits. */ @@ -914,42 +948,32 @@ 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->cache->cloth_sim = SCULPT_cloth_brush_simulation_create( 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->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)); - } - } + SCULPT_cloth_brush_simulation_init(ss, ss->cache->cloth_sim); } /* Build the constraints. */ const float radius = ss->cache->initial_radius; const float limit = radius + (radius * brush->cloth_sim_limit); - cloth_brush_build_nodes_constraints( + SCULPT_cloth_brush_build_nodes_constraints( sd, ob, nodes, totnode, ss->cache->cloth_sim, ss->cache->location, limit); return; } /* Store the initial state in the simulation. */ - for (int i = 0; i < totverts; i++) { - copy_v3_v3(ss->cache->cloth_sim->pos[i], SCULPT_vertex_co_get(ss, i)); - } + SCULPT_cloth_brush_store_simulation_state(ss, ss->cache->cloth_sim); /* Apply forces to the vertices. */ cloth_brush_apply_brush_foces(sd, ob, nodes, totnode); /* Update and write the simulation to the nodes. */ - cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode); + SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode); } void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim) @@ -1043,11 +1067,20 @@ static EnumPropertyItem prop_cloth_filter_type[] = { {CLOTH_FILTER_GRAVITY, "GRAVITY", 0, "Gravity", "Applies gravity to the simulation"}, {CLOTH_FILTER_INFLATE, "INFLATE", 0, "Inflate", "Inflates the cloth"}, {CLOTH_FILTER_EXPAND, "EXPAND", 0, "Expand", "Expands the cloth's dimensions"}, - {CLOTH_FILTER_PINCH, - "PINCH", - 0, - "Pinch", - "Pinches the cloth to the point were the cursor was when the filter started"}, + {CLOTH_FILTER_PINCH, "PINCH", 0, "Pinch", "Pulls the cloth to the cursor's start position"}, + {0, NULL, 0, NULL, NULL}, +}; + +typedef enum eClothFilterForceAxis { + CLOTH_FILTER_FORCE_X = 1 << 0, + CLOTH_FILTER_FORCE_Y = 1 << 1, + CLOTH_FILTER_FORCE_Z = 1 << 2, +} eClothFilterForceAxis; + +static EnumPropertyItem prop_cloth_filter_force_axis_items[] = { + {CLOTH_FILTER_FORCE_X, "X", 0, "X", "Apply force in the X axis"}, + {CLOTH_FILTER_FORCE_Y, "Y", 0, "Y", "Apply force in the Y axis"}, + {CLOTH_FILTER_FORCE_Z, "Z", 0, "Z", "Apply force in the Z axis"}, {0, NULL, 0, NULL, NULL}, }; @@ -1105,6 +1138,12 @@ static void cloth_filter_apply_forces_task_cb(void *__restrict userdata, break; } + for (int axis = 0; axis < 3; axis++) { + if (!ss->filter_cache->enabled_force_axis[axis]) { + force[axis] = 0.0f; + } + } + add_v3_v3(force, sculpt_gravity); cloth_brush_apply_force_to_vertex(ss, cloth_sim, force, vd.index); @@ -1161,7 +1200,7 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent 0, ss->filter_cache->totnode, &data, cloth_filter_apply_forces_task_cb, &settings); /* Update and write the simulation to the nodes. */ - cloth_brush_do_simulation_step( + SCULPT_cloth_brush_do_simulation_step( sd, ob, ss->filter_cache->cloth_sim, ss->filter_cache->nodes, ss->filter_cache->totnode); if (ss->deform_modifiers_active || ss->shapekey_active) { @@ -1191,31 +1230,26 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false); SCULPT_undo_push_begin("Cloth filter"); - SCULPT_filter_cache_init(ob, sd, SCULPT_UNDO_COORDS); + SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COORDS); const float cloth_mass = RNA_float_get(op->ptr, "cloth_mass"); const float cloth_damping = RNA_float_get(op->ptr, "cloth_damping"); const bool use_collisions = RNA_boolean_get(op->ptr, "use_collisions"); - ss->filter_cache->cloth_sim = cloth_brush_simulation_create( + ss->filter_cache->cloth_sim = SCULPT_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)); - } + SCULPT_cloth_brush_simulation_init(ss, ss->filter_cache->cloth_sim); float origin[3] = {0.0f, 0.0f, 0.0f}; - cloth_brush_build_nodes_constraints(sd, - ob, - ss->filter_cache->nodes, - ss->filter_cache->totnode, - ss->filter_cache->cloth_sim, - origin, - FLT_MAX); + SCULPT_cloth_brush_build_nodes_constraints(sd, + ob, + ss->filter_cache->nodes, + ss->filter_cache->totnode, + ss->filter_cache->cloth_sim, + origin, + FLT_MAX); const bool use_face_sets = RNA_boolean_get(op->ptr, "use_face_sets"); if (use_face_sets) { @@ -1225,6 +1259,11 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent ss->filter_cache->active_face_set = SCULPT_FACE_SET_NONE; } + const int force_axis = RNA_enum_get(op->ptr, "force_axis"); + ss->filter_cache->enabled_force_axis[0] = force_axis & CLOTH_FILTER_FORCE_X; + ss->filter_cache->enabled_force_axis[1] = force_axis & CLOTH_FILTER_FORCE_Y; + ss->filter_cache->enabled_force_axis[2] = force_axis & CLOTH_FILTER_FORCE_Z; + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -1252,6 +1291,12 @@ void SCULPT_OT_cloth_filter(struct wmOperatorType *ot) "Operation that is going to be applied to the mesh"); RNA_def_float( ot->srna, "strength", 1.0f, -10.0f, 10.0f, "Strength", "Filter Strength", -10.0f, 10.0f); + RNA_def_enum_flag(ot->srna, + "force_axis", + prop_cloth_filter_force_axis_items, + CLOTH_FILTER_FORCE_X | CLOTH_FILTER_FORCE_Y | CLOTH_FILTER_FORCE_Z, + "Force axis", + "Apply the force in the selected axis"); RNA_def_float(ot->srna, "cloth_mass", 1.0f, diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c index 2afa3556dd9..b9265380a35 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.c +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c @@ -71,6 +71,37 @@ #include <math.h> #include <stdlib.h> +/* Utils. */ +int ED_sculpt_face_sets_find_next_available_id(struct Mesh *mesh) +{ + int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS); + if (!face_sets) { + return SCULPT_FACE_SET_NONE; + } + + int next_face_set_id = 0; + for (int i = 0; i < mesh->totpoly; i++) { + next_face_set_id = max_ii(next_face_set_id, abs(face_sets[i])); + } + next_face_set_id++; + + return next_face_set_id; +} + +void ED_sculpt_face_sets_initialize_none_to_id(struct Mesh *mesh, const int new_id) +{ + int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS); + if (!face_sets) { + return; + } + + for (int i = 0; i < mesh->totpoly; i++) { + if (face_sets[i] == SCULPT_FACE_SET_NONE) { + face_sets[i] = new_id; + } + } +} + /* Draw Face Sets Brush. */ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata, @@ -901,6 +932,25 @@ static int sculpt_face_sets_change_visibility_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int sculpt_face_sets_change_visibility_invoke(bContext *C, + wmOperator *op, + const wmEvent *event) +{ + Object *ob = CTX_data_active_object(C); + SculptSession *ss = ob->sculpt; + + /* Update the active vertex and Face Set using the cursor position to avoid relying on the paint + * cursor updates. */ + SculptCursorGeometryInfo sgi; + float mouse[2]; + mouse[0] = event->mval[0]; + mouse[1] = event->mval[1]; + SCULPT_vertex_random_access_ensure(ss); + SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false); + + return sculpt_face_sets_change_visibility_exec(C, op); +} + void SCULPT_OT_face_sets_change_visibility(wmOperatorType *ot) { /* Identifiers. */ @@ -910,6 +960,7 @@ void SCULPT_OT_face_sets_change_visibility(wmOperatorType *ot) /* Api callbacks. */ ot->exec = sculpt_face_sets_change_visibility_exec; + ot->invoke = sculpt_face_sets_change_visibility_invoke; ot->poll = SCULPT_mode_poll; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.c b/source/blender/editors/sculpt_paint/sculpt_filter_color.c index 576536cac03..c5acf736f3e 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_color.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.c @@ -289,7 +289,7 @@ static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent return OPERATOR_CANCELLED; } - SCULPT_filter_cache_init(ob, sd, SCULPT_UNDO_COLOR); + SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COLOR); WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c index f9ae91fce7f..56e70a8d47a 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c @@ -50,6 +50,7 @@ #include "ED_object.h" #include "ED_screen.h" #include "ED_sculpt.h" +#include "ED_view3d.h" #include "paint_intern.h" #include "sculpt_intern.h" @@ -63,6 +64,39 @@ #include <math.h> #include <stdlib.h> +/* Filter orientation utils. */ +void SCULPT_filter_to_orientation_space(float r_v[3], struct FilterCache *filter_cache) +{ + switch (filter_cache->orientation) { + case SCULPT_FILTER_ORIENTATION_LOCAL: + /* Do nothing, Sculpt Mode already works in object space. */ + break; + case SCULPT_FILTER_ORIENTATION_WORLD: + mul_mat3_m4_v3(filter_cache->obmat, r_v); + break; + case SCULPT_FILTER_ORIENTATION_VIEW: + mul_mat3_m4_v3(filter_cache->obmat, r_v); + mul_mat3_m4_v3(filter_cache->viewmat, r_v); + break; + } +} + +void SCULPT_filter_to_object_space(float r_v[3], struct FilterCache *filter_cache) +{ + switch (filter_cache->orientation) { + case SCULPT_FILTER_ORIENTATION_LOCAL: + /* Do nothing, Sculpt Mode already works in object space. */ + break; + case SCULPT_FILTER_ORIENTATION_WORLD: + mul_mat3_m4_v3(filter_cache->obmat_inv, r_v); + break; + case SCULPT_FILTER_ORIENTATION_VIEW: + mul_mat3_m4_v3(filter_cache->viewmat_inv, r_v); + mul_mat3_m4_v3(filter_cache->obmat_inv, r_v); + break; + } +} + static void filter_cache_init_task_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls)) @@ -73,7 +107,7 @@ static void filter_cache_init_task_cb(void *__restrict userdata, SCULPT_undo_push_node(data->ob, node, data->filter_undo_type); } -void SCULPT_filter_cache_init(Object *ob, Sculpt *sd, const int undo_type) +void SCULPT_filter_cache_init(bContext *C, Object *ob, Sculpt *sd, const int undo_type) { SculptSession *ss = ob->sculpt; PBVH *pbvh = ob->sculpt->pbvh; @@ -117,6 +151,16 @@ void SCULPT_filter_cache_init(Object *ob, Sculpt *sd, const int undo_type) BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode); BLI_task_parallel_range( 0, ss->filter_cache->totnode, &data, filter_cache_init_task_cb, &settings); + + /* Setup orientation matrices. */ + copy_m4_m4(ss->filter_cache->obmat, ob->obmat); + invert_m4_m4(ss->filter_cache->obmat_inv, ob->obmat); + + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + ViewContext vc; + ED_view3d_viewcontext_init(C, &vc, depsgraph); + copy_m4_m4(ss->filter_cache->viewmat, vc.rv3d->viewmat); + copy_m4_m4(ss->filter_cache->viewmat_inv, vc.rv3d->viewinv); } void SCULPT_filter_cache_free(SculptSession *ss) @@ -132,7 +176,8 @@ 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->detail_directions); + MEM_SAFE_FREE(ss->filter_cache->limit_surface_co); MEM_SAFE_FREE(ss->filter_cache); } @@ -146,6 +191,8 @@ typedef enum eSculptMeshFilterTypes { MESH_FILTER_RELAX_FACE_SETS = 6, MESH_FILTER_SURFACE_SMOOTH = 7, MESH_FILTER_SHARPEN = 8, + MESH_FILTER_ENHANCE_DETAILS = 9, + MESH_FILTER_ERASE_DISPLACEMENT = 10, } eSculptMeshFilterTypes; static EnumPropertyItem prop_mesh_filter_types[] = { @@ -166,6 +213,16 @@ static EnumPropertyItem prop_mesh_filter_types[] = { "Surface Smooth", "Smooth the surface of the mesh, preserving the volume"}, {MESH_FILTER_SHARPEN, "SHARPEN", 0, "Sharpen", "Sharpen the cavities of the mesh"}, + {MESH_FILTER_ENHANCE_DETAILS, + "ENHANCE_DETAILS", + 0, + "Enhance Details", + "Enhance the high frequency surface detail"}, + {MESH_FILTER_ERASE_DISPLACEMENT, + "ERASE_DISCPLACEMENT", + 0, + "Erase Displacement", + "Deletes the displacement of the Multires Modifier"}, {0, NULL, 0, NULL, NULL}, }; @@ -182,6 +239,25 @@ static EnumPropertyItem prop_mesh_filter_deform_axis_items[] = { {0, NULL, 0, NULL, NULL}, }; +static EnumPropertyItem prop_mesh_filter_orientation_items[] = { + {SCULPT_FILTER_ORIENTATION_LOCAL, + "LOCAL", + 0, + "Local", + "Use the local axis to limit the displacement"}, + {SCULPT_FILTER_ORIENTATION_WORLD, + "WORLD", + 0, + "World", + "Use the global axis to limit the displacement"}, + {SCULPT_FILTER_ORIENTATION_VIEW, + "VIEW", + 0, + "View", + "Use the view axis to limit the displacement"}, + {0, NULL, 0, NULL, NULL}, +}; + static bool sculpt_mesh_filter_needs_pmap(int filter_type, bool use_face_sets) { return use_face_sets || ELEM(filter_type, @@ -189,6 +265,7 @@ static bool sculpt_mesh_filter_needs_pmap(int filter_type, bool use_face_sets) MESH_FILTER_RELAX, MESH_FILTER_RELAX_FACE_SETS, MESH_FILTER_SURFACE_SMOOTH, + MESH_FILTER_ENHANCE_DETAILS, MESH_FILTER_SHARPEN); } @@ -306,7 +383,7 @@ static void mesh_filter_task_cb(void *__restrict userdata, const uint *hash_co = (const uint *)orig_co; const uint hash = BLI_hash_int_2d(hash_co[0], hash_co[1]) ^ BLI_hash_int_2d(hash_co[2], ss->filter_cache->random_seed); - mul_v3_fl(normal, hash * (1.0f / 0xFFFFFFFF) - 0.5f); + mul_v3_fl(normal, hash * (1.0f / (float)0xFFFFFFFF) - 0.5f); mul_v3_v3fl(disp, normal, fade); break; } @@ -362,7 +439,7 @@ static void mesh_filter_task_cb(void *__restrict userdata, 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]); + copy_v3_v3(detail_strength, ss->filter_cache->detail_directions[vd.index]); madd_v3_v3fl(disp, detail_strength, -ss->filter_cache->sharpen_intensify_detail_strength * @@ -370,13 +447,25 @@ static void mesh_filter_task_cb(void *__restrict userdata, } break; } + + case MESH_FILTER_ENHANCE_DETAILS: { + mul_v3_v3fl(disp, ss->filter_cache->detail_directions[vd.index], -fabsf(fade)); + } break; + case MESH_FILTER_ERASE_DISPLACEMENT: { + fade = clamp_f(fade, 0.0f, 1.0f); + sub_v3_v3v3(disp, ss->filter_cache->limit_surface_co[vd.index], orig_co); + mul_v3_fl(disp, fade); + break; + } } + SCULPT_filter_to_orientation_space(disp, ss->filter_cache); for (int it = 0; it < 3; it++) { if (!ss->filter_cache->enabled_axis[it]) { disp[it] = 0.0f; } } + SCULPT_filter_to_object_space(disp, ss->filter_cache); if (ELEM(filter_type, MESH_FILTER_SURFACE_SMOOTH, MESH_FILTER_SHARPEN)) { madd_v3_v3v3fl(final_pos, vd.co, disp, clamp_f(fade, 0.0f, 1.0f)); @@ -394,14 +483,34 @@ static void mesh_filter_task_cb(void *__restrict userdata, BKE_pbvh_node_mark_update(node); } +static void mesh_filter_enhance_details_init_directions(SculptSession *ss) +{ + const int totvert = SCULPT_vertex_count_get(ss); + for (int i = 0; i < totvert; i++) { + float avg[3]; + SCULPT_neighbor_coords_average(ss, avg, i); + sub_v3_v3v3(ss->filter_cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, i)); + } +} + +static void mesh_filter_init_limit_surface_co(SculptSession *ss) +{ + const int totvert = SCULPT_vertex_count_get(ss); + ss->filter_cache->limit_surface_co = MEM_malloc_arrayN( + 3 * sizeof(float), totvert, "limit surface co"); + for (int i = 0; i < totvert; i++) { + SCULPT_vertex_limit_surface_get(ss, i, ss->filter_cache->limit_surface_co[i]); + } +} + static void mesh_filter_sharpen_init_factors(SculptSession *ss) { const int totvert = SCULPT_vertex_count_get(ss); for (int i = 0; i < totvert; i++) { float avg[3]; SCULPT_neighbor_coords_average(ss, avg, 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]); + sub_v3_v3v3(ss->filter_cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, i)); + ss->filter_cache->sharpen_factor[i] = len_v3(ss->filter_cache->detail_directions[i]); } float max_factor = 0.0f; @@ -428,14 +537,14 @@ static void mesh_filter_sharpen_init_factors(SculptSession *ss) SculptVertexNeighborIter ni; SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) { - add_v3_v3(direction_avg, ss->filter_cache->sharpen_detail_directions[ni.index]); + add_v3_v3(direction_avg, ss->filter_cache->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 / total); + mul_v3_v3fl(ss->filter_cache->detail_directions[i], direction_avg, 1.0f / total); ss->filter_cache->sharpen_factor[i] = sharpen_avg / total; } } @@ -584,7 +693,7 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent SCULPT_boundary_info_ensure(ob); } - SCULPT_filter_cache_init(ob, sd, SCULPT_UNDO_COORDS); + SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COORDS); if (use_face_sets) { ss->filter_cache->active_face_set = SCULPT_active_face_set_get(ss); @@ -610,16 +719,29 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent 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( + ss->filter_cache->detail_directions = MEM_malloc_arrayN( totvert, sizeof(float[3]), "sharpen detail direction"); mesh_filter_sharpen_init_factors(ss); } + if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_ENHANCE_DETAILS) { + ss->filter_cache->detail_directions = MEM_malloc_arrayN( + totvert, sizeof(float[3]), "detail direction"); + mesh_filter_enhance_details_init_directions(ss); + } + + if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_ERASE_DISPLACEMENT) { + mesh_filter_init_limit_surface_co(ss); + } + ss->filter_cache->enabled_axis[0] = deform_axis & MESH_FILTER_DEFORM_X; ss->filter_cache->enabled_axis[1] = deform_axis & MESH_FILTER_DEFORM_Y; ss->filter_cache->enabled_axis[2] = deform_axis & MESH_FILTER_DEFORM_Z; + SculptFilterOrientation orientation = RNA_enum_get(op->ptr, "orientation"); + ss->filter_cache->orientation = orientation; + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -653,6 +775,12 @@ void SCULPT_OT_mesh_filter(struct wmOperatorType *ot) MESH_FILTER_DEFORM_X | MESH_FILTER_DEFORM_Y | MESH_FILTER_DEFORM_Z, "Deform axis", "Apply the deformation in the selected axis"); + RNA_def_enum(ot->srna, + "orientation", + prop_mesh_filter_orientation_items, + SCULPT_FILTER_ORIENTATION_LOCAL, + "Orientation", + "Orientation of the axis to limit the filter displacement"); ot->prop = RNA_def_boolean(ot->srna, "use_face_sets", false, diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 22316eb4631..548ef00ad87 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -100,10 +100,16 @@ 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]); -/* Returs the info of the limit surface when Multires is available, otherwise it returns the +/* Returns the info of the limit surface when Multires is available, otherwise it returns the * current coordinate of the vertex. */ void SCULPT_vertex_limit_surface_get(SculptSession *ss, int index, float r_co[3]); +/* Returns the pointer to the coordinates that should be edited from a brush tool iterator + * depending on the given deformation target. */ +float *SCULPT_brush_deform_target_vertex_co_get(SculptSession *ss, + const int deform_target, + PBVHVertexIter *iter); + #define SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY 256 typedef struct SculptVertexNeighborIter { /* Storage */ @@ -337,7 +343,7 @@ float *SCULPT_boundary_automasking_init(Object *ob, float *automask_factor); /* Filters. */ -void SCULPT_filter_cache_init(Object *ob, Sculpt *sd, const int undo_type); +void SCULPT_filter_cache_init(struct bContext *C, Object *ob, Sculpt *sd, const int undo_type); void SCULPT_filter_cache_free(SculptSession *ss); void SCULPT_mask_filter_smooth_apply( @@ -350,8 +356,33 @@ void SCULPT_do_cloth_brush(struct Sculpt *sd, struct Object *ob, struct PBVHNode **nodes, int totnode); + void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim); +struct SculptClothSimulation *SCULPT_cloth_brush_simulation_create(struct SculptSession *ss, + struct Brush *brush, + const float cloth_mass, + const float cloth_damping, + const bool use_collisions); +void SCULPT_cloth_brush_simulation_init(struct SculptSession *ss, + struct SculptClothSimulation *cloth_sim); +void SCULPT_cloth_brush_store_simulation_state(struct SculptSession *ss, + struct SculptClothSimulation *cloth_sim); + +void SCULPT_cloth_brush_do_simulation_step(struct Sculpt *sd, + struct Object *ob, + struct SculptClothSimulation *cloth_sim, + struct PBVHNode **nodes, + int totnode); + +void SCULPT_cloth_brush_build_nodes_constraints(struct Sculpt *sd, + struct Object *ob, + struct PBVHNode **nodes, + int totnode, + struct SculptClothSimulation *cloth_sim, + float initial_location[3], + const float radius); + void SCULPT_cloth_simulation_limits_draw(const uint gpuattr, const struct Brush *brush, const float location[3], @@ -367,8 +398,12 @@ void SCULPT_cloth_plane_falloff_preview_draw(const uint gpuattr, BLI_INLINE bool SCULPT_is_cloth_deform_brush(const Brush *brush) { - return brush->sculpt_tool == SCULPT_TOOL_CLOTH && - brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB; + return (brush->sculpt_tool == SCULPT_TOOL_CLOTH && + brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) || + /* All brushes that are not the cloth brush deform the simulation using softbody + constriants instead of applying forces. */ + (brush->sculpt_tool != SCULPT_TOOL_CLOTH && + brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM); } /* Pose Brush. */ @@ -401,7 +436,7 @@ struct SculptBoundary *SCULPT_boundary_data_init(Object *object, Brush *brush, const int initial_vertex, const float radius); -void SCULPT_boundary_data_free(struct SculptBoundary *bdata); +void SCULPT_boundary_data_free(struct SculptBoundary *boundary); void SCULPT_do_boundary_brush(struct Sculpt *sd, struct Object *ob, struct PBVHNode **nodes, @@ -865,6 +900,9 @@ typedef struct StrokeCache { /* Pose brush */ struct SculptPoseIKChain *pose_ik_chain; + /* Enhance Details. */ + float (*detail_directions)[3]; + /* Clay Thumb brush */ /* Angle of the front tilting plane of the brush to simulate clay accumulation. */ float clay_thumb_front_angle; @@ -880,7 +918,7 @@ typedef struct StrokeCache { float true_initial_normal[3]; /* Boundary brush */ - struct SculptBoundary *bdata[PAINT_SYMM_AREAS]; + struct SculptBoundary *boundaries[PAINT_SYMM_AREAS]; /* Surface Smooth Brush */ /* Stores the displacement produced by the laplacian step of HC smooth. */ @@ -920,8 +958,19 @@ typedef struct StrokeCache { } StrokeCache; +/* Sculpt Filters */ +typedef enum SculptFilterOrientation { + SCULPT_FILTER_ORIENTATION_LOCAL = 0, + SCULPT_FILTER_ORIENTATION_WORLD = 1, + SCULPT_FILTER_ORIENTATION_VIEW = 2, +} SculptFilterOrientation; + +void SCULPT_filter_to_orientation_space(float r_v[3], struct FilterCache *filter_cache); +void SCULPT_filter_to_object_space(float r_v[3], struct FilterCache *filter_cache); + typedef struct FilterCache { bool enabled_axis[3]; + bool enabled_force_axis[3]; int random_seed; /* Used for alternating between filter operations in filters that need to apply different ones to @@ -938,7 +987,17 @@ typedef struct FilterCache { float sharpen_intensify_detail_strength; int sharpen_curvature_smooth_iterations; float *sharpen_factor; - float (*sharpen_detail_directions)[3]; + float (*detail_directions)[3]; + + /* Filter orientaiton. */ + SculptFilterOrientation orientation; + float obmat[4][4]; + float obmat_inv[4][4]; + float viewmat[4][4]; + float viewmat_inv[4][4]; + + /* Displacement eraser. */ + float (*limit_surface_co)[3]; /* unmasked nodes */ PBVHNode **nodes; diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c index 4d41d069155..e53e33c1186 100644 --- a/source/blender/editors/sculpt_paint/sculpt_pose.c +++ b/source/blender/editors/sculpt_paint/sculpt_pose.c @@ -165,6 +165,7 @@ static void do_pose_brush_task_cb_ex(void *__restrict userdata, SculptSession *ss = data->ob->sculpt; SculptPoseIKChain *ik_chain = ss->cache->pose_ik_chain; SculptPoseIKChainSegment *segments = ik_chain->segments; + const Brush *brush = data->brush; PBVHVertexIter vd; float disp[3], new_co[3]; @@ -206,7 +207,9 @@ static void do_pose_brush_task_cb_ex(void *__restrict userdata, /* Apply the accumulated displacement to the vertex. */ add_v3_v3v3(final_pos, orig_data.co, total_disp); - copy_v3_v3(vd.co, final_pos); + + float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd); + copy_v3_v3(target_co, final_pos); if (vd.mvert) { vd.mvert->flag |= ME_VERT_PBVH_UPDATE; diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c index 2b93298ac4a..63fe8643628 100644 --- a/source/blender/editors/sculpt_paint/sculpt_smooth.c +++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c @@ -195,6 +195,85 @@ void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], int index } } +static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata, + const int n, + const TaskParallelTLS *__restrict tls) +{ + SculptThreadedTaskData *data = userdata; + SculptSession *ss = data->ob->sculpt; + Sculpt *sd = data->sd; + const Brush *brush = data->brush; + + PBVHVertexIter vd; + + float bstrength = ss->cache->bstrength; + CLAMP(bstrength, -1.0f, 1.0f); + + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape( + ss, &test, data->brush->falloff_shape); + + const int thread_id = BLI_task_parallel_thread_id(tls); + BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) + { + if (sculpt_brush_test_sq_fn(&test, vd.co)) { + const float fade = bstrength * SCULPT_brush_strength_factor(ss, + brush, + vd.co, + sqrtf(test.dist), + vd.no, + vd.fno, + vd.mask ? *vd.mask : 0.0f, + vd.index, + thread_id); + + float disp[3]; + madd_v3_v3v3fl(disp, vd.co, ss->cache->detail_directions[vd.index], fade); + SCULPT_clip(sd, ss, vd.co, disp); + + if (vd.mvert) { + vd.mvert->flag |= ME_VERT_PBVH_UPDATE; + } + } + } + BKE_pbvh_vertex_iter_end; +} + +static void SCULPT_enhance_details_brush(Sculpt *sd, + Object *ob, + PBVHNode **nodes, + const int totnode) +{ + SculptSession *ss = ob->sculpt; + Brush *brush = BKE_paint_brush(&sd->paint); + + SCULPT_vertex_random_access_ensure(ss); + SCULPT_boundary_info_ensure(ob); + + if (SCULPT_stroke_is_first_brush_step(ss->cache)) { + const int totvert = SCULPT_vertex_count_get(ss); + ss->cache->detail_directions = MEM_malloc_arrayN( + totvert, 3 * sizeof(float), "details directions"); + + for (int i = 0; i < totvert; i++) { + float avg[3]; + SCULPT_neighbor_coords_average(ss, avg, i); + sub_v3_v3v3(ss->cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, i)); + } + } + + SculptThreadedTaskData data = { + .sd = sd, + .ob = ob, + .brush = brush, + .nodes = nodes, + }; + + TaskParallelSettings settings; + BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BLI_task_parallel_range(0, totnode, &data, do_enhance_details_brush_task_cb_ex, &settings); +} + static void do_smooth_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) @@ -300,7 +379,14 @@ void SCULPT_smooth(Sculpt *sd, void SCULPT_do_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) { SculptSession *ss = ob->sculpt; - SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, false); + if (ss->cache->bstrength <= 0.0f) { + /* Invert mode, intensify details. */ + SCULPT_enhance_details_brush(sd, ob, nodes, totnode); + } + else { + /* Regular mode, smooth. */ + SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, false); + } } /* HC Smooth Algorithm. */ diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.c b/source/blender/editors/sculpt_paint/sculpt_transform.c index 4c54a0465b9..bdada4d2565 100644 --- a/source/blender/editors/sculpt_paint/sculpt_transform.c +++ b/source/blender/editors/sculpt_paint/sculpt_transform.c @@ -76,7 +76,7 @@ void ED_sculpt_init_transform(struct bContext *C) ss->pivot_rot[3] = 1.0f; SCULPT_vertex_random_access_ensure(ss); - SCULPT_filter_cache_init(ob, sd, SCULPT_UNDO_COORDS); + SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COORDS); } static void sculpt_transform_task_cb(void *__restrict userdata, diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 050dca07c34..e8eddc014db 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -306,7 +306,6 @@ static void SOUND_OT_update_animation_flags(wmOperatorType *ot) static int sound_bake_animation_exec(bContext *C, wmOperator *UNUSED(op)) { - Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); /* NOTE: We will be forcefully evaluating dependency graph at every frame, so no need to ensure * current scene state is evaluated as it will be lost anyway. */ @@ -318,11 +317,11 @@ static int sound_bake_animation_exec(bContext *C, wmOperator *UNUSED(op)) for (cfra = (scene->r.sfra > 0) ? (scene->r.sfra - 1) : 0; cfra <= scene->r.efra + 1; cfra++) { scene->r.cfra = cfra; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); } scene->r.cfra = oldfra; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c index ada4243ab4e..8634e5a5f29 100644 --- a/source/blender/editors/space_action/action_draw.c +++ b/source/blender/editors/space_action/action_draw.c @@ -169,7 +169,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* first backdrop strips */ float ymax = ACHANNEL_FIRST_TOP(ac); @@ -276,7 +276,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region } } } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* black line marking 'current frame' for Time-Slide transform mode */ if (saction->flag & SACTION_MOVING) { @@ -558,7 +558,7 @@ void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene) immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* Iterate over pointcaches on the active object, and draw each one's range. */ float y_offset = 0.0f; @@ -577,7 +577,7 @@ void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene) y_offset += cache_draw_height; } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); BLI_freelistN(&pidlist); diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt index 25ff6bbd098..75d91174470 100644 --- a/source/blender/editors/space_buttons/CMakeLists.txt +++ b/source/blender/editors/space_buttons/CMakeLists.txt @@ -54,4 +54,9 @@ if(WITH_FREESTYLE) add_definitions(-DWITH_FREESTYLE) endif() +if(WITH_EXPERIMENTAL_FEATURES) + add_definitions(-DWITH_PARTICLE_NODES) + add_definitions(-DWITH_HAIR_NODES) +endif() + blender_add_lib(bf_editor_space_buttons "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 5885d3dcbb0..3976e18d70c 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -249,12 +249,16 @@ static bool buttons_context_path_data(ButsContextPath *path, int type) if (RNA_struct_is_a(ptr->type, &RNA_GreasePencil) && (type == -1 || type == OB_GPENCIL)) { return true; } +#ifdef WITH_HAIR_NODES if (RNA_struct_is_a(ptr->type, &RNA_Hair) && (type == -1 || type == OB_HAIR)) { return true; } +#endif +#ifdef WITH_PARTICLE_NODES if (RNA_struct_is_a(ptr->type, &RNA_PointCloud) && (type == -1 || type == OB_POINTCLOUD)) { return true; } +#endif if (RNA_struct_is_a(ptr->type, &RNA_Volume) && (type == -1 || type == OB_VOLUME)) { return true; } @@ -871,14 +875,18 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r set_pointer_type(path, result, &RNA_LightProbe); return 1; } +#ifdef WITH_HAIR_NODES if (CTX_data_equals(member, "hair")) { set_pointer_type(path, result, &RNA_Hair); return 1; } +#endif +#ifdef WITH_PARTICLE_NODES if (CTX_data_equals(member, "pointcloud")) { set_pointer_type(path, result, &RNA_PointCloud); return 1; } +#endif if (CTX_data_equals(member, "volume")) { set_pointer_type(path, result, &RNA_Volume); return 1; diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index c7328ae9f8f..8aaf3faffec 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -142,7 +142,7 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *region, Scene *scene) strip[3] = 0.5f; selected_strip[3] = 1.0f; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); clip_draw_dopesheet_background(region, clip, pos_id); @@ -288,7 +288,7 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *region, Scene *scene) immUnbindProgram(); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } @@ -389,7 +389,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *region) PropertyRNA *chan_prop_lock = RNA_struct_type_find_property(&RNA_MovieTrackingTrack, "lock"); BLI_assert(chan_prop_lock); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); for (channel = dopesheet->channels.first; channel; channel = channel->next) { float yminc = (float)(y - CHANNEL_HEIGHT_HALF); float ymaxc = (float)(y + CHANNEL_HEIGHT_HALF); @@ -426,7 +426,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *region) /* adjust y-position for next one */ y -= CHANNEL_STEP; } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); UI_block_end(C, block); UI_block_draw(C, block); diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 07bdd337269..17539b2c423 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -153,9 +153,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *region, MovieClip *clip MovieTrackingPlaneTrack *act_plane_track = BKE_tracking_plane_track_get_active(&clip->tracking); MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); /* cache background */ ED_region_cache_draw_background(region); @@ -245,7 +243,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *region, MovieClip *clip } } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* current frame */ x = (sc->user.framenr - sfra) / (efra - sfra + 1) * region->winx; @@ -330,9 +328,7 @@ static void draw_movieclip_buffer(const bContext *C, /* checkerboard for case alpha */ if (ibuf->planes == 32) { - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); imm_draw_box_checker_2d(x, y, x + zoomx * ibuf->x, y + zoomy * ibuf->y); } @@ -346,7 +342,7 @@ static void draw_movieclip_buffer(const bContext *C, 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); + GPU_blend(GPU_BLEND_NONE); } if (sc->flag & SC_SHOW_METADATA) { @@ -1212,9 +1208,7 @@ static void draw_plane_marker_image(Scene *scene, if (plane_track->image_opacity != 1.0f || ibuf->planes == 32) { transparent = true; - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); } GPUTexture *texture = GPU_texture_create_nD(ibuf->x, @@ -1266,7 +1260,7 @@ static void draw_plane_marker_image(Scene *scene, GPU_texture_free(texture); if (transparent) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c index 277930495bd..4cf3e3e0798 100644 --- a/source/blender/editors/space_clip/clip_graph_draw.c +++ b/source/blender/editors/space_clip/clip_graph_draw.c @@ -192,7 +192,7 @@ static void draw_tracks_motion_and_error_curves(View2D *v2d, SpaceClip *sc, uint } /* Draw graph lines. */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); clip_graph_tracking_values_iterate(sc, (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0, (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0, @@ -200,7 +200,7 @@ static void draw_tracks_motion_and_error_curves(View2D *v2d, SpaceClip *sc, uint tracking_segment_point_cb, tracking_segment_start_cb, tracking_segment_end_cb); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* Selected knot handles on top of curves. */ if (draw_knots) { diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c index 03f791ad70d..bcbf843f51c 100644 --- a/source/blender/editors/space_clip/clip_utils.c +++ b/source/blender/editors/space_clip/clip_utils.c @@ -415,9 +415,7 @@ void clip_draw_sfra_efra(View2D *v2d, Scene *scene) UI_view2d_view_ortho(v2d); /* currently clip editor supposes that editing clip length is equal to scene frame range */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -426,7 +424,7 @@ void clip_draw_sfra_efra(View2D *v2d, Scene *scene) immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, (float)SFRA, v2d->cur.ymax); immRectf(pos, (float)EFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUniformThemeColorShade(TH_BACK, -60); diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 083d41747b3..51e6c99ff39 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -267,7 +267,7 @@ static void file_draw_preview(uiBlock *block, xco = sx + (int)dx; yco = sy - layout->prv_h + (int)dy; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* the large image */ @@ -290,8 +290,7 @@ static void file_draw_preview(uiBlock *block, if (!is_icon && typeflags & FILE_TYPE_BLENDERLIB) { /* Datablock preview images use premultiplied alpha. */ - GPU_blend_set_func_separate( - GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA_PREMULT); } IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); @@ -309,8 +308,7 @@ static void file_draw_preview(uiBlock *block, 1.0f, col); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); if (icon && is_icon) { /* Small icon in the middle of large image, scaled to fit container and UI scale */ @@ -391,7 +389,7 @@ static void file_draw_preview(uiBlock *block, UI_but_drag_set_image(but, BLI_strdup(path), icon, imb, scale, true); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname) diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index f5861e792bc..ac860b72e84 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -290,7 +290,7 @@ static void draw_fcurve_vertices(ARegion *region, uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_program_point_size(true); /* draw the two handles first (if they're shown, the curve doesn't @@ -303,7 +303,7 @@ static void draw_fcurve_vertices(ARegion *region, draw_fcurve_keyframe_vertices(fcu, v2d, !(fcu->flag & FCURVE_PROTECTED), pos); GPU_program_point_size(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* Handles ---------------- */ @@ -344,7 +344,7 @@ static void draw_fcurve_handles(SpaceGraph *sipo, FCurve *fcu) if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) { GPU_line_smooth(true); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immBeginAtMost(GPU_PRIM_LINES, 4 * 2 * fcu->totvert); @@ -421,7 +421,7 @@ static void draw_fcurve_handles(SpaceGraph *sipo, FCurve *fcu) immEnd(); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) { GPU_line_smooth(false); } @@ -474,7 +474,7 @@ static void draw_fcurve_samples(SpaceGraph *sipo, ARegion *region, FCurve *fcu) if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) { GPU_line_smooth(true); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -486,7 +486,7 @@ static void draw_fcurve_samples(SpaceGraph *sipo, ARegion *region, FCurve *fcu) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) { GPU_line_smooth(false); } @@ -1002,7 +1002,7 @@ void graph_draw_ghost_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *region if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) { GPU_line_smooth(true); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); const uint shdr_pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -1034,7 +1034,7 @@ void graph_draw_ghost_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *region if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) { GPU_line_smooth(false); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* This is called twice from space_graph.c -> graph_main_region_draw() @@ -1088,7 +1088,7 @@ void graph_draw_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *region, shor if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) { GPU_line_smooth(true); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); const uint shdr_pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -1149,7 +1149,7 @@ void graph_draw_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *region, shor if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) { GPU_line_smooth(false); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* 2) draw handles and vertices as appropriate based on active @@ -1262,9 +1262,7 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region) float ymax = ACHANNEL_FIRST_TOP(ac); /* set blending again, as may not be set in previous step */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac), channel_index++) { float ymin = ymax - ACHANNEL_HEIGHT(ac); @@ -1282,7 +1280,7 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region) UI_block_end(C, block); UI_block_draw(C, block); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* free tempolary channels */ diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index a4f76384cc6..4e0f60544e6 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -249,7 +249,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *region) /* Draw a green line to indicate the cursor value */ immUniformThemeColorShadeAlpha(TH_CFRAME, -10, -50); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_width(2.0); immBegin(GPU_PRIM_LINES, 2); @@ -257,7 +257,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *region) immVertex2f(pos, v2d->cur.xmax, y); immEnd(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* current frame or vertical component of vertical component of the cursor */ @@ -268,7 +268,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *region) /* to help differentiate this from the current frame, * draw slightly darker like the horizontal one */ immUniformThemeColorShadeAlpha(TH_CFRAME, -40, -50); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_width(2.0); immBegin(GPU_PRIM_LINES, 2); @@ -276,7 +276,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *region) immVertex2f(pos, x, v2d->cur.ymax); immEnd(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } immUnbindProgram(); diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index f70589ac5f1..d58f5ede7d7 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -175,9 +175,7 @@ void ED_image_draw_info(Scene *scene, float hue = 0, sat = 0, val = 0, lum = 0, u = 0, v = 0; float col[4], finalcol[4]; - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); @@ -189,7 +187,7 @@ void ED_image_draw_info(Scene *scene, immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); BLF_size(blf_mono_font, 11 * U.pixelsize, U.dpi); @@ -350,7 +348,7 @@ void ED_image_draw_info(Scene *scene, copy_v4_v4(finalcol, col); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); dx += 0.25f * UI_UNIT_X; BLI_rcti_init(&color_rect, @@ -389,10 +387,10 @@ void ED_image_draw_info(Scene *scene, immRecti(pos, color_quater_x, color_quater_y, color_rect_half.xmax, color_rect_half.ymax); immRecti(pos, color_rect_half.xmin, color_rect_half.ymin, color_quater_x, color_quater_y); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor3fvAlpha(finalcol, fp ? fp[3] : (cp[3] / 255.0f)); immRecti(pos, color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } else { immUniformColor3fv(finalcol); @@ -540,9 +538,7 @@ static void draw_udim_label(ARegion *region, float fx, float fy, const char *lab int x, y; UI_view2d_view_to_region(®ion->v2d, fx, fy, &x, &y); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); int textwidth = BLF_width(blf_mono_font, label, strlen(label)) + 10; float stepx = BLI_rcti_size_x(®ion->v2d.mask) / BLI_rctf_size_x(®ion->v2d.cur); @@ -560,7 +556,7 @@ static void draw_udim_label(ARegion *region, float fx, float fy, const char *lab BLF_position(blf_mono_font, (int)(x + 10), (int)(y + 10), 0); BLF_draw_ascii(blf_mono_font, label, strlen(label)); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void draw_image_buffer(const bContext *C, @@ -602,9 +598,7 @@ static void draw_image_buffer(const bContext *C, if (sima_flag & SI_USE_ALPHA) { imm_draw_box_checker_2d(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); } /* If RGBA display with color management */ @@ -662,7 +656,7 @@ static void draw_image_buffer(const bContext *C, } if (sima_flag & SI_USE_ALPHA) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } @@ -771,15 +765,13 @@ static void draw_image_paint_helpers( return; } - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); immDrawPixelsTex( &state, x, y, ibuf->x, ibuf->y, GPU_RGBA8, false, display_buffer, zoomx, zoomy, col); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); BKE_image_release_ibuf(brush->clone.image, ibuf, NULL); IMB_display_buffer_release(cache_handle); @@ -1058,9 +1050,7 @@ void draw_image_cache(const bContext *C, ARegion *region) const rcti *rect_visible = ED_region_visible_rect(region); const int region_bottom = rect_visible->ymin; - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); /* Draw cache background. */ ED_region_cache_draw_background(region); @@ -1076,7 +1066,7 @@ void draw_image_cache(const bContext *C, ARegion *region) region, num_segments, points, sfra + sima->iuser.offset, efra + sima->iuser.offset); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* Draw current frame. */ x = (cfra - sfra) / (efra - sfra + 1) * region->winx; diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c index 4e91da01cc9..e97031736ca 100644 --- a/source/blender/editors/space_info/info_stats.c +++ b/source/blender/editors/space_info/info_stats.c @@ -547,19 +547,20 @@ static void get_stats_string( info + *ofs, len - *ofs, TIP_(" | Objects:%s/%s"), stats_fmt->totobjsel, stats_fmt->totobj); } -const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C) +static const char *info_statusbar_string(Main *bmain, + Scene *scene, + ViewLayer *view_layer, + char statusbar_flag) { char formatted_mem[15]; size_t ofs = 0; - char *info = screen->statusbar_info; - int len = sizeof(screen->statusbar_info); + static char info[256]; + int len = sizeof(info); info[0] = '\0'; /* Scene statistics. */ - if (U.statusbar_flag & STATUSBAR_SHOW_STATS) { - ViewLayer *view_layer = CTX_data_view_layer(C); - Scene *scene = CTX_data_scene(C); + if (statusbar_flag & STATUSBAR_SHOW_STATS) { SceneStatsFmt stats_fmt; if (format_stats(bmain, scene, view_layer, &stats_fmt)) { get_stats_string(info + ofs, len, &ofs, view_layer, &stats_fmt); @@ -567,7 +568,7 @@ const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C) } /* Memory status. */ - if (U.statusbar_flag & STATUSBAR_SHOW_MEMORY) { + if (statusbar_flag & STATUSBAR_SHOW_MEMORY) { if (info[0]) { ofs += BLI_snprintf(info + ofs, len - ofs, " | "); } @@ -577,7 +578,7 @@ const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C) } /* GPU VRAM status. */ - if ((U.statusbar_flag & STATUSBAR_SHOW_VRAM) && (GPU_mem_stats_supported())) { + if ((statusbar_flag & STATUSBAR_SHOW_VRAM) && (GPU_mem_stats_supported())) { int gpu_free_mem_kb, gpu_tot_mem_kb; GPU_mem_stats_get(&gpu_tot_mem_kb, &gpu_free_mem_kb); float gpu_total_gb = gpu_tot_mem_kb / 1048576.0f; @@ -599,7 +600,7 @@ const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C) } /* Blender version. */ - if (U.statusbar_flag & STATUSBAR_SHOW_VERSION) { + if (statusbar_flag & STATUSBAR_SHOW_VERSION) { if (info[0]) { ofs += BLI_snprintf(info + ofs, len - ofs, " | "); } @@ -609,6 +610,20 @@ const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C) return info; } +const char *ED_info_statusbar_string(Main *bmain, Scene *scene, ViewLayer *view_layer) +{ + return info_statusbar_string(bmain, scene, view_layer, U.statusbar_flag); +} + +const char *ED_info_statistics_string(Main *bmain, Scene *scene, ViewLayer *view_layer) +{ + const eUserpref_StatusBar_Flag statistics_status_bar_flag = STATUSBAR_SHOW_STATS | + STATUSBAR_SHOW_MEMORY | + STATUSBAR_SHOW_VERSION; + + return info_statusbar_string(bmain, scene, view_layer, statistics_status_bar_flag); +} + static void stats_row(int col1, const char *key, int col2, diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c index 93a79d9a2bc..4d9a4fb2706 100644 --- a/source/blender/editors/space_info/textview.c +++ b/source/blender/editors/space_info/textview.c @@ -84,9 +84,7 @@ static void textview_draw_sel(const char *str, const int sta = BLI_str_utf8_offset_to_column(str, max_ii(sel[0], 0)); const int end = BLI_str_utf8_offset_to_column(str, min_ii(sel[1], str_len_draw)); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); @@ -97,7 +95,7 @@ static void textview_draw_sel(const char *str, immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } @@ -240,7 +238,7 @@ static bool textview_draw_string(TextViewDrawState *tds, int vpadding = (tds->lheight + (tds->row_vpadding * 2) - UI_DPI_ICON_SIZE) / 2; int hpadding = tds->draw_rect->xmin - (UI_DPI_ICON_SIZE * 1.3f); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_icon_draw_ex(hpadding, line_top - UI_DPI_ICON_SIZE - vpadding, icon, @@ -249,7 +247,7 @@ static bool textview_draw_string(TextViewDrawState *tds, 0.0f, icon_fg, false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } tds->xy[1] += tds->row_vpadding; diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index 97939a93d01..b0d5360e29b 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -321,7 +321,7 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uin /* draw with AA'd line */ GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* influence -------------------------- */ if (strip->flag & NLASTRIP_FLAG_USR_INFLUENCE) { @@ -374,7 +374,7 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uin /* turn off AA'd lines */ GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* helper call to setup dashed-lines for strip outlines */ @@ -434,9 +434,7 @@ static void nla_draw_strip(SpaceNla *snla, */ if ((strip->extendmode != NLASTRIP_EXTEND_NOTHING) && (non_solo == 0)) { /* enable transparency... */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); switch (strip->extendmode) { /* since this does both sides, @@ -468,7 +466,7 @@ static void nla_draw_strip(SpaceNla *snla, break; } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* draw 'inside' of strip itself */ @@ -487,9 +485,9 @@ static void nla_draw_strip(SpaceNla *snla, /* strip is in disabled track - make less visible */ immUniformColor3fvAlpha(color, 0.1f); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immRectf(shdr_pos, strip->start, yminc, strip->end, ymaxc); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* draw strip's control 'curves' @@ -746,9 +744,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *region) /* just draw a semi-shaded rect spanning the width of the viewable area if there's data, * and a second darker rect within which we draw keyframe indicator dots if there's data */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* get colors for drawing */ float color[4]; @@ -790,7 +786,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *region) nla_action_draw_keyframes( v2d, adt, ale->data, ycenter, ymin + NLACHANNEL_SKIP, ymax - NLACHANNEL_SKIP); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); break; } } @@ -854,9 +850,7 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *region) float ymax = NLACHANNEL_FIRST_TOP(ac); /* set blending again, as may not be set in previous step */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* loop through channels, and set up drawing depending on their type */ for (ale = anim_data.first; ale; @@ -876,7 +870,7 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *region) UI_block_end(C, block); UI_block_draw(C, block); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* free temporary channels */ diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 37daa881317..fcc02f49d07 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -602,7 +602,7 @@ static void node_draw_reroute(const bContext *C, /* outline active and selected emphasis */ if (node->flag & SELECT) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); /* using different shades of TH_TEXT_HI for the empasis, like triangle */ if (node->flag & NODE_ACTIVE) { @@ -614,7 +614,7 @@ static void node_draw_reroute(const bContext *C, UI_draw_roundbox_4fv(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax, size, debug_color); GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } #endif @@ -3688,13 +3688,11 @@ void draw_nodespace_back_pix(const bContext *C, GPU_shader_unbind(); } else if (snode->flag & SNODE_USE_ALPHA) { - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); ED_draw_imbuf_ctx(C, ibuf, x, y, false, snode->zoom, snode->zoom); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } else { ED_draw_imbuf_ctx(C, ibuf, x, y, false, snode->zoom, snode->zoom); @@ -4013,7 +4011,7 @@ static void nodelink_batch_draw(SpaceNode *snode) return; } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); float colors[6][4] = {{0.0f}}; UI_GetThemeColor4fv(TH_WIRE_INNER, colors[nodelink_get_color_id(TH_WIRE_INNER)]); @@ -4026,14 +4024,14 @@ static void nodelink_batch_draw(SpaceNode *snode) GPU_vertbuf_use(g_batch_link.inst_vbo); /* force update. */ GPU_batch_program_set_builtin(g_batch_link.batch, GPU_SHADER_2D_NODELINK_INST); - GPU_batch_uniform_4fv_array(g_batch_link.batch, "colors", 6, (float *)colors); + GPU_batch_uniform_4fv_array(g_batch_link.batch, "colors", 6, colors); GPU_batch_uniform_1f(g_batch_link.batch, "expandSize", snode->aspect * LINK_WIDTH); GPU_batch_uniform_1f(g_batch_link.batch, "arrowSize", ARROW_SIZE); GPU_batch_draw(g_batch_link.batch); nodelink_batch_reset(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } void nodelink_batch_start(SpaceNode *UNUSED(snode)) @@ -4108,8 +4106,8 @@ void node_draw_link_bezier( GPUBatch *batch = g_batch_link.batch_single; GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_NODELINK); - GPU_batch_uniform_2fv_array(batch, "bezierPts", 4, (float *)vec); - GPU_batch_uniform_4fv_array(batch, "colors", 3, (float *)colors); + GPU_batch_uniform_2fv_array(batch, "bezierPts", 4, vec); + GPU_batch_uniform_4fv_array(batch, "colors", 3, colors); GPU_batch_uniform_1f(batch, "expandSize", snode->aspect * LINK_WIDTH); GPU_batch_uniform_1f(batch, "arrowSize", ARROW_SIZE); GPU_batch_uniform_1i(batch, "doArrow", drawarrow); diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 3fd0b0a5a58..814473b0e9a 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -52,6 +52,7 @@ #include "GPU_immediate_util.h" #include "GPU_matrix.h" #include "GPU_state.h" +#include "GPU_viewport.h" #include "WM_api.h" #include "WM_types.h" @@ -690,13 +691,13 @@ static void node_draw_mute_line(View2D *v2d, SpaceNode *snode, bNode *node) { bNodeLink *link; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); for (link = node->internal_links.first; link; link = link->next) { node_draw_link_bezier(v2d, snode, link, TH_REDALERT, TH_REDALERT, -1); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* flags used in gpu_shader_keyframe_diamond_frag.glsl */ @@ -834,8 +835,8 @@ void ED_node_socket_draw(bNodeSocket *sock, const rcti *rect, const float color[ uint outline_col_id = GPU_vertformat_attr_add( format, "outlineColor", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - gpuPushAttr(GPU_BLEND_BIT); - GPU_blend(true); + eGPUBlend state = GPU_blend_get(); + GPU_blend(GPU_BLEND_ALPHA); GPU_program_point_size(true); immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); @@ -859,53 +860,27 @@ void ED_node_socket_draw(bNodeSocket *sock, const rcti *rect, const float color[ immUnbindProgram(); GPU_program_point_size(false); - gpuPopAttr(); + + /* Restore. */ + GPU_blend(state); } /* ************** Socket callbacks *********** */ -static void node_draw_preview_background(float tile, rctf *rect) +static void node_draw_preview_background(rctf *rect) { - float x, y; - GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immBindBuiltinProgram(GPU_SHADER_2D_CHECKER); - /* draw checkerboard backdrop to show alpha */ - immUniformColor3ub(120, 120, 120); + /* Drawing the checkerboard. */ + const float checker_dark = UI_ALPHA_CHECKER_DARK / 255.0f; + const float checker_light = UI_ALPHA_CHECKER_LIGHT / 255.0f; + immUniform4f("color1", checker_dark, checker_dark, checker_dark, 1.0f); + immUniform4f("color2", checker_light, checker_light, checker_light, 1.0f); + immUniform1i("size", 8); immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax); - immUniformColor3ub(160, 160, 160); - - for (y = rect->ymin; y < rect->ymax; y += tile * 2) { - for (x = rect->xmin; x < rect->xmax; x += tile * 2) { - float tilex = tile, tiley = tile; - - if (x + tile > rect->xmax) { - tilex = rect->xmax - x; - } - if (y + tile > rect->ymax) { - tiley = rect->ymax - y; - } - - immRectf(pos, x, y, x + tilex, y + tiley); - } - } - for (y = rect->ymin + tile; y < rect->ymax; y += tile * 2) { - for (x = rect->xmin + tile; x < rect->xmax; x += tile * 2) { - float tilex = tile, tiley = tile; - - if (x + tile > rect->xmax) { - tilex = rect->xmax - x; - } - if (y + tile > rect->ymax) { - tiley = rect->ymax - y; - } - - immRectf(pos, x, y, x + tilex, y + tiley); - } - } immUnbindProgram(); } @@ -934,12 +909,11 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv) scale = yscale; } - node_draw_preview_background(BLI_rctf_size_x(prv) / 10.0f, &draw_rect); + node_draw_preview_background(&draw_rect); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* premul graphics */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); immDrawPixelsTex(&state, @@ -954,7 +928,7 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv) scale, NULL); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -978,23 +952,8 @@ static void node_toggle_button_cb(struct bContext *C, void *node_argv, void *op_ void node_draw_shadow(SpaceNode *snode, bNode *node, float radius, float alpha) { rctf *rct = &node->totr; - UI_draw_roundbox_corner_set(UI_CNR_ALL); - if (node->parent == NULL) { - ui_draw_dropshadow(rct, radius, snode->aspect, alpha, node->flag & SELECT); - } - else { - const float margin = 3.0f; - - const float color[4] = {0.0f, 0.0f, 0.0f, 0.33f}; - UI_draw_roundbox_aa(true, - rct->xmin - margin, - rct->ymin - margin, - rct->xmax + margin, - rct->ymax + margin, - radius + margin, - color); - } + ui_draw_dropshadow(rct, radius, snode->aspect, alpha, node->flag & SELECT); } void node_draw_sockets(View2D *v2d, @@ -1024,7 +983,7 @@ void node_draw_sockets(View2D *v2d, uint outline_col_id = GPU_vertformat_attr_add( format, "outlineColor", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_program_point_size(true); immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); immUniform1f("outline_scale", 0.7f); @@ -1158,7 +1117,7 @@ void node_draw_sockets(View2D *v2d, immUnbindProgram(); GPU_program_point_size(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void node_draw_basis(const bContext *C, @@ -1434,7 +1393,7 @@ static void node_draw_hidden(const bContext *C, /* custom color inline */ if (node->flag & NODE_CUSTOM_COLOR) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); UI_draw_roundbox_3fv_alpha(false, @@ -1447,7 +1406,7 @@ static void node_draw_hidden(const bContext *C, 1.0f); GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* title */ @@ -1681,7 +1640,7 @@ void node_draw_nodetree(const bContext *C, } /* node lines */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); nodelink_batch_start(snode); for (link = ntree->links.first; link; link = link->next) { if (!nodeLinkIsHidden(link)) { @@ -1689,7 +1648,7 @@ void node_draw_nodetree(const bContext *C, } } nodelink_batch_end(snode); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* draw foreground nodes, last nodes in front */ for (a = 0, node = ntree->nodes.first; node; node = node->next, a++) { @@ -1750,12 +1709,12 @@ static void draw_group_overlay(const bContext *C, ARegion *region) float color[4]; /* shade node groups to separate them visually */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_GetThemeColorShadeAlpha4fv(TH_NODE_GROUP, 0, 0, color); UI_draw_roundbox_corner_set(UI_CNR_NONE); UI_draw_roundbox_4fv(true, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 0, color); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* set the block bounds to clip mouse events from underlying nodes */ block = UI_block_begin(C, region, "node tree bounds block", UI_EMBOSS); @@ -1770,10 +1729,16 @@ void drawnodespace(const bContext *C, ARegion *region) SpaceNode *snode = CTX_wm_space_node(C); View2D *v2d = ®ion->v2d; - UI_ThemeClearColor(TH_BACK); - GPU_clear(GPU_COLOR_BIT); + /* Setup offscreen buffers. */ + GPUViewport *viewport = WM_draw_region_get_viewport(region); + + GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport); + GPU_framebuffer_bind_no_srgb(framebuffer_overlay); UI_view2d_view_ortho(v2d); + UI_ThemeClearColor(TH_BACK); + GPU_clear(GPU_COLOR_BIT); + GPU_depth_test(false); /* XXX snode->cursor set in coordspace for placing new nodes, used for drawing noodles too */ UI_view2d_region_to_view(®ion->v2d, @@ -1789,8 +1754,7 @@ void drawnodespace(const bContext *C, ARegion *region) ED_region_draw_cb_draw(C, region, REGION_DRAW_PRE_VIEW); /* only set once */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); /* nodes */ snode_set_context(C); @@ -1876,7 +1840,7 @@ void drawnodespace(const bContext *C, ARegion *region) } /* temporary links */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); for (nldrag = snode->linkdrag.first; nldrag; nldrag = nldrag->next) { for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) { @@ -1884,7 +1848,7 @@ void drawnodespace(const bContext *C, ARegion *region) } } GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); if (snode->flag & SNODE_SHOW_GPENCIL) { /* draw grease-pencil ('canvas' strokes) */ diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index c88b6a1b297..ef931dd9bb8 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -207,12 +207,11 @@ static void compo_initjob(void *cjv) ViewLayer *view_layer = cj->view_layer; cj->compositor_depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_RENDER); - DEG_graph_build_for_compositor_preview( - cj->compositor_depsgraph, bmain, scene, view_layer, cj->ntree); + DEG_graph_build_for_compositor_preview(cj->compositor_depsgraph, cj->ntree); /* NOTE: Don't update animation to preserve unkeyed changes, this means can not use * evaluate_on_framechange. */ - DEG_evaluate_on_refresh(bmain, cj->compositor_depsgraph); + DEG_evaluate_on_refresh(cj->compositor_depsgraph); bNodeTree *ntree_eval = (bNodeTree *)DEG_get_evaluated_id(cj->compositor_depsgraph, &cj->ntree->id); diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 28e233b6dd2..1705b9dd606 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -2729,7 +2729,7 @@ static void outliner_draw_iconrow_number(const uiFontStyle *fstyle, number_text, text_col); UI_fontstyle_set(fstyle); - GPU_blend(true); /* Roundbox and text drawing disables. */ + GPU_blend(GPU_BLEND_ALPHA); /* Roundbox and text drawing disables. */ } static void outliner_icon_background_colors(float icon_color[4], float icon_border[4]) @@ -2780,7 +2780,7 @@ static void outliner_draw_iconrow_doit(uiBlock *block, (float)ys + UI_UNIT_Y - ufac, (float)UI_UNIT_Y / 4.0f, icon_border); - GPU_blend(true); /* Roundbox disables. */ + GPU_blend(GPU_BLEND_ALPHA); /* Roundbox disables. */ } if (tselem->flag & TSE_HIGHLIGHTED) { @@ -2981,7 +2981,7 @@ static void outliner_draw_tree_element(bContext *C, xmax -= restrict_column_width + UI_UNIT_X; } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* colors for active/selected data */ if (tselem->type == 0) { @@ -3068,7 +3068,7 @@ static void outliner_draw_tree_element(bContext *C, (float)*starty + UI_UNIT_Y - ufac, UI_UNIT_Y / 4.0f, icon_border); - GPU_blend(true); /* roundbox disables it */ + GPU_blend(GPU_BLEND_ALPHA); /* roundbox disables it */ te->flag |= TE_ACTIVE; /* For lookup in display hierarchies. */ } @@ -3116,7 +3116,7 @@ static void outliner_draw_tree_element(bContext *C, offsx += UI_UNIT_X + 4 * ufac; } } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* name */ if ((tselem->flag & TSE_TEXTBUT) == 0) { @@ -3140,7 +3140,7 @@ static void outliner_draw_tree_element(bContext *C, else if (tselem->type != TSE_R_LAYER) { int tempx = startx + offsx; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); MergedIconRow merged = {{0}}; outliner_draw_iconrow(C, @@ -3156,7 +3156,7 @@ static void outliner_draw_tree_element(bContext *C, alpha_fac, &merged); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } } @@ -3315,9 +3315,9 @@ static void outliner_draw_hierarchy_lines(SpaceOutliner *space_outliner, UI_GetThemeColorBlend3ubv(TH_BACK, TH_TEXT, 0.4f, col); col[3] = 255; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); outliner_draw_hierarchy_lines_recursive(pos, space_outliner, lb, startx, col, false, starty); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); } @@ -3464,7 +3464,7 @@ static void outliner_draw_highlights(ARegion *region, UI_GetThemeColor4fv(TH_MATCH, col_searchmatch); col_searchmatch[3] = 0.5f; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -3479,7 +3479,7 @@ static void outliner_draw_highlights(ARegion *region, startx, starty); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void outliner_draw_tree(bContext *C, @@ -3493,8 +3493,7 @@ static void outliner_draw_tree(bContext *C, const uiFontStyle *fstyle = UI_FSTYLE_WIDGET; int starty, startx; - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); /* Only once. */ + GPU_blend(GPU_BLEND_ALPHA); /* Only once. */ if (space_outliner->outlinevis == SO_DATA_API) { /* struct marks */ @@ -3508,12 +3507,12 @@ static void outliner_draw_tree(bContext *C, outliner_draw_highlights(region, space_outliner, startx, &starty); /* set scissor so tree elements or lines can't overlap restriction icons */ - float scissor[4] = {0}; + int scissor[4] = {0}; if (restrict_column_width > 0.0f) { int mask_x = BLI_rcti_size_x(®ion->v2d.mask) - (int)restrict_column_width + 1; CLAMP_MIN(mask_x, 0); - GPU_scissor_get_f(scissor); + GPU_scissor_get(scissor); GPU_scissor(0, 0, mask_x, region->winy); } diff --git a/source/blender/editors/space_script/script_edit.c b/source/blender/editors/space_script/script_edit.c index e9ed1cec228..f739bfe367e 100644 --- a/source/blender/editors/space_script/script_edit.c +++ b/source/blender/editors/space_script/script_edit.c @@ -42,7 +42,7 @@ #include "script_intern.h" // own include #ifdef WITH_PYTHON -# include "BPY_extern.h" /* BPY_script_exec */ +# include "BPY_extern_run.h" #endif static int run_pyfile_exec(bContext *C, wmOperator *op) @@ -50,7 +50,7 @@ static int run_pyfile_exec(bContext *C, wmOperator *op) char path[512]; RNA_string_get(op->ptr, "filepath", path); #ifdef WITH_PYTHON - if (BPY_execute_filepath(C, path, op->reports)) { + if (BPY_run_filepath(C, path, op->reports)) { ARegion *region = CTX_wm_region(C); ED_region_tag_redraw(region); return OPERATOR_FINISHED; @@ -120,7 +120,7 @@ static int script_reload_exec(bContext *C, wmOperator *op) /* TODO, this crashes on netrender and keying sets, need to look into why * disable for now unless running in debug mode */ WM_cursor_wait(1); - BPY_execute_string( + BPY_run_string_eval( C, (const char *[]){"bpy", NULL}, "bpy.utils.load_scripts(reload_scripts=True)"); WM_cursor_wait(0); WM_event_add_notifier(C, NC_WINDOW, NULL); diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 0f4690c11d5..8a6b97b3834 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -56,6 +56,7 @@ #include "GPU_matrix.h" #include "GPU_state.h" #include "GPU_vertex_buffer.h" +#include "GPU_viewport.h" #include "ED_anim_api.h" #include "ED_gpencil.h" @@ -294,7 +295,7 @@ static void draw_seq_waveform(View2D *v2d, /* Fcurve lookup is quite expensive, so do this after precondition. */ FCurve *fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, NULL); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); @@ -350,7 +351,7 @@ static void draw_seq_waveform(View2D *v2d, immEnd(); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } @@ -381,9 +382,7 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, offset = 0; } - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); for (seq = seqbase->first; seq; seq = seq->next) { chan_min = min_ii(chan_min, seq->machine); @@ -443,7 +442,7 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* Get handle width in pixels. */ @@ -489,10 +488,9 @@ static void draw_seq_handle(View2D *v2d, } if (!(seq->type & SEQ_TYPE_EFFECT) || BKE_sequence_effect_get_num_inputs(seq->type) == 0) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); if (seq->flag & whichsel) { if (seq_active) { @@ -511,7 +509,7 @@ static void draw_seq_handle(View2D *v2d, } immRectf(pos, rx1, y1, rx2, y2); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* Draw numbers for start and end of the strip next to its handles. */ @@ -753,9 +751,7 @@ static void draw_sequence_extensions(Scene *scene, Sequence *seq, uint pos, floa y1 = seq->machine + SEQ_STRIP_OFSBOTTOM; y2 = seq->machine + SEQ_STRIP_OFSTOP; - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); color3ubv_from_seq(scene, seq, col); if (seq->flag & SELECT) { @@ -781,7 +777,7 @@ static void draw_sequence_extensions(Scene *scene, Sequence *seq, uint pos, floa imm_draw_box_wire_2d( pos, x2, y2 + pixely, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void draw_color_strip_band(Sequence *seq, uint pos, float text_margin_y, float y1) @@ -791,7 +787,7 @@ static void draw_color_strip_band(Sequence *seq, uint pos, float text_margin_y, rgb_float_to_uchar(col, colvars->col); if (seq->flag & SEQ_MUTE) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); col[3] = MUTE_ALPHA; } else { @@ -812,7 +808,7 @@ static void draw_color_strip_band(Sequence *seq, uint pos, float text_margin_y, immEnd(); if (seq->flag & SEQ_MUTE) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } @@ -843,9 +839,7 @@ static void draw_seq_background(Scene *scene, } if (seq->flag & SEQ_MUTE) { - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); col[3] = MUTE_ALPHA; } @@ -910,13 +904,13 @@ static void draw_seq_background(Scene *scene, } if (seq->flag & SEQ_MUTE) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } static void draw_seq_locked(float x1, float y1, float x2, float y2) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_DIAG_STRIPES); @@ -930,12 +924,12 @@ static void draw_seq_locked(float x1, float y1, float x2, float y2) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void draw_seq_invalid(float x1, float x2, float y2, float text_margin_y) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -943,7 +937,7 @@ static void draw_seq_invalid(float x1, float x2, float y2, float text_margin_y) immRectf(pos, x1, y2, x2, text_margin_y); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void calculate_seq_text_offsets( @@ -1056,13 +1050,13 @@ static void draw_seq_fcurve( GPU_vertbuf_data_len_set(vbo, vert_count); GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR); GPU_batch_uniform_4f(batch, "color", 0.0f, 0.0f, 0.0f, 0.15f); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); if (vert_count > 0) { GPU_batch_draw(batch); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_batch_discard(batch); } } @@ -1180,7 +1174,7 @@ static void draw_effect_inputs_highlight(Sequence *seq) Sequence *seq1 = seq->seq1; Sequence *seq2 = seq->seq2; Sequence *seq3 = seq->seq3; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -1207,7 +1201,7 @@ static void draw_effect_inputs_highlight(Sequence *seq) seq3->machine + SEQ_STRIP_OFSTOP); } immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } void sequencer_special_update_set(Sequence *seq) @@ -1537,7 +1531,7 @@ static void sequencer_preview_clear(void) float col[3]; UI_GetThemeColor3fv(TH_SEQ_PREVIEW, col); - GPU_clear_color(col[0], col[1], col[2], 0.0); + GPU_clear_color(col[0], col[1], col[2], 1.0f); GPU_clear(GPU_COLOR_BIT); } @@ -1594,9 +1588,7 @@ static void sequencer_draw_display_buffer(const bContext *C, void *display_buffer; if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) { - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); } /* Format needs to be created prior to any immBindShader call. @@ -1681,7 +1673,7 @@ static void sequencer_draw_display_buffer(const bContext *C, } if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } if (draw_backdrop) { @@ -1775,6 +1767,13 @@ void sequencer_draw_preview(const bContext *C, return; } + /* Setup offscreen buffers. */ + GPUViewport *viewport = WM_draw_region_get_viewport(region); + + GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport); + GPU_framebuffer_bind_no_srgb(framebuffer_overlay); + GPU_depth_test(false); + if (sseq->render_size == SEQ_PROXY_RENDER_SIZE_NONE) { sequencer_preview_clear(); return; @@ -1798,6 +1797,9 @@ void sequencer_draw_preview(const bContext *C, ibuf = sequencer_ibuf_get( bmain, depsgraph, scene, sseq, cfra, frame_ofs, names[sseq->multiview_eye]); + /* sequencer_ibuf_get can call GPU_framebuffer_bind. So disable srgb framebuffer again. */ + GPU_framebuffer_bind_no_srgb(framebuffer_overlay); + if (ibuf) { scope = sequencer_get_scope(scene, sseq, ibuf, draw_backdrop); @@ -1928,7 +1930,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region) else if (last_seq->type == SEQ_TYPE_MULTICAM) { int channel = last_seq->multicam_source; if (channel != 0) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -1937,7 +1939,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region) immRectf(pos, v2d->cur.xmin, channel, v2d->cur.xmax, channel + 1); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } } @@ -1945,7 +1947,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region) /* Draw highlight if "solo preview" is used. */ if (special_seq_update) { const Sequence *seq = special_seq_update; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -1959,7 +1961,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } @@ -1969,7 +1971,7 @@ static void seq_draw_sfra_efra(Scene *scene, View2D *v2d) const int frame_sta = scene->r.sfra; const int frame_end = scene->r.efra + 1; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -2030,7 +2032,7 @@ static void seq_draw_sfra_efra(Scene *scene, View2D *v2d) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } typedef struct CacheDrawData { @@ -2154,7 +2156,7 @@ static void draw_cache_view(const bContext *C) return; } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -2241,7 +2243,7 @@ static void draw_cache_view(const bContext *C) draw_cache_view_batch( userdata.final_out_vbo, userdata.final_out_vert_count, 1.0f, 0.4f, 0.2f, 0.4f); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* Draw sequencer timeline. */ diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 99d4c2d9f1a..78ca2832c55 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2642,6 +2642,8 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) seq = ed->seqbasep->first; /* Poll checks this is valid. */ + BKE_sequencer_prefetch_stop(scene); + while (seq) { if ((seq->flag & SELECT) && (seq->type == SEQ_TYPE_IMAGE) && (seq->len > 1)) { Sequence *seq_next; @@ -2837,6 +2839,8 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } + BKE_sequencer_prefetch_stop(scene); + /* Remove all selected from main list, and put in meta. */ seqm = BKE_sequence_alloc(ed->seqbasep, 1, 1, SEQ_TYPE_META); /* Channel number set later. */ @@ -2922,6 +2926,8 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_CANCELLED; } + BKE_sequencer_prefetch_stop(scene); + for (seq = last_seq->seqbase.first; seq != NULL; seq = seq->next) { BKE_sequence_invalidate_cache_composite(scene, seq); } diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index e9ac6946032..f1b1d6760f3 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -1353,11 +1353,9 @@ static void draw_text_decoration(SpaceText *st, ARegion *region) UI_GetThemeColor4fv(TH_TEXT, highlight_color); highlight_color[3] = 0.1f; immUniformColor4fv(highlight_color); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immRecti(pos, 0, y1, region->winx, y2); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } @@ -1708,9 +1706,9 @@ void draw_text_main(SpaceText *st, ARegion *region) UI_GetThemeColor4fv(TH_TEXT, margin_color); margin_color[3] = 0.2f; immUniformColor4fv(margin_color); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immRecti(pos, margin_column_x, 0, margin_column_x + U.pixelsize, region->winy); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); } } diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 201f9dae5d5..688dce3c54e 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -55,6 +55,7 @@ #ifdef WITH_PYTHON # include "BPY_extern.h" +# include "BPY_extern_run.h" #endif #include "text_format.h" @@ -756,7 +757,7 @@ static int text_run_script(bContext *C, ReportList *reports) void *curl_prev = text->curl; int curc_prev = text->curc; - if (BPY_execute_text(C, text, reports, !is_live)) { + if (BPY_run_text(C, text, reports, !is_live)) { if (is_live) { /* for nice live updates */ WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 1ffa653372c..6969ecf197e 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -131,9 +131,7 @@ void ED_draw_object_facemap(Depsgraph *depsgraph, /* Just to create the data to pass to immediate mode, grr! */ const int *facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP); if (facemap_data) { - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); const MVert *mvert = me->mvert; const MPoly *mpoly = me->mpoly; @@ -209,6 +207,6 @@ void ED_draw_object_facemap(Depsgraph *depsgraph, GPU_batch_discard(draw_batch); GPU_vertbuf_discard(vbo_pos); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index ac70547c293..33b365b45aa 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -588,9 +588,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region, float alpha = 1.0f; if (ca->passepartalpha != 1.0f) { - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); alpha = ca->passepartalpha; } @@ -609,7 +607,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region, immRectf(shdr_pos, x1i, y1i, x2i, 0.0f); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } immUniformThemeColor3(TH_BACK); @@ -668,7 +666,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region, /* safety border */ if (ca) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immUniformThemeColorAlpha(TH_VIEW_OVERLAY, 0.75f); if (ca->dtx & CAM_DTX_CENTER) { @@ -780,7 +778,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region, imm_draw_box_wire_2d(shdr_pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } immUnbindProgram(); @@ -1027,9 +1025,7 @@ static void draw_view_axis(RegionView3D *rv3d, const rcti *rect) /* draw axis lines */ GPU_line_width(2.0f); GPU_line_smooth(true); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -1072,9 +1068,7 @@ static void draw_rotation_guide(const RegionView3D *rv3d) negate_v3_v3(o, rv3d->ofs); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPU_depth_mask(false); /* don't overwrite zbuf */ GPUVertFormat *format = immVertexFormat(); @@ -1164,7 +1158,7 @@ static void draw_rotation_guide(const RegionView3D *rv3d) immEnd(); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_depth_mask(true); } #endif /* WITH_INPUT_NDOF */ diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index ac9d12cdd58..5912bea4919 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -822,7 +822,7 @@ static void viewrotate_apply(ViewOpsData *vod, const int event_xy[2]) float xaxis[3]; /* Radians per-pixel. */ - const float sensitivity = U.view_rotate_sensitivity_turntable / U.pixelsize; + const float sensitivity = U.view_rotate_sensitivity_turntable / U.dpi_fac; /* Get the 3x3 matrix and its inverse from the quaternion */ quat_to_mat3(m, vod->curr.viewquat); @@ -2015,7 +2015,7 @@ static void view_zoom_to_window_xy_3d(ARegion *region, float dfac, const int zoo } static float viewzoom_scale_value(const rcti *winrct, - const short viewzoom, + const eViewZoom_Style viewzoom, const bool zoom_invert, const bool zoom_invert_force, const int xy_curr[2], @@ -2038,7 +2038,7 @@ static float viewzoom_scale_value(const rcti *winrct, fac = (float)(xy_init[1] - xy_curr[1]); } - fac /= U.pixelsize; + fac /= U.dpi_fac; if (zoom_invert != zoom_invert_force) { fac = -fac; @@ -2055,8 +2055,8 @@ static float viewzoom_scale_value(const rcti *winrct, BLI_rcti_cent_x(winrct), BLI_rcti_cent_y(winrct), }; - float len_new = (5 * U.pixelsize) + ((float)len_v2v2_int(ctr, xy_curr) / U.pixelsize); - float len_old = (5 * U.pixelsize) + ((float)len_v2v2_int(ctr, xy_init) / U.pixelsize); + float len_new = (5 * U.dpi_fac) + ((float)len_v2v2_int(ctr, xy_curr) / U.dpi_fac); + float len_old = (5 * U.dpi_fac) + ((float)len_v2v2_int(ctr, xy_init) / U.dpi_fac); /* intentionally ignore 'zoom_invert' for scale */ if (zoom_invert_force) { @@ -2066,16 +2066,16 @@ static float viewzoom_scale_value(const rcti *winrct, zfac = val_orig * (len_old / max_ff(len_new, 1.0f)) / val; } else { /* USER_ZOOM_DOLLY */ - float len_new = 5 * U.pixelsize; - float len_old = 5 * U.pixelsize; + float len_new = 5 * U.dpi_fac; + float len_old = 5 * U.dpi_fac; if (U.uiflag & USER_ZOOM_HORIZ) { - len_new += (winrct->xmax - (xy_curr[0])) / U.pixelsize; - len_old += (winrct->xmax - (xy_init[0])) / U.pixelsize; + len_new += (winrct->xmax - (xy_curr[0])) / U.dpi_fac; + len_old += (winrct->xmax - (xy_init[0])) / U.dpi_fac; } else { - len_new += (winrct->ymax - (xy_curr[1])) / U.pixelsize; - len_old += (winrct->ymax - (xy_init[1])) / U.pixelsize; + len_new += (winrct->ymax - (xy_curr[1])) / U.dpi_fac; + len_old += (winrct->ymax - (xy_init[1])) / U.dpi_fac; } if (zoom_invert != zoom_invert_force) { @@ -2089,7 +2089,7 @@ static float viewzoom_scale_value(const rcti *winrct, } static float viewzoom_scale_value_offset(const rcti *winrct, - const short viewzoom, + const eViewZoom_Style viewzoom, const bool zoom_invert, const bool zoom_invert_force, const int xy_curr[2], @@ -2120,7 +2120,7 @@ static float viewzoom_scale_value_offset(const rcti *winrct, static void viewzoom_apply_camera(ViewOpsData *vod, const int xy[2], - const short viewzoom, + const eViewZoom_Style viewzoom, const bool zoom_invert, const bool zoom_to_pos) { @@ -2155,7 +2155,7 @@ static void viewzoom_apply_camera(ViewOpsData *vod, static void viewzoom_apply_3d(ViewOpsData *vod, const int xy[2], - const short viewzoom, + const eViewZoom_Style viewzoom, const bool zoom_invert, const bool zoom_to_pos) { @@ -2197,7 +2197,7 @@ static void viewzoom_apply_3d(ViewOpsData *vod, static void viewzoom_apply(ViewOpsData *vod, const int xy[2], - const short viewzoom, + const eViewZoom_Style viewzoom, const bool zoom_invert, const bool zoom_to_pos) { @@ -2248,7 +2248,7 @@ static int viewzoom_modal(bContext *C, wmOperator *op, const wmEvent *event) const bool use_cursor_init = RNA_boolean_get(op->ptr, "use_cursor_init"); viewzoom_apply(vod, &event->x, - U.viewzoom, + (eViewZoom_Style)U.viewzoom, (U.uiflag & USER_ZOOM_INVERT) != 0, (use_cursor_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS))); if (ED_screen_animation_playing(CTX_wm_manager(C))) { diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c index 3ce4c8dc9a8..5f8ffc5f3f9 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c @@ -407,7 +407,7 @@ static void axis_geom_draw(const wmGizmo *gz, BLF_width_and_height(font.id, axis_str, 2, &offset[0], &offset[1]); BLF_position(font.id, roundf(offset[0] * -0.5f), roundf(offset[1] * -0.5f), 0); BLF_draw_ascii(font.id, axis_str, 2); - GPU_blend(true); /* XXX, blf disables */ + GPU_blend(GPU_BLEND_ALPHA); /* XXX, blf disables */ GPU_matrix_pop(); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); @@ -465,9 +465,9 @@ static void axis3d_draw_intern(const bContext *C, UNUSED_VARS(C); #endif - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); axis_geom_draw(gz, color, select, &draw_info); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_matrix_pop(); } @@ -478,9 +478,9 @@ static void gizmo_axis_draw(const bContext *C, wmGizmo *gz) (void)is_modal; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); axis3d_draw_intern(C, gz, false, is_highlight); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static int gizmo_axis_test_select(bContext *UNUSED(C), wmGizmo *gz, const int mval[2]) diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c index 7799aba5c19..5aba1fecc53 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c @@ -607,7 +607,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) GPU_matrix_projection_set(rv3d->winmat); GPU_matrix_set(rv3d->viewmat); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); const uint shdr_pos_3d = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); @@ -735,7 +735,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) rot_90_vec_b[1] = dir_ruler[0]; normalize_v2(rot_90_vec_b); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); if (proj_ok[1] && is_act && (ruler_item->flag & RULERITEM_USE_ANGLE_ACTIVE)) { GPU_line_width(3.0f); @@ -781,7 +781,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) immEnd(); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* text */ @@ -800,13 +800,13 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) /* draw text (bg) */ if (proj_ok[1]) { immUniformColor4fv(color_back); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immRectf(shdr_pos_2d, posit[0] - bg_margin, posit[1] - bg_margin, posit[0] + bg_margin + numstr_size[0], posit[1] + bg_margin + numstr_size[1]); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } immUnbindProgram(); @@ -831,7 +831,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) normalize_v2(rot_90_vec); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor3ubv(color_wire); @@ -855,7 +855,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) immEnd(); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* text */ @@ -877,13 +877,13 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) /* draw text (bg) */ if (proj_ok[0] && proj_ok[2]) { immUniformColor4fv(color_back); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immRectf(shdr_pos_2d, posit[0] - bg_margin, posit[1] - bg_margin, posit[0] + bg_margin + numstr_size[0], posit[1] + bg_margin + numstr_size[1]); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } immUnbindProgram(); diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c index a21c1458286..6c61c83731d 100644 --- a/source/blender/editors/space_view3d/view3d_placement.c +++ b/source/blender/editors/space_view3d/view3d_placement.c @@ -258,7 +258,7 @@ static void draw_line_loop(const float coords[][3], int coords_len, const float GPU_vertbuf_attr_set(vert, pos, i, coords[i]); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_LINE_LOOP, vert, NULL, GPU_BATCH_OWNS_VBO); GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR); @@ -272,7 +272,7 @@ static void draw_line_loop(const float coords[][3], int coords_len, const float GPU_batch_draw(batch); GPU_batch_discard(batch); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void draw_line_pairs(const float coords_a[][3], @@ -291,7 +291,7 @@ static void draw_line_pairs(const float coords_a[][3], GPU_vertbuf_attr_set(vert, pos, (i * 2) + 1, coords_b[i]); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_LINES, vert, NULL, GPU_BATCH_OWNS_VBO); GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR); @@ -305,7 +305,7 @@ static void draw_line_pairs(const float coords_a[][3], GPU_batch_draw(batch); GPU_batch_discard(batch); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void draw_line_bounds(const BoundBox *bounds, const float color[4]) @@ -339,7 +339,7 @@ static void draw_line_bounds(const BoundBox *bounds, const float color[4]) GPU_vertbuf_attr_set(vert, pos, j++, bounds->vec[edges[i][1]]); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_LINES, vert, NULL, GPU_BATCH_OWNS_VBO); GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR); @@ -353,7 +353,7 @@ static void draw_line_bounds(const BoundBox *bounds, const float color[4]) GPU_batch_draw(batch); GPU_batch_discard(batch); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static bool calc_bbox(struct InteractivePlaceData *ipd, BoundBox *bounds) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 76cce5e725f..2fa291e7ae4 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1544,16 +1544,14 @@ static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *region) #endif /* autokey recording icon... */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); xco -= U.widget_unit; yco -= (int)printable_size[1] / 2; UI_icon_draw(xco, yco, ICON_REC); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void drawTransformPixel(const struct bContext *C, ARegion *region, void *arg) diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index d0e37f22236..0aa6b4f6131 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -884,7 +884,7 @@ void drawPropCircle(const struct bContext *C, TransInfo *t) float viewport[4]; GPU_viewport_size_get_f(viewport); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immUniform2fv("viewportSize", &viewport[2]); immUniform1f("lineWidth", 3.0f * U.pixelsize); diff --git a/source/blender/editors/transform/transform_convert_object.c b/source/blender/editors/transform/transform_convert_object.c index 2e92b4e5c09..61af4ebbe46 100644 --- a/source/blender/editors/transform/transform_convert_object.c +++ b/source/blender/editors/transform/transform_convert_object.c @@ -357,7 +357,7 @@ static void set_trans_object_base_flags(TransInfo *t) /* Makes sure base flags and object flags are identical. */ BKE_scene_base_flag_to_objects(t->view_layer); /* Make sure depsgraph is here. */ - DEG_graph_relations_update(depsgraph, bmain, scene, view_layer); + DEG_graph_relations_update(depsgraph); /* Clear all flags we need. It will be used to detect dependencies. */ trans_object_base_deps_flag_prepare(view_layer); /* Traverse all bases and set all possible flags. */ diff --git a/source/blender/editors/transform/transform_draw_cursors.c b/source/blender/editors/transform/transform_draw_cursors.c index 95ca5ae0c30..84fc45e2b45 100644 --- a/source/blender/editors/transform/transform_draw_cursors.c +++ b/source/blender/editors/transform/transform_draw_cursors.c @@ -191,7 +191,7 @@ void transform_draw_cursor_draw(bContext *UNUSED(C), int x, int y, void *customd } GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_matrix_push(); @@ -339,6 +339,6 @@ void transform_draw_cursor_draw(bContext *UNUSED(C), int x, int y, void *customd GPU_matrix_pop(); GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c index 6155042f555..dffee72205b 100644 --- a/source/blender/editors/transform/transform_gizmo_3d.c +++ b/source/blender/editors/transform/transform_gizmo_3d.c @@ -1344,7 +1344,7 @@ void drawDial3d(const TransInfo *t) gizmo_get_axis_color(axis_idx, NULL, color, color); GPU_depth_test(false); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); ED_gizmotypes_dial_3d_draw_util(mat_basis, @@ -1360,7 +1360,7 @@ void drawDial3d(const TransInfo *t) GPU_line_smooth(false); GPU_depth_test(true); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c index 1886f95beae..45debe964f4 100644 --- a/source/blender/editors/transform/transform_mode_edge_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_slide.c @@ -1149,9 +1149,7 @@ void drawEdgeSlide(TransInfo *t) GPU_depth_test(false); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPU_matrix_push(); GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat); @@ -1266,7 +1264,7 @@ void drawEdgeSlide(TransInfo *t) GPU_matrix_pop(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_depth_test(true); } diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c index 38537194af3..11d0b375e6f 100644 --- a/source/blender/editors/transform/transform_mode_vert_slide.c +++ b/source/blender/editors/transform/transform_mode_vert_slide.c @@ -392,9 +392,7 @@ void drawVertSlide(TransInfo *t) GPU_depth_test(false); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPU_matrix_push(); GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat); diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index a700dd320b7..09b5df82c2b 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -245,7 +245,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t) size = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -271,7 +271,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } } diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c index 384da6fb931..041b2fec00b 100644 --- a/source/blender/editors/util/numinput.c +++ b/source/blender/editors/util/numinput.c @@ -38,7 +38,7 @@ #include "WM_types.h" #ifdef WITH_PYTHON -# include "BPY_extern.h" +# include "BPY_extern_run.h" #endif #include "ED_numinput.h" @@ -294,10 +294,10 @@ bool user_string_to_number(bContext *C, 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, error_prefix, r_value); + return BPY_run_string_as_number(C, NULL, str_unit_convert, error_prefix, r_value); } - int success = BPY_execute_string_as_number(C, NULL, str, error_prefix, r_value); + int success = BPY_run_string_as_number(C, NULL, str, error_prefix, r_value); *r_value *= bUnit_PreferredInputUnitScalar(unit, type); *r_value /= unit_scale; return success; diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index f26e95d8861..faeefcb989e 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -237,10 +237,10 @@ static void draw_uvs_shadow(SpaceImage *sima, if (edges) { if (sima->flag & SI_SMOOTH_UV) { GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); } else if (overlay_alpha < 1.0f) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); } col[3] = overlay_alpha; @@ -250,10 +250,10 @@ static void draw_uvs_shadow(SpaceImage *sima, if (sima->flag & SI_SMOOTH_UV) { GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } else if (overlay_alpha < 1.0f) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } } @@ -349,8 +349,7 @@ static void draw_uvs(SpaceImage *sima, interpedges = (ts->uv_selectmode == UV_SELECT_VERTEX); } - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); if (batch->faces) { GPU_batch_program_set_builtin(batch->faces, @@ -360,7 +359,7 @@ static void draw_uvs(SpaceImage *sima, GPU_SHADER_2D_UV_FACES); if (!draw_stretch) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_GetThemeColor4fv(TH_FACE, col1); UI_GetThemeColor4fv(TH_FACE_SELECT, col2); @@ -387,16 +386,16 @@ static void draw_uvs(SpaceImage *sima, GPU_batch_draw(batch->faces); if (!draw_stretch) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } if (batch->edges) { if (sima->flag & SI_SMOOTH_UV) { GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); } else if (overlay_alpha < 1.0f) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); } { @@ -465,10 +464,10 @@ static void draw_uvs(SpaceImage *sima, if (sima->flag & SI_SMOOTH_UV) { GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } else if (overlay_alpha < 1.0f) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } @@ -478,7 +477,7 @@ static void draw_uvs(SpaceImage *sima, const float point_size = UI_GetThemeValuef(TH_VERTEX_SIZE); const float pinned_col[4] = {1.0f, 0.0f, 0.0f, 1.0f}; /* TODO Theme? */ UI_GetThemeColor4fv(TH_VERTEX, col1); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_program_point_size(true); GPU_batch_program_set_builtin(batch->verts, GPU_SHADER_2D_UV_VERTS); @@ -498,7 +497,7 @@ static void draw_uvs(SpaceImage *sima, GPU_batch_uniform_4fv(batch->verts, "selectColor", col2); GPU_batch_draw(batch->verts); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_program_point_size(false); } if (batch->facedots) { diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 6332a6ab48f..6dac31794b4 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -1765,7 +1765,7 @@ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), void pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* Static Tris */ if (stitch_preview->static_tris) { @@ -1829,7 +1829,7 @@ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), void stitch_draw_vbo(vbo_line, GPU_PRIM_LINES, col); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* draw stitch vert/lines preview */ if (ssc->mode == STITCH_VERT) { diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index 68b5b4baeca..4b2fd7b6735 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -869,8 +869,7 @@ Render *BlenderStrokeRenderer::RenderScene(Render * /*re*/, bool render) #endif Render *freestyle_render = RE_NewSceneRender(freestyle_scene); - ViewLayer *view_layer = (ViewLayer *)freestyle_scene->view_layers.first; - DEG_graph_relations_update(freestyle_depsgraph, freestyle_bmain, freestyle_scene, view_layer); + DEG_graph_relations_update(freestyle_depsgraph); RE_RenderFreestyleStrokes( freestyle_render, freestyle_bmain, freestyle_scene, render && get_stroke_count() > 0); diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp index 388c2f35774..2446bfc13dc 100644 --- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp +++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp @@ -655,7 +655,7 @@ void FRS_do_stroke_rendering(Render *re, ViewLayer *view_layer) ViewLayer *scene_view_layer = (ViewLayer *)BLI_findstring( &re->scene->view_layers, view_layer->name, offsetof(ViewLayer, name)); Depsgraph *depsgraph = DEG_graph_new(re->main, re->scene, scene_view_layer, DAG_EVAL_RENDER); - BKE_scene_graph_update_for_newframe(depsgraph, re->main); + BKE_scene_graph_update_for_newframe(depsgraph); // prepare Freestyle: // - load mesh diff --git a/source/blender/freestyle/intern/system/PythonInterpreter.h b/source/blender/freestyle/intern/system/PythonInterpreter.h index bae69aa0a42..50ebacbd6e8 100644 --- a/source/blender/freestyle/intern/system/PythonInterpreter.h +++ b/source/blender/freestyle/intern/system/PythonInterpreter.h @@ -42,7 +42,7 @@ extern "C" { #include "BKE_report.h" #include "BKE_text.h" -#include "BPY_extern.h" +#include "BPY_extern_run.h" #include "bpy_capi_utils.h" @@ -68,12 +68,12 @@ class PythonInterpreter : public Interpreter { BKE_reports_clear(reports); char *fn = const_cast<char *>(filename.c_str()); #if 0 - bool ok = BPY_execute_filepath(_context, fn, reports); + bool ok = BPY_run_filepath(_context, fn, reports); #else bool ok; Text *text = BKE_text_load(&_freestyle_bmain, fn, G_MAIN->name); if (text) { - ok = BPY_execute_text(_context, text, reports, false); + ok = BPY_run_text(_context, text, reports, false); BKE_id_delete(&_freestyle_bmain, text); } else { @@ -102,7 +102,7 @@ class PythonInterpreter : public Interpreter { BKE_reports_clear(reports); - if (!BPY_execute_string(_context, NULL, str.c_str())) { + if (!BPY_run_string_eval(_context, NULL, str.c_str())) { BPy_errors_to_report(reports); cerr << "\nError executing Python script from PythonInterpreter::interpretString" << endl; cerr << "Name: " << name << endl; @@ -122,7 +122,7 @@ class PythonInterpreter : public Interpreter { BKE_reports_clear(reports); - if (!BPY_execute_text(_context, text, reports, false)) { + if (!BPY_run_text(_context, text, reports, false)) { cerr << "\nError executing Python script from PythonInterpreter::interpretText" << endl; cerr << "Name: " << name << endl; cerr << "Errors: " << endl; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c index 60c3877b89a..41365da1153 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c @@ -128,7 +128,10 @@ static void deformStroke(GpencilModifierData *md, BKE_gpencil_stroke_geometry_update(gps); } -static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob) +static void bakeModifier(Main *UNUSED(bmain), + Depsgraph *depsgraph, + GpencilModifierData *md, + Object *ob) { Scene *scene = DEG_get_evaluated_scene(depsgraph); Object *object_eval = DEG_get_evaluated_object(depsgraph, ob); @@ -147,7 +150,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData * NOTE: this assumes that we don't want armature animation on non-keyframed frames */ CFRA = gpf->framenum; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); /* compute armature effects on this frame */ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { @@ -158,7 +161,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData /* return frame state and DB to original state */ CFRA = oldframe; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); } static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams)) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c index 30ac18c64ae..1608d7a2d4c 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c @@ -280,7 +280,10 @@ static void deformStroke(GpencilModifierData *md, /* FIXME: Ideally we be doing this on a copy of the main depsgraph * (i.e. one where we don't have to worry about restoring state) */ -static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob) +static void bakeModifier(Main *UNUSED(bmain), + Depsgraph *depsgraph, + GpencilModifierData *md, + Object *ob) { HookGpencilModifierData *mmd = (HookGpencilModifierData *)md; Scene *scene = DEG_get_evaluated_scene(depsgraph); @@ -297,7 +300,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData * NOTE: this assumes that we don't want hook animation on non-keyframed frames */ CFRA = gpf->framenum; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); /* compute hook effects on this frame */ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { @@ -308,7 +311,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData /* return frame state and DB to original state */ CFRA = oldframe; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); } static void freeData(GpencilModifierData *md) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c index 0f5fc4d5cf6..2d2f39f0189 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c @@ -126,7 +126,10 @@ static void deformStroke(GpencilModifierData *md, /* FIXME: Ideally we be doing this on a copy of the main depsgraph * (i.e. one where we don't have to worry about restoring state) */ -static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob) +static void bakeModifier(Main *UNUSED(bmain), + Depsgraph *depsgraph, + GpencilModifierData *md, + Object *ob) { LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md; Scene *scene = DEG_get_evaluated_scene(depsgraph); @@ -144,7 +147,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData * NOTE: this assumes that we don't want lattice animation on non-keyframed frames */ CFRA = gpf->framenum; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); /* recalculate lattice data */ BKE_gpencil_lattice_init(ob); @@ -165,7 +168,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData /* return frame state and DB to original state */ CFRA = oldframe; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); } static void freeData(GpencilModifierData *md) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c index c99ca64325c..3554cf2e4eb 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c @@ -174,7 +174,10 @@ static void generateStrokes(GpencilModifierData *md, Depsgraph *depsgraph, Objec } } -static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob) +static void bakeModifier(Main *UNUSED(bmain), + Depsgraph *depsgraph, + GpencilModifierData *md, + Object *ob) { Scene *scene = DEG_get_evaluated_scene(depsgraph); bGPdata *gpd = ob->data; @@ -184,7 +187,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) { /* apply mirror effects on this frame */ CFRA = gpf->framenum; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); /* compute mirror effects on this frame */ generate_geometry(md, ob, gpl, gpf); @@ -193,7 +196,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData /* return frame state and DB to original state */ CFRA = oldframe; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); } static bool isDisabled(GpencilModifierData *UNUSED(md), int UNUSED(userRenderParams)) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c index 9d10fcbe49b..9e86ea6ecdc 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c @@ -259,7 +259,10 @@ static void deformStroke(GpencilModifierData *md, /* FIXME: Ideally we be doing this on a copy of the main depsgraph * (i.e. one where we don't have to worry about restoring state) */ -static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob) +static void bakeModifier(Main *UNUSED(bmain), + Depsgraph *depsgraph, + GpencilModifierData *md, + Object *ob) { TintGpencilModifierData *mmd = (TintGpencilModifierData *)md; Scene *scene = DEG_get_evaluated_scene(depsgraph); @@ -276,7 +279,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData * NOTE: this assumes that we don't want animation on non-keyframed frames */ CFRA = gpf->framenum; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); /* compute effects on this frame */ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { @@ -287,7 +290,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData /* return frame state and DB to original state */ CFRA = oldframe; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); } static void freeData(GpencilModifierData *md) diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 906ae31fbc7..45b379c5e0a 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -92,6 +92,8 @@ set(SRC opengl/gl_batch.cc opengl/gl_context.cc opengl/gl_drawlist.cc + opengl/gl_shader.cc + opengl/gl_state.cc opengl/gl_vertex_array.cc GPU_attr_binding.h @@ -137,13 +139,16 @@ set(SRC intern/gpu_primitive_private.h intern/gpu_private.h intern/gpu_select_private.h - intern/gpu_shader_private.h + intern/gpu_shader_private.hh + intern/gpu_state_private.hh intern/gpu_vertex_format_private.h opengl/gl_backend.hh opengl/gl_batch.hh opengl/gl_context.hh opengl/gl_drawlist.hh + opengl/gl_shader.hh + opengl/gl_state.hh opengl/gl_vertex_array.hh ) diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h index d57739156f8..e87ad328f1d 100644 --- a/source/blender/gpu/GPU_batch.h +++ b/source/blender/gpu/GPU_batch.h @@ -128,18 +128,24 @@ void GPU_batch_program_set_builtin_with_config(GPUBatch *batch, eGPUShaderConfig sh_cfg); /* Will only work after setting the batch program. */ -void GPU_batch_uniform_1i(GPUBatch *, const char *name, int value); -void GPU_batch_uniform_1b(GPUBatch *, const char *name, bool value); -void GPU_batch_uniform_1f(GPUBatch *, const char *name, float value); -void GPU_batch_uniform_2f(GPUBatch *, const char *name, float x, float y); -void GPU_batch_uniform_3f(GPUBatch *, const char *name, float x, float y, float z); -void GPU_batch_uniform_4f(GPUBatch *, const char *name, float x, float y, float z, float w); -void GPU_batch_uniform_2fv(GPUBatch *, const char *name, const float data[2]); -void GPU_batch_uniform_3fv(GPUBatch *, const char *name, const float data[3]); -void GPU_batch_uniform_4fv(GPUBatch *, const char *name, const float data[4]); -void GPU_batch_uniform_2fv_array(GPUBatch *, const char *name, const int len, const float *data); -void GPU_batch_uniform_4fv_array(GPUBatch *, const char *name, const int len, const float *data); -void GPU_batch_uniform_mat4(GPUBatch *, const char *name, const float data[4][4]); +/* TODO(fclem) Theses needs to be replaced by GPU_shader_uniform_* with explicit shader. */ +#define GPU_batch_uniform_1i(batch, name, x) GPU_shader_uniform_1i((batch)->shader, name, x); +#define GPU_batch_uniform_1b(batch, name, x) GPU_shader_uniform_1b((batch)->shader, name, x); +#define GPU_batch_uniform_1f(batch, name, x) GPU_shader_uniform_1f((batch)->shader, name, x); +#define GPU_batch_uniform_2f(batch, name, x, y) GPU_shader_uniform_2f((batch)->shader, name, x, y); +#define GPU_batch_uniform_3f(batch, name, x, y, z) \ + GPU_shader_uniform_3f((batch)->shader, name, x, y, z); +#define GPU_batch_uniform_4f(batch, name, x, y, z, w) \ + GPU_shader_uniform_4f((batch)->shader, name, x, y, z, w); +#define GPU_batch_uniform_2fv(batch, name, val) GPU_shader_uniform_2fv((batch)->shader, name, val); +#define GPU_batch_uniform_3fv(batch, name, val) GPU_shader_uniform_3fv((batch)->shader, name, val); +#define GPU_batch_uniform_4fv(batch, name, val) GPU_shader_uniform_4fv((batch)->shader, name, val); +#define GPU_batch_uniform_2fv_array(batch, name, len, val) \ + GPU_shader_uniform_2fv_array((batch)->shader, name, len, val); +#define GPU_batch_uniform_4fv_array(batch, name, len, val) \ + GPU_shader_uniform_4fv_array((batch)->shader, name, len, val); +#define GPU_batch_uniform_mat4(batch, name, val) \ + GPU_shader_uniform_mat4((batch)->shader, name, val); void GPU_batch_draw(GPUBatch *batch); void GPU_batch_draw_range(GPUBatch *batch, int v_first, int v_count); diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h index 9dc07fefd4e..7103317e4d6 100644 --- a/source/blender/gpu/GPU_framebuffer.h +++ b/source/blender/gpu/GPU_framebuffer.h @@ -61,6 +61,7 @@ typedef struct GPUOffScreen GPUOffScreen; GPUFrameBuffer *GPU_framebuffer_create(void); void GPU_framebuffer_free(GPUFrameBuffer *fb); void GPU_framebuffer_bind(GPUFrameBuffer *fb); +void GPU_framebuffer_bind_no_srgb(GPUFrameBuffer *fb); void GPU_framebuffer_restore(void); bool GPU_framebuffer_bound(GPUFrameBuffer *fb); diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index b8957ff1819..9dcf9b7d5bb 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -112,15 +112,6 @@ typedef enum eGPUMatFlag { GPU_MATFLAG_BARYCENTRIC = (1 << 4), } eGPUMatFlag; -typedef enum eGPUBlendMode { - GPU_BLEND_SOLID = 0, - GPU_BLEND_ADD = 1, - GPU_BLEND_ALPHA = 2, - GPU_BLEND_CLIP = 4, - GPU_BLEND_ALPHA_SORT = 8, - GPU_BLEND_ALPHA_TO_COVERAGE = 16, -} eGPUBlendMode; - typedef struct GPUNodeStack { eGPUType type; float vec[4]; diff --git a/source/blender/gpu/GPU_matrix.h b/source/blender/gpu/GPU_matrix.h index 7b94a535a30..aad6ae9e2ba 100644 --- a/source/blender/gpu/GPU_matrix.h +++ b/source/blender/gpu/GPU_matrix.h @@ -29,7 +29,7 @@ extern "C" { #endif -struct GPUShaderInterface; +struct GPUShader; void GPU_matrix_reset(void); /* to Identity transform & empty stack */ @@ -147,7 +147,7 @@ const float (*GPU_matrix_normal_get(float m[3][3]))[3]; const float (*GPU_matrix_normal_inverse_get(float m[3][3]))[3]; /* set uniform values for currently bound shader */ -void GPU_matrix_bind(const struct GPUShaderInterface *); +void GPU_matrix_bind(struct GPUShader *shader); bool GPU_matrix_dirty_get(void); /* since last bind */ /* own working polygon offset */ diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 0b9109fbd4b..99fcae19984 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -27,14 +27,19 @@ extern "C" { #endif -typedef struct GPUShader GPUShader; struct GPUShaderInterface; struct GPUTexture; struct GPUUniformBuffer; +struct GPUVertBuf; -/* GPU Shader - * - only for fragment shaders now - * - must call texture bind before setting a texture as uniform! */ +/* TODO(fclem) These members should be private and the + * whole struct should just be an opaque pointer. */ +typedef struct GPUShader { + /** Uniform & attribute locations for shader. */ + struct GPUShaderInterface *interface; + /** For debugging purpose. */ + char name[64]; +} GPUShader; typedef enum eGPUShaderTFBType { GPU_SHADER_TFB_NONE = 0, /* Transform feedback unsupported. */ @@ -63,17 +68,16 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, const char **tf_names, const int tf_count, const char *shader_name); -GPUShader *GPU_shader_load_from_binary(const char *binary, - const int binary_format, - const int binary_len, - const char *shname); + struct GPU_ShaderCreateFromArray_Params { const char **vert, **geom, **frag, **defs; }; struct GPUShader *GPU_shader_create_from_arrays_impl( - const struct GPU_ShaderCreateFromArray_Params *params); + const struct GPU_ShaderCreateFromArray_Params *params, const char *func, int line); + #define GPU_shader_create_from_arrays(...) \ - GPU_shader_create_from_arrays_impl(&(const struct GPU_ShaderCreateFromArray_Params)__VA_ARGS__) + GPU_shader_create_from_arrays_impl( \ + &(const struct GPU_ShaderCreateFromArray_Params)__VA_ARGS__, __func__, __LINE__) void GPU_shader_free(GPUShader *shader); @@ -81,12 +85,12 @@ void GPU_shader_bind(GPUShader *shader); void GPU_shader_unbind(void); /* Returns true if transform feedback was successfully enabled. */ -bool GPU_shader_transform_feedback_enable(GPUShader *shader, unsigned int vbo_id); +bool GPU_shader_transform_feedback_enable(GPUShader *shader, struct GPUVertBuf *vertbuf); void GPU_shader_transform_feedback_disable(GPUShader *shader); int GPU_shader_get_program(GPUShader *shader); -void GPU_shader_set_srgb_uniform(const struct GPUShaderInterface *interface); +void GPU_shader_set_srgb_uniform(GPUShader *shader); int GPU_shader_get_uniform(GPUShader *shader, const char *name); int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin); diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h index 4a2c90e241b..be3250f6654 100644 --- a/source/blender/gpu/GPU_state.h +++ b/source/blender/gpu/GPU_state.h @@ -20,49 +20,92 @@ #pragma once -#ifdef __cplusplus -extern "C" { -#endif +#include "BLI_utildefines.h" + +typedef enum eGPUWriteMask { + GPU_WRITE_NONE = 0, + GPU_WRITE_RED = (1 << 0), + GPU_WRITE_GREEN = (1 << 1), + GPU_WRITE_BLUE = (1 << 2), + GPU_WRITE_ALPHA = (1 << 3), + GPU_WRITE_DEPTH = (1 << 4), + GPU_WRITE_COLOR = (GPU_WRITE_RED | GPU_WRITE_GREEN | GPU_WRITE_BLUE | GPU_WRITE_ALPHA), +} eGPUWriteMask; + +ENUM_OPERATORS(eGPUWriteMask) + +/** + * Defines the fixed pipeline blending equation. + * SRC is the output color from the shader. + * DST is the color from the framebuffer. + * The blending equation is : + * (SRC * A) + (DST * B). + * The blend mode will modify the A and B parameters. + */ +typedef enum eGPUBlend { + GPU_BLEND_NONE = 0, + /** Premult variants will _NOT_ multiply rgb output by alpha. */ + GPU_BLEND_ALPHA, + GPU_BLEND_ALPHA_PREMULT, + GPU_BLEND_ADDITIVE, + GPU_BLEND_ADDITIVE_PREMULT, + GPU_BLEND_MULTIPLY, + GPU_BLEND_SUBTRACT, + /** Replace logic op: SRC * (1 - DST) + * NOTE: Does not modify alpha. */ + GPU_BLEND_INVERT, + /** Order independent transparency. + * NOTE: Cannot be used as is. Needs special setup (framebuffer, shader ...). */ + GPU_BLEND_OIT, + /** Special blend to add color under and multiply dst color by src alpha. */ + GPU_BLEND_BACKGROUND, + /** Custom blend parameters using dual source blending : SRC0 + SRC1 * DST + * NOTE: Can only be used with _ONE_ Draw Buffer and shader needs to be specialized. */ + GPU_BLEND_CUSTOM, +} eGPUBlend; + +typedef enum eGPUDepthTest { + GPU_DEPTH_NONE = 0, + GPU_DEPTH_ALWAYS, + GPU_DEPTH_LESS, + GPU_DEPTH_LESS_EQUAL, + GPU_DEPTH_EQUAL, + GPU_DEPTH_GREATER, + GPU_DEPTH_GREATER_EQUAL, +} eGPUDepthTest; + +typedef enum eGPUStencilTest { + GPU_STENCIL_NONE = 0, + GPU_STENCIL_ALWAYS, + GPU_STENCIL_EQUAL, + GPU_STENCIL_NEQUAL, +} eGPUStencilTest; + +typedef enum eGPUStencilOp { + GPU_STENCIL_OP_NONE = 0, + GPU_STENCIL_OP_REPLACE, + /** Special values for stencil shadows. */ + GPU_STENCIL_OP_COUNT_DEPTH_PASS, + GPU_STENCIL_OP_COUNT_DEPTH_FAIL, +} eGPUStencilOp; -/* These map directly to the GL_ blend functions, to minimize API add as needed*/ -typedef enum eGPUBlendFunction { - GPU_ONE, - GPU_SRC_ALPHA, - GPU_ONE_MINUS_SRC_ALPHA, - GPU_DST_COLOR, - GPU_ZERO, -} eGPUBlendFunction; - -/* These map directly to the GL_ filter functions, to minimize API add as needed*/ -typedef enum eGPUFilterFunction { - GPU_NEAREST, - GPU_LINEAR, -} eGPUFilterFunction; - -typedef enum eGPUFaceCull { +typedef enum eGPUFaceCullTest { GPU_CULL_NONE = 0, /* Culling disabled. */ GPU_CULL_FRONT, GPU_CULL_BACK, -} eGPUFaceCull; +} eGPUFaceCullTest; typedef enum eGPUProvokingVertex { - GPU_VERTEX_FIRST = 0, - GPU_VERTEX_LAST, /* Default */ + GPU_VERTEX_LAST = 0, /* Default. */ + GPU_VERTEX_FIRST = 1, /* Follow Blender loop order. */ } eGPUProvokingVertex; -/* Initialize - * - sets the default Blender opengl state, if in doubt, check - * the contents of this function - * - this is called when starting Blender, for opengl rendering. */ -void GPU_state_init(void); - -void GPU_blend(bool enable); -void GPU_blend_set_func(eGPUBlendFunction sfactor, eGPUBlendFunction dfactor); -void GPU_blend_set_func_separate(eGPUBlendFunction src_rgb, - eGPUBlendFunction dst_rgb, - eGPUBlendFunction src_alpha, - eGPUBlendFunction dst_alpha); -void GPU_face_culling(eGPUFaceCull culling); +#ifdef __cplusplus +extern "C" { +#endif + +void GPU_blend(eGPUBlend blend); +void GPU_face_culling(eGPUFaceCullTest culling); void GPU_front_facing(bool invert); void GPU_provoking_vertex(eGPUProvokingVertex vert); void GPU_depth_range(float near, float far); @@ -71,39 +114,40 @@ bool GPU_depth_test_enabled(void); void GPU_scissor_test(bool enable); void GPU_line_smooth(bool enable); void GPU_line_width(float width); +void GPU_logic_op_xor_set(bool enable); void GPU_point_size(float size); void GPU_polygon_smooth(bool enable); void GPU_program_point_size(bool enable); void GPU_scissor(int x, int y, int width, int height); -void GPU_scissor_get_f(float coords[4]); -void GPU_scissor_get_i(int coords[4]); +void GPU_scissor_get(int coords[4]); void GPU_viewport(int x, int y, int width, int height); void GPU_viewport_size_get_f(float coords[4]); void GPU_viewport_size_get_i(int coords[4]); +void GPU_write_mask(eGPUWriteMask mask); void GPU_color_mask(bool r, bool g, bool b, bool a); void GPU_depth_mask(bool depth); bool GPU_depth_mask_get(void); -void GPU_stencil_mask(uint stencil); void GPU_unpack_row_length_set(uint len); +void GPU_shadow_offset(bool enable); void GPU_clip_distances(int enabled_len); bool GPU_mipmap_enabled(void); +void GPU_state_set(eGPUWriteMask write_mask, + eGPUBlend blend, + eGPUFaceCullTest culling_test, + eGPUDepthTest depth_test, + eGPUStencilTest stencil_test, + eGPUStencilOp stencil_op, + eGPUProvokingVertex provoking_vert); -void GPU_flush(void); -void GPU_finish(void); +void GPU_stencil_reference_set(uint reference); +void GPU_stencil_write_mask_set(uint write_mask); +void GPU_stencil_compare_mask_set(uint compare_mask); -void GPU_logic_op_xor_set(bool enable); +eGPUBlend GPU_blend_get(void); +eGPUWriteMask GPU_write_mask_get(void); -/* Attribute push & pop. */ -typedef enum eGPUAttrMask { - GPU_DEPTH_BUFFER_BIT = (1 << 0), - GPU_ENABLE_BIT = (1 << 1), - GPU_SCISSOR_BIT = (1 << 2), - GPU_VIEWPORT_BIT = (1 << 3), - GPU_BLEND_BIT = (1 << 4), -} eGPUAttrMask; - -void gpuPushAttr(eGPUAttrMask mask); -void gpuPopAttr(void); +void GPU_flush(void); +void GPU_finish(void); #ifdef __cplusplus } diff --git a/source/blender/gpu/intern/gpu_backend.hh b/source/blender/gpu/intern/gpu_backend.hh index 25d165098a7..ab6e9cd7351 100644 --- a/source/blender/gpu/intern/gpu_backend.hh +++ b/source/blender/gpu/intern/gpu_backend.hh @@ -28,6 +28,10 @@ #include "gpu_batch_private.hh" #include "gpu_context_private.hh" #include "gpu_drawlist_private.hh" +<<<<<<< HEAD +======= +#include "gpu_shader_private.hh" +>>>>>>> master namespace blender { namespace gpu { @@ -43,7 +47,7 @@ class GPUBackend { virtual Batch *batch_alloc(void) = 0; virtual DrawList *drawlist_alloc(int list_length) = 0; // virtual FrameBuffer *framebuffer_alloc(void) = 0; - // virtual Shader *shader_alloc(void) = 0; + virtual Shader *shader_alloc(const char *name) = 0; // virtual Texture *texture_alloc(void) = 0; }; diff --git a/source/blender/gpu/intern/gpu_batch.cc b/source/blender/gpu/intern/gpu_batch.cc index 7b006bdc6c2..36f60c3dcc8 100644 --- a/source/blender/gpu/intern/gpu_batch.cc +++ b/source/blender/gpu/intern/gpu_batch.cc @@ -39,7 +39,7 @@ #include "gpu_batch_private.hh" #include "gpu_context_private.hh" #include "gpu_primitive_private.h" -#include "gpu_shader_private.h" +#include "gpu_shader_private.hh" #include "gpu_vertex_format_private.h" #include <limits.h> @@ -176,8 +176,7 @@ int GPU_batch_instbuf_add_ex(GPUBatch *batch, GPUVertBuf *insts, bool own_vbo) if (batch->inst[v] == NULL) { /* for now all VertexBuffers must have same vertex_len */ if (batch->inst[0]) { - /* Allow for different size of vertex buf (will choose the smallest - * number of verts). */ + /* Allow for different size of vertex buffer (will choose the smallest number of verts). */ // BLI_assert(insts->vertex_len == batch->inst[0]->vertex_len); } @@ -227,87 +226,6 @@ void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader) GPU_shader_bind(batch->shader); } -#define GET_UNIFORM \ - const GPUShaderInput *uniform = GPU_shaderinterface_uniform(batch->shader->interface, name); \ - BLI_assert(uniform); - -void GPU_batch_uniform_1i(GPUBatch *batch, const char *name, int value) -{ - GET_UNIFORM - GPU_shader_uniform_int(batch->shader, uniform->location, value); -} - -void GPU_batch_uniform_1b(GPUBatch *batch, const char *name, bool value) -{ - GPU_batch_uniform_1i(batch, name, value ? GL_TRUE : GL_FALSE); -} - -void GPU_batch_uniform_2f(GPUBatch *batch, const char *name, float x, float y) -{ - const float data[2] = {x, y}; - GPU_batch_uniform_2fv(batch, name, data); -} - -void GPU_batch_uniform_3f(GPUBatch *batch, const char *name, float x, float y, float z) -{ - const float data[3] = {x, y, z}; - GPU_batch_uniform_3fv(batch, name, data); -} - -void GPU_batch_uniform_4f(GPUBatch *batch, const char *name, float x, float y, float z, float w) -{ - const float data[4] = {x, y, z, w}; - GPU_batch_uniform_4fv(batch, name, data); -} - -void GPU_batch_uniform_1f(GPUBatch *batch, const char *name, float x) -{ - GET_UNIFORM - GPU_shader_uniform_float(batch->shader, uniform->location, x); -} - -void GPU_batch_uniform_2fv(GPUBatch *batch, const char *name, const float data[2]) -{ - GET_UNIFORM - GPU_shader_uniform_vector(batch->shader, uniform->location, 2, 1, data); -} - -void GPU_batch_uniform_3fv(GPUBatch *batch, const char *name, const float data[3]) -{ - GET_UNIFORM - GPU_shader_uniform_vector(batch->shader, uniform->location, 3, 1, data); -} - -void GPU_batch_uniform_4fv(GPUBatch *batch, const char *name, const float data[4]) -{ - GET_UNIFORM - GPU_shader_uniform_vector(batch->shader, uniform->location, 4, 1, data); -} - -void GPU_batch_uniform_2fv_array(GPUBatch *batch, - const char *name, - const int len, - const float *data) -{ - GET_UNIFORM - GPU_shader_uniform_vector(batch->shader, uniform->location, 2, len, data); -} - -void GPU_batch_uniform_4fv_array(GPUBatch *batch, - const char *name, - const int len, - const float *data) -{ - GET_UNIFORM - GPU_shader_uniform_vector(batch->shader, uniform->location, 4, len, data); -} - -void GPU_batch_uniform_mat4(GPUBatch *batch, const char *name, const float data[4][4]) -{ - GET_UNIFORM - GPU_shader_uniform_vector(batch->shader, uniform->location, 16, 1, (const float *)data); -} - /** \} */ /* -------------------------------------------------------------------- */ @@ -364,6 +282,8 @@ void GPU_batch_draw_advanced(GPUBatch *batch, int v_first, int v_count, int i_fi /* just draw some vertices and let shader place them where we want. */ void GPU_draw_primitive(GPUPrimType prim_type, int v_count) { + GPU_context_active_get()->state_manager->apply_state(); + /* we cannot draw without vao ... annoying ... */ glBindVertexArray(GPU_vao_default()); diff --git a/source/blender/gpu/intern/gpu_batch_presets.c b/source/blender/gpu/intern/gpu_batch_presets.c index 71c971d8656..8adb1ba1ed3 100644 --- a/source/blender/gpu/intern/gpu_batch_presets.c +++ b/source/blender/gpu/intern/gpu_batch_presets.c @@ -35,7 +35,6 @@ #include "GPU_batch.h" #include "GPU_batch_presets.h" /* own include */ #include "GPU_batch_utils.h" -#include "gpu_shader_private.h" /* -------------------------------------------------------------------- */ /** \name Local Structures diff --git a/source/blender/gpu/intern/gpu_batch_utils.c b/source/blender/gpu/intern/gpu_batch_utils.c index 0660d4a1724..e2d03d27035 100644 --- a/source/blender/gpu/intern/gpu_batch_utils.c +++ b/source/blender/gpu/intern/gpu_batch_utils.c @@ -28,7 +28,6 @@ #include "GPU_batch.h" #include "GPU_batch_utils.h" /* own include */ -#include "gpu_shader_private.h" /* -------------------------------------------------------------------- */ /** \name Polygon Creation (2D) diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc index e04631910c1..ef02ec24a00 100644 --- a/source/blender/gpu/intern/gpu_context.cc +++ b/source/blender/gpu/intern/gpu_context.cc @@ -70,6 +70,7 @@ GPUContext::GPUContext() GPUContext::~GPUContext() { GPU_matrix_state_discard(matrix_state); + delete state_manager; } bool GPUContext::is_active_on_thread(void) diff --git a/source/blender/gpu/intern/gpu_context_private.hh b/source/blender/gpu/intern/gpu_context_private.hh index 3f9fca16ff7..b774d6b0995 100644 --- a/source/blender/gpu/intern/gpu_context_private.hh +++ b/source/blender/gpu/intern/gpu_context_private.hh @@ -29,6 +29,8 @@ #include "GPU_context.h" +#include "gpu_state_private.hh" + #include <mutex> #include <pthread.h> #include <string.h> @@ -44,6 +46,7 @@ struct GPUContext { GPUShader *shader = NULL; GPUFrameBuffer *current_fbo = NULL; GPUMatrixState *matrix_state = NULL; + blender::gpu::GPUStateManager *state_manager = NULL; protected: /** Thread on which this context is active. */ diff --git a/source/blender/gpu/intern/gpu_framebuffer.cc b/source/blender/gpu/intern/gpu_framebuffer.cc index 5f3089b2ffb..da8ab80b347 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.cc +++ b/source/blender/gpu/intern/gpu_framebuffer.cc @@ -552,7 +552,19 @@ void GPU_framebuffer_bind(GPUFrameBuffer *fb) } #endif - glViewport(0, 0, fb->width, fb->height); + GPU_viewport(0, 0, fb->width, fb->height); +} + +/* Workaround for binding a srgb framebuffer without doing the srgb transform. */ +void GPU_framebuffer_bind_no_srgb(GPUFrameBuffer *fb) +{ + GPU_framebuffer_bind(fb); + + glDisable(GL_FRAMEBUFFER_SRGB); + + GPUTexture *first_target = fb->attachments[GPU_FB_COLOR_ATTACHMENT0].tex; + const bool is_srgb_target = (first_target && (GPU_texture_format(first_target) == GPU_SRGB8_A8)); + GPU_shader_set_framebuffer_srgb_target(!is_srgb_target); } void GPU_framebuffer_restore(void) @@ -599,7 +611,7 @@ void GPU_framebuffer_viewport_set(GPUFrameBuffer *fb, int x, int y, int w, int h { CHECK_FRAMEBUFFER_IS_BOUND(fb); - glViewport(x, y, w, h); + GPU_viewport(x, y, w, h); } void GPU_framebuffer_clear(GPUFrameBuffer *fb, @@ -610,6 +622,8 @@ void GPU_framebuffer_clear(GPUFrameBuffer *fb, { CHECK_FRAMEBUFFER_IS_BOUND(fb); + GPU_context_active_get()->state_manager->apply_state(); + if (buffers & GPU_COLOR_BIT) { glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glClearColor(clear_col[0], clear_col[1], clear_col[2], clear_col[3]); @@ -774,6 +788,8 @@ void GPU_framebuffer_blit(GPUFrameBuffer *fb_read, GLbitfield mask = convert_buffer_bits_to_gl(blit_buffers); + GPU_context_active_get()->state_manager->apply_state(); + glBlitFramebuffer(0, 0, fb_read->width, @@ -850,7 +866,7 @@ void GPU_framebuffer_recursive_downsample(GPUFrameBuffer *fb, BLI_assert(GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_FRAMEBUFFER)); - glViewport(0, 0, current_dim[0], current_dim[1]); + GPU_viewport(0, 0, current_dim[0], current_dim[1]); callback(userData, i); if (current_dim[0] == 1 && current_dim[1] == 1) { @@ -889,6 +905,13 @@ struct GPUOffScreen { GPUTexture *color; GPUTexture *depth; + + /** Saved state of the previously bound framebuffer. */ + /* TODO(fclem) This is quite hacky and a proper fix would be to + * put these states directly inside the GPUFrambuffer. + * But we don't have a GPUFramebuffer for the default framebuffer yet. */ + int saved_viewport[4]; + int saved_scissor[4]; }; /* Returns the correct framebuffer for the current context. */ @@ -952,21 +975,19 @@ GPUOffScreen *GPU_offscreen_create( return NULL; } - gpuPushAttr(GPU_VIEWPORT_BIT); + int viewport[4]; + GPU_viewport_size_get_i(viewport); GPUFrameBuffer *fb = gpu_offscreen_fb_get(ofs); /* check validity at the very end! */ if (!GPU_framebuffer_check_valid(fb, err_out)) { GPU_offscreen_free(ofs); - gpuPopAttr(); + GPU_viewport(UNPACK4(viewport)); return NULL; } - GPU_framebuffer_restore(); - - gpuPopAttr(); - + GPU_viewport(UNPACK4(viewport)); return ofs; } @@ -990,7 +1011,9 @@ void GPU_offscreen_free(GPUOffScreen *ofs) void GPU_offscreen_bind(GPUOffScreen *ofs, bool save) { if (save) { - gpuPushAttr((eGPUAttrMask)(GPU_SCISSOR_BIT | GPU_VIEWPORT_BIT)); + GPU_scissor_get(ofs->saved_scissor); + GPU_viewport_size_get_i(ofs->saved_viewport); + GPUFrameBuffer *fb = GPU_framebuffer_active_get(); gpuPushFrameBuffer(fb); } @@ -1001,12 +1024,13 @@ void GPU_offscreen_bind(GPUOffScreen *ofs, bool save) GPU_shader_set_framebuffer_srgb_target(false); } -void GPU_offscreen_unbind(GPUOffScreen *UNUSED(ofs), bool restore) +void GPU_offscreen_unbind(GPUOffScreen *ofs, bool restore) { GPUFrameBuffer *fb = NULL; if (restore) { - gpuPopAttr(); + GPU_scissor(UNPACK4(ofs->saved_scissor)); + GPU_viewport(UNPACK4(ofs->saved_viewport)); fb = gpuPopFrameBuffer(); } @@ -1023,6 +1047,8 @@ void GPU_offscreen_draw_to_screen(GPUOffScreen *ofs, int x, int y) const int w = GPU_texture_width(ofs->color); const int h = GPU_texture_height(ofs->color); + GPU_context_active_get()->state_manager->apply_state(); + GPUFrameBuffer *ofs_fb = gpu_offscreen_fb_get(ofs); glBindFramebuffer(GL_READ_FRAMEBUFFER, ofs_fb->object); @@ -1087,6 +1113,7 @@ void GPU_clear_depth(float depth) void GPU_clear(eGPUFrameBufferBits flags) { + GPU_context_active_get()->state_manager->apply_state(); glClear(convert_buffer_bits_to_gl(flags)); } diff --git a/source/blender/gpu/intern/gpu_immediate.cc b/source/blender/gpu/intern/gpu_immediate.cc index 2d137c2f21c..dd05689d69a 100644 --- a/source/blender/gpu/intern/gpu_immediate.cc +++ b/source/blender/gpu/intern/gpu_immediate.cc @@ -35,7 +35,7 @@ #include "gpu_attr_binding_private.h" #include "gpu_context_private.hh" #include "gpu_primitive_private.h" -#include "gpu_shader_private.h" +#include "gpu_shader_private.hh" #include "gpu_vertex_format_private.h" #include <stdlib.h> @@ -145,10 +145,7 @@ GPUVertFormat *immVertexFormat(void) void immBindShader(GPUShader *shader) { -#if TRUST_NO_ONE - assert(imm.bound_program == NULL); - assert(glIsProgram(shader->program)); -#endif + BLI_assert(imm.bound_program == NULL); imm.bound_program = shader; imm.shader_interface = shader->interface; @@ -159,8 +156,8 @@ void immBindShader(GPUShader *shader) 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); + GPU_matrix_bind(shader); + GPU_shader_set_srgb_uniform(shader); } void immBindBuiltinProgram(eGPUBuiltinShader shader_id) @@ -213,6 +210,8 @@ static bool vertex_count_makes_sense_for_primitive(uint vertex_len, GPUPrimType void immBegin(GPUPrimType prim_type, uint vertex_len) { + GPU_context_active_get()->state_manager->apply_state(); + #if TRUST_NO_ONE assert(initialized); assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we haven't already begun */ @@ -375,7 +374,7 @@ static void immDrawSetup(void) } if (GPU_matrix_dirty_get()) { - GPU_matrix_bind(imm.shader_interface); + GPU_matrix_bind(imm.bound_program); } } diff --git a/source/blender/gpu/intern/gpu_matrix.cc b/source/blender/gpu/intern/gpu_matrix.cc index 5d8d77bbf1c..951652b9393 100644 --- a/source/blender/gpu/intern/gpu_matrix.cc +++ b/source/blender/gpu/intern/gpu_matrix.cc @@ -643,13 +643,13 @@ const float (*GPU_matrix_normal_inverse_get(float m[3][3]))[3] return m; } -void GPU_matrix_bind(const GPUShaderInterface *shaderface) +void GPU_matrix_bind(GPUShader *shader) { /* set uniform values to matrix stack values * call this before a draw call if desired matrices are dirty * call glUseProgram before this, as glUniform expects program to be bound */ - + const GPUShaderInterface *shaderface = shader->interface; int32_t MV = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_MODELVIEW); int32_t P = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_PROJECTION); int32_t MVP = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_MVP); @@ -658,32 +658,30 @@ 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) { - GPU_shader_uniform_vector(sh, MV, 16, 1, (const float *)GPU_matrix_model_view_get(NULL)); + GPU_shader_uniform_vector(shader, MV, 16, 1, (const float *)GPU_matrix_model_view_get(NULL)); } if (P != -1) { - GPU_shader_uniform_vector(sh, P, 16, 1, (const float *)GPU_matrix_projection_get(NULL)); + GPU_shader_uniform_vector(shader, P, 16, 1, (const float *)GPU_matrix_projection_get(NULL)); } if (MVP != -1) { GPU_shader_uniform_vector( - sh, MVP, 16, 1, (const float *)GPU_matrix_model_view_projection_get(NULL)); + shader, MVP, 16, 1, (const float *)GPU_matrix_model_view_projection_get(NULL)); } if (N != -1) { - GPU_shader_uniform_vector(sh, N, 9, 1, (const float *)GPU_matrix_normal_get(NULL)); + GPU_shader_uniform_vector(shader, 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); - GPU_shader_uniform_vector(sh, MV_inv, 16, 1, (const float *)m); + GPU_shader_uniform_vector(shader, MV_inv, 16, 1, (const float *)m); } if (P_inv != -1) { Mat4 m; GPU_matrix_projection_get(m); invert_m4(m); - GPU_shader_uniform_vector(sh, P_inv, 16, 1, (const float *)m); + GPU_shader_uniform_vector(shader, P_inv, 16, 1, (const float *)m); } gpu_matrix_state_active_set_dirty(false); @@ -734,8 +732,8 @@ float GPU_polygon_offset_calc(const float (*winmat)[4], float viewdist, float di #else static float depth_fac = 0.0f; if (depth_fac == 0.0f) { - int depthbits; - glGetIntegerv(GL_DEPTH_BITS, &depthbits); + /* Hardcode for 24 bit precision. */ + int depthbits = 24; depth_fac = 1.0f / (float)((1 << depthbits) - 1); } offs = (-1.0 / winmat[2][2]) * dist * depth_fac; diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c index 0f6f29fab40..29e2615345c 100644 --- a/source/blender/gpu/intern/gpu_select_pick.c +++ b/source/blender/gpu/intern/gpu_select_pick.c @@ -282,6 +282,12 @@ typedef struct GPUPickState { uint *rect_id; } nearest; }; + + /* Previous state to restore after drawing. */ + int viewport[4]; + int scissor[4]; + eGPUWriteMask write_mask; + bool depth_test; } GPUPickState; static GPUPickState g_pick_state = {0}; @@ -304,7 +310,9 @@ void gpu_select_pick_begin(uint (*buffer)[4], uint bufsize, const rcti *input, c /* Restrict OpenGL operations for when we don't have cache */ if (ps->is_cached == false) { - gpuPushAttr(GPU_DEPTH_BUFFER_BIT | GPU_VIEWPORT_BIT); + ps->write_mask = GPU_write_mask_get(); + ps->depth_test = GPU_depth_test_enabled(); + GPU_scissor_get(ps->scissor); /* disable writing to the framebuffer */ GPU_color_mask(false, false, false, false); @@ -535,8 +543,9 @@ uint gpu_select_pick_end(void) /* force finishing last pass */ gpu_select_pick_load_id(ps->gl.prev_id, true); } - gpuPopAttr(); - GPU_color_mask(true, true, true, true); + GPU_write_mask(ps->write_mask); + GPU_depth_test(ps->depth_test); + GPU_viewport(UNPACK4(ps->viewport)); } /* assign but never free directly since it may be in cache */ diff --git a/source/blender/gpu/intern/gpu_select_sample_query.c b/source/blender/gpu/intern/gpu_select_sample_query.c index f67c9c36a6b..62414febb44 100644 --- a/source/blender/gpu/intern/gpu_select_sample_query.c +++ b/source/blender/gpu/intern/gpu_select_sample_query.c @@ -60,6 +60,12 @@ typedef struct GPUQueryState { char mode; uint index; int oldhits; + + /* Previous state to restore after drawing. */ + int viewport[4]; + int scissor[4]; + eGPUWriteMask write_mask; + bool depth_test; } GPUQueryState; static GPUQueryState g_query_state = {0}; @@ -67,8 +73,6 @@ static GPUQueryState g_query_state = {0}; void gpu_select_query_begin( uint (*buffer)[4], uint bufsize, const rcti *input, char mode, int oldhits) { - float viewport[4]; - g_query_state.query_issued = false; g_query_state.active_query = 0; g_query_state.num_of_queries = 0; @@ -86,7 +90,10 @@ void gpu_select_query_begin( "gpu selection ids"); glGenQueries(g_query_state.num_of_queries, g_query_state.queries); - gpuPushAttr(GPU_DEPTH_BUFFER_BIT | GPU_VIEWPORT_BIT | GPU_SCISSOR_BIT); + g_query_state.write_mask = GPU_write_mask_get(); + g_query_state.depth_test = GPU_depth_test_enabled(); + GPU_scissor_get(g_query_state.scissor); + /* disable writing to the framebuffer */ GPU_color_mask(false, false, false, false); @@ -94,8 +101,11 @@ void gpu_select_query_begin( * We need to get the region of the viewport so that our geometry doesn't * get rejected before the depth test. Should probably cull rect against * the viewport but this is a rare case I think */ - GPU_viewport_size_get_f(viewport); - GPU_viewport(viewport[0], viewport[1], BLI_rcti_size_x(input), BLI_rcti_size_y(input)); + GPU_viewport_size_get_i(g_query_state.viewport); + GPU_viewport(g_query_state.viewport[0], + g_query_state.viewport[1], + BLI_rcti_size_x(input), + BLI_rcti_size_y(input)); /* occlusion queries operates on fragments that pass tests and since we are interested on all * objects in the view frustum independently of their order, we need to disable the depth test */ @@ -204,8 +214,10 @@ uint gpu_select_query_end(void) glDeleteQueries(g_query_state.num_of_queries, g_query_state.queries); MEM_freeN(g_query_state.queries); MEM_freeN(g_query_state.id); - gpuPopAttr(); - GPU_color_mask(true, true, true, true); + + GPU_write_mask(g_query_state.write_mask); + GPU_depth_test(g_query_state.depth_test); + GPU_viewport(UNPACK4(g_query_state.viewport)); return hits; } diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc index 7a44efce7fb..536396ad3c6 100644 --- a/source/blender/gpu/intern/gpu_shader.cc +++ b/source/blender/gpu/intern/gpu_shader.cc @@ -29,6 +29,7 @@ #include "BLI_string.h" #include "BLI_string_utils.h" #include "BLI_utildefines.h" +#include "BLI_vector.hh" #include "BKE_appdir.h" #include "BKE_global.h" @@ -42,226 +43,198 @@ #include "GPU_texture.h" #include "GPU_uniformbuffer.h" +#include "gpu_backend.hh" #include "gpu_context_private.hh" -#include "gpu_shader_private.h" +#include "gpu_shader_private.hh" 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 +using namespace blender; +using namespace blender::gpu; /* -------------------------------------------------------------------- */ -/** \name Convenience functions +/** \name Debug functions * \{ */ -static void shader_print_errors(const char *task, const char *log, const char **code, int totcode) +void Shader::print_errors(Span<const char *> sources, char *log) { - 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); + const bool pretty = true; + const char line_prefix[] = " | "; + char *sources_combined = BLI_string_join_arrayN((const char **)sources.data(), sources.size()); - 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++; + if (pretty) { + fprintf(stderr, "\n \033[1mShader Compilation Log : \033[0m%s\n", this->name); + } + else { + fprintf(stderr, "\n Shader Compilation Log : %s\n", this->name); + } + + char *log_line = log, *line_end; + char *error_line_number_end; + int error_line, error_char, last_error_line = -2, last_error_char = -1; + bool found_line_id = false; + while ((line_end = strchr(log_line, '\n'))) { + /* Skip empty lines. */ + if (line_end == log_line) { + log_line++; + continue; + } + /* Skip ERROR: or WARNING:. */ + const char *prefix[] = {"ERROR", "WARNING"}; + for (int i = 0; i < ARRAY_SIZE(prefix); i++) { + if (STREQLEN(log_line, prefix[i], strlen(prefix[i]))) { + log_line += strlen(prefix[i]); + break; } - - fprintf(stderr, "%s", c); } + error_line = error_char = -1; + if (ELEM(log_line[0], '0', ':') && ELEM(log_line[1], ':', '(', ' ')) { + error_line = (int)strtol(log_line + 2, &error_line_number_end, 10); + /* Try to fetch the error caracter (not always available). */ + if (ELEM(error_line_number_end[0], '(', ':')) { + error_char = (int)strtol(error_line_number_end + 1, NULL, 10); + } + } + if (error_line == -1) { + found_line_id = false; + } + const char *src_line = sources_combined; + /* Some drivers use (source:line) instead of (line:char) */ + if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OFFICIAL) && (error_line != -1) && + (error_char != -1)) { + int error_source = error_line; + if (error_source < sources.size()) { + src_line = sources[error_source]; + error_line = error_char; + error_char = -1; + } + } + /* Separate from previous block. */ + if (last_error_line != error_line) { + fprintf(stderr, "\n"); + } + /* Print line from the source file that is producing the error. */ + if ((error_line != -1) && (error_line != last_error_line || error_char != last_error_char)) { + const char *src_line_end = src_line; + found_line_id = false; + /* error_line is 1 based in this case. */ + int src_line_index = 1; + while ((src_line_end = strchr(src_line, '\n'))) { + if (src_line_index == error_line) { + found_line_id = true; + break; + } + /* Continue to next line. */ + src_line = src_line_end + 1; + src_line_index++; + } + /* Print error source. */ + if (found_line_id) { + fprintf(stderr, "%5d | ", src_line_index); + fwrite(src_line, (src_line_end + 1) - src_line, 1, stderr); + /* Print char offset. */ + fprintf(stderr, line_prefix); + if (error_char != -1) { + for (int i = 0; i < error_char; i++) { + fprintf(stderr, " "); + } + fprintf(stderr, "^"); + } + fprintf(stderr, "\n"); + } + } + fprintf(stderr, line_prefix); + if (found_line_id) { + /* Skip to message. Avoid redundant info. */ + const char *keywords[] = {"error", "warning"}; + for (int i = 0; i < ARRAY_SIZE(keywords); i++) { + /* Avoid searching following lines. */ + line_end[0] = '\0'; + if (strstr(log_line, keywords[i])) { + log_line = strstr(log_line, keywords[i]); + if (pretty) { + if (STREQ(keywords[i], "error")) { + fprintf(stderr, "\033[31;1mError\033[0m "); + } + else if (STREQ(keywords[i], "warning")) { + fprintf(stderr, "\033[33;1mWarning\033[0m "); + } + log_line += strlen(keywords[i]); + } + break; + } + } + line_end[0] = '\n'; + } + /* Print the error itself. */ + if (pretty) { + fprintf(stderr, "\033[2m"); + } + fwrite(log_line, (line_end + 1) - log_line, 1, stderr); + if (pretty) { + fprintf(stderr, "\033[0m"); + } + /* Continue to next line. */ + log_line = line_end + 1; + last_error_line = error_line; + last_error_char = error_char; } - - fprintf(stderr, "%s\n", log); + fprintf(stderr, "\n\n"); + MEM_freeN(sources_combined); } -static const char *gpu_shader_version(void) +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Creation / Destruction + * \{ */ + +Shader::Shader(const char *sh_name) { - return "#version 330\n"; + BLI_strncpy(this->name, sh_name, sizeof(this->name)); } -static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH]) +Shader::~Shader() { - /* 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"); - strcat(defines, "#define GPU_ARB_shader_draw_parameters\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"); + if (this->interface) { + GPU_shaderinterface_discard(this->interface); } } -static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH]) +static void standard_defines(Vector<const char *> &sources) { + BLI_assert(sources.size() == 0); + /* Version needs to be first. Exact values will be added by implementation. */ + sources.append("version"); /* 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"); - } + sources.append("#define GPU_ATI\n"); } else if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY)) { - strcat(defines, "#define GPU_NVIDIA\n"); + sources.append("#define GPU_NVIDIA\n"); } else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) { - strcat(defines, "#define GPU_INTEL\n"); + sources.append("#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"); + sources.append("#define OS_WIN\n"); } else if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY)) { - strcat(defines, "#define OS_MAC\n"); + sources.append("#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; + sources.append("#define OS_UNIX\n"); } - /* 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; + if (GPU_crappy_amd_driver()) { + sources.append("#define GPU_DEPRECATED_AMD_DRIVER\n"); } - - /* 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_create_ex(const char *vertexcode, +GPUShader *GPU_shader_create_ex(const char *vertcode, const char *fragcode, - const char *geocode, + const char *geomcode, const char *libcode, const char *defines, const eGPUShaderTFBType tf_type, @@ -269,223 +242,113 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, 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)); + BLI_assert((fragcode != NULL) && (vertcode != 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; - } + Shader *shader = GPUBackend::get()->shader_alloc(shname); - 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 (vertcode) { + Vector<const char *> sources; + standard_defines(sources); + sources.append("#define GPU_VERTEX_SHADER\n"); + sources.append("#define IN_OUT out\n"); + if (geomcode) { + sources.append("#define USE_GEOMETRY_SHADER\n"); } if (defines) { - source[num_source++] = defines; + sources.append(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); + sources.append(vertcode); - 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; - } + shader->vertex_shader_from_glsl(sources); } 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"; + Vector<const char *> sources; + standard_defines(sources); + sources.append("#define GPU_FRAGMENT_SHADER\n"); + sources.append("#define IN_OUT in\n"); + if (geomcode) { + sources.append("#define USE_GEOMETRY_SHADER\n"); } if (defines) { - source[num_source++] = defines; + sources.append(defines); } if (libcode) { - source[num_source++] = libcode; + sources.append(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); + sources.append(fragcode); - if (!status) { - glGetShaderInfoLog(shader->fragment, sizeof(log), &length, log); - shader_print_errors("compile", log, source, num_source); - - GPU_shader_free(shader); - return NULL; - } + shader->fragment_shader_from_glsl(sources); } - 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 (geomcode) { + Vector<const char *> sources; + standard_defines(sources); + sources.append("#define GPU_GEOMETRY_SHADER\n"); if (defines) { - source[num_source++] = defines; + sources.append(defines); } - source[num_source++] = geocode; - - gpu_dump_shaders(source, num_source, DEBUG_SHADER_GEOMETRY); + sources.append(geomcode); - 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; - } + shader->geometry_shader_from_glsl(sources); } - if (tf_names != NULL) { - glTransformFeedbackVaryings(shader->program, tf_count, tf_names, GL_INTERLEAVED_ATTRIBS); - /* Primitive type must be setup */ + if (tf_names != NULL && tf_count > 0) { BLI_assert(tf_type != GPU_SHADER_TFB_NONE); - shader->feedback_transform_type = tf_type; + shader->transform_feedback_names_set(Span<const char *>(tf_names, tf_count), 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); + if (!shader->finalize()) { + delete shader; return NULL; - } + }; - glUseProgram(shader->program); - shader->interface = GPU_shaderinterface_create(shader->program); + return static_cast<GPUShader *>(shader); +} - return shader; +void GPU_shader_free(GPUShader *shader) +{ + delete static_cast<Shader *>(shader); } -#undef DEBUG_SHADER_GEOMETRY -#undef DEBUG_SHADER_FRAGMENT -#undef DEBUG_SHADER_VERTEX -#undef DEBUG_SHADER_NONE +/** \} */ -void GPU_shader_free(GPUShader *shader) +/* -------------------------------------------------------------------- */ +/** \name Creation utils + * \{ */ + +GPUShader *GPU_shader_create(const char *vertcode, + const char *fragcode, + const char *geomcode, + const char *libcode, + const char *defines, + const char *shname) { -#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); + return GPU_shader_create_ex( + vertcode, fragcode, geomcode, libcode, defines, GPU_SHADER_TFB_NONE, NULL, 0, shname); +} - if (shader->vertex) { - glDeleteShader(shader->vertex); - } - if (shader->geometry) { - glDeleteShader(shader->geometry); - } - if (shader->fragment) { - glDeleteShader(shader->fragment); +GPUShader *GPU_shader_create_from_python(const char *vertcode, + const char *fragcode, + const char *geomcode, + const char *libcode, + const char *defines) +{ + char *libcodecat = NULL; + + if (libcode == NULL) { + libcode = datatoc_gpu_shader_colorspace_lib_glsl; } - if (shader->program) { - glDeleteProgram(shader->program); + else { + libcode = libcodecat = BLI_strdupcat(libcode, datatoc_gpu_shader_colorspace_lib_glsl); } - if (shader->interface) { - GPU_shaderinterface_discard(shader->interface); - } + GPUShader *sh = GPU_shader_create_ex( + vertcode, fragcode, geomcode, libcode, defines, GPU_SHADER_TFB_NONE, NULL, 0, NULL); - MEM_freeN(shader); + MEM_SAFE_FREE(libcodecat); + return sh; } static const char *string_join_array_maybe_alloc(const char **str_arr, bool *r_is_alloc) @@ -534,7 +397,7 @@ static const char *string_join_array_maybe_alloc(const char **str_arr, bool *r_i * \endcode */ struct GPUShader *GPU_shader_create_from_arrays_impl( - const struct GPU_ShaderCreateFromArray_Params *params) + const struct GPU_ShaderCreateFromArray_Params *params, const char *func, int line) { struct { const char *str; @@ -546,8 +409,11 @@ struct GPUShader *GPU_shader_create_from_arrays_impl( str_dst[i].str = string_join_array_maybe_alloc(str_src[i], &str_dst[i].is_alloc); } + char name[64]; + BLI_snprintf(name, sizeof(name), "%s_%d", func, line); + GPUShader *sh = GPU_shader_create( - str_dst[0].str, str_dst[1].str, str_dst[2].str, NULL, str_dst[3].str, __func__); + str_dst[0].str, str_dst[1].str, str_dst[2].str, NULL, str_dst[3].str, name); for (int i = 0; i < ARRAY_SIZE(str_dst); i++) { if (str_dst[i].is_alloc) { @@ -563,21 +429,21 @@ struct GPUShader *GPU_shader_create_from_arrays_impl( /** \name Binding * \{ */ -void GPU_shader_bind(GPUShader *shader) +void GPU_shader_bind(GPUShader *gpu_shader) { - BLI_assert(shader && shader->program); + Shader *shader = static_cast<Shader *>(gpu_shader); GPUContext *ctx = GPU_context_active_get(); if (ctx->shader != shader) { ctx->shader = shader; - glUseProgram(shader->program); - GPU_matrix_bind(shader->interface); - GPU_shader_set_srgb_uniform(shader->interface); + shader->bind(); + GPU_matrix_bind(shader); + GPU_shader_set_srgb_uniform(shader); } if (GPU_matrix_dirty_get()) { - GPU_matrix_bind(shader->interface); + GPU_matrix_bind(shader); } } @@ -585,8 +451,10 @@ void GPU_shader_unbind(void) { #ifndef NDEBUG GPUContext *ctx = GPU_context_active_get(); + if (ctx->shader) { + static_cast<Shader *>(ctx->shader)->unbind(); + } ctx->shader = NULL; - glUseProgram(0); #endif } @@ -594,34 +462,18 @@ void GPU_shader_unbind(void) /* -------------------------------------------------------------------- */ /** \name Transform feedback + * + * TODO(fclem) Should be replaced by compute shaders. * \{ */ -bool GPU_shader_transform_feedback_enable(GPUShader *shader, uint vbo_id) +bool GPU_shader_transform_feedback_enable(GPUShader *shader, GPUVertBuf *vertbuf) { - 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; - } + return static_cast<Shader *>(shader)->transform_feedback_enable(vertbuf); } -void GPU_shader_transform_feedback_disable(GPUShader *UNUSED(shader)) +void GPU_shader_transform_feedback_disable(GPUShader *shader) { - glEndTransformFeedback(); + static_cast<Shader *>(shader)->transform_feedback_disable(); } /** \} */ @@ -632,49 +484,42 @@ void GPU_shader_transform_feedback_disable(GPUShader *UNUSED(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, 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; } @@ -686,9 +531,10 @@ int GPU_shader_get_attribute(GPUShader *shader, const char *name) * \{ */ /* Clement : Temp */ -int GPU_shader_get_program(GPUShader *shader) +int GPU_shader_get_program(GPUShader *UNUSED(shader)) { - return (int)shader->program; + /* TODO fixme */ + return (int)0; } /** \} */ @@ -698,57 +544,15 @@ int GPU_shader_get_program(GPUShader *shader) * \{ */ void GPU_shader_uniform_vector( - GPUShader *UNUSED(shader), int location, int length, int arraysize, const float *value) + GPUShader *shader, int loc, int len, 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; - } + static_cast<Shader *>(shader)->uniform_float(loc, len, arraysize, value); } void GPU_shader_uniform_vector_int( - GPUShader *UNUSED(shader), int location, int length, int arraysize, const int *value) -{ - 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; - } + GPUShader *shader, int loc, int len, int arraysize, const int *value) +{ + static_cast<Shader *>(shader)->uniform_int(loc, len, arraysize, value); } void GPU_shader_uniform_int(GPUShader *shader, int location, int value) @@ -851,11 +655,11 @@ void GPU_shader_uniform_4fv_array(GPUShader *sh, const char *name, int len, cons static int g_shader_builtin_srgb_transform = 0; -void GPU_shader_set_srgb_uniform(const GPUShaderInterface *interface) +void GPU_shader_set_srgb_uniform(GPUShader *shader) { - int32_t loc = GPU_shaderinterface_uniform_builtin(interface, GPU_UNIFORM_SRGB_TRANSFORM); + int32_t loc = GPU_shaderinterface_uniform_builtin(shader->interface, GPU_UNIFORM_SRGB_TRANSFORM); if (loc != -1) { - glUniform1i(loc, g_shader_builtin_srgb_transform); + GPU_shader_uniform_vector_int(shader, loc, 1, 1, &g_shader_builtin_srgb_transform); } } diff --git a/source/blender/gpu/intern/gpu_shader_builtin.c b/source/blender/gpu/intern/gpu_shader_builtin.c index 9c0692b76e2..da5bcaeca17 100644 --- a/source/blender/gpu/intern/gpu_shader_builtin.c +++ b/source/blender/gpu/intern/gpu_shader_builtin.c @@ -42,8 +42,6 @@ #include "GPU_texture.h" #include "GPU_uniformbuffer.h" -#include "gpu_shader_private.h" - /* Adjust these constants as needed. */ #define MAX_DEFINE_LENGTH 256 #define MAX_EXT_DEFINE_LENGTH 512 diff --git a/source/blender/gpu/intern/gpu_shader_private.hh b/source/blender/gpu/intern/gpu_shader_private.hh new file mode 100644 index 00000000000..1f667fb4cf9 --- /dev/null +++ b/source/blender/gpu/intern/gpu_shader_private.hh @@ -0,0 +1,63 @@ +/* + * 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 gpu + */ + +#pragma once + +#include "BLI_span.hh" + +#include "GPU_shader.h" +#include "GPU_shader_interface.h" +#include "GPU_vertex_buffer.h" + +namespace blender { +namespace gpu { + +class Shader : public GPUShader { + public: + Shader(const char *name); + virtual ~Shader(); + + virtual void vertex_shader_from_glsl(MutableSpan<const char *> sources) = 0; + virtual void geometry_shader_from_glsl(MutableSpan<const char *> sources) = 0; + virtual void fragment_shader_from_glsl(MutableSpan<const char *> sources) = 0; + virtual bool finalize(void) = 0; + + virtual void transform_feedback_names_set(Span<const char *> name_list, + const eGPUShaderTFBType geom_type) = 0; + virtual bool transform_feedback_enable(GPUVertBuf *) = 0; + virtual void transform_feedback_disable(void) = 0; + + virtual void bind(void) = 0; + virtual void unbind(void) = 0; + + virtual void uniform_float(int location, int comp_len, int array_size, const float *data) = 0; + virtual void uniform_int(int location, int comp_len, int array_size, const int *data) = 0; + + virtual void vertformat_from_shader(GPUVertFormat *) const = 0; + + protected: + void print_errors(Span<const char *> sources, char *log); +}; + +} // namespace gpu +} // namespace blender + +/* XXX do not use it. Special hack to use OCIO with batch API. */ +GPUShader *immGetShader(void); diff --git a/source/blender/gpu/intern/gpu_state.cc b/source/blender/gpu/intern/gpu_state.cc index 794c7a3eb97..f02ec9c5cd4 100644 --- a/source/blender/gpu/intern/gpu_state.cc +++ b/source/blender/gpu/intern/gpu_state.cc @@ -25,6 +25,7 @@ # define PIXELSIZE (1.0f) #endif +#include "BLI_math_vector.h" #include "BLI_utildefines.h" #include "BKE_global.h" @@ -33,239 +34,242 @@ #include "GPU_glew.h" #include "GPU_state.h" -static GLenum gpu_get_gl_blendfunction(eGPUBlendFunction blend) -{ - switch (blend) { - case GPU_ONE: - return GL_ONE; - case GPU_SRC_ALPHA: - return GL_SRC_ALPHA; - case GPU_ONE_MINUS_SRC_ALPHA: - return GL_ONE_MINUS_SRC_ALPHA; - case GPU_DST_COLOR: - return GL_DST_COLOR; - case GPU_ZERO: - return GL_ZERO; - default: - BLI_assert(!"Unhandled blend mode"); - return GL_ZERO; - } -} +#include "gpu_context_private.hh" + +#include "gpu_state_private.hh" + +using namespace blender::gpu; + +#define SET_STATE(_prefix, _state, _value) \ + do { \ + GPUStateManager *stack = GPU_context_active_get()->state_manager; \ + auto &state_object = stack->_prefix##state; \ + state_object._state = _value; \ + } while (0) -void GPU_blend(bool enable) +#define SET_IMMUTABLE_STATE(_state, _value) SET_STATE(, _state, _value) +#define SET_MUTABLE_STATE(_state, _value) SET_STATE(mutable_, _state, _value) + +/* -------------------------------------------------------------------- */ +/** \name Immutable state Setters + * \{ */ + +void GPU_blend(eGPUBlend blend) { - if (enable) { - glEnable(GL_BLEND); - } - else { - glDisable(GL_BLEND); - } + SET_IMMUTABLE_STATE(blend, blend); } -void GPU_blend_set_func(eGPUBlendFunction sfactor, eGPUBlendFunction dfactor) +void GPU_face_culling(eGPUFaceCullTest culling) { - glBlendFunc(gpu_get_gl_blendfunction(sfactor), gpu_get_gl_blendfunction(dfactor)); + SET_IMMUTABLE_STATE(culling_test, culling); } -void GPU_blend_set_func_separate(eGPUBlendFunction src_rgb, - eGPUBlendFunction dst_rgb, - eGPUBlendFunction src_alpha, - eGPUBlendFunction dst_alpha) +void GPU_front_facing(bool invert) { - glBlendFuncSeparate(gpu_get_gl_blendfunction(src_rgb), - gpu_get_gl_blendfunction(dst_rgb), - gpu_get_gl_blendfunction(src_alpha), - gpu_get_gl_blendfunction(dst_alpha)); + SET_IMMUTABLE_STATE(invert_facing, invert); } -void GPU_face_culling(eGPUFaceCull culling) +void GPU_provoking_vertex(eGPUProvokingVertex vert) { - if (culling == GPU_CULL_NONE) { - glDisable(GL_CULL_FACE); - } - else { - glEnable(GL_CULL_FACE); - glCullFace((culling == GPU_CULL_FRONT) ? GL_FRONT : GL_BACK); - } + SET_IMMUTABLE_STATE(provoking_vert, vert); } -void GPU_front_facing(bool invert) +/* TODO explicit depth test. */ +void GPU_depth_test(bool enable) { - glFrontFace((invert) ? GL_CW : GL_CCW); + SET_IMMUTABLE_STATE(depth_test, (enable) ? GPU_DEPTH_LESS_EQUAL : GPU_DEPTH_NONE); } -void GPU_provoking_vertex(eGPUProvokingVertex vert) +void GPU_line_smooth(bool enable) { - glProvokingVertex((vert == GPU_VERTEX_FIRST) ? GL_FIRST_VERTEX_CONVENTION : - GL_LAST_VERTEX_CONVENTION); + SET_IMMUTABLE_STATE(line_smooth, enable); } -void GPU_depth_range(float near, float far) +void GPU_polygon_smooth(bool enable) { - /* glDepthRangef is only for OpenGL 4.1 or higher */ - glDepthRange(near, far); + SET_IMMUTABLE_STATE(polygon_smooth, enable); } -void GPU_depth_test(bool enable) +void GPU_logic_op_xor_set(bool enable) { - if (enable) { - glEnable(GL_DEPTH_TEST); - } - else { - glDisable(GL_DEPTH_TEST); - } + SET_IMMUTABLE_STATE(logic_op_xor, enable); } -bool GPU_depth_test_enabled() +void GPU_write_mask(eGPUWriteMask mask) { - return glIsEnabled(GL_DEPTH_TEST); + SET_IMMUTABLE_STATE(write_mask, mask); } -void GPU_line_smooth(bool enable) +void GPU_color_mask(bool r, bool g, bool b, bool a) { - if (enable && ((G.debug & G_DEBUG_GPU) == 0)) { - glEnable(GL_LINE_SMOOTH); - } - else { - glDisable(GL_LINE_SMOOTH); - } + GPUStateManager *stack = GPU_context_active_get()->state_manager; + auto &state = stack->state; + eGPUWriteMask write_mask = state.write_mask; + SET_FLAG_FROM_TEST(write_mask, r, GPU_WRITE_RED); + SET_FLAG_FROM_TEST(write_mask, g, GPU_WRITE_GREEN); + SET_FLAG_FROM_TEST(write_mask, b, GPU_WRITE_BLUE); + SET_FLAG_FROM_TEST(write_mask, a, GPU_WRITE_ALPHA); + state.write_mask = write_mask; } -void GPU_line_width(float width) +void GPU_depth_mask(bool depth) { - float max_size = GPU_max_line_width(); - float final_size = width * PIXELSIZE; - /* Fix opengl errors on certain platform / drivers. */ - CLAMP(final_size, 1.0f, max_size); - glLineWidth(final_size); + GPUStateManager *stack = GPU_context_active_get()->state_manager; + auto &state = stack->state; + eGPUWriteMask write_mask = state.write_mask; + SET_FLAG_FROM_TEST(write_mask, depth, GPU_WRITE_DEPTH); + state.write_mask = write_mask; } -void GPU_point_size(float size) +void GPU_shadow_offset(bool enable) { - glPointSize(size * PIXELSIZE); + SET_IMMUTABLE_STATE(shadow_bias, enable); } -void GPU_polygon_smooth(bool enable) +void GPU_clip_distances(int distances_enabled) { - if (enable && ((G.debug & G_DEBUG_GPU) == 0)) { - glEnable(GL_POLYGON_SMOOTH); - } - else { - glDisable(GL_POLYGON_SMOOTH); - } + SET_IMMUTABLE_STATE(clip_distances, distances_enabled); } -/* Programmable point size - * - shaders set their own point size when enabled - * - use glPointSize when disabled */ -void GPU_program_point_size(bool enable) +void GPU_state_set(eGPUWriteMask write_mask, + eGPUBlend blend, + eGPUFaceCullTest culling_test, + eGPUDepthTest depth_test, + eGPUStencilTest stencil_test, + eGPUStencilOp stencil_op, + eGPUProvokingVertex provoking_vert) { - if (enable) { - glEnable(GL_PROGRAM_POINT_SIZE); - } - else { - glDisable(GL_PROGRAM_POINT_SIZE); - } + GPUStateManager *stack = GPU_context_active_get()->state_manager; + auto &state = stack->state; + state.write_mask = write_mask; + state.blend = blend; + state.culling_test = culling_test; + state.depth_test = depth_test; + state.stencil_test = stencil_test; + state.stencil_op = stencil_op; + state.provoking_vert = provoking_vert; } -void GPU_scissor_test(bool enable) +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Mutable State Setters + * \{ */ + +void GPU_depth_range(float near, float far) { - if (enable) { - glEnable(GL_SCISSOR_TEST); - } - else { - glDisable(GL_SCISSOR_TEST); - } + GPUStateManager *stack = GPU_context_active_get()->state_manager; + auto &state = stack->mutable_state; + copy_v2_fl2(state.depth_range, near, far); } -void GPU_scissor(int x, int y, int width, int height) +void GPU_line_width(float width) { - glScissor(x, y, width, height); + SET_MUTABLE_STATE(line_width, width * PIXELSIZE); } -void GPU_viewport(int x, int y, int width, int height) +void GPU_point_size(float size) { - glViewport(x, y, width, height); + SET_MUTABLE_STATE(point_size, size * PIXELSIZE); } -void GPU_scissor_get_f(float coords[4]) +/* Programmable point size + * - shaders set their own point size when enabled + * - use glPointSize when disabled */ +/* TODO remove and use program point size everywhere */ +void GPU_program_point_size(bool enable) { - glGetFloatv(GL_SCISSOR_BOX, coords); + GPUStateManager *stack = GPU_context_active_get()->state_manager; + auto &state = stack->mutable_state; + /* Set point size sign negative to disable. */ + state.point_size = fabsf(state.point_size) * (enable ? 1 : -1); } -void GPU_scissor_get_i(int coords[4]) +void GPU_scissor_test(bool enable) { - glGetIntegerv(GL_SCISSOR_BOX, coords); + GPUStateManager *stack = GPU_context_active_get()->state_manager; + auto &state = stack->mutable_state; + /* Set point size sign negative to disable. */ + state.scissor_rect[2] = abs(state.scissor_rect[2]) * (enable ? 1 : -1); } -void GPU_viewport_size_get_f(float coords[4]) +void GPU_scissor(int x, int y, int width, int height) { - glGetFloatv(GL_VIEWPORT, coords); + GPUStateManager *stack = GPU_context_active_get()->state_manager; + auto &state = stack->mutable_state; + int scissor_rect[4] = {x, y, width, height}; + copy_v4_v4_int(state.scissor_rect, scissor_rect); } -void GPU_viewport_size_get_i(int coords[4]) +void GPU_viewport(int x, int y, int width, int height) { - glGetIntegerv(GL_VIEWPORT, coords); + GPUStateManager *stack = GPU_context_active_get()->state_manager; + auto &state = stack->mutable_state; + int viewport_rect[4] = {x, y, width, height}; + copy_v4_v4_int(state.viewport_rect, viewport_rect); } -void GPU_flush(void) +void GPU_stencil_reference_set(uint reference) { - glFlush(); + SET_MUTABLE_STATE(stencil_reference, (uint8_t)reference); } - -void GPU_finish(void) +void GPU_stencil_write_mask_set(uint write_mask) { - glFinish(); + SET_MUTABLE_STATE(stencil_write_mask, (uint8_t)write_mask); +} +void GPU_stencil_compare_mask_set(uint compare_mask) +{ + SET_MUTABLE_STATE(stencil_compare_mask, (uint8_t)compare_mask); } -void GPU_unpack_row_length_set(uint len) +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name State Getters + * \{ */ + +eGPUBlend GPU_blend_get() { - glPixelStorei(GL_UNPACK_ROW_LENGTH, len); + GPUState &state = GPU_context_active_get()->state_manager->state; + return state.blend; } -void GPU_logic_op_xor_set(bool enable) +eGPUWriteMask GPU_write_mask_get() { - if (enable) { - glLogicOp(GL_XOR); - glEnable(GL_COLOR_LOGIC_OP); - } - else { - glDisable(GL_COLOR_LOGIC_OP); - } + GPUState &state = GPU_context_active_get()->state_manager->state; + return state.write_mask; } -void GPU_color_mask(bool r, bool g, bool b, bool a) +bool GPU_depth_test_enabled() { - glColorMask(r, g, b, a); + GPUState &state = GPU_context_active_get()->state_manager->state; + return state.depth_test != GPU_DEPTH_NONE; } -void GPU_depth_mask(bool depth) +void GPU_scissor_get(int coords[4]) { - glDepthMask(depth); + GPUStateMutable &state = GPU_context_active_get()->state_manager->mutable_state; + copy_v4_v4_int(coords, state.scissor_rect); } -bool GPU_depth_mask_get(void) +void GPU_viewport_size_get_f(float coords[4]) { - GLint mask; - glGetIntegerv(GL_DEPTH_WRITEMASK, &mask); - return mask == GL_TRUE; + GPUStateMutable &state = GPU_context_active_get()->state_manager->mutable_state; + for (int i = 0; i < 4; i++) { + coords[i] = state.viewport_rect[i]; + } } -void GPU_stencil_mask(uint stencil) +void GPU_viewport_size_get_i(int coords[4]) { - glStencilMask(stencil); + GPUStateMutable &state = GPU_context_active_get()->state_manager->mutable_state; + copy_v4_v4_int(coords, state.viewport_rect); } -void GPU_clip_distances(int distances_new) +bool GPU_depth_mask_get(void) { - static int distances_enabled = 0; - for (int i = 0; i < distances_new; i++) { - glEnable(GL_CLIP_DISTANCE0 + i); - } - for (int i = distances_new; i < distances_enabled; i++) { - glDisable(GL_CLIP_DISTANCE0 + i); - } - distances_enabled = distances_new; + GPUState &state = GPU_context_active_get()->state_manager->state; + return (state.write_mask & GPU_WRITE_DEPTH) != 0; } bool GPU_mipmap_enabled(void) @@ -274,163 +278,71 @@ bool GPU_mipmap_enabled(void) return true; } -/** \name GPU Push/Pop State - * \{ */ - -#define STATE_STACK_DEPTH 16 - -typedef struct { - eGPUAttrMask mask; - - /* GL_BLEND_BIT */ - uint is_blend : 1; - - /* GL_DEPTH_BUFFER_BIT */ - 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; - - /* GL_VIEWPORT_BIT */ - int viewport[4]; - double near_far[2]; -} GPUAttrValues; - -typedef struct { - GPUAttrValues attr_stack[STATE_STACK_DEPTH]; - uint top; -} GPUAttrStack; - -static GPUAttrStack state = { - {}, - 0, -}; +/** \} */ -#define AttrStack state -#define Attr state.attr_stack[state.top] +/* -------------------------------------------------------------------- */ +/** \name Context Utils + * \{ */ -/** - * Replacement for glPush/PopAttributes - * - * We don't need to cover all the options of legacy OpenGL - * but simply the ones used by Blender. - */ -void gpuPushAttr(eGPUAttrMask mask) +void GPU_flush(void) { - Attr.mask = mask; - - if ((mask & GPU_DEPTH_BUFFER_BIT) != 0) { - Attr.is_depth_test = glIsEnabled(GL_DEPTH_TEST); - glGetIntegerv(GL_DEPTH_FUNC, &Attr.depth_func); - glGetDoublev(GL_DEPTH_CLEAR_VALUE, &Attr.depth_clear_value); - glGetBooleanv(GL_DEPTH_WRITEMASK, (GLboolean *)&Attr.depth_write_mask); - } - - if ((mask & GPU_SCISSOR_BIT) != 0) { - Attr.is_scissor_test = glIsEnabled(GL_SCISSOR_TEST); - glGetIntegerv(GL_SCISSOR_BOX, (GLint *)&Attr.scissor_box); - } - - if ((mask & GPU_VIEWPORT_BIT) != 0) { - glGetDoublev(GL_DEPTH_RANGE, (GLdouble *)&Attr.near_far); - glGetIntegerv(GL_VIEWPORT, (GLint *)&Attr.viewport); - } - - if ((mask & GPU_BLEND_BIT) != 0) { - Attr.is_blend = glIsEnabled(GL_BLEND); - } - - BLI_assert(AttrStack.top < STATE_STACK_DEPTH); - AttrStack.top++; + glFlush(); } -static void restore_mask(GLenum cap, const bool value) +void GPU_finish(void) { - if (value) { - glEnable(cap); - } - else { - glDisable(cap); - } + glFinish(); } -void gpuPopAttr(void) +void GPU_unpack_row_length_set(uint len) { - BLI_assert(AttrStack.top > 0); - AttrStack.top--; - - GLint mask = Attr.mask; - - if ((mask & GPU_DEPTH_BUFFER_BIT) != 0) { - restore_mask(GL_DEPTH_TEST, Attr.is_depth_test); - glDepthFunc(Attr.depth_func); - glClearDepth(Attr.depth_clear_value); - glDepthMask(Attr.depth_write_mask); - } - - 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]); - } - - if ((mask & GPU_SCISSOR_BIT) != 0) { - restore_mask(GL_SCISSOR_TEST, Attr.is_scissor_test); - glScissor(Attr.scissor_box[0], Attr.scissor_box[1], Attr.scissor_box[2], Attr.scissor_box[3]); - } - - if ((mask & GPU_BLEND_BIT) != 0) { - restore_mask(GL_BLEND, Attr.is_blend); - } + glPixelStorei(GL_UNPACK_ROW_LENGTH, len); } -#undef Attr -#undef AttrStack +/** \} */ -/* Default OpenGL State +/* -------------------------------------------------------------------- */ +/** \name Default OpenGL State * * This is called on startup, for opengl offscreen render. * Generally we should always return to this state when * temporarily modifying the state for drawing, though that are (undocumented) - * exceptions that we should try to get rid of. */ - -void GPU_state_init(void) -{ - GPU_program_point_size(false); - - glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); - - glDisable(GL_BLEND); - glDisable(GL_DEPTH_TEST); - glDisable(GL_COLOR_LOGIC_OP); - glDisable(GL_STENCIL_TEST); - glDisable(GL_DITHER); - - glDepthFunc(GL_LEQUAL); - glDepthRange(0.0, 1.0); - - glFrontFace(GL_CCW); - glCullFace(GL_BACK); - glDisable(GL_CULL_FACE); - - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - - /* Is default but better be explicit. */ - glEnable(GL_MULTISAMPLE); - - /* This is a bit dangerous since addons could change this. */ - glEnable(GL_PRIMITIVE_RESTART); - glPrimitiveRestartIndex((GLuint)0xFFFFFFFF); + * exceptions that we should try to get rid of. + * \{ */ - /* TODO: Should become default. But needs at least GL 4.3 */ - if (GLEW_ARB_ES3_compatibility) { - /* Takes predecence over GL_PRIMITIVE_RESTART */ - glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX); - } +GPUStateManager::GPUStateManager(void) +{ + /* Set default state. */ + state.write_mask = GPU_WRITE_COLOR; + state.blend = GPU_BLEND_NONE; + state.culling_test = GPU_CULL_NONE; + state.depth_test = GPU_DEPTH_NONE; + state.stencil_test = GPU_STENCIL_NONE; + state.stencil_op = GPU_STENCIL_OP_NONE; + state.provoking_vert = GPU_VERTEX_LAST; + state.logic_op_xor = false; + state.invert_facing = false; + state.shadow_bias = false; + state.polygon_smooth = false; + state.clip_distances = 0; + + /* TODO: We should have better default for viewport and scissors. + * For now it's not important since they are overwritten at soon as a framebuffer is bound. */ + mutable_state.viewport_rect[0] = 0; + mutable_state.viewport_rect[1] = 0; + mutable_state.viewport_rect[2] = 10; + mutable_state.viewport_rect[3] = 10; + mutable_state.scissor_rect[0] = 0; + mutable_state.scissor_rect[1] = 0; + mutable_state.scissor_rect[2] = -10; /* Disable */ + mutable_state.scissor_rect[3] = 10; + mutable_state.depth_range[0] = 0.0f; + mutable_state.depth_range[1] = 1.0f; + mutable_state.point_size = 1.0f; + mutable_state.line_width = 1.0f; + mutable_state.stencil_write_mask = 0x00; + mutable_state.stencil_compare_mask = 0x00; + mutable_state.stencil_reference = 0x00; } /** \} */ diff --git a/source/blender/gpu/intern/gpu_state_private.hh b/source/blender/gpu/intern/gpu_state_private.hh new file mode 100644 index 00000000000..1ba79c7c048 --- /dev/null +++ b/source/blender/gpu/intern/gpu_state_private.hh @@ -0,0 +1,167 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2020, Blender Foundation. + */ + +/** \file + * \ingroup gpu + */ + +#pragma once + +#include "BLI_utildefines.h" + +#include "GPU_state.h" + +#include <cstring> + +namespace blender { +namespace gpu { + +/* Encapsulate all pipeline state that we need to track. + * Try to keep small to reduce validation time. */ +union GPUState { + struct { + eGPUWriteMask write_mask : 13; + eGPUBlend blend : 4; + eGPUFaceCullTest culling_test : 2; + eGPUDepthTest depth_test : 3; + eGPUStencilTest stencil_test : 3; + eGPUStencilOp stencil_op : 3; + eGPUProvokingVertex provoking_vert : 1; + /** Enable bits. */ + uint32_t logic_op_xor : 1; + uint32_t invert_facing : 1; + uint32_t shadow_bias : 1; + /** Number of clip distances enabled. */ + /* TODO(fclem) This should be a shader property. */ + uint32_t clip_distances : 3; + /* TODO(fclem) remove, old opengl features. */ + uint32_t polygon_smooth : 1; + uint32_t line_smooth : 1; + }; + /* Here to allow fast bitwise ops. */ + uint64_t data; +}; + +BLI_STATIC_ASSERT(sizeof(GPUState) == sizeof(uint64_t), "GPUState is too big."); + +inline bool operator==(const GPUState &a, const GPUState &b) +{ + return a.data == b.data; +} + +inline bool operator!=(const GPUState &a, const GPUState &b) +{ + return !(a == b); +} + +inline GPUState operator^(const GPUState &a, const GPUState &b) +{ + GPUState r; + r.data = a.data ^ b.data; + return r; +} + +inline GPUState operator~(const GPUState &a) +{ + GPUState r; + r.data = ~a.data; + return r; +} + +/* Mutable state that does not require pipeline change. */ +union GPUStateMutable { + struct { + /* Viewport State */ + /** TODO put inside GPUFramebuffer. */ + /** Offset + Extent of the drawable region inside the framebuffer. */ + int viewport_rect[4]; + /** Offset + Extent of the scissor region inside the framebuffer. */ + int scissor_rect[4]; + /** TODO remove */ + float depth_range[2]; + /** TODO remove, use explicit clear calls. */ + float clear_color[4]; + float clear_depth; + /** Negative if using program point size. */ + /* TODO(fclem) should be passed as uniform to all shaders. */ + float point_size; + /** Not supported on every platform. Prefer using wideline shader. */ + float line_width; + /** Mutable stencil states. */ + uint8_t stencil_write_mask; + uint8_t stencil_compare_mask; + uint8_t stencil_reference; + uint8_t _pad0; + /* IMPORTANT: ensure x64 stuct alignment. */ + }; + /* Here to allow fast bitwise ops. */ + uint64_t data[9]; +}; + +BLI_STATIC_ASSERT(sizeof(GPUStateMutable) == sizeof(GPUStateMutable::data), + "GPUStateMutable is too big."); + +inline bool operator==(const GPUStateMutable &a, const GPUStateMutable &b) +{ + return memcmp(&a, &b, sizeof(GPUStateMutable)) == 0; +} + +inline bool operator!=(const GPUStateMutable &a, const GPUStateMutable &b) +{ + return !(a == b); +} + +inline GPUStateMutable operator^(const GPUStateMutable &a, const GPUStateMutable &b) +{ + GPUStateMutable r; + for (int i = 0; i < ARRAY_SIZE(a.data); i++) { + r.data[i] = a.data[i] ^ b.data[i]; + } + return r; +} + +inline GPUStateMutable operator~(const GPUStateMutable &a) +{ + GPUStateMutable r; + for (int i = 0; i < ARRAY_SIZE(a.data); i++) { + r.data[i] = ~a.data[i]; + } + return r; +} + +class GPUStateManager { + public: + GPUState state; + GPUStateMutable mutable_state; + + public: + GPUStateManager(); + virtual ~GPUStateManager(){}; + + virtual void set_state(const GPUState &state) = 0; + virtual void set_mutable_state(const GPUStateMutable &state) = 0; + + inline void apply_state(void) + { + this->set_state(this->state); + this->set_mutable_state(this->mutable_state); + }; +}; + +} // namespace gpu +} // namespace blender diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc index a45bd222664..91990dac83f 100644 --- a/source/blender/gpu/intern/gpu_texture.cc +++ b/source/blender/gpu/intern/gpu_texture.cc @@ -615,7 +615,7 @@ static bool gpu_texture_check_capacity( GPUTexture *tex, GLenum proxy, GLenum internalformat, GLenum data_format, GLenum data_type) { if (proxy == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB && - GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_MAC, GPU_DRIVER_ANY)) { + GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY)) { /* Special fix for T79703. */ /* Depth has already been checked. */ return tex->w <= GPU_max_cube_map_size(); @@ -1611,6 +1611,9 @@ void GPU_texture_clear(GPUTexture *tex, eGPUDataFormat gpu_data_format, const vo /* This means that this function can only be used in one context for each texture. */ BLI_assert(tex->copy_fb_ctx == GPU_context_active_get()); + int viewport[4]; + GPU_viewport_size_get_i(viewport); + glBindFramebuffer(GL_FRAMEBUFFER, tex->copy_fb); glViewport(0, 0, tex->w, tex->h); @@ -1675,6 +1678,8 @@ void GPU_texture_clear(GPUTexture *tex, eGPUDataFormat gpu_data_format, const vo glClear(GL_COLOR_BUFFER_BIT); } + glViewport(UNPACK4(viewport)); + if (prev_fb) { GPU_framebuffer_bind(prev_fb); } diff --git a/source/blender/gpu/intern/gpu_vertex_format.cc b/source/blender/gpu/intern/gpu_vertex_format.cc index 2e8017660d0..2b16f4482b4 100644 --- a/source/blender/gpu/intern/gpu_vertex_format.cc +++ b/source/blender/gpu/intern/gpu_vertex_format.cc @@ -24,7 +24,9 @@ */ #include "GPU_vertex_format.h" +#include "gpu_shader_private.hh" #include "gpu_vertex_format_private.h" + #include <stddef.h> #include <string.h> @@ -32,15 +34,14 @@ #include "BLI_string.h" #include "BLI_utildefines.h" -#include "GPU_shader.h" -#include "gpu_shader_private.h" - #define PACK_DEBUG 0 #if PACK_DEBUG # include <stdio.h> #endif +using namespace blender::gpu; + void GPU_vertformat_clear(GPUVertFormat *format) { #if TRUST_NO_ONE @@ -404,112 +405,8 @@ void VertexFormat_pack(GPUVertFormat *format) format->packed = true; } -static uint calc_component_size(const GLenum gl_type) +void GPU_vertformat_from_shader(GPUVertFormat *format, const struct GPUShader *gpushader) { - switch (gl_type) { - case GL_FLOAT_VEC2: - case GL_INT_VEC2: - case GL_UNSIGNED_INT_VEC2: - return 2; - case GL_FLOAT_VEC3: - case GL_INT_VEC3: - case GL_UNSIGNED_INT_VEC3: - return 3; - case GL_FLOAT_VEC4: - case GL_FLOAT_MAT2: - case GL_INT_VEC4: - case GL_UNSIGNED_INT_VEC4: - return 4; - case GL_FLOAT_MAT3: - return 9; - case GL_FLOAT_MAT4: - return 16; - case GL_FLOAT_MAT2x3: - case GL_FLOAT_MAT3x2: - return 6; - case GL_FLOAT_MAT2x4: - case GL_FLOAT_MAT4x2: - return 8; - case GL_FLOAT_MAT3x4: - case GL_FLOAT_MAT4x3: - return 12; - default: - return 1; - } -} - -static void get_fetch_mode_and_comp_type(int gl_type, - GPUVertCompType *r_comp_type, - GPUVertFetchMode *r_fetch_mode) -{ - switch (gl_type) { - case GL_FLOAT: - case GL_FLOAT_VEC2: - case GL_FLOAT_VEC3: - case GL_FLOAT_VEC4: - case GL_FLOAT_MAT2: - case GL_FLOAT_MAT3: - case GL_FLOAT_MAT4: - case GL_FLOAT_MAT2x3: - case GL_FLOAT_MAT2x4: - case GL_FLOAT_MAT3x2: - case GL_FLOAT_MAT3x4: - case GL_FLOAT_MAT4x2: - case GL_FLOAT_MAT4x3: - *r_comp_type = GPU_COMP_F32; - *r_fetch_mode = GPU_FETCH_FLOAT; - break; - case GL_INT: - case GL_INT_VEC2: - case GL_INT_VEC3: - case GL_INT_VEC4: - *r_comp_type = GPU_COMP_I32; - *r_fetch_mode = GPU_FETCH_INT; - break; - case GL_UNSIGNED_INT: - case GL_UNSIGNED_INT_VEC2: - case GL_UNSIGNED_INT_VEC3: - case GL_UNSIGNED_INT_VEC4: - *r_comp_type = GPU_COMP_U32; - *r_fetch_mode = GPU_FETCH_INT; - break; - default: - BLI_assert(0); - } -} - -void GPU_vertformat_from_shader(GPUVertFormat *format, const GPUShader *shader) -{ - GPU_vertformat_clear(format); - GPUVertAttr *attr = &format->attrs[0]; - - GLint attr_len; - glGetProgramiv(shader->program, GL_ACTIVE_ATTRIBUTES, &attr_len); - - for (int i = 0; i < attr_len; i++) { - char name[256]; - GLenum gl_type; - GLint size; - glGetActiveAttrib(shader->program, i, sizeof(name), NULL, &size, &gl_type, name); - - /* Ignore OpenGL names like `gl_BaseInstanceARB`, `gl_InstanceID` and `gl_VertexID`. */ - if (glGetAttribLocation(shader->program, name) == -1) { - continue; - } - - format->name_len++; /* multiname support */ - format->attr_len++; - - GPUVertCompType comp_type; - GPUVertFetchMode fetch_mode; - get_fetch_mode_and_comp_type(gl_type, &comp_type, &fetch_mode); - - attr->names[attr->name_len++] = copy_attr_name(format, name); - attr->offset = 0; /* offsets & stride are calculated later (during pack) */ - attr->comp_len = calc_component_size(gl_type) * size; - attr->sz = attr->comp_len * 4; - attr->fetch_mode = fetch_mode; - attr->comp_type = comp_type; - attr += 1; - } + const Shader *shader = static_cast<const Shader *>(gpushader); + shader->vertformat_from_shader(format); } diff --git a/source/blender/gpu/opengl/gl_backend.hh b/source/blender/gpu/opengl/gl_backend.hh index eba275f0245..63a14af6612 100644 --- a/source/blender/gpu/opengl/gl_backend.hh +++ b/source/blender/gpu/opengl/gl_backend.hh @@ -30,6 +30,7 @@ #include "gl_batch.hh" #include "gl_context.hh" #include "gl_drawlist.hh" +#include "gl_shader.hh" namespace blender { namespace gpu { @@ -54,6 +55,11 @@ class GLBackend : public GPUBackend { return new GLDrawList(list_length); }; + Shader *shader_alloc(const char *name) + { + return new GLShader(name); + }; + /* TODO remove */ void buf_free(GLuint buf_id); void tex_free(GLuint tex_id); diff --git a/source/blender/gpu/opengl/gl_batch.cc b/source/blender/gpu/opengl/gl_batch.cc index 00e1a61f7cf..fade8763065 100644 --- a/source/blender/gpu/opengl/gl_batch.cc +++ b/source/blender/gpu/opengl/gl_batch.cc @@ -33,7 +33,6 @@ #include "gpu_batch_private.hh" #include "gpu_primitive_private.h" -#include "gpu_shader_private.h" #include "gl_batch.hh" #include "gl_context.hh" @@ -301,6 +300,8 @@ GLBatch::~GLBatch() void GLBatch::bind(int i_first) { + GPU_context_active_get()->state_manager->apply_state(); + if (flag & GPU_BATCH_DIRTY) { vao_cache_.clear(); } @@ -325,6 +326,8 @@ void GLBatch::draw(int v_first, int v_count, int i_first, int i_count) { this->bind(i_first); + BLI_assert(v_count > 0 && i_count > 0); + GLenum gl_type = convert_prim_type_to_gl(prim_type); if (elem) { diff --git a/source/blender/gpu/opengl/gl_context.cc b/source/blender/gpu/opengl/gl_context.cc index dd413612879..11f313f639b 100644 --- a/source/blender/gpu/opengl/gl_context.cc +++ b/source/blender/gpu/opengl/gl_context.cc @@ -30,6 +30,8 @@ #include "gpu_context_private.hh" +#include "gl_state.hh" + #include "gl_backend.hh" /* TODO remove */ #include "gl_context.hh" @@ -54,6 +56,8 @@ GLContext::GLContext(void *ghost_window, GLSharedOrphanLists &shared_orphan_list glBindBuffer(GL_ARRAY_BUFFER, default_attr_vbo_); glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); + + state_manager = new GLStateManager(); } GLContext::~GLContext() diff --git a/source/blender/gpu/opengl/gl_drawlist.cc b/source/blender/gpu/opengl/gl_drawlist.cc index c121fb9ba2c..16ea924d8dc 100644 --- a/source/blender/gpu/opengl/gl_drawlist.cc +++ b/source/blender/gpu/opengl/gl_drawlist.cc @@ -151,6 +151,11 @@ void GLDrawList::append(GPUBatch *batch, int i_first, int i_count) v_count_ = batch->elem ? batch->elem->index_len : batch->verts[0]->vertex_len; } + if (v_count_ == 0) { + /* Nothing to draw. */ + return; + } + if (MDI_INDEXED) { GLDrawCommandIndexed *cmd = reinterpret_cast<GLDrawCommandIndexed *>(data_ + command_offset_); cmd->v_first = v_first_; @@ -235,6 +240,8 @@ void GLDrawList::submit(void) } /* Do not submit this buffer again. */ command_len_ = 0; + /* Avoid keeping reference to the batch. */ + batch_ = NULL; } -/** \} */
\ No newline at end of file +/** \} */ diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc new file mode 100644 index 00000000000..ea33ff00d69 --- /dev/null +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -0,0 +1,443 @@ +/* + * 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 gpu + */ + +#include "BKE_global.h" + +#include "BLI_string.h" + +#include "GPU_extensions.h" +#include "GPU_platform.h" + +#include "gl_shader.hh" + +using namespace blender; +using namespace blender::gpu; + +/* -------------------------------------------------------------------- */ +/** \name Creation / Destruction + * \{ */ + +GLShader::GLShader(const char *name) : Shader(name) +{ +#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 + shader_program_ = glCreateProgram(); + +#ifndef __APPLE__ + if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) { + char sh_name[64]; + BLI_snprintf(sh_name, sizeof(sh_name), "ShaderProgram-%s", name); + glObjectLabel(GL_PROGRAM, shader_program_, -1, sh_name); + } +#endif +} + +GLShader::~GLShader(void) +{ +#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 + /* Invalid handles are silently ignored. */ + glDeleteShader(vert_shader_); + glDeleteShader(geom_shader_); + glDeleteShader(frag_shader_); + glDeleteProgram(shader_program_); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Shader stage creation + * \{ */ + +char *GLShader::glsl_patch_get(void) +{ + /** Used for shader patching. Init once. */ + static char patch[512] = "\0"; + if (patch[0] != '\0') { + return patch; + } + + size_t slen = 0; + /* Version need to go first. */ + STR_CONCAT(patch, slen, "#version 330\n"); + + /* 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) { + STR_CONCAT(patch, slen, "#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) { + STR_CONCAT(patch, slen, "#ifdef GL_ARB_texture_gather\n"); + STR_CONCAT(patch, slen, "# define GPU_ARB_texture_gather\n"); + STR_CONCAT(patch, slen, "#endif\n"); + } + else { + STR_CONCAT(patch, slen, "#define GPU_ARB_texture_gather\n"); + } + } + } + if (GLEW_ARB_shader_draw_parameters) { + STR_CONCAT(patch, slen, "#extension GL_ARB_shader_draw_parameters : enable\n"); + STR_CONCAT(patch, slen, "#define GPU_ARB_shader_draw_parameters\n"); + } + if (GPU_arb_texture_cube_map_array_is_supported()) { + STR_CONCAT(patch, slen, "#extension GL_ARB_texture_cube_map_array : enable\n"); + STR_CONCAT(patch, slen, "#define GPU_ARB_texture_cube_map_array\n"); + } + + /* Derivative sign can change depending on implementation. */ + float derivatives[2]; + GPU_get_dfdy_factors(derivatives); + STR_CONCATF(patch, slen, "#define DFDX_SIGN %1.1f\n", derivatives[0]); + STR_CONCATF(patch, slen, "#define DFDY_SIGN %1.1f\n", derivatives[1]); + + BLI_assert(slen < sizeof(patch)); + return patch; +} + +/* Create, compile and attach the shader stage to the shader program. */ +GLuint GLShader::create_shader_stage(GLenum gl_stage, MutableSpan<const char *> sources) +{ + GLuint shader = glCreateShader(gl_stage); + if (shader == 0) { + fprintf(stderr, "GLShader: Error: Could not create shader object."); + return 0; + } + + /* Patch the shader code using the first source slot. */ + sources[0] = glsl_patch_get(); + + glShaderSource(shader, sources.size(), sources.data(), NULL); + glCompileShader(shader); + + GLint status; + glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + if (!status || (G.debug & G_DEBUG_GPU)) { + char log[5000] = ""; + glGetShaderInfoLog(shader, sizeof(log), NULL, log); + if (log[0] != '\0') { + this->print_errors(sources, log); + } + } + if (!status) { + glDeleteShader(shader); + return 0; + } + +#ifndef __APPLE__ + if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) { + char sh_name[64]; + switch (gl_stage) { + case GL_VERTEX_SHADER: + BLI_snprintf(sh_name, sizeof(sh_name), "VertShader-%s", name); + break; + case GL_GEOMETRY_SHADER: + BLI_snprintf(sh_name, sizeof(sh_name), "GeomShader-%s", name); + break; + case GL_FRAGMENT_SHADER: + BLI_snprintf(sh_name, sizeof(sh_name), "FragShader-%s", name); + break; + } + glObjectLabel(GL_SHADER, shader, -1, sh_name); + } +#endif + + glAttachShader(shader_program_, shader); + return shader; +} + +void GLShader::vertex_shader_from_glsl(MutableSpan<const char *> sources) +{ + vert_shader_ = this->create_shader_stage(GL_VERTEX_SHADER, sources); +} + +void GLShader::geometry_shader_from_glsl(MutableSpan<const char *> sources) +{ + geom_shader_ = this->create_shader_stage(GL_GEOMETRY_SHADER, sources); +} + +void GLShader::fragment_shader_from_glsl(MutableSpan<const char *> sources) +{ + frag_shader_ = this->create_shader_stage(GL_FRAGMENT_SHADER, sources); +} + +bool GLShader::finalize(void) +{ + glLinkProgram(shader_program_); + + GLint status; + glGetProgramiv(shader_program_, GL_LINK_STATUS, &status); + if (!status) { + char log[5000]; + glGetProgramInfoLog(shader_program_, sizeof(log), NULL, log); + fprintf(stderr, "\nLinking Error:\n\n%s", log); + return false; + } + + /* TODO(fclem) We need this to modify the image binding points using glUniform. + * This could be avoided using glProgramUniform in GL 4.1. */ + glUseProgram(shader_program_); + interface = GPU_shaderinterface_create(shader_program_); + + return true; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Binding + * \{ */ + +void GLShader::bind(void) +{ + BLI_assert(shader_program_ != 0); + glUseProgram(shader_program_); +} + +void GLShader::unbind(void) +{ +#ifndef NDEBUG + glUseProgram(0); +#endif +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Transform feedback + * + * TODO(fclem) Should be replaced by compute shaders. + * \{ */ + +/* Should be called before linking. */ +void GLShader::transform_feedback_names_set(Span<const char *> name_list, + const eGPUShaderTFBType geom_type) +{ + glTransformFeedbackVaryings( + shader_program_, name_list.size(), name_list.data(), GL_INTERLEAVED_ATTRIBS); + transform_feedback_type_ = geom_type; +} + +bool GLShader::transform_feedback_enable(GPUVertBuf *buf) +{ + if (transform_feedback_type_ == GPU_SHADER_TFB_NONE) { + return false; + } + + BLI_assert(buf->vbo_id != 0); + + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf->vbo_id); + + switch (transform_feedback_type_) { + case GPU_SHADER_TFB_POINTS: + glBeginTransformFeedback(GL_POINTS); + break; + case GPU_SHADER_TFB_LINES: + glBeginTransformFeedback(GL_LINES); + break; + case GPU_SHADER_TFB_TRIANGLES: + glBeginTransformFeedback(GL_TRIANGLES); + break; + default: + return false; + } + return true; +} + +void GLShader::transform_feedback_disable(void) +{ + glEndTransformFeedback(); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Uniforms setters + * \{ */ + +void GLShader::uniform_float(int location, int comp_len, int array_size, const float *data) +{ + switch (comp_len) { + case 1: + glUniform1fv(location, array_size, data); + break; + case 2: + glUniform2fv(location, array_size, data); + break; + case 3: + glUniform3fv(location, array_size, data); + break; + case 4: + glUniform4fv(location, array_size, data); + break; + case 9: + glUniformMatrix3fv(location, array_size, 0, data); + break; + case 16: + glUniformMatrix4fv(location, array_size, 0, data); + break; + default: + BLI_assert(0); + break; + } +} + +void GLShader::uniform_int(int location, int comp_len, int array_size, const int *data) +{ + switch (comp_len) { + case 1: + glUniform1iv(location, array_size, data); + break; + case 2: + glUniform2iv(location, array_size, data); + break; + case 3: + glUniform3iv(location, array_size, data); + break; + case 4: + glUniform4iv(location, array_size, data); + break; + default: + BLI_assert(0); + break; + } +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name GPUVertFormat from Shader + * \{ */ + +static uint calc_component_size(const GLenum gl_type) +{ + switch (gl_type) { + case GL_FLOAT_VEC2: + case GL_INT_VEC2: + case GL_UNSIGNED_INT_VEC2: + return 2; + case GL_FLOAT_VEC3: + case GL_INT_VEC3: + case GL_UNSIGNED_INT_VEC3: + return 3; + case GL_FLOAT_VEC4: + case GL_FLOAT_MAT2: + case GL_INT_VEC4: + case GL_UNSIGNED_INT_VEC4: + return 4; + case GL_FLOAT_MAT3: + return 9; + case GL_FLOAT_MAT4: + return 16; + case GL_FLOAT_MAT2x3: + case GL_FLOAT_MAT3x2: + return 6; + case GL_FLOAT_MAT2x4: + case GL_FLOAT_MAT4x2: + return 8; + case GL_FLOAT_MAT3x4: + case GL_FLOAT_MAT4x3: + return 12; + default: + return 1; + } +} + +static void get_fetch_mode_and_comp_type(int gl_type, + GPUVertCompType *r_comp_type, + GPUVertFetchMode *r_fetch_mode) +{ + switch (gl_type) { + case GL_FLOAT: + case GL_FLOAT_VEC2: + case GL_FLOAT_VEC3: + case GL_FLOAT_VEC4: + case GL_FLOAT_MAT2: + case GL_FLOAT_MAT3: + case GL_FLOAT_MAT4: + case GL_FLOAT_MAT2x3: + case GL_FLOAT_MAT2x4: + case GL_FLOAT_MAT3x2: + case GL_FLOAT_MAT3x4: + case GL_FLOAT_MAT4x2: + case GL_FLOAT_MAT4x3: + *r_comp_type = GPU_COMP_F32; + *r_fetch_mode = GPU_FETCH_FLOAT; + break; + case GL_INT: + case GL_INT_VEC2: + case GL_INT_VEC3: + case GL_INT_VEC4: + *r_comp_type = GPU_COMP_I32; + *r_fetch_mode = GPU_FETCH_INT; + break; + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_VEC2: + case GL_UNSIGNED_INT_VEC3: + case GL_UNSIGNED_INT_VEC4: + *r_comp_type = GPU_COMP_U32; + *r_fetch_mode = GPU_FETCH_INT; + break; + default: + BLI_assert(0); + } +} + +void GLShader::vertformat_from_shader(GPUVertFormat *format) const +{ + GPU_vertformat_clear(format); + + GLint attr_len; + glGetProgramiv(shader_program_, GL_ACTIVE_ATTRIBUTES, &attr_len); + + for (int i = 0; i < attr_len; i++) { + char name[256]; + GLenum gl_type; + GLint size; + glGetActiveAttrib(shader_program_, i, sizeof(name), NULL, &size, &gl_type, name); + + /* Ignore OpenGL names like `gl_BaseInstanceARB`, `gl_InstanceID` and `gl_VertexID`. */ + if (glGetAttribLocation(shader_program_, name) == -1) { + continue; + } + + GPUVertCompType comp_type; + GPUVertFetchMode fetch_mode; + get_fetch_mode_and_comp_type(gl_type, &comp_type, &fetch_mode); + + int comp_len = calc_component_size(gl_type) * size; + + GPU_vertformat_attr_add(format, name, comp_type, comp_len, fetch_mode); + } +} + +/** \} */ diff --git a/source/blender/gpu/opengl/gl_shader.hh b/source/blender/gpu/opengl/gl_shader.hh new file mode 100644 index 00000000000..b432a04abaa --- /dev/null +++ b/source/blender/gpu/opengl/gl_shader.hh @@ -0,0 +1,81 @@ +/* + * 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 gpu + * + * GPUDrawList is an API to do lots of similar draw-calls very fast using + * multi-draw-indirect. There is a fallback if the feature is not supported. + */ + +#pragma once + +#include "MEM_guardedalloc.h" + +#include "glew-mx.h" + +#include "gpu_shader_private.hh" + +namespace blender { +namespace gpu { + +class GLShader : public Shader { + private: + /** Handle for full program (links shader stages below). */ + GLuint shader_program_ = 0; + + GLuint vert_shader_ = 0; + GLuint geom_shader_ = 0; + GLuint frag_shader_ = 0; + + eGPUShaderTFBType transform_feedback_type_ = GPU_SHADER_TFB_NONE; + + public: + GLShader(const char *name); + ~GLShader(); + + /* Return true on success. */ + void vertex_shader_from_glsl(MutableSpan<const char *> sources) override; + void geometry_shader_from_glsl(MutableSpan<const char *> sources) override; + void fragment_shader_from_glsl(MutableSpan<const char *> sources) override; + bool finalize(void) override; + + void transform_feedback_names_set(Span<const char *> name_list, + const eGPUShaderTFBType geom_type) override; + bool transform_feedback_enable(GPUVertBuf *buf) override; + void transform_feedback_disable(void) override; + + void bind(void) override; + void unbind(void) override; + + void uniform_float(int location, int comp_len, int array_size, const float *data) override; + void uniform_int(int location, int comp_len, int array_size, const int *data) override; + + void vertformat_from_shader(GPUVertFormat *format) const override; + + private: + char *glsl_patch_get(void); + + GLuint create_shader_stage(GLenum gl_stage, MutableSpan<const char *> sources); + + MEM_CXX_CLASS_ALLOC_FUNCS("GLShader"); +}; + +} // namespace gpu +} // namespace blender diff --git a/source/blender/gpu/opengl/gl_state.cc b/source/blender/gpu/opengl/gl_state.cc new file mode 100644 index 00000000000..3e3695e0b48 --- /dev/null +++ b/source/blender/gpu/opengl/gl_state.cc @@ -0,0 +1,423 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2020, Blender Foundation. + */ + +/** \file + * \ingroup gpu + */ + +#include "BLI_math_base.h" + +#include "GPU_extensions.h" + +#include "glew-mx.h" + +#include "gl_state.hh" + +using namespace blender::gpu; + +/* -------------------------------------------------------------------- */ +/** \name GLStateManager + * \{ */ + +GLStateManager::GLStateManager(void) : GPUStateManager() +{ + /* Set other states that never change. */ + glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); + glEnable(GL_MULTISAMPLE); + glEnable(GL_PRIMITIVE_RESTART); + + glDisable(GL_DITHER); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + + glPrimitiveRestartIndex((GLuint)0xFFFFFFFF); + /* TODO: Should become default. But needs at least GL 4.3 */ + if (GLEW_ARB_ES3_compatibility) { + /* Takes predecence over GL_PRIMITIVE_RESTART */ + glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX); + } + + /* Force update using default state. */ + current_ = ~state; + current_mutable_ = ~mutable_state; + set_state(state); + set_mutable_state(mutable_state); +} + +void GLStateManager::set_state(const GPUState &state) +{ + GPUState changed = state ^ current_; + + if (changed.blend != 0) { + set_blend(state.blend); + } + if (changed.write_mask != 0) { + set_write_mask(state.write_mask); + } + if (changed.depth_test != 0) { + set_depth_test(state.depth_test); + } + if (changed.stencil_test != 0 || changed.stencil_op != 0) { + set_stencil_test(state.stencil_test, state.stencil_op); + set_stencil_mask(state.stencil_test, mutable_state); + } + if (changed.clip_distances != 0) { + set_clip_distances(state.clip_distances, current_.clip_distances); + } + if (changed.culling_test != 0) { + set_backface_culling(state.culling_test); + } + if (changed.logic_op_xor != 0) { + set_logic_op(state.logic_op_xor); + } + if (changed.invert_facing != 0) { + set_facing(state.invert_facing); + } + if (changed.provoking_vert != 0) { + set_provoking_vert(state.provoking_vert); + } + if (changed.shadow_bias != 0) { + set_shadow_bias(state.shadow_bias); + } + + /* TODO remove */ + if (changed.polygon_smooth) { + if (state.polygon_smooth) { + glEnable(GL_POLYGON_SMOOTH); + } + else { + glDisable(GL_POLYGON_SMOOTH); + } + } + if (changed.line_smooth) { + if (state.line_smooth) { + glEnable(GL_LINE_SMOOTH); + } + else { + glDisable(GL_LINE_SMOOTH); + } + } + + current_ = state; +} + +void GLStateManager::set_mutable_state(const GPUStateMutable &state) +{ + GPUStateMutable changed = state ^ current_mutable_; + + if ((changed.viewport_rect[0] != 0) || (changed.viewport_rect[1] != 0) || + (changed.viewport_rect[2] != 0) || (changed.viewport_rect[3] != 0)) { + glViewport(UNPACK4(state.viewport_rect)); + } + + if ((changed.scissor_rect[0] != 0) || (changed.scissor_rect[1] != 0) || + (changed.scissor_rect[2] != 0) || (changed.scissor_rect[3] != 0)) { + if ((state.scissor_rect[2] > 0)) { + glScissor(UNPACK4(state.scissor_rect)); + glEnable(GL_SCISSOR_TEST); + } + else { + glDisable(GL_SCISSOR_TEST); + } + } + + /* TODO remove, should be uniform. */ + if (changed.point_size != 0) { + if (state.point_size > 0.0f) { + glEnable(GL_PROGRAM_POINT_SIZE); + glPointSize(state.point_size); + } + else { + glDisable(GL_PROGRAM_POINT_SIZE); + } + } + + if (changed.line_width != 0) { + /* TODO remove, should use wide line shader. */ + glLineWidth(clamp_f(state.line_width, 1.0f, GPU_max_line_width())); + } + + if (changed.depth_range[0] != 0 || changed.depth_range[1] != 0) { + /* TODO remove, should modify the projection matrix instead. */ + glDepthRange(UNPACK2(state.depth_range)); + } + + if (changed.stencil_compare_mask != 0 || changed.stencil_reference != 0 || + changed.stencil_write_mask != 0) { + set_stencil_mask(current_.stencil_test, state); + } + + current_mutable_ = state; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name State set functions + * \{ */ + +void GLStateManager::set_write_mask(const eGPUWriteMask value) +{ + glDepthMask((value & GPU_WRITE_DEPTH) != 0); + glColorMask((value & GPU_WRITE_RED) != 0, + (value & GPU_WRITE_GREEN) != 0, + (value & GPU_WRITE_BLUE) != 0, + (value & GPU_WRITE_ALPHA) != 0); + + if (value == GPU_WRITE_NONE) { + glEnable(GL_RASTERIZER_DISCARD); + } + else { + glDisable(GL_RASTERIZER_DISCARD); + } +} + +void GLStateManager::set_depth_test(const eGPUDepthTest value) +{ + GLenum func; + switch (value) { + case GPU_DEPTH_LESS: + func = GL_LESS; + break; + case GPU_DEPTH_LESS_EQUAL: + func = GL_LEQUAL; + break; + case GPU_DEPTH_EQUAL: + func = GL_EQUAL; + break; + case GPU_DEPTH_GREATER: + func = GL_GREATER; + break; + case GPU_DEPTH_GREATER_EQUAL: + func = GL_GEQUAL; + break; + case GPU_DEPTH_ALWAYS: + default: + func = GL_ALWAYS; + break; + } + + if (value != GPU_DEPTH_NONE) { + glEnable(GL_DEPTH_TEST); + glDepthFunc(func); + } + else { + glDisable(GL_DEPTH_TEST); + } +} + +void GLStateManager::set_stencil_test(const eGPUStencilTest test, const eGPUStencilOp operation) +{ + switch (operation) { + case GPU_STENCIL_OP_REPLACE: + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + break; + case GPU_STENCIL_OP_COUNT_DEPTH_PASS: + glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR_WRAP); + glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR_WRAP); + break; + case GPU_STENCIL_OP_COUNT_DEPTH_FAIL: + glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_KEEP); + glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_KEEP); + break; + case GPU_STENCIL_OP_NONE: + default: + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + } + + if (test != GPU_STENCIL_NONE) { + glEnable(GL_STENCIL_TEST); + } + else { + glDisable(GL_STENCIL_TEST); + } +} + +void GLStateManager::set_stencil_mask(const eGPUStencilTest test, const GPUStateMutable state) +{ + GLenum func; + switch (test) { + case GPU_STENCIL_NEQUAL: + func = GL_NOTEQUAL; + break; + case GPU_STENCIL_EQUAL: + func = GL_EQUAL; + break; + case GPU_STENCIL_ALWAYS: + func = GL_ALWAYS; + break; + case GPU_STENCIL_NONE: + default: + glStencilMask(0x00); + glStencilFunc(GL_ALWAYS, 0x00, 0x00); + return; + } + + glStencilMask(state.stencil_write_mask); + glStencilFunc(func, state.stencil_reference, state.stencil_compare_mask); +} + +void GLStateManager::set_clip_distances(const int new_dist_len, const int old_dist_len) +{ + for (int i = 0; i < new_dist_len; i++) { + glEnable(GL_CLIP_DISTANCE0 + i); + } + for (int i = new_dist_len; i < old_dist_len; i++) { + glDisable(GL_CLIP_DISTANCE0 + i); + } +} + +void GLStateManager::set_logic_op(const bool enable) +{ + if (enable) { + glEnable(GL_COLOR_LOGIC_OP); + glLogicOp(GL_XOR); + } + else { + glDisable(GL_COLOR_LOGIC_OP); + } +} + +void GLStateManager::set_facing(const bool invert) +{ + glFrontFace((invert) ? GL_CW : GL_CCW); +} + +void GLStateManager::set_backface_culling(const eGPUFaceCullTest test) +{ + if (test != GPU_CULL_NONE) { + glEnable(GL_CULL_FACE); + glCullFace((test == GPU_CULL_FRONT) ? GL_FRONT : GL_BACK); + } + else { + glDisable(GL_CULL_FACE); + } +} + +void GLStateManager::set_provoking_vert(const eGPUProvokingVertex vert) +{ + GLenum value = (vert == GPU_VERTEX_FIRST) ? GL_FIRST_VERTEX_CONVENTION : + GL_LAST_VERTEX_CONVENTION; + glProvokingVertex(value); +} + +void GLStateManager::set_shadow_bias(const bool enable) +{ + if (enable) { + glEnable(GL_POLYGON_OFFSET_FILL); + glEnable(GL_POLYGON_OFFSET_LINE); + /* 2.0 Seems to be the lowest possible slope bias that works in every case. */ + glPolygonOffset(2.0f, 1.0f); + } + else { + glDisable(GL_POLYGON_OFFSET_FILL); + glDisable(GL_POLYGON_OFFSET_LINE); + } +} + +void GLStateManager::set_blend(const eGPUBlend value) +{ + /** + * Factors to the equation. + * SRC is fragment shader output. + * DST is framebuffer color. + * final.rgb = SRC.rgb * src_rgb + DST.rgb * dst_rgb; + * final.a = SRC.a * src_alpha + DST.a * dst_alpha; + **/ + GLenum src_rgb, src_alpha, dst_rgb, dst_alpha; + switch (value) { + default: + case GPU_BLEND_ALPHA: { + src_rgb = GL_SRC_ALPHA; + dst_rgb = GL_ONE_MINUS_SRC_ALPHA; + src_alpha = GL_ONE; + dst_alpha = GL_ONE_MINUS_SRC_ALPHA; + break; + } + case GPU_BLEND_ALPHA_PREMULT: { + src_rgb = GL_ONE; + dst_rgb = GL_ONE_MINUS_SRC_ALPHA; + src_alpha = GL_ONE; + dst_alpha = GL_ONE_MINUS_SRC_ALPHA; + break; + } + case GPU_BLEND_ADDITIVE: { + /* Do not let alpha accumulate but premult the source RGB by it. */ + src_rgb = GL_SRC_ALPHA; + dst_rgb = GL_ONE; + src_alpha = GL_ZERO; + dst_alpha = GL_ONE; + break; + } + case GPU_BLEND_SUBTRACT: + case GPU_BLEND_ADDITIVE_PREMULT: { + /* Let alpha accumulate. */ + src_rgb = GL_ONE; + dst_rgb = GL_ONE; + src_alpha = GL_ONE; + dst_alpha = GL_ONE; + break; + } + case GPU_BLEND_MULTIPLY: { + src_rgb = GL_DST_COLOR; + dst_rgb = GL_ZERO; + src_alpha = GL_DST_ALPHA; + dst_alpha = GL_ZERO; + break; + } + case GPU_BLEND_INVERT: { + src_rgb = GL_ONE_MINUS_DST_COLOR; + dst_rgb = GL_ZERO; + src_alpha = GL_ZERO; + dst_alpha = GL_ONE; + break; + } + case GPU_BLEND_OIT: { + src_rgb = GL_ONE; + dst_rgb = GL_ONE; + src_alpha = GL_ZERO; + dst_alpha = GL_ONE_MINUS_SRC_ALPHA; + break; + } + case GPU_BLEND_BACKGROUND: { + src_rgb = GL_ONE_MINUS_DST_ALPHA; + dst_rgb = GL_SRC_ALPHA; + src_alpha = GL_ZERO; + dst_alpha = GL_SRC_ALPHA; + break; + } + case GPU_BLEND_CUSTOM: { + src_rgb = GL_ONE; + dst_rgb = GL_SRC1_COLOR; + src_alpha = GL_ONE; + dst_alpha = GL_SRC1_ALPHA; + break; + } + } + + if (value != GPU_BLEND_NONE) { + glBlendFuncSeparate(src_rgb, dst_rgb, src_alpha, dst_alpha); + glEnable(GL_BLEND); + } + else { + glDisable(GL_BLEND); + } +} + +/** \} */ diff --git a/source/blender/gpu/opengl/gl_state.hh b/source/blender/gpu/opengl/gl_state.hh new file mode 100644 index 00000000000..b05fcc5d044 --- /dev/null +++ b/source/blender/gpu/opengl/gl_state.hh @@ -0,0 +1,63 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2020, Blender Foundation. + */ + +/** \file + * \ingroup gpu + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" + +#include "gpu_state_private.hh" + +#include "glew-mx.h" + +namespace blender { +namespace gpu { + +class GLStateManager : public GPUStateManager { + private: + /** Current state of the GL implementation. Avoids resetting the whole state for every change. */ + GPUState current_; + GPUStateMutable current_mutable_; + + public: + GLStateManager(); + + void set_state(const GPUState &state) override; + void set_mutable_state(const GPUStateMutable &state) override; + + private: + static void set_write_mask(const eGPUWriteMask value); + static void set_depth_test(const eGPUDepthTest value); + static void set_stencil_test(const eGPUStencilTest test, const eGPUStencilOp operation); + static void set_stencil_mask(const eGPUStencilTest test, const GPUStateMutable state); + static void set_clip_distances(const int new_dist_len, const int old_dist_len); + static void set_logic_op(const bool enable); + static void set_facing(const bool invert); + static void set_backface_culling(const eGPUFaceCullTest test); + static void set_provoking_vert(const eGPUProvokingVertex vert); + static void set_shadow_bias(const bool enable); + static void set_blend(const eGPUBlend value); + + MEM_CXX_CLASS_ALLOC_FUNCS("GLStateManager") +}; + +} // namespace gpu +} // namespace blender diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_output_world.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_output_world.glsl index 27ca96501ae..5eb853a4c1a 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_output_world.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_output_world.glsl @@ -6,7 +6,8 @@ void node_output_world(Closure surface, Closure volume, out Closure result) float alpha = renderPassEnvironment ? 1.0 : backgroundAlpha; result = CLOSURE_DEFAULT; result.radiance = surface.radiance * alpha; - result.transmittance = vec3(1.0 - alpha); + result.transmittance = vec3(0.0); + result.holdout = (1.0 - alpha); #else result = volume; #endif /* VOLUMETRICS */ diff --git a/source/blender/io/alembic/exporter/abc_export_capi.cc b/source/blender/io/alembic/exporter/abc_export_capi.cc index 8c5f3d89870..6412379c126 100644 --- a/source/blender/io/alembic/exporter/abc_export_capi.cc +++ b/source/blender/io/alembic/exporter/abc_export_capi.cc @@ -67,11 +67,14 @@ namespace io { namespace alembic { // Construct the depsgraph for exporting. -static void build_depsgraph(Depsgraph *depsgraph, Main *bmain) +static void build_depsgraph(Depsgraph *depsgraph, const bool visible_objects_only) { - Scene *scene = DEG_get_input_scene(depsgraph); - ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph); - DEG_graph_build_from_view_layer(depsgraph, bmain, scene, view_layer); + if (visible_objects_only) { + DEG_graph_build_from_view_layer(depsgraph); + } + else { + DEG_graph_build_for_all_objects(depsgraph); + } } static void export_startjob(void *customdata, @@ -91,7 +94,7 @@ static void export_startjob(void *customdata, *progress = 0.0f; *do_update = true; - build_depsgraph(data->depsgraph, data->bmain); + build_depsgraph(data->depsgraph, data->params.visible_objects_only); SubdivModifierDisabler subdiv_disabler(data->depsgraph); if (!data->params.apply_subdiv) { subdiv_disabler.disable_modifiers(); @@ -150,7 +153,7 @@ static void export_startjob(void *customdata, // Update the scene for the next frame to render. scene->r.cfra = static_cast<int>(frame); scene->r.subframe = frame - scene->r.cfra; - BKE_scene_graph_update_for_newframe(data->depsgraph, data->bmain); + BKE_scene_graph_update_for_newframe(data->depsgraph); CLOG_INFO(&LOG, 2, "Exporting frame %.2f", frame); ExportSubset export_subset = abc_archive->export_subset_for_frame(frame); @@ -171,7 +174,7 @@ static void export_startjob(void *customdata, // Finish up by going back to the keyframe that was current before we started. if (CFRA != orig_frame) { CFRA = orig_frame; - BKE_scene_graph_update_for_newframe(data->depsgraph, data->bmain); + BKE_scene_graph_update_for_newframe(data->depsgraph); } data->export_ok = !data->was_canceled; diff --git a/source/blender/io/alembic/exporter/abc_writer_abstract.cc b/source/blender/io/alembic/exporter/abc_writer_abstract.cc index e43b394e27f..84527a12e85 100644 --- a/source/blender/io/alembic/exporter/abc_writer_abstract.cc +++ b/source/blender/io/alembic/exporter/abc_writer_abstract.cc @@ -25,6 +25,10 @@ #include "DNA_modifier_types.h" +#include "DEG_depsgraph.h" + +#include <Alembic/AbcGeom/Visibility.h> + #include "CLG_log.h" static CLG_LogRef LOG = {"io.alembic"}; @@ -96,6 +100,18 @@ void ABCAbstractWriter::update_bounding_box(Object *object) bounding_box_.max.z = -bb->vec[0][1]; } +void ABCAbstractWriter::write_visibility(const HierarchyContext &context) +{ + const bool is_visible = context.is_object_visible(DAG_EVAL_RENDER); + Alembic::Abc::OObject abc_object = get_alembic_object(); + + if (!abc_visibility_.valid()) { + abc_visibility_ = Alembic::AbcGeom::CreateVisibilityProperty(abc_object, timesample_index_); + } + abc_visibility_.set(is_visible ? Alembic::AbcGeom::kVisibilityVisible : + Alembic::AbcGeom::kVisibilityHidden); +} + } // namespace alembic } // namespace io } // namespace blender diff --git a/source/blender/io/alembic/exporter/abc_writer_abstract.h b/source/blender/io/alembic/exporter/abc_writer_abstract.h index a83373a567a..f46409b7902 100644 --- a/source/blender/io/alembic/exporter/abc_writer_abstract.h +++ b/source/blender/io/alembic/exporter/abc_writer_abstract.h @@ -43,6 +43,9 @@ class ABCAbstractWriter : public AbstractHierarchyWriter { uint32_t timesample_index_; Imath::Box3d bounding_box_; + /* Visibility of this writer's data in Alembic. */ + Alembic::Abc::OCharProperty abc_visibility_; + public: explicit ABCAbstractWriter(const ABCWriterConstructorArgs &args); virtual ~ABCAbstractWriter(); @@ -70,6 +73,8 @@ class ABCAbstractWriter : public AbstractHierarchyWriter { virtual void do_write(HierarchyContext &context) = 0; virtual void update_bounding_box(Object *object); + + void write_visibility(const HierarchyContext &context); }; } // namespace alembic diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc index 89cb76db9a6..517f0212712 100644 --- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc +++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc @@ -159,27 +159,10 @@ ModifierData *ABCGenericMeshWriter::get_liquid_sim_modifier(Scene *scene, Object bool ABCGenericMeshWriter::is_supported(const HierarchyContext *context) const { - Object *object = context->object; - bool is_dupli = context->duplicator != nullptr; - int base_flag; - - if (is_dupli) { - /* Construct the object's base flags from its dupli-parent, just like is done in - * deg_objects_dupli_iterator_next(). Without this, the visibility check below will fail. Doing - * this here, instead of a more suitable location in AbstractHierarchyIterator, prevents - * copying the Object for every dupli. */ - base_flag = object->base_flag; - object->base_flag = context->duplicator->base_flag | BASE_FROM_DUPLI; + if (args_.export_params->visible_objects_only) { + return context->is_object_visible(DAG_EVAL_RENDER); } - - int visibility = BKE_object_visibility( - object, DAG_EVAL_RENDER /* TODO(Sybren): add evaluation mode to export options? */); - - if (is_dupli) { - object->base_flag = base_flag; - } - - return (visibility & OB_VISIBLE_SELF) != 0; + return true; } void ABCGenericMeshWriter::do_write(HierarchyContext &context) diff --git a/source/blender/io/alembic/exporter/abc_writer_transform.cc b/source/blender/io/alembic/exporter/abc_writer_transform.cc index 39af99c142c..7694066a13d 100644 --- a/source/blender/io/alembic/exporter/abc_writer_transform.cc +++ b/source/blender/io/alembic/exporter/abc_writer_transform.cc @@ -92,6 +92,8 @@ void ABCTransformWriter::do_write(HierarchyContext &context) xform_sample.setMatrix(convert_matrix_datatype(parent_relative_matrix)); xform_sample.setInheritsXforms(true); abc_xform_schema_.set(xform_sample); + + write_visibility(context); } const OObject ABCTransformWriter::get_alembic_object() const diff --git a/source/blender/io/common/IO_abstract_hierarchy_iterator.h b/source/blender/io/common/IO_abstract_hierarchy_iterator.h index d0d9d72b880..1d78cc38746 100644 --- a/source/blender/io/common/IO_abstract_hierarchy_iterator.h +++ b/source/blender/io/common/IO_abstract_hierarchy_iterator.h @@ -37,6 +37,8 @@ #include "IO_dupli_persistent_id.hh" +#include "DEG_depsgraph.h" + #include <map> #include <set> #include <string> @@ -111,6 +113,8 @@ struct HierarchyContext { bool is_instance() const; void mark_as_instance_of(const std::string &reference_export_path); void mark_as_not_instanced(); + + bool is_object_visible(const enum eEvaluationMode evaluation_mode) const; }; /* Abstract writer for objects. Create concrete subclasses to write to USD, Alembic, etc. diff --git a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc index fbefc8c8e7e..d825625cafc 100644 --- a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc +++ b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc @@ -28,6 +28,7 @@ #include "BKE_anim_data.h" #include "BKE_duplilist.h" #include "BKE_key.h" +#include "BKE_object.h" #include "BKE_particle.h" #include "BLI_assert.h" @@ -77,6 +78,29 @@ void HierarchyContext::mark_as_not_instanced() original_export_path.clear(); } +bool HierarchyContext::is_object_visible(const enum eEvaluationMode evaluation_mode) const +{ + const bool is_dupli = duplicator != nullptr; + int base_flag; + + if (is_dupli) { + /* Construct the object's base flags from its dupli-parent, just like is done in + * deg_objects_dupli_iterator_next(). Without this, the visibility check below will fail. Doing + * this here, instead of a more suitable location in AbstractHierarchyIterator, prevents + * copying the Object for every dupli. */ + base_flag = object->base_flag; + object->base_flag = duplicator->base_flag | BASE_FROM_DUPLI; + } + + const int visibility = BKE_object_visibility(object, evaluation_mode); + + if (is_dupli) { + object->base_flag = base_flag; + } + + return (visibility & OB_VISIBLE_SELF) != 0; +} + EnsuredWriter::EnsuredWriter() : writer_(nullptr), newly_created_(false) { } diff --git a/source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc b/source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc index cbb2e63a99f..27196994a3c 100644 --- a/source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc +++ b/source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc @@ -20,8 +20,11 @@ #include "tests/blendfile_loading_base_test.h" +#include "BKE_scene.h" #include "BLI_math.h" +#include "BLO_readfile.h" #include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" #include "DNA_object_types.h" #include <map> @@ -99,7 +102,7 @@ class TestingHierarchyIterator : public AbstractHierarchyIterator { } }; -class USDHierarchyIteratorTest : public BlendfileLoadingBaseTest { +class AbstractHierarchyIteratorTest : public BlendfileLoadingBaseTest { protected: TestingHierarchyIterator *iterator; @@ -131,7 +134,7 @@ class USDHierarchyIteratorTest : public BlendfileLoadingBaseTest { } }; -TEST_F(USDHierarchyIteratorTest, ExportHierarchyTest) +TEST_F(AbstractHierarchyIteratorTest, ExportHierarchyTest) { /* Load the test blend file. */ if (!blendfile_load("usd/usd_hierarchy_export_test.blend")) { @@ -206,7 +209,7 @@ TEST_F(USDHierarchyIteratorTest, ExportHierarchyTest) EXPECT_EQ(expected_data, iterator->data_writers); } -TEST_F(USDHierarchyIteratorTest, ExportSubsetTest) +TEST_F(AbstractHierarchyIteratorTest, ExportSubsetTest) { // The scene has no hair or particle systems, and this is already covered by ExportHierarchyTest, // so not included here. Update this test when hair & particle systems are included. @@ -317,4 +320,44 @@ TEST_F(USDHierarchyIteratorTest, ExportSubsetTest) EXPECT_EQ(expected_transforms, iterator->transform_writers); EXPECT_EQ(expected_data, iterator->data_writers); } + +/* Test class that constructs a depsgraph in such a way that it includes invisible objects. */ +class AbstractHierarchyIteratorInvisibleTest : public AbstractHierarchyIteratorTest { + protected: + void depsgraph_create(eEvaluationMode depsgraph_evaluation_mode) override + { + depsgraph = DEG_graph_new( + bfile->main, bfile->curscene, bfile->cur_view_layer, depsgraph_evaluation_mode); + DEG_graph_build_for_all_objects(depsgraph); + BKE_scene_graph_update_tagged(depsgraph, bfile->main); + } +}; + +TEST_F(AbstractHierarchyIteratorInvisibleTest, ExportInvisibleTest) +{ + if (!blendfile_load("alembic/visibility.blend")) { + return; + } + depsgraph_create(DAG_EVAL_RENDER); + iterator_create(); + + iterator->iterate_and_write(); + + // Mapping from object name to set of export paths. + used_writers expected_transforms = {{"OBInvisibleAnimatedCube", {"/InvisibleAnimatedCube"}}, + {"OBInvisibleCube", {"/InvisibleCube"}}, + {"OBVisibleCube", {"/VisibleCube"}}}; + EXPECT_EQ(expected_transforms, iterator->transform_writers); + + used_writers expected_data = {{"OBInvisibleAnimatedCube", {"/InvisibleAnimatedCube/Cube"}}, + {"OBInvisibleCube", {"/InvisibleCube/Cube"}}, + {"OBVisibleCube", {"/VisibleCube/Cube"}}}; + + EXPECT_EQ(expected_data, iterator->data_writers); + + // The scene has no hair or particle systems. + EXPECT_EQ(0, iterator->hair_writers.size()); + EXPECT_EQ(0, iterator->particle_writers.size()); +} + } // namespace blender::io diff --git a/source/blender/io/usd/intern/usd_capi.cc b/source/blender/io/usd/intern/usd_capi.cc index 98aef62f38e..83b8c18d436 100644 --- a/source/blender/io/usd/intern/usd_capi.cc +++ b/source/blender/io/usd/intern/usd_capi.cc @@ -75,8 +75,12 @@ static void export_startjob(void *customdata, // Construct the depsgraph for exporting. Scene *scene = DEG_get_input_scene(data->depsgraph); - ViewLayer *view_layer = DEG_get_input_view_layer(data->depsgraph); - DEG_graph_build_from_view_layer(data->depsgraph, data->bmain, scene, view_layer); + if (data->params.visible_objects_only) { + DEG_graph_build_from_view_layer(data->depsgraph); + } + else { + DEG_graph_build_for_all_objects(data->depsgraph); + } BKE_scene_graph_update_tagged(data->depsgraph, data->bmain); *progress = 0.0f; @@ -122,7 +126,7 @@ static void export_startjob(void *customdata, // Update the scene for the next frame to render. scene->r.cfra = static_cast<int>(frame); scene->r.subframe = frame - scene->r.cfra; - BKE_scene_graph_update_for_newframe(data->depsgraph, data->bmain); + BKE_scene_graph_update_for_newframe(data->depsgraph); iter.set_export_frame(frame); iter.iterate_and_write(); @@ -142,7 +146,7 @@ static void export_startjob(void *customdata, // Finish up by going back to the keyframe that was current before we started. if (CFRA != orig_frame) { CFRA = orig_frame; - BKE_scene_graph_update_for_newframe(data->depsgraph, data->bmain); + BKE_scene_graph_update_for_newframe(data->depsgraph); } data->export_ok = true; diff --git a/source/blender/io/usd/intern/usd_writer_abstract.cc b/source/blender/io/usd/intern/usd_writer_abstract.cc index a416941fb4d..4910b7f11dd 100644 --- a/source/blender/io/usd/intern/usd_writer_abstract.cc +++ b/source/blender/io/usd/intern/usd_writer_abstract.cc @@ -114,6 +114,20 @@ pxr::UsdShadeMaterial USDAbstractWriter::ensure_usd_material(Material *material) return usd_material; } +void USDAbstractWriter::write_visibility(const HierarchyContext &context, + const pxr::UsdTimeCode timecode, + pxr::UsdGeomImageable &usd_geometry) +{ + pxr::UsdAttribute attr_visibility = usd_geometry.CreateVisibilityAttr(pxr::VtValue(), true); + + const bool is_visible = context.is_object_visible( + usd_export_context_.export_params.evaluation_mode); + const pxr::TfToken visibility = is_visible ? pxr::UsdGeomTokens->inherited : + pxr::UsdGeomTokens->invisible; + + usd_value_writer_.SetAttribute(attr_visibility, pxr::VtValue(visibility), timecode); +} + } // namespace usd } // namespace io } // namespace blender diff --git a/source/blender/io/usd/intern/usd_writer_abstract.h b/source/blender/io/usd/intern/usd_writer_abstract.h index a689deaf0d8..248bdd22a3b 100644 --- a/source/blender/io/usd/intern/usd_writer_abstract.h +++ b/source/blender/io/usd/intern/usd_writer_abstract.h @@ -72,6 +72,10 @@ class USDAbstractWriter : public AbstractHierarchyWriter { pxr::UsdTimeCode get_export_time_code() const; pxr::UsdShadeMaterial ensure_usd_material(Material *material); + + void write_visibility(const HierarchyContext &context, + const pxr::UsdTimeCode timecode, + pxr::UsdGeomImageable &usd_geometry); }; } // namespace usd diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc index bd2c549e729..75d1ca605d4 100644 --- a/source/blender/io/usd/intern/usd_writer_mesh.cc +++ b/source/blender/io/usd/intern/usd_writer_mesh.cc @@ -42,6 +42,8 @@ #include "DNA_object_fluidsim_types.h" #include "DNA_particle_types.h" +#include <iostream> + namespace blender { namespace io { namespace usd { @@ -52,27 +54,10 @@ USDGenericMeshWriter::USDGenericMeshWriter(const USDExporterContext &ctx) : USDA bool USDGenericMeshWriter::is_supported(const HierarchyContext *context) const { - Object *object = context->object; - bool is_dupli = context->duplicator != nullptr; - int base_flag; - - if (is_dupli) { - /* Construct the object's base flags from its dupli-parent, just like is done in - * deg_objects_dupli_iterator_next(). Without this, the visibility check below will fail. Doing - * this here, instead of a more suitable location in AbstractHierarchyIterator, prevents - * copying the Object for every dupli. */ - base_flag = object->base_flag; - object->base_flag = context->duplicator->base_flag | BASE_FROM_DUPLI; - } - - int visibility = BKE_object_visibility(object, - usd_export_context_.export_params.evaluation_mode); - - if (is_dupli) { - object->base_flag = base_flag; + if (usd_export_context_.export_params.visible_objects_only) { + return context->is_object_visible(usd_export_context_.export_params.evaluation_mode); } - - return (visibility & OB_VISIBLE_SELF) != 0; + return true; } void USDGenericMeshWriter::do_write(HierarchyContext &context) @@ -169,6 +154,8 @@ void USDGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh) const pxr::SdfPath &usd_path = usd_export_context_.usd_path; pxr::UsdGeomMesh usd_mesh = pxr::UsdGeomMesh::Define(stage, usd_path); + write_visibility(context, timecode, usd_mesh); + USDMeshData usd_mesh_data; get_geometry_data(mesh, usd_mesh_data); diff --git a/source/blender/io/usd/usd.h b/source/blender/io/usd/usd.h index f2826cd1d7c..b9ea90736ff 100644 --- a/source/blender/io/usd/usd.h +++ b/source/blender/io/usd/usd.h @@ -35,6 +35,7 @@ struct USDExportParams { bool export_normals; bool export_materials; bool selected_objects_only; + bool visible_objects_only; bool use_instancing; enum eEvaluationMode evaluation_mode; }; diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index 6c4d2856526..3873763e3e0 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -322,6 +322,11 @@ typedef enum eBrushCurvePreset { BRUSH_CURVE_SMOOTHER = 9, } eBrushCurvePreset; +typedef enum eBrushDeformTarget { + BRUSH_DEFORM_TARGET_GEOMETRY = 0, + BRUSH_DEFORM_TARGET_CLOTH_SIM = 1, +} eBrushDeformTarget; + typedef enum eBrushElasticDeformType { BRUSH_ELASTIC_DEFORM_GRAB = 0, BRUSH_ELASTIC_DEFORM_GRAB_BISCALE = 1, @@ -539,7 +544,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; @@ -587,6 +592,8 @@ typedef struct Brush { /* Maximun distance to search fake neighbors from a vertex. */ float disconnected_distance_max; + int deform_target; + /* automasking */ int automasking_flags; int automasking_boundary_edges_propagation_steps; diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index fc50261eb03..b92c9f42a73 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -1033,6 +1033,7 @@ typedef enum { eMultiresModifierFlag_PlainUv_DEPRECATED = (1 << 1), eMultiresModifierFlag_UseCrease = (1 << 2), eMultiresModifierFlag_UseCustomNormals = (1 << 3), + eMultiresModifierFlag_UseSculptBaseMesh = (1 << 4), } MultiresModifierFlag; /* DEPRECATED, only used for versioning. */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 6568281a8d4..62c072831b4 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -537,8 +537,6 @@ enum { OB_TRANSFLAG_UNUSED_12 = 1 << 12, /* cleared */ /* runtime constraints disable */ OB_NO_CONSTRAINTS = 1 << 13, - /* hack to work around particle issue */ - OB_NO_PSYS_UPDATE = 1 << 14, OB_DUPLI = OB_DUPLIVERTS | OB_DUPLICOLLECTION | OB_DUPLIFACES | OB_DUPLIPARTS, }; diff --git a/source/blender/makesdna/DNA_scene_defaults.h b/source/blender/makesdna/DNA_scene_defaults.h index ec64eea0aae..69580da8c5f 100644 --- a/source/blender/makesdna/DNA_scene_defaults.h +++ b/source/blender/makesdna/DNA_scene_defaults.h @@ -364,4 +364,3 @@ } /* clang-format off */ - diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index d5b828c898d..e8c4d5cde20 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -68,8 +68,6 @@ typedef struct bScreen { /** User-setting for which editors get redrawn during anim playback. */ short redraws_flag; - char statusbar_info[256]; - /** Temp screen in a temp window, don't save (like user prefs). */ char temp; /** Temp screen for image render display or fileselect. */ @@ -635,13 +633,21 @@ typedef enum eRegionType { RGN_TYPE_EXECUTE = 10, RGN_TYPE_FOOTER = 11, RGN_TYPE_TOOL_HEADER = 12, + +#define RGN_TYPE_LEN (RGN_TYPE_TOOL_HEADER + 1) } eRegionType; + /* use for function args */ #define RGN_TYPE_ANY -1 /* Region supports panel tabs (categories). */ #define RGN_TYPE_HAS_CATEGORY_MASK (1 << RGN_TYPE_UI) +/* Check for any kind of header region. */ +#define RGN_TYPE_IS_HEADER_ANY(regiontype) \ + (((1 << (regiontype)) & \ + ((1 << RGN_TYPE_HEADER) | 1 << (RGN_TYPE_TOOL_HEADER) | (1 << RGN_TYPE_FOOTER))) != 0) + /** #ARegion.alignment */ enum { RGN_ALIGN_NONE = 0, @@ -661,6 +667,7 @@ enum { /** Mask out flags so we can check the alignment. */ #define RGN_ALIGN_ENUM_FROM_MASK(align) ((align) & ((1 << 4) - 1)) +#define RGN_ALIGN_FLAG_FROM_MASK(align) ((align) & ~((1 << 4) - 1)) /** #ARegion.flag */ enum { diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index c2ed6c97d3d..136fe3744ef 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -689,16 +689,17 @@ typedef struct UserDef { int audioformat; int audiochannels; - /** Setting for UI scale. */ + /** Setting for UI scale (fractional), before screen DPI has been applied. */ float ui_scale; /** Setting for UI line width. */ int ui_line_width; /** Runtime, full DPI divided by `pixelsize`. */ int dpi; - /** Runtime, multiplier to scale UI elements based on DPI. */ + /** Runtime, multiplier to scale UI elements based on DPI (fractional). */ float dpi_fac; + /** Runtime, `1.0 / dpi_fac` */ float inv_dpi_fac; - /** Runtime, line width and point size based on DPI. */ + /** Runtime, calculated from line-width and point-size based on DPI (rounded to int). */ float pixelsize; /** Deprecated, for forward compatibility. */ int virtual_pixel; diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index 0b43a5a6653..1896813bdb3 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -47,7 +47,6 @@ set(DEFSRC rna_fluid.c rna_gpencil.c rna_gpencil_modifier.c - rna_hair.c rna_image.c rna_key.c rna_lattice.c @@ -69,7 +68,6 @@ set(DEFSRC rna_packedfile.c rna_palette.c rna_particle.c - rna_pointcloud.c rna_pose.c rna_render.c rna_rigidbody.c @@ -79,7 +77,6 @@ set(DEFSRC rna_sculpt_paint.c rna_sequencer.c rna_shader_fx.c - rna_simulation.c rna_sound.c rna_space.c rna_speaker.c @@ -99,6 +96,16 @@ set(DEFSRC rna_xr.c ) +if(WITH_EXPERIMENTAL_FEATURES) + add_definitions(-DWITH_PARTICLE_NODES) + add_definitions(-DWITH_HAIR_NODES) + list(APPEND DEFSRC + rna_pointcloud.c + rna_simulation.c + rna_hair.c + ) +endif() + set(APISRC rna_action_api.c rna_animation_api.c diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 779e4363be0..2b1e5b3c702 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -599,7 +599,7 @@ static void rna_float_print(FILE *f, float num) else if (num == FLT_MAX) { fprintf(f, "FLT_MAX"); } - else if ((fabsf(num) < INT64_MAX) && ((int64_t)num == num)) { + else if ((fabsf(num) < (float)INT64_MAX) && ((int64_t)num == num)) { fprintf(f, "%.1ff", num); } else { @@ -4285,7 +4285,9 @@ static RNAProcessItem PROCESS_ITEMS[] = { {"rna_dynamicpaint.c", NULL, RNA_def_dynamic_paint}, {"rna_fcurve.c", "rna_fcurve_api.c", RNA_def_fcurve}, {"rna_gpencil.c", NULL, RNA_def_gpencil}, +#ifdef WITH_HAIR_NODES {"rna_hair.c", NULL, RNA_def_hair}, +#endif {"rna_image.c", "rna_image_api.c", RNA_def_image}, {"rna_key.c", NULL, RNA_def_key}, {"rna_light.c", NULL, RNA_def_light}, @@ -4308,7 +4310,9 @@ static RNAProcessItem PROCESS_ITEMS[] = { {"rna_packedfile.c", NULL, RNA_def_packedfile}, {"rna_palette.c", NULL, RNA_def_palette}, {"rna_particle.c", NULL, RNA_def_particle}, +#ifdef WITH_PARTICLE_NODES {"rna_pointcloud.c", NULL, RNA_def_pointcloud}, +#endif {"rna_pose.c", "rna_pose_api.c", RNA_def_pose}, {"rna_curveprofile.c", NULL, RNA_def_profile}, {"rna_lightprobe.c", NULL, RNA_def_lightprobe}, @@ -4318,7 +4322,9 @@ static RNAProcessItem PROCESS_ITEMS[] = { {"rna_screen.c", NULL, RNA_def_screen}, {"rna_sculpt_paint.c", NULL, RNA_def_sculpt_paint}, {"rna_sequencer.c", "rna_sequencer_api.c", RNA_def_sequencer}, +#ifdef WITH_PARTICLE_NODES {"rna_simulation.c", NULL, RNA_def_simulation}, +#endif {"rna_space.c", "rna_space_api.c", RNA_def_space}, {"rna_speaker.c", NULL, RNA_def_speaker}, {"rna_test.c", NULL, RNA_def_test}, diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index e9ca0d577ce..f1c125fcbb9 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -251,9 +251,11 @@ short RNA_type_to_ID_code(const StructRNA *type) if (base_type == &RNA_FreestyleLineStyle) { return ID_LS; } +# ifdef WITH_HAIR_NODES if (base_type == &RNA_Hair) { return ID_HA; } +# endif if (base_type == &RNA_Lattice) { return ID_LT; } @@ -287,9 +289,11 @@ short RNA_type_to_ID_code(const StructRNA *type) if (base_type == &RNA_PaintCurve) { return ID_PC; } +# ifdef WITH_PARTICLE_NODES if (base_type == &RNA_PointCloud) { return ID_PT; } +# endif if (base_type == &RNA_LightProbe) { return ID_LP; } @@ -299,9 +303,11 @@ short RNA_type_to_ID_code(const StructRNA *type) if (base_type == &RNA_Screen) { return ID_SCR; } +# ifdef WITH_PARTICLE_NODES if (base_type == &RNA_Simulation) { return ID_SIM; } +# endif if (base_type == &RNA_Sound) { return ID_SO; } @@ -355,7 +361,11 @@ StructRNA *ID_code_to_RNA_type(short idcode) case ID_GR: return &RNA_Collection; case ID_HA: +# ifdef WITH_HAIR_NODES return &RNA_Hair; +# else + return &RNA_ID; +# endif case ID_IM: return &RNA_Image; case ID_KE: @@ -389,7 +399,11 @@ StructRNA *ID_code_to_RNA_type(short idcode) case ID_PC: return &RNA_PaintCurve; case ID_PT: +# ifdef WITH_PARTICLE_NODES return &RNA_PointCloud; +# else + return &RNA_ID; +# endif case ID_LP: return &RNA_LightProbe; case ID_SCE: @@ -397,7 +411,11 @@ StructRNA *ID_code_to_RNA_type(short idcode) case ID_SCR: return &RNA_Screen; case ID_SIM: +# ifdef WITH_PARTICLE_NODES return &RNA_Simulation; +# else + return &RNA_ID; +# endif case ID_SO: return &RNA_Sound; case ID_SPK: diff --git a/source/blender/makesrna/intern/rna_access_compare_override.c b/source/blender/makesrna/intern/rna_access_compare_override.c index 0a739dcfc5a..ac4553349cc 100644 --- a/source/blender/makesrna/intern/rna_access_compare_override.c +++ b/source/blender/makesrna/intern/rna_access_compare_override.c @@ -484,13 +484,13 @@ static bool rna_property_override_operation_apply(Main *bmain, /* Special case for IDProps, we use default callback then. */ if (prop_dst->magic != RNA_MAGIC) { override_apply = rna_property_override_apply_default; - if (prop_src->magic == RNA_MAGIC && prop_src->override_apply != override_apply) { + if (prop_src->magic == RNA_MAGIC && !ELEM(prop_src->override_apply, NULL, override_apply)) { override_apply = NULL; } } else if (prop_src->magic != RNA_MAGIC) { override_apply = rna_property_override_apply_default; - if (prop_dst->override_apply != override_apply) { + if (!ELEM(prop_dst->override_apply, NULL, override_apply)) { override_apply = NULL; } } diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index 8454d5c125f..155943b3b8d 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -1264,6 +1264,7 @@ static void rna_def_edit_bone(BlenderRNA *brna) prop = RNA_def_property(srna, "head", PROP_FLOAT, PROP_TRANSLATION); RNA_def_property_float_sdna(prop, NULL, "head"); + RNA_def_property_ui_range(prop, 0, FLT_MAX, 10, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Head", "Location of head end of the bone"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); @@ -1271,6 +1272,7 @@ static void rna_def_edit_bone(BlenderRNA *brna) prop = RNA_def_property(srna, "tail", PROP_FLOAT, PROP_TRANSLATION); RNA_def_property_float_sdna(prop, NULL, "tail"); + RNA_def_property_ui_range(prop, 0, FLT_MAX, 10, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Tail", "Location of tail end of the bone"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index a3fa4fed575..f48a7e6715d 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -45,6 +45,18 @@ static const EnumPropertyItem prop_direction_items[] = { {0, NULL, 0, NULL, NULL}, }; +#ifdef RNA_RUNTIME +static const EnumPropertyItem prop_smooth_direction_items[] = { + {0, "SMOOTH", ICON_ADD, "Smooth", "Smooth the surfae"}, + {BRUSH_DIR_IN, + "ENHANCE_DETAILS", + ICON_REMOVE, + "Enhance Details", + "Enhance the surface detail"}, + {0, NULL, 0, NULL, NULL}, +}; +#endif + static const EnumPropertyItem sculpt_stroke_method_items[] = { {0, "DOTS", 0, "Dots", "Apply paint on each mouse move step"}, {BRUSH_DRAG_DOT, "DRAG_DOT", 0, "Drag Dot", "Allows a single dot to be carefully positioned"}, @@ -527,6 +539,7 @@ static bool rna_BrushCapabilitiesSculpt_has_direction_get(PointerRNA *ptr) SCULPT_TOOL_DRAW_SHARP, SCULPT_TOOL_CLAY, SCULPT_TOOL_CLAY_STRIPS, + SCULPT_TOOL_SMOOTH, SCULPT_TOOL_LAYER, SCULPT_TOOL_INFLATE, SCULPT_TOOL_BLOB, @@ -795,7 +808,8 @@ static const EnumPropertyItem *rna_Brush_direction_itemf(bContext *C, case SCULPT_TOOL_CLAY: case SCULPT_TOOL_CLAY_STRIPS: return prop_direction_items; - + case SCULPT_TOOL_SMOOTH: + return prop_smooth_direction_items; case SCULPT_TOOL_MASK: switch ((BrushMaskTool)me->mask_tool) { case BRUSH_MASK_DRAW: @@ -1967,6 +1981,20 @@ static void rna_def_brush(BlenderRNA *brna) {0, NULL, 0, NULL, NULL}, }; + static const EnumPropertyItem brush_deformation_target_items[] = { + {BRUSH_DEFORM_TARGET_GEOMETRY, + "GEOMETRY", + 0, + "Geometry", + "Brush deformation displaces the vertices of the mesh"}, + {BRUSH_DEFORM_TARGET_CLOTH_SIM, + "CLOTH_SIM", + 0, + "Cloth Simulation", + "Brush deforms the mesh by deforming the constraints of a cloth simulation"}, + {0, NULL, 0, NULL, NULL}, + }; + static const EnumPropertyItem brush_elastic_deform_type_items[] = { {BRUSH_ELASTIC_DEFORM_GRAB, "GRAB", 0, "Grab", ""}, {BRUSH_ELASTIC_DEFORM_GRAB_BISCALE, "GRAB_BISCALE", 0, "Bi-scale Grab", ""}, @@ -2195,6 +2223,12 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Curve Preset", ""); RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "deform_target", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, brush_deformation_target_items); + RNA_def_property_ui_text( + prop, "Deformation Target", "How the deformation of the brush will affect the object"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "elastic_deform_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, brush_elastic_deform_type_items); RNA_def_property_ui_text(prop, "Deformation", "Deformation type that is used in the brush"); diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index c8d16ab65cc..9bcf2b81557 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -106,7 +106,7 @@ static const EnumPropertyItem rna_enum_keyframe_type_items[] = { }; static const EnumPropertyItem rna_enum_onion_keyframe_type_items[] = { - {-1, "ALL", ICON_ACTION, "All Types", "Include all Keyframe types"}, + {-1, "ALL", 0, "All", "Include all Keyframe types"}, {BEZT_KEYTYPE_KEYFRAME, "KEYFRAME", ICON_KEYTYPE_KEYFRAME_VEC, diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 8045279eef2..6254e40a410 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -455,10 +455,16 @@ void RNA_def_main_cachefiles(BlenderRNA *brna, PropertyRNA *cprop); void RNA_def_main_paintcurves(BlenderRNA *brna, PropertyRNA *cprop); void RNA_def_main_workspaces(BlenderRNA *brna, PropertyRNA *cprop); void RNA_def_main_lightprobes(BlenderRNA *brna, PropertyRNA *cprop); +#ifdef WITH_PARTICLE_NODES void RNA_def_main_hairs(BlenderRNA *brna, PropertyRNA *cprop); +#endif +#ifdef WITH_HAIR_NODES void RNA_def_main_pointclouds(BlenderRNA *brna, PropertyRNA *cprop); +#endif void RNA_def_main_volumes(BlenderRNA *brna, PropertyRNA *cprop); +#ifdef WITH_PARTICLE_NODES void RNA_def_main_simulations(BlenderRNA *brna, PropertyRNA *cprop); +#endif /* ID Properties */ diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c index 97702b06b6f..d83fca69278 100644 --- a/source/blender/makesrna/intern/rna_main.c +++ b/source/blender/makesrna/intern/rna_main.c @@ -109,7 +109,9 @@ RNA_MAIN_LISTBASE_FUNCS_DEF(collections) RNA_MAIN_LISTBASE_FUNCS_DEF(curves) RNA_MAIN_LISTBASE_FUNCS_DEF(fonts) RNA_MAIN_LISTBASE_FUNCS_DEF(gpencils) +# ifdef WITH_HAIR_NODES RNA_MAIN_LISTBASE_FUNCS_DEF(hairs) +# endif RNA_MAIN_LISTBASE_FUNCS_DEF(images) RNA_MAIN_LISTBASE_FUNCS_DEF(lattices) RNA_MAIN_LISTBASE_FUNCS_DEF(libraries) @@ -126,11 +128,15 @@ RNA_MAIN_LISTBASE_FUNCS_DEF(objects) RNA_MAIN_LISTBASE_FUNCS_DEF(paintcurves) RNA_MAIN_LISTBASE_FUNCS_DEF(palettes) RNA_MAIN_LISTBASE_FUNCS_DEF(particles) +# ifdef WITH_PARTICLE_NODES RNA_MAIN_LISTBASE_FUNCS_DEF(pointclouds) +# endif RNA_MAIN_LISTBASE_FUNCS_DEF(scenes) RNA_MAIN_LISTBASE_FUNCS_DEF(screens) RNA_MAIN_LISTBASE_FUNCS_DEF(shapekeys) +# ifdef WITH_PARTICLE_NODES RNA_MAIN_LISTBASE_FUNCS_DEF(simulations) +# endif RNA_MAIN_LISTBASE_FUNCS_DEF(sounds) RNA_MAIN_LISTBASE_FUNCS_DEF(speakers) RNA_MAIN_LISTBASE_FUNCS_DEF(texts) @@ -384,25 +390,31 @@ void RNA_def_main(BlenderRNA *brna) "LightProbes", "LightProbe data-blocks", RNA_def_main_lightprobes}, +# ifdef WITH_HAIR_NODES {"hairs", "Hair", "rna_Main_hairs_begin", "Hairs", "Hair data-blocks", RNA_def_main_hairs}, +# endif +# ifdef WITH_PARTICLE_NODES {"pointclouds", "PointCloud", "rna_Main_pointclouds_begin", "Point Clouds", "Point cloud data-blocks", RNA_def_main_pointclouds}, +# endif {"volumes", "Volume", "rna_Main_volumes_begin", "Volumes", "Volume data-blocks", RNA_def_main_volumes}, +# ifdef WITH_PARTICLE_NODES {"simulations", "Simulation", "rna_Main_simulations_begin", "Simulations", "Simulation data-blocks", RNA_def_main_simulations}, +# endif {NULL, NULL, NULL, NULL, NULL, NULL}, }; diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 990a5412093..7c941ddb524 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -708,6 +708,7 @@ static bGPdata *rna_Main_gpencils_new(Main *bmain, const char *name) return gpd; } +# ifdef WITH_HAIR_NODES static Hair *rna_Main_hairs_new(Main *bmain, const char *name) { char safe_name[MAX_ID_NAME - 2]; @@ -717,7 +718,9 @@ static Hair *rna_Main_hairs_new(Main *bmain, const char *name) id_us_min(&hair->id); return hair; } +# endif +# ifdef WITH_PARTICLE_NODES static PointCloud *rna_Main_pointclouds_new(Main *bmain, const char *name) { char safe_name[MAX_ID_NAME - 2]; @@ -727,6 +730,7 @@ static PointCloud *rna_Main_pointclouds_new(Main *bmain, const char *name) id_us_min(&pointcloud->id); return pointcloud; } +# endif static Volume *rna_Main_volumes_new(Main *bmain, const char *name) { @@ -738,6 +742,7 @@ static Volume *rna_Main_volumes_new(Main *bmain, const char *name) return volume; } +# ifdef WITH_PARTICLE_NODES static Simulation *rna_Main_simulations_new(Main *bmain, const char *name) { char safe_name[MAX_ID_NAME - 2]; @@ -747,6 +752,7 @@ static Simulation *rna_Main_simulations_new(Main *bmain, const char *name) id_us_min(&simulation->id); return simulation; } +# endif /* tag functions, all the same */ # define RNA_MAIN_ID_TAG_FUNCS_DEF(_func_name, _listbase_name, _id_type) \ @@ -790,10 +796,16 @@ RNA_MAIN_ID_TAG_FUNCS_DEF(cachefiles, cachefiles, ID_CF) RNA_MAIN_ID_TAG_FUNCS_DEF(paintcurves, paintcurves, ID_PC) RNA_MAIN_ID_TAG_FUNCS_DEF(workspaces, workspaces, ID_WS) RNA_MAIN_ID_TAG_FUNCS_DEF(lightprobes, lightprobes, ID_LP) +# ifdef WITH_HAIR_NODES RNA_MAIN_ID_TAG_FUNCS_DEF(hairs, hairs, ID_HA) +# endif +# ifdef WITH_PARTICLE_NODES RNA_MAIN_ID_TAG_FUNCS_DEF(pointclouds, pointclouds, ID_PT) +# endif RNA_MAIN_ID_TAG_FUNCS_DEF(volumes, volumes, ID_VO) +# ifdef WITH_PARTICLE_NODES RNA_MAIN_ID_TAG_FUNCS_DEF(simulations, simulations, ID_SIM) +# endif # undef RNA_MAIN_ID_TAG_FUNCS_DEF @@ -2194,6 +2206,7 @@ void RNA_def_main_lightprobes(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); } +# ifdef WITH_HAIR_NODES void RNA_def_main_hairs(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; @@ -2237,7 +2250,9 @@ void RNA_def_main_hairs(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); } +# endif +# ifdef WITH_PARTICLE_NODES void RNA_def_main_pointclouds(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; @@ -2284,6 +2299,7 @@ void RNA_def_main_pointclouds(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); } +# endif void RNA_def_main_volumes(BlenderRNA *brna, PropertyRNA *cprop) { @@ -2329,6 +2345,7 @@ void RNA_def_main_volumes(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); } +# ifdef WITH_PARTICLE_NODES void RNA_def_main_simulations(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; @@ -2368,5 +2385,6 @@ void RNA_def_main_simulations(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); } +# endif #endif diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index f95899262d3..0338a094d14 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -723,7 +723,9 @@ static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr) case eModifierType_WeightedNormal: return &RNA_WeightedNormalModifier; case eModifierType_Simulation: +# ifdef WITH_PARTICLE_NODES return &RNA_SimulationModifier; +# endif /* Default */ case eModifierType_Fluidsim: /* deprecated */ case eModifierType_None: @@ -1630,6 +1632,7 @@ static void rna_ParticleInstanceModifier_particle_system_set(PointerRNA *ptr, CLAMP_MIN(psmd->psys, 1); } +# ifdef WITH_PARTICLE_NODES static void rna_SimulationModifier_simulation_update(Main *bmain, Scene *scene, PointerRNA *ptr) { SimulationModifierData *smd = ptr->data; @@ -1672,6 +1675,7 @@ static void rna_SimulationModifier_data_path_set(PointerRNA *ptr, const char *va smd->data_path = NULL; } } +# endif /** * Special set callback that just changes the first bit of the expansion flag. @@ -2076,6 +2080,14 @@ static void rna_def_modifier_multires(BlenderRNA *brna) prop, "Use Custom Normals", "Interpolates existing custom normals to resulting mesh"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "use_sculpt_base_mesh", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", eMultiresModifierFlag_UseSculptBaseMesh); + RNA_def_property_ui_text(prop, + "Sculpt Base Mesh", + "Make Sculpt Mode tools deform the base mesh while previewing the " + "displacement of higher subdivision levels"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + RNA_define_lib_overridable(false); } @@ -6999,6 +7011,7 @@ static void rna_def_modifier_weightednormal(BlenderRNA *brna) RNA_define_lib_overridable(false); } +# ifdef WITH_PARTICLE_NODES static void rna_def_modifier_simulation(BlenderRNA *brna) { StructRNA *srna; @@ -7027,6 +7040,7 @@ static void rna_def_modifier_simulation(BlenderRNA *brna) RNA_define_lib_overridable(false); } +# endif void RNA_def_modifier(BlenderRNA *brna) { @@ -7156,7 +7170,9 @@ void RNA_def_modifier(BlenderRNA *brna) rna_def_modifier_meshseqcache(brna); rna_def_modifier_surfacedeform(brna); rna_def_modifier_weightednormal(brna); +# ifdef WITH_PARTICLE_NODES rna_def_modifier_simulation(brna); +# endif } #endif diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 08ca3f16b6d..39e1f17d33d 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -570,9 +570,17 @@ static StructRNA *rna_Object_data_typef(PointerRNA *ptr) case OB_GPENCIL: return &RNA_GreasePencil; case OB_HAIR: +# ifdef WITH_HAIR_NODES return &RNA_Hair; +# else + return &RNA_ID; +# endif case OB_POINTCLOUD: +# ifdef WITH_PARTICLE_NODES return &RNA_PointCloud; +# else + return &RNA_ID; +# endif case OB_VOLUME: return &RNA_Volume; default: diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 5d266e910ad..3ec7963a81e 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -924,6 +924,23 @@ static void rna_Scene_volume_update(Main *UNUSED(bmain), Scene *UNUSED(scene), P DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_VOLUME | ID_RECALC_SEQUENCER_STRIPS); } +static const char *rna_Scene_statistics_string_get(Scene *scene, + Main *bmain, + ReportList *reports, + ViewLayer *view_layer) +{ + if (BKE_scene_find_from_view_layer(bmain, view_layer) != scene) { + BKE_reportf(reports, + RPT_ERROR, + "View Layer '%s' not found in scene '%s'", + view_layer->name, + scene->id.name + 2); + return ""; + } + + return ED_info_statistics_string(bmain, scene, view_layer); +} + static void rna_Scene_framelen_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr)) { scene->r.framelen = (float)scene->r.framapto / (float)scene->r.images; @@ -7277,6 +7294,9 @@ void RNA_def_scene(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + FunctionRNA *func; + PropertyRNA *parm; + static const EnumPropertyItem audio_distance_model_items[] = { {0, "NONE", 0, "None", "No distance attenuation"}, {1, "INVERSE", 0, "Inverse", "Inverse distance model"}, @@ -7668,6 +7688,14 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE, NULL); RNA_def_property_update(prop, NC_SCENE, "rna_Scene_volume_update"); + /* Statistics */ + func = RNA_def_function(srna, "statistics", "rna_Scene_statistics_string_get"); + RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS); + parm = RNA_def_pointer(func, "view_layer", "ViewLayer", "View Layer", ""); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); + parm = RNA_def_string(func, "statistics", NULL, 0, "Statistics", ""); + RNA_def_function_return(func, parm); + /* Grease Pencil */ prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "gpd"); diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index 06c73fbb19c..d258677c606 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -73,7 +73,7 @@ static void rna_Scene_frame_set(Scene *scene, Main *bmain, int frame, float subf for (ViewLayer *view_layer = scene->view_layers.first; view_layer != NULL; view_layer = view_layer->next) { Depsgraph *depsgraph = BKE_scene_get_depsgraph(bmain, scene, view_layer, true); - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); } # ifdef WITH_PYTHON diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c index fb2a60db0fd..ab84dcb0aba 100644 --- a/source/blender/makesrna/intern/rna_screen.c +++ b/source/blender/makesrna/intern/rna_screen.c @@ -288,9 +288,11 @@ static void rna_View2D_view_to_region( } } -static const char *rna_Screen_statusbar_info_get(struct bScreen *screen, Main *bmain, bContext *C) +static const char *rna_Screen_statusbar_info_get(struct bScreen *UNUSED(screen), + Main *bmain, + bContext *C) { - return ED_info_statusbar_string(bmain, screen, C); + return ED_info_statusbar_string(bmain, CTX_data_scene(C), CTX_data_view_layer(C)); } #else diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 0cfc6fd569c..629dc104ab5 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -637,6 +637,8 @@ static void rna_Sequence_name_set(PointerRNA *ptr, const char *value) char oldname[sizeof(seq->name)]; AnimData *adt; + BKE_sequencer_prefetch_stop(scene); + /* make a copy of the old name first */ BLI_strncpy(oldname, seq->name + 2, sizeof(seq->name) - 2); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 9f259aba0c7..03a70be6def 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1297,15 +1297,13 @@ static const EnumPropertyItem *rna_3DViewShading_render_pass_itemf(bContext *C, { Scene *scene = CTX_data_scene(C); - const bool ao_enabled = scene->eevee.flag & SCE_EEVEE_GTAO_ENABLED; const bool bloom_enabled = scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED; int totitem = 0; EnumPropertyItem *result = NULL; for (int i = 0; rna_enum_view3dshading_render_pass_type_items[i].identifier != NULL; i++) { const EnumPropertyItem *item = &rna_enum_view3dshading_render_pass_type_items[i]; - if (!((!ao_enabled && item->value == EEVEE_RENDER_PASS_AO) || - (!bloom_enabled && + if (!((!bloom_enabled && (item->value == EEVEE_RENDER_PASS_BLOOM || STREQ(item->name, "Effects"))))) { RNA_enum_item_add(&result, &totitem, item); } @@ -1321,9 +1319,6 @@ static int rna_3DViewShading_render_pass_get(PointerRNA *ptr) eViewLayerEEVEEPassType result = shading->render_pass; Scene *scene = rna_3DViewShading_scene(ptr); - if (result == EEVEE_RENDER_PASS_AO && ((scene->eevee.flag & SCE_EEVEE_GTAO_ENABLED) == 0)) { - result = EEVEE_RENDER_PASS_COMBINED; - } if (result == EEVEE_RENDER_PASS_BLOOM && ((scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) == 0)) { result = EEVEE_RENDER_PASS_COMBINED; } @@ -2122,6 +2117,7 @@ static void rna_SpaceNodeEditor_node_tree_update(const bContext *C, PointerRNA * ED_node_tree_update(C); } +# ifdef WITH_PARTICLE_NODES static PointerRNA rna_SpaceNodeEditor_simulation_get(PointerRNA *ptr) { SpaceNode *snode = (SpaceNode *)ptr->data; @@ -2153,6 +2149,7 @@ static void rna_SpaceNodeEditor_simulation_set(PointerRNA *ptr, } snode->id = &sim->id; } +# endif static int rna_SpaceNodeEditor_tree_type_get(PointerRNA *ptr) { @@ -4796,7 +4793,7 @@ static void rna_def_space_sequencer(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Waveform Displaying", "How Waveforms are drawn"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); - prop = RNA_def_property(srna, "zoom_to_fit", PROP_BOOLEAN, PROP_NONE); + prop = RNA_def_property(srna, "use_zoom_to_fit", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_ZOOM_TO_FIT); RNA_def_property_ui_text( prop, "Zoom to Fit", "Automatically zoom preview image to make it fully fit the region"); @@ -6213,6 +6210,7 @@ static void rna_def_space_node(BlenderRNA *brna) RNA_def_property_ui_text( prop, "ID From", "Data-block from which the edited data-block is linked"); +# ifdef WITH_PARTICLE_NODES prop = RNA_def_property(srna, "simulation", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "Simulation"); @@ -6223,6 +6221,7 @@ static void rna_def_space_node(BlenderRNA *brna) NULL, NULL); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE, NULL); +# endif prop = RNA_def_property(srna, "path", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "treepath", NULL); diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index 7853bc4acac..9ced297bb48 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -238,7 +238,9 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* Needed when rendering or baking will in sculpt mode. */ const bool for_render = (ctx->flag & MOD_APPLY_RENDER) != 0; - if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco && !for_render) { + const bool sculpt_base_mesh = mmd->flags & eMultiresModifierFlag_UseSculptBaseMesh; + + if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco && !for_render && !sculpt_base_mesh) { /* NOTE: CCG takes ownership over Subdiv. */ result = multires_as_ccg(mmd, ctx, mesh, subdiv); result->runtime.subdiv_ccg_tot_level = mmd->totlvl; @@ -341,6 +343,12 @@ static void panel_draw(const bContext *C, Panel *panel) uiItemR(col, &ptr, "sculpt_levels", 0, IFACE_("Sculpt"), ICON_NONE); uiItemR(col, &ptr, "render_levels", 0, IFACE_("Render"), ICON_NONE); + const bool is_sculpt_mode = CTX_data_active_object(C)->mode & OB_MODE_SCULPT; + uiBlock *block = uiLayoutGetBlock(panel->layout); + UI_block_lock_set(block, !is_sculpt_mode, IFACE_("Sculpt Base Mesh")); + uiItemR(col, &ptr, "use_sculpt_base_mesh", 0, IFACE_("Sculpt Base Mesh"), ICON_NONE); + UI_block_lock_clear(block); + uiItemR(layout, &ptr, "show_only_control_edges", 0, NULL, ICON_NONE); modifier_panel_end(layout, &ptr); diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index ea0c63da1b0..4ef1b19dc64 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -219,7 +219,7 @@ static void deformVerts(ModifierData *md, psmd->totdmedge = psmd->mesh_final->totedge; psmd->totdmface = psmd->mesh_final->totface; - if (!(ctx->object->transflag & OB_NO_PSYS_UPDATE)) { + { struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); psmd->flag &= ~eParticleSystemFlag_psys_updated; particle_system_update( diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h index 7bcf96116b9..e1e0d01055a 100644 --- a/source/blender/python/BPY_extern.h +++ b/source/blender/python/BPY_extern.h @@ -50,12 +50,6 @@ void BPY_pyconstraint_update(struct Object *owner, struct bConstraint *con); int BPY_is_pyconstraint(struct Text *text); // void BPY_free_pyconstraint_links(struct Text *text); -void BPY_python_start(int argc, const char **argv); -void BPY_python_end(void); -void BPY_python_reset(struct bContext *C); -void BPY_python_use_system_env(void); -void BPY_python_backtrace(/* FILE */ void *file); - /* global interpreter lock */ typedef void *BPy_ThreadStatePtr; @@ -73,40 +67,6 @@ void BPY_thread_restore(BPy_ThreadStatePtr tstate); } \ (void)0 -bool BPY_execute_filepath(struct bContext *C, const char *filepath, struct ReportList *reports); -bool BPY_execute_text(struct bContext *C, - struct Text *text, - struct ReportList *reports, - const bool do_jump); - -bool BPY_execute_string_as_number(struct bContext *C, - const char *imports[], - const char *expr, - const char *report_prefix, - double *r_value); -bool BPY_execute_string_as_intptr(struct bContext *C, - const char *imports[], - const char *expr, - 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 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 char *report_prefix, - char **r_value); - -bool BPY_execute_string_ex(struct bContext *C, - const char *imports[], - const char *expr, - bool use_eval); -bool BPY_execute_string(struct bContext *C, const char *imports[], const char *expr); - void BPY_text_free_code(struct Text *text); void BPY_modules_update( struct bContext *C); // XXX - annoying, need this for pointers that get out of date diff --git a/source/blender/gpu/intern/gpu_shader_private.h b/source/blender/python/BPY_extern_python.h index 0f89fbda737..348f6986863 100644 --- a/source/blender/gpu/intern/gpu_shader_private.h +++ b/source/blender/python/BPY_extern_python.h @@ -15,40 +15,29 @@ */ /** \file - * \ingroup gpu + * \ingroup python + * + * Functionality relating to Python setup & tear down. */ #pragma once -#include "GPU_shader_interface.h" +struct bContext; #ifdef __cplusplus extern "C" { #endif -struct GPUShader { - /** Handle for full program (links shader stages below). */ - GLuint program; - - /** Handle for vertex shader. */ - GLuint vertex; - /** Handle for geometry shader. */ - GLuint geometry; - /** Handle for fragment shader. */ - GLuint fragment; - - /** Cached uniform & attribute interface for shader. */ - GPUShaderInterface *interface; - - int feedback_transform_type; -#ifndef NDEBUG - char name[64]; -#endif -}; +/* For 'FILE'. */ +#include <stdio.h> -/* XXX do not use it. Special hack to use OCIO with batch API. */ -GPUShader *immGetShader(void); +/* bpy_interface.c */ +void BPY_python_start(int argc, const char **argv); +void BPY_python_end(void); +void BPY_python_reset(struct bContext *C); +void BPY_python_use_system_env(void); +void BPY_python_backtrace(FILE *file); #ifdef __cplusplus -} +} /* extern "C" */ #endif diff --git a/source/blender/python/BPY_extern_run.h b/source/blender/python/BPY_extern_run.h new file mode 100644 index 00000000000..5f12ada4ff2 --- /dev/null +++ b/source/blender/python/BPY_extern_run.h @@ -0,0 +1,70 @@ +/* + * 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 python + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "BLI_sys_types.h" + +struct ReportList; +struct Text; +struct bContext; + +/* bpy_interface_run.c */ +bool BPY_run_filepath(struct bContext *C, const char *filepath, struct ReportList *reports); +bool BPY_run_text(struct bContext *C, + struct Text *text, + struct ReportList *reports, + const bool do_jump); + +/* Use the 'eval' for simple single-line expressions, + * otherwise 'exec' for full multi-line scripts. */ +bool BPY_run_string_exec(struct bContext *C, const char *imports[], const char *expr); +bool BPY_run_string_eval(struct bContext *C, const char *imports[], const char *expr); + +/* Run, evaluating to fixed type result. */ +bool BPY_run_string_as_number(struct bContext *C, + const char *imports[], + const char *expr, + const char *report_prefix, + double *r_value); +bool BPY_run_string_as_intptr(struct bContext *C, + const char *imports[], + const char *expr, + const char *report_prefix, + intptr_t *r_value); +bool BPY_run_string_as_string_and_size(struct bContext *C, + const char *imports[], + const char *expr, + const char *report_prefix, + char **r_value, + size_t *r_value_size); +bool BPY_run_string_as_string(struct bContext *C, + const char *imports[], + const char *expr, + const char *report_prefix, + char **r_value); + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index e39b5faf3c4..04bceb17c20 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -1134,7 +1134,7 @@ static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args, PyObject return NULL; } - me_eval = mesh_create_eval_final_render(depsgraph, scene_eval, ob_eval, &data_masks); + me_eval = mesh_create_eval_final(depsgraph, scene_eval, ob_eval, &data_masks); } else { if (use_cage) { diff --git a/source/blender/python/generic/CMakeLists.txt b/source/blender/python/generic/CMakeLists.txt index 785c1d66407..dce6a7e1c91 100644 --- a/source/blender/python/generic/CMakeLists.txt +++ b/source/blender/python/generic/CMakeLists.txt @@ -32,18 +32,18 @@ set(INC_SYS set(SRC bgl.c + bl_math_py_api.c blf_py_api.c bpy_threads.c idprop_py_api.c imbuf_py_api.c - bl_math_py_api.c py_capi_utils.c bgl.h + bl_math_py_api.h blf_py_api.h idprop_py_api.h imbuf_py_api.h - bl_math_py_api.h py_capi_utils.h # header-only diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index caae5c4e122..838a1239210 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -382,20 +382,6 @@ void PyC_StackSpit(void) PyGILState_Release(gilstate); } -void PyC_StackPrint(/* FILE */ void *fp) -{ - PyThreadState *tstate = PyGILState_GetThisThreadState(); - if (tstate != NULL && tstate->frame != NULL) { - PyFrameObject *frame = tstate->frame; - do { - const int line = PyCode_Addr2Line(frame->f_code, frame->f_lasti); - const char *filename = _PyUnicode_AsString(frame->f_code->co_filename); - const char *funcname = _PyUnicode_AsString(frame->f_code->co_name); - fprintf(fp, " File \"%s\", line %d in %s\n", filename, line, funcname); - } while ((frame = frame->f_back)); - } -} - /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h index dde450012d0..e8b2e8ff502 100644 --- a/source/blender/python/generic/py_capi_utils.h +++ b/source/blender/python/generic/py_capi_utils.h @@ -28,7 +28,6 @@ void PyC_ObSpit(const char *name, PyObject *var); void PyC_ObSpitStr(char *result, size_t result_len, PyObject *var); void PyC_LineSpit(void); void PyC_StackSpit(void); -void PyC_StackPrint(/* FILE */ void *fp); PyObject *PyC_ExceptionBuffer(void); PyObject *PyC_ExceptionBuffer_Simple(void); PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...); diff --git a/source/blender/python/gpu/gpu_py_shader.c b/source/blender/python/gpu/gpu_py_shader.c index 165286c3661..c1a6ce09d37 100644 --- a/source/blender/python/gpu/gpu_py_shader.c +++ b/source/blender/python/gpu/gpu_py_shader.c @@ -604,7 +604,8 @@ PyDoc_STRVAR( " ``GPU_ATI``, ``GPU_NVIDIA`` and ``GPU_INTEL``.\n" "\n" " The following extensions are enabled by default if supported by the GPU:\n" - " ``GL_ARB_texture_gather`` and ``GL_ARB_texture_query_lod``.\n" + " ``GL_ARB_texture_gather``, ``GL_ARB_texture_cube_map_array`` and " + "``GL_ARB_shader_draw_parameters``.\n" "\n" " To debug shaders, use the --debug-gpu-shaders command line option" " to see full GLSL shader compilation and linking errors.\n" diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt index 769618005af..44949c478cc 100644 --- a/source/blender/python/intern/CMakeLists.txt +++ b/source/blender/python/intern/CMakeLists.txt @@ -62,6 +62,7 @@ set(SRC bpy_gizmo_wrap.c bpy_interface.c bpy_interface_atexit.c + bpy_interface_run.c bpy_intern_string.c bpy_library_load.c bpy_library_write.c diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index c311041e4cb..b0b36baa839 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -25,6 +25,7 @@ */ #include <Python.h> +#include <frameobject.h> #include "MEM_guardedalloc.h" @@ -62,6 +63,8 @@ #endif #include "BPY_extern.h" +#include "BPY_extern_python.h" +#include "BPY_extern_run.h" #include "../generic/py_capi_utils.h" @@ -426,180 +429,19 @@ void BPY_python_use_system_env(void) py_use_system_env = true; } -static void python_script_error_jump_text(struct Text *text) -{ - int lineno; - int offset; - python_script_error_jump(text->id.name + 2, &lineno, &offset); - if (lineno != -1) { - /* select the line with the error */ - txt_move_to(text, lineno - 1, INT_MAX, false); - txt_move_to(text, lineno - 1, offset, true); - } -} - -void BPY_python_backtrace(/* FILE */ void *fp) +void BPY_python_backtrace(FILE *fp) { fputs("\n# Python backtrace\n", fp); - PyC_StackPrint(fp); -} - -/* super annoying, undo _PyModule_Clear(), bug [#23871] */ -#define PYMODULE_CLEAR_WORKAROUND - -#ifdef PYMODULE_CLEAR_WORKAROUND -/* bad!, we should never do this, but currently only safe way I could find to keep namespace. - * from being cleared. - campbell */ -typedef struct { - PyObject_HEAD PyObject *md_dict; - /* omit other values, we only want the dict. */ -} PyModuleObject; -#endif - -/* returns a dummy filename for a textblock so we can tell what file a text block comes from */ -static void bpy_text_filename_get(char *fn, const Main *bmain, size_t fn_len, const Text *text) -{ - BLI_snprintf(fn, fn_len, "%s%c%s", ID_BLEND_PATH(bmain, &text->id), SEP, text->id.name + 2); -} - -static bool python_script_exec( - bContext *C, const char *fn, struct Text *text, struct ReportList *reports, const bool do_jump) -{ - Main *bmain_old = CTX_data_main(C); - PyObject *main_mod = NULL; - PyObject *py_dict = NULL, *py_result = NULL; - PyGILState_STATE gilstate; - - BLI_assert(fn || text); - - if (fn == NULL && text == NULL) { - return 0; - } - - bpy_context_set(C, &gilstate); - - PyC_MainModule_Backup(&main_mod); - - if (text) { - char fn_dummy[FILE_MAXDIR]; - bpy_text_filename_get(fn_dummy, bmain_old, sizeof(fn_dummy), text); - - if (text->compiled == NULL) { /* if it wasn't already compiled, do it now */ - char *buf; - PyObject *fn_dummy_py; - - fn_dummy_py = PyC_UnicodeFromByte(fn_dummy); - - buf = txt_to_buf(text, NULL); - text->compiled = Py_CompileStringObject(buf, fn_dummy_py, Py_file_input, NULL, -1); - MEM_freeN(buf); - - Py_DECREF(fn_dummy_py); - - if (PyErr_Occurred()) { - if (do_jump) { - python_script_error_jump_text(text); - } - BPY_text_free_code(text); - } - } - - if (text->compiled) { - py_dict = PyC_DefaultNameSpace(fn_dummy); - py_result = PyEval_EvalCode(text->compiled, py_dict, py_dict); - } - } - else { - FILE *fp = BLI_fopen(fn, "r"); - - if (fp) { - py_dict = PyC_DefaultNameSpace(fn); - -#ifdef _WIN32 - /* Previously we used PyRun_File to run directly the code on a FILE - * object, but as written in the Python/C API Ref Manual, chapter 2, - * 'FILE structs for different C libraries can be different and - * incompatible'. - * So now we load the script file data to a buffer. - * - * Note on use of 'globals()', it's important not copy the dictionary because - * tools may inspect 'sys.modules["__main__"]' for variables defined in the code - * where using a copy of 'globals()' causes code execution - * to leave the main namespace untouched. see: T51444 - * - * This leaves us with the problem of variables being included, - * currently this is worked around using 'dict.__del__' it's ugly but works. - */ - { - const char *pystring = - "with open(__file__, 'rb') as f:" - "exec(compile(f.read(), __file__, 'exec'), globals().__delitem__('f') or globals())"; - - fclose(fp); - - py_result = PyRun_String(pystring, Py_file_input, py_dict, py_dict); - } -#else - py_result = PyRun_File(fp, fn, Py_file_input, py_dict, py_dict); - fclose(fp); -#endif - } - else { - PyErr_Format( - PyExc_IOError, "Python file \"%s\" could not be opened: %s", fn, strerror(errno)); - py_result = NULL; - } - } - - if (!py_result) { - if (text) { - if (do_jump) { - /* ensure text is valid before use, the script may have freed its self */ - Main *bmain_new = CTX_data_main(C); - if ((bmain_old == bmain_new) && (BLI_findindex(&bmain_new->texts, text) != -1)) { - python_script_error_jump_text(text); - } - } - } - BPy_errors_to_report(reports); + PyThreadState *tstate = PyGILState_GetThisThreadState(); + if (tstate != NULL && tstate->frame != NULL) { + PyFrameObject *frame = tstate->frame; + do { + const int line = PyCode_Addr2Line(frame->f_code, frame->f_lasti); + const char *filename = _PyUnicode_AsString(frame->f_code->co_filename); + const char *funcname = _PyUnicode_AsString(frame->f_code->co_name); + fprintf(fp, " File \"%s\", line %d in %s\n", filename, line, funcname); + } while ((frame = frame->f_back)); } - else { - Py_DECREF(py_result); - } - - if (py_dict) { -#ifdef PYMODULE_CLEAR_WORKAROUND - PyModuleObject *mmod = (PyModuleObject *)PyDict_GetItem(PyImport_GetModuleDict(), - bpy_intern_str___main__); - PyObject *dict_back = mmod->md_dict; - /* freeing the module will clear the namespace, - * gives problems running classes defined in this namespace being used later. */ - mmod->md_dict = NULL; - Py_DECREF(dict_back); -#endif - -#undef PYMODULE_CLEAR_WORKAROUND - } - - PyC_MainModule_Restore(main_mod); - - bpy_context_clear(C, &gilstate); - - return (py_result != NULL); -} - -/* Can run a file or text block */ -bool BPY_execute_filepath(bContext *C, const char *filepath, struct ReportList *reports) -{ - return python_script_exec(C, filepath, NULL, reports, false); -} - -bool BPY_execute_text(bContext *C, - struct Text *text, - struct ReportList *reports, - const bool do_jump) -{ - return python_script_exec(C, NULL, text, reports, do_jump); } void BPY_DECREF(void *pyob_ptr) @@ -620,177 +462,6 @@ void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr) PyGILState_Release(gilstate); } -/** - * \return success - */ -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; - - if (!r_value || !expr) { - return -1; - } - - if (expr[0] == '\0') { - *r_value = 0.0; - return ok; - } - - bpy_context_set(C, &gilstate); - - ok = PyC_RunString_AsNumber(imports, expr, "<expr as number>", r_value); - - if (ok == false) { - if (report_prefix != NULL) { - BPy_errors_to_report_ex(CTX_wm_reports(C), report_prefix, false, false); - } - else { - PyErr_Clear(); - } - } - - bpy_context_clear(C, &gilstate); - - return ok; -} - -/** - * \return success - */ -bool BPY_execute_string_as_string_and_size(bContext *C, - const char *imports[], - const char *expr, - const char *report_prefix, - char **r_value, - size_t *r_value_size) -{ - BLI_assert(r_value && expr); - PyGILState_STATE gilstate; - bool ok = true; - - if (expr[0] == '\0') { - *r_value = NULL; - return ok; - } - - bpy_context_set(C, &gilstate); - - ok = PyC_RunString_AsStringAndSize(imports, expr, "<expr as str>", r_value, r_value_size); - - if (ok == false) { - if (report_prefix != NULL) { - BPy_errors_to_report_ex(CTX_wm_reports(C), false, false, report_prefix); - } - else { - PyErr_Clear(); - } - } - - bpy_context_clear(C, &gilstate); - - return ok; -} - -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, report_prefix, r_value, &value_dummy_size); -} - -/** - * Support both int and pointers. - * - * \return success - */ -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; - bool ok = true; - - if (expr[0] == '\0') { - *r_value = 0; - return ok; - } - - bpy_context_set(C, &gilstate); - - ok = PyC_RunString_AsIntPtr(imports, expr, "<expr as intptr>", r_value); - - if (ok == false) { - if (report_prefix != NULL) { - BPy_errors_to_report_ex(CTX_wm_reports(C), report_prefix, false, false); - } - else { - PyErr_Clear(); - } - } - - bpy_context_clear(C, &gilstate); - - return ok; -} - -bool BPY_execute_string_ex(bContext *C, const char *imports[], const char *expr, bool use_eval) -{ - BLI_assert(expr); - PyGILState_STATE gilstate; - PyObject *main_mod = NULL; - PyObject *py_dict, *retval; - bool ok = true; - - if (expr[0] == '\0') { - return ok; - } - - bpy_context_set(C, &gilstate); - - PyC_MainModule_Backup(&main_mod); - - py_dict = PyC_DefaultNameSpace("<blender string>"); - - if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) { - Py_DECREF(py_dict); - retval = NULL; - } - else { - retval = PyRun_String(expr, use_eval ? Py_eval_input : Py_file_input, py_dict, py_dict); - } - - if (retval == NULL) { - ok = false; - BPy_errors_to_report(CTX_wm_reports(C)); - } - else { - Py_DECREF(retval); - } - - PyC_MainModule_Restore(main_mod); - - bpy_context_clear(C, &gilstate); - - return ok; -} - -bool BPY_execute_string(bContext *C, const char *imports[], const char *expr) -{ - return BPY_execute_string_ex(C, imports, expr, true); -} - void BPY_modules_load_user(bContext *C) { PyGILState_STATE gilstate; @@ -823,7 +494,7 @@ void BPY_modules_load_user(bContext *C) } } else { - BPY_execute_text(C, text, NULL, false); + BPY_run_text(C, text, NULL, false); /* Check if the script loaded a new file. */ if (bmain != CTX_data_main(C)) { diff --git a/source/blender/python/intern/bpy_interface_run.c b/source/blender/python/intern/bpy_interface_run.c new file mode 100644 index 00000000000..a7593ae7d79 --- /dev/null +++ b/source/blender/python/intern/bpy_interface_run.c @@ -0,0 +1,422 @@ +/* + * 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 pythonintern + */ + +#include <stdio.h> + +#include <Python.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_fileops.h" +#include "BLI_listbase.h" +#include "BLI_path_util.h" +#include "BLI_string.h" + +#include "BKE_context.h" +#include "BKE_main.h" +#include "BKE_text.h" + +#include "DNA_text_types.h" + +#include "BPY_extern.h" +#include "BPY_extern_run.h" + +#include "bpy_capi_utils.h" +#include "bpy_intern_string.h" +#include "bpy_traceback.h" + +#include "../generic/py_capi_utils.h" + +/* -------------------------------------------------------------------- */ +/** \name Private Utilities + * \{ */ + +static void python_script_error_jump_text(Text *text) +{ + int lineno; + int offset; + python_script_error_jump(text->id.name + 2, &lineno, &offset); + if (lineno != -1) { + /* select the line with the error */ + txt_move_to(text, lineno - 1, INT_MAX, false); + txt_move_to(text, lineno - 1, offset, true); + } +} + +/* returns a dummy filename for a textblock so we can tell what file a text block comes from */ +static void bpy_text_filename_get(char *fn, const Main *bmain, size_t fn_len, const Text *text) +{ + BLI_snprintf(fn, fn_len, "%s%c%s", ID_BLEND_PATH(bmain, &text->id), SEP, text->id.name + 2); +} + +/* Very annoying! Undo #_PyModule_Clear(), see T23871. */ +#define PYMODULE_CLEAR_WORKAROUND + +#ifdef PYMODULE_CLEAR_WORKAROUND +/* bad!, we should never do this, but currently only safe way I could find to keep namespace. + * from being cleared. - campbell */ +typedef struct { + PyObject_HEAD PyObject *md_dict; + /* omit other values, we only want the dict. */ +} PyModuleObject; +#endif + +static bool python_script_exec( + bContext *C, const char *fn, struct Text *text, struct ReportList *reports, const bool do_jump) +{ + Main *bmain_old = CTX_data_main(C); + PyObject *main_mod = NULL; + PyObject *py_dict = NULL, *py_result = NULL; + PyGILState_STATE gilstate; + + BLI_assert(fn || text); + + if (fn == NULL && text == NULL) { + return 0; + } + + bpy_context_set(C, &gilstate); + + PyC_MainModule_Backup(&main_mod); + + if (text) { + char fn_dummy[FILE_MAXDIR]; + bpy_text_filename_get(fn_dummy, bmain_old, sizeof(fn_dummy), text); + + if (text->compiled == NULL) { /* if it wasn't already compiled, do it now */ + char *buf; + PyObject *fn_dummy_py; + + fn_dummy_py = PyC_UnicodeFromByte(fn_dummy); + + buf = txt_to_buf(text, NULL); + text->compiled = Py_CompileStringObject(buf, fn_dummy_py, Py_file_input, NULL, -1); + MEM_freeN(buf); + + Py_DECREF(fn_dummy_py); + + if (PyErr_Occurred()) { + if (do_jump) { + python_script_error_jump_text(text); + } + BPY_text_free_code(text); + } + } + + if (text->compiled) { + py_dict = PyC_DefaultNameSpace(fn_dummy); + py_result = PyEval_EvalCode(text->compiled, py_dict, py_dict); + } + } + else { + FILE *fp = BLI_fopen(fn, "r"); + + if (fp) { + py_dict = PyC_DefaultNameSpace(fn); + +#ifdef _WIN32 + /* Previously we used PyRun_File to run directly the code on a FILE + * object, but as written in the Python/C API Ref Manual, chapter 2, + * 'FILE structs for different C libraries can be different and + * incompatible'. + * So now we load the script file data to a buffer. + * + * Note on use of 'globals()', it's important not copy the dictionary because + * tools may inspect 'sys.modules["__main__"]' for variables defined in the code + * where using a copy of 'globals()' causes code execution + * to leave the main namespace untouched. see: T51444 + * + * This leaves us with the problem of variables being included, + * currently this is worked around using 'dict.__del__' it's ugly but works. + */ + { + const char *pystring = + "with open(__file__, 'rb') as f:" + "exec(compile(f.read(), __file__, 'exec'), globals().__delitem__('f') or globals())"; + + fclose(fp); + + py_result = PyRun_String(pystring, Py_file_input, py_dict, py_dict); + } +#else + py_result = PyRun_File(fp, fn, Py_file_input, py_dict, py_dict); + fclose(fp); +#endif + } + else { + PyErr_Format( + PyExc_IOError, "Python file \"%s\" could not be opened: %s", fn, strerror(errno)); + py_result = NULL; + } + } + + if (!py_result) { + if (text) { + if (do_jump) { + /* ensure text is valid before use, the script may have freed its self */ + Main *bmain_new = CTX_data_main(C); + if ((bmain_old == bmain_new) && (BLI_findindex(&bmain_new->texts, text) != -1)) { + python_script_error_jump_text(text); + } + } + } + BPy_errors_to_report(reports); + } + else { + Py_DECREF(py_result); + } + + if (py_dict) { +#ifdef PYMODULE_CLEAR_WORKAROUND + PyModuleObject *mmod = (PyModuleObject *)PyDict_GetItem(PyImport_GetModuleDict(), + bpy_intern_str___main__); + PyObject *dict_back = mmod->md_dict; + /* freeing the module will clear the namespace, + * gives problems running classes defined in this namespace being used later. */ + mmod->md_dict = NULL; + Py_DECREF(dict_back); +#endif + +#undef PYMODULE_CLEAR_WORKAROUND + } + + PyC_MainModule_Restore(main_mod); + + bpy_context_clear(C, &gilstate); + + return (py_result != NULL); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Run Text / Filename / String + * \{ */ + +/* Can run a file or text block */ +bool BPY_run_filepath(bContext *C, const char *filepath, struct ReportList *reports) +{ + return python_script_exec(C, filepath, NULL, reports, false); +} + +bool BPY_run_text(bContext *C, struct Text *text, struct ReportList *reports, const bool do_jump) +{ + return python_script_exec(C, NULL, text, reports, do_jump); +} + +/** + * \param mode: Passed to #PyRun_String, matches Python's `compile` functions mode argument. + * #Py_eval_input for `eval`, #Py_file_input for `exec`. + */ +static bool bpy_run_string_impl(bContext *C, + const char *imports[], + const char *expr, + const int mode) +{ + BLI_assert(expr); + PyGILState_STATE gilstate; + PyObject *main_mod = NULL; + PyObject *py_dict, *retval; + bool ok = true; + + if (expr[0] == '\0') { + return ok; + } + + bpy_context_set(C, &gilstate); + + PyC_MainModule_Backup(&main_mod); + + py_dict = PyC_DefaultNameSpace("<blender string>"); + + if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) { + Py_DECREF(py_dict); + retval = NULL; + } + else { + retval = PyRun_String(expr, mode, py_dict, py_dict); + } + + if (retval == NULL) { + ok = false; + BPy_errors_to_report(CTX_wm_reports(C)); + } + else { + Py_DECREF(retval); + } + + PyC_MainModule_Restore(main_mod); + + bpy_context_clear(C, &gilstate); + + return ok; +} + +/** + * Run an expression, matches: `exec(compile(..., "eval"))` + */ +bool BPY_run_string_eval(bContext *C, const char *imports[], const char *expr) +{ + return bpy_run_string_impl(C, imports, expr, Py_eval_input); +} + +/** + * Run an entire script, matches: `exec(compile(..., "exec"))` + */ +bool BPY_run_string_exec(bContext *C, const char *imports[], const char *expr) +{ + return bpy_run_string_impl(C, imports, expr, Py_file_input); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Run Python & Evaluate Utilities + * + * Return values as plain C types, useful to run Python scripts + * in code that doesn't deal with Python data-types. + * \{ */ + +/** + * \return success + */ +bool BPY_run_string_as_number(bContext *C, + const char *imports[], + const char *expr, + const char *report_prefix, + double *r_value) +{ + PyGILState_STATE gilstate; + bool ok = true; + + if (!r_value || !expr) { + return -1; + } + + if (expr[0] == '\0') { + *r_value = 0.0; + return ok; + } + + bpy_context_set(C, &gilstate); + + ok = PyC_RunString_AsNumber(imports, expr, "<expr as number>", r_value); + + if (ok == false) { + if (report_prefix != NULL) { + BPy_errors_to_report_ex(CTX_wm_reports(C), report_prefix, false, false); + } + else { + PyErr_Clear(); + } + } + + bpy_context_clear(C, &gilstate); + + return ok; +} + +/** + * \return success + */ +bool BPY_run_string_as_string_and_size(bContext *C, + const char *imports[], + const char *expr, + const char *report_prefix, + char **r_value, + size_t *r_value_size) +{ + BLI_assert(r_value && expr); + PyGILState_STATE gilstate; + bool ok = true; + + if (expr[0] == '\0') { + *r_value = NULL; + return ok; + } + + bpy_context_set(C, &gilstate); + + ok = PyC_RunString_AsStringAndSize(imports, expr, "<expr as str>", r_value, r_value_size); + + if (ok == false) { + if (report_prefix != NULL) { + BPy_errors_to_report_ex(CTX_wm_reports(C), false, false, report_prefix); + } + else { + PyErr_Clear(); + } + } + + bpy_context_clear(C, &gilstate); + + return ok; +} + +bool BPY_run_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_run_string_as_string_and_size( + C, imports, expr, report_prefix, r_value, &value_dummy_size); +} + +/** + * Support both int and pointers. + * + * \return success + */ +bool BPY_run_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; + bool ok = true; + + if (expr[0] == '\0') { + *r_value = 0; + return ok; + } + + bpy_context_set(C, &gilstate); + + ok = PyC_RunString_AsIntPtr(imports, expr, "<expr as intptr>", r_value); + + if (ok == false) { + if (report_prefix != NULL) { + BPy_errors_to_report_ex(CTX_wm_reports(C), report_prefix, false, false); + } + else { + PyErr_Clear(); + } + } + + bpy_context_clear(C, &gilstate); + + return ok; +} + +/** \} */ diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c index 9d76f07e4fb..16ea05771d0 100644 --- a/source/blender/python/mathutils/mathutils_bvhtree.c +++ b/source/blender/python/mathutils/mathutils_bvhtree.c @@ -1053,7 +1053,7 @@ static Mesh *bvh_get_mesh(const char *funcname, } *r_free_mesh = true; - return mesh_create_eval_final_render(depsgraph, scene, ob, &data_masks); + return mesh_create_eval_final(depsgraph, scene, ob, &data_masks); } if (ob_eval != NULL) { if (use_cage) { diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 0790d40d56c..440c54f5eeb 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -519,9 +519,8 @@ float RE_engine_get_camera_shift_x(RenderEngine *engine, Object *camera, bool us if (use_spherical_stereo || re == NULL) { return BKE_camera_multiview_shift_x(NULL, camera, NULL); } - else { - return BKE_camera_multiview_shift_x(&re->r, camera, re->viewname); - } + + return BKE_camera_multiview_shift_x(&re->r, camera, re->viewname); } void RE_engine_get_camera_model_matrix(RenderEngine *engine, @@ -610,13 +609,13 @@ static void engine_depsgraph_init(RenderEngine *engine, ViewLayer *view_layer) if (engine->re->r.scemode & R_BUTS_PREVIEW) { Depsgraph *depsgraph = engine->depsgraph; - DEG_graph_relations_update(depsgraph, bmain, scene, view_layer); - DEG_evaluate_on_framechange(bmain, depsgraph, CFRA); + DEG_graph_relations_update(depsgraph); + DEG_evaluate_on_framechange(depsgraph, CFRA); DEG_ids_check_recalc(bmain, depsgraph, scene, view_layer, true); DEG_ids_clear_recalc(bmain, depsgraph); } else { - BKE_scene_graph_update_for_newframe(engine->depsgraph, bmain); + BKE_scene_graph_update_for_newframe(engine->depsgraph); } } @@ -638,7 +637,7 @@ void RE_engine_frame_set(RenderEngine *engine, int frame, float subframe) CLAMP(cfra, MINAFRAME, MAXFRAME); BKE_scene_frame_set(re->scene, cfra); - BKE_scene_graph_update_for_newframe(engine->depsgraph, re->main); + BKE_scene_graph_update_for_newframe(engine->depsgraph); BKE_scene_camera_switch_update(re->scene); } diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 3236026c69f..86c9c64098b 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1964,7 +1964,7 @@ void RE_SetReports(Render *re, ReportList *reports) static void render_update_depsgraph(Render *re) { Scene *scene = re->scene; - DEG_evaluate_on_framechange(re->main, re->pipeline_depsgraph, CFRA); + DEG_evaluate_on_framechange(re->pipeline_depsgraph, CFRA); BKE_scene_update_sound(re->pipeline_depsgraph, re->main); } @@ -1977,7 +1977,7 @@ static void render_init_depsgraph(Render *re) DEG_debug_name_set(re->pipeline_depsgraph, "RENDER PIPELINE"); /* Make sure there is a correct evaluated scene pointer. */ - DEG_graph_build_for_render_pipeline(re->pipeline_depsgraph, re->main, scene, view_layer); + DEG_graph_build_for_render_pipeline(re->pipeline_depsgraph); /* Update immediately so we have proper evaluated scene. */ render_update_depsgraph(re); diff --git a/source/blender/simulation/CMakeLists.txt b/source/blender/simulation/CMakeLists.txt index cbc6ee65303..e47586d55cc 100644 --- a/source/blender/simulation/CMakeLists.txt +++ b/source/blender/simulation/CMakeLists.txt @@ -45,8 +45,8 @@ set(SRC 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_solver_influences.cc intern/simulation_update.cc intern/ConstrainedConjugateGradient.h @@ -56,8 +56,8 @@ set(SRC intern/particle_function.hh intern/particle_mesh_emitter.hh intern/simulation_collect_influences.hh - intern/simulation_solver_influences.hh intern/simulation_solver.hh + intern/simulation_solver_influences.hh intern/time_interval.hh SIM_mass_spring.h diff --git a/source/blender/windowmanager/gizmo/WM_gizmo_types.h b/source/blender/windowmanager/gizmo/WM_gizmo_types.h index bddf54b846f..8e2b5e04e42 100644 --- a/source/blender/windowmanager/gizmo/WM_gizmo_types.h +++ b/source/blender/windowmanager/gizmo/WM_gizmo_types.h @@ -244,7 +244,7 @@ struct wmGizmo { int drag_part; /** Distance to bias this gizmo above others when picking - * (in worldspace, scaled by the gizmo scale - when used). */ + * (in world-space, scaled by the gizmo scale - when used). */ float select_bias; /** diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index 43c08a2b980..5d0520bb674 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -66,6 +66,7 @@ #ifdef WITH_PYTHON # include "BPY_extern.h" +# include "BPY_extern_run.h" #endif /* ****************************************************** */ @@ -270,7 +271,7 @@ void WM_keyconfig_reload(bContext *C) { if (CTX_py_init_get(C) && !G.background) { #ifdef WITH_PYTHON - BPY_execute_string(C, (const char *[]){"bpy", NULL}, "bpy.utils.keyconfig_init()"); + BPY_run_string_eval(C, (const char *[]){"bpy", NULL}, "bpy.utils.keyconfig_init()"); #endif } } diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c index ec18a401fa4..37ed9f89bc7 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.c +++ b/source/blender/windowmanager/intern/wm_dragdrop.c @@ -401,7 +401,7 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect) } /* XXX todo, multiline drag draws... but maybe not, more types mixed wont work well */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); for (drag = wm->drags.first; drag; drag = drag->next) { const uchar text_col[] = {255, 255, 255, 255}; int iconsize = UI_DPI_ICON_SIZE; @@ -495,5 +495,5 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect) } } } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index b8cb5432a49..6f3fbf77987 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -307,7 +307,9 @@ static void wm_region_test_xr_do_draw(const wmWindowManager *wm, static bool wm_region_use_viewport_by_type(short space_type, short region_type) { - return (ELEM(space_type, SPACE_VIEW3D, SPACE_IMAGE) && region_type == RGN_TYPE_WINDOW); + return (ELEM(space_type, SPACE_VIEW3D, SPACE_IMAGE, SPACE_NODE) && + region_type == RGN_TYPE_WINDOW) || + ((space_type == SPACE_SEQ) && region_type == RGN_TYPE_PREVIEW); } bool WM_region_use_viewport(ScrArea *area, ARegion *region) @@ -574,9 +576,8 @@ void wm_draw_region_blend(ARegion *region, int view, bool blend) 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. */ - GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + /* Regions drawn offscreen have premultiplied alpha. */ + GPU_blend(GPU_BLEND_ALPHA_PREMULT); } /* setup actual texture */ @@ -601,8 +602,7 @@ void wm_draw_region_blend(ARegion *region, int view, bool blend) GPU_texture_unbind(texture); if (blend) { - GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index bea4faa779a..c363fdcc9d4 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -352,7 +352,7 @@ void wm_event_do_depsgraph(bContext *C, bool is_after_open_file) */ Depsgraph *depsgraph = BKE_scene_get_depsgraph(bmain, scene, view_layer, true); if (is_after_open_file) { - DEG_graph_relations_update(depsgraph, bmain, scene, view_layer); + DEG_graph_relations_update(depsgraph); DEG_graph_on_visible_update(bmain, depsgraph, true); } DEG_make_active(depsgraph); @@ -1363,8 +1363,7 @@ static int wm_operator_invoke(bContext *C, ScrArea *area = CTX_wm_area(C); /* Wrap only in X for header. */ - if (region && - ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER, RGN_TYPE_FOOTER)) { + if (region && RGN_TYPE_IS_HEADER_ANY(region->regiontype)) { wrap = WM_CURSOR_WRAP_X; } diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index ef4f2b4a62a..62d9c099cd5 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -121,7 +121,8 @@ #include "RE_engine.h" #ifdef WITH_PYTHON -# include "BPY_extern.h" +# include "BPY_extern_python.h" +# include "BPY_extern_run.h" #endif #include "DEG_depsgraph.h" @@ -579,14 +580,14 @@ static void wm_file_read_post(bContext *C, if (use_userdef || reset_app_template) { /* Only run when we have a template path found. */ if (BKE_appdir_app_template_any()) { - BPY_execute_string( + BPY_run_string_eval( C, (const char *[]){"bl_app_template_utils", NULL}, "bl_app_template_utils.reset()"); reset_all = true; } } if (reset_all) { /* sync addons, these may have changed from the defaults */ - BPY_execute_string(C, (const char *[]){"addon_utils", NULL}, "addon_utils.reset_all()"); + BPY_run_string_eval(C, (const char *[]){"addon_utils", NULL}, "addon_utils.reset_all()"); } if (use_data) { BPY_python_reset(C); @@ -923,7 +924,7 @@ void wm_homefile_read(bContext *C, * * Note that this fits into 'wm_file_read_pre' function but gets messy * since we need to know if 'reset_app_template' is true. */ - BPY_execute_string(C, (const char *[]){"addon_utils", NULL}, "addon_utils.disable_all()"); + BPY_run_string_eval(C, (const char *[]){"addon_utils", NULL}, "addon_utils.disable_all()"); } #endif /* WITH_PYTHON */ } diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index 55233168ab2..67733ffc673 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -236,7 +236,7 @@ static void wm_gesture_draw_rect(wmGesture *gt) uint shdr_pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4f(1.0f, 1.0f, 1.0f, 0.05f); @@ -245,7 +245,7 @@ static void wm_gesture_draw_rect(wmGesture *gt) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -274,7 +274,7 @@ static void wm_gesture_draw_circle(wmGesture *gt) { rcti *rect = (rcti *)gt->customdata; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); const uint shdr_pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -286,7 +286,7 @@ static void wm_gesture_draw_circle(wmGesture *gt) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); @@ -353,9 +353,7 @@ static void draw_filled_lasso(wmGesture *gt) draw_filled_lasso_px_cb, &lasso_fill_data); - /* Additive Blending */ - GPU_blend(true); - GPU_blend_set_func(GPU_ONE, GPU_ONE); + GPU_blend(GPU_BLEND_ADDITIVE); IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR); GPU_shader_bind(state.shader); @@ -369,8 +367,7 @@ static void draw_filled_lasso(wmGesture *gt) MEM_freeN(pixel_buf); - GPU_blend(false); - GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_NONE); } MEM_freeN(mcoords); diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 03e84f098c0..e8f663b0c4a 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -85,6 +85,7 @@ #ifdef WITH_PYTHON # include "BPY_extern.h" +# include "BPY_extern_python.h" #endif #include "GHOST_C-api.h" @@ -349,8 +350,6 @@ void WM_init(bContext *C, int argc, const char **argv) BKE_material_copybuf_clear(); ED_render_clear_mtex_copybuf(); - // GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - wm_history_file_read(); /* allow a path of "", this is what happens when making a new file */ diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 1964813fff9..9b25d660ff6 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2393,7 +2393,7 @@ static void radial_control_paint_cursor(bContext *UNUSED(C), int x, int y, void } GPU_matrix_translate_2f((float)x, (float)y); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); /* apply zoom if available */ @@ -2472,7 +2472,7 @@ static void radial_control_paint_cursor(bContext *UNUSED(C), int x, int y, void BLF_position(fontid, -0.5f * strwidth, -0.5f * strheight, 0.0f); BLF_draw(fontid, str, strdrawlen); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); } @@ -3151,7 +3151,6 @@ static const EnumPropertyItem redraw_timer_type_items[] = { }; static void redraw_timer_step(bContext *C, - Main *bmain, Scene *scene, struct Depsgraph *depsgraph, wmWindow *win, @@ -3202,7 +3201,7 @@ static void redraw_timer_step(bContext *C, } else if (type == eRTAnimationStep) { scene->r.cfra += (cfra == scene->r.cfra) ? 1 : -1; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); } else if (type == eRTAnimationPlay) { /* play anim, return on same frame as started with */ @@ -3215,7 +3214,7 @@ static void redraw_timer_step(bContext *C, scene->r.cfra = scene->r.sfra; } - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); redraw_timer_window_swap(C); } } @@ -3231,7 +3230,6 @@ static void redraw_timer_step(bContext *C, static int redraw_timer_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); wmWindow *win = CTX_wm_window(C); ScrArea *area = CTX_wm_area(C); @@ -3256,7 +3254,7 @@ static int redraw_timer_exec(bContext *C, wmOperator *op) wm_window_make_drawable(wm, win); for (a = 0; a < iter; a++) { - redraw_timer_step(C, bmain, scene, depsgraph, win, area, region, type, cfra); + redraw_timer_step(C, scene, depsgraph, win, area, region, type, cfra); iter_steps += 1; if (time_limit != 0.0) { diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index a0a21fadbbb..9d472ed4597 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -315,9 +315,7 @@ static void playanim_toscreen( /* checkerboard for case alpha */ if (ibuf->planes == 32) { - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); imm_draw_box_checker_2d_ex(offs_x, offs_y, @@ -342,7 +340,7 @@ static void playanim_toscreen( ((ps->draw_flip[1] ? -1.0f : 1.0f)) * (ps->zoom / (float)ps->win_y), NULL); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); pupdate_time(); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index a8a1817be5e..ac00fc36a89 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -658,9 +658,6 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm, wm_window_swap_buffers(win); // GHOST_SetWindowState(ghostwin, GHOST_kWindowStateModified); - - /* standard state vars for window */ - GPU_state_init(); } else { wm_window_set_drawable(wm, prev_windrawable, false); diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c index b8e99899821..164e670c444 100644 --- a/source/creator/creator_args.c +++ b/source/creator/creator_args.c @@ -61,7 +61,8 @@ # endif # ifdef WITH_PYTHON -# include "BPY_extern.h" +# include "BPY_extern_python.h" +# include "BPY_extern_run.h" # endif # include "RE_engine.h" @@ -1779,7 +1780,7 @@ static int arg_handle_python_file_run(int argc, const char **argv, void *data) BLI_path_abs_from_cwd(filename, sizeof(filename)); bool ok; - BPY_CTX_SETUP(ok = BPY_execute_filepath(C, filename, NULL)); + BPY_CTX_SETUP(ok = BPY_run_filepath(C, filename, NULL)); if (!ok && app_state.exit_code_on_error.python) { printf("\nError: script failed, file: '%s', exiting.\n", argv[1]); BPY_python_end(); @@ -1814,7 +1815,7 @@ static int arg_handle_python_text_run(int argc, const char **argv, void *data) bool ok; if (text) { - BPY_CTX_SETUP(ok = BPY_execute_text(C, text, NULL, false)); + BPY_CTX_SETUP(ok = BPY_run_text(C, text, NULL, false)); } else { printf("\nError: text block not found %s.\n", argv[1]); @@ -1851,7 +1852,7 @@ static int arg_handle_python_expr_run(int argc, const char **argv, void *data) /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */ if (argc > 1) { bool ok; - BPY_CTX_SETUP(ok = BPY_execute_string_ex(C, NULL, argv[1], false)); + BPY_CTX_SETUP(ok = BPY_run_string_exec(C, NULL, argv[1])); if (!ok && app_state.exit_code_on_error.python) { printf("\nError: script failed, expr: '%s', exiting.\n", argv[1]); BPY_python_end(); @@ -1878,7 +1879,7 @@ static int arg_handle_python_console_run(int UNUSED(argc), const char **argv, vo # ifdef WITH_PYTHON bContext *C = data; - BPY_CTX_SETUP(BPY_execute_string(C, (const char *[]){"code", NULL}, "code.interact()")); + BPY_CTX_SETUP(BPY_run_string_eval(C, (const char *[]){"code", NULL}, "code.interact()")); return 0; # else @@ -1951,7 +1952,7 @@ static int arg_handle_addons_set(int argc, const char **argv, void *data) BLI_snprintf(str, slen, script_str, argv[1]); BLI_assert(strlen(str) + 1 == slen); - BPY_CTX_SETUP(BPY_execute_string_ex(C, NULL, str, false)); + BPY_CTX_SETUP(BPY_run_string_exec(C, NULL, str)); free(str); # else UNUSED_VARS(argv, data); diff --git a/source/creator/creator_signals.c b/source/creator/creator_signals.c index ad0b7b2547d..29e12a96fe1 100644 --- a/source/creator/creator_signals.c +++ b/source/creator/creator_signals.c @@ -60,7 +60,7 @@ # include <signal.h> # ifdef WITH_PYTHON -# include "BPY_extern.h" /* BPY_python_backtrace */ +# include "BPY_extern_python.h" /* BPY_python_backtrace */ # endif # include "creator_intern.h" /* own include */ |